diff --git a/headers/private/app/LaunchDaemonDefs.h b/headers/private/app/LaunchDaemonDefs.h index e3e1a5e515..78980a819c 100644 --- a/headers/private/app/LaunchDaemonDefs.h +++ b/headers/private/app/LaunchDaemonDefs.h @@ -1,5 +1,5 @@ /* - * Copyright 2015, Haiku, Inc. All Rights Reserved. + * Copyright 2015-2016, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -27,6 +27,7 @@ enum { B_GET_LAUNCH_DATA = 'lnda', B_LAUNCH_TARGET = 'lntg', B_LAUNCH_JOB = 'lnjo', + B_ENABLE_LAUNCH_JOB = 'lnje', B_STOP_LAUNCH_JOB = 'lnsj', B_LAUNCH_SESSION = 'lnse', B_REGISTER_SESSION_DAEMON = 'lnrs', diff --git a/headers/private/app/LaunchRoster.h b/headers/private/app/LaunchRoster.h index 46332de246..9b2459518b 100644 --- a/headers/private/app/LaunchRoster.h +++ b/headers/private/app/LaunchRoster.h @@ -1,5 +1,5 @@ /* - * Copyright 2015 Haiku, Inc. All rights reserved. + * Copyright 2015-2016 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _LAUNCH_ROSTER_H @@ -36,6 +36,7 @@ public: status_t Start(const char* name); status_t Stop(const char* name, bool force = false); + status_t SetEnabled(const char* name, bool enabled); status_t StartSession(const char* login); diff --git a/src/bin/launch_roster.cpp b/src/bin/launch_roster.cpp index f66a6f1e6b..9a04bfc4dd 100644 --- a/src/bin/launch_roster.cpp +++ b/src/bin/launch_roster.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2015, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2015-2016, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -113,6 +113,19 @@ stop_job(const char* name) } +static void +enable_job(const char* name, bool enable) +{ + BLaunchRoster roster; + status_t status = roster.SetEnabled(name, enable); + if (status != B_OK) { + fprintf(stderr, "%s: %s job \"%s\" failed: %s\n", kProgramName, + enable ? "Enabling" : "Disabling", name, strerror(status)); + exit(EXIT_FAILURE); + } +} + + static void usage(int status) { @@ -160,10 +173,11 @@ main(int argc, char** argv) list_jobs(verbose); } else if (strcmp(command, "list-targets") == 0) { list_targets(verbose); + } else if (argc == optind + 1) { + // For convenience (the "info" command can be omitted) + get_info(command); } else { // All commands that need a name following - if (argc == optind + 1) - usage(1); const char* name = argv[argc - 1]; @@ -173,6 +187,10 @@ main(int argc, char** argv) start_job(name); } else if (strcmp(command, "stop") == 0) { stop_job(name); + } else if (strcmp(command, "enable") == 0) { + enable_job(name, true); + } else if (strcmp(command, "disable") == 0) { + enable_job(name, false); } else { fprintf(stderr, "%s: Unknown command \"%s\".\n", kProgramName, command); diff --git a/src/kits/app/LaunchRoster.cpp b/src/kits/app/LaunchRoster.cpp index b990d0ed08..4f887cdfe8 100644 --- a/src/kits/app/LaunchRoster.cpp +++ b/src/kits/app/LaunchRoster.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2015 Haiku, Inc. All rights reserved. + * Copyright 2015-2016 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -202,6 +202,25 @@ BLaunchRoster::Stop(const char* name, bool force) } +status_t +BLaunchRoster::SetEnabled(const char* name, bool enable) +{ + if (name == NULL) + return B_BAD_VALUE; + + BMessage request(B_ENABLE_LAUNCH_JOB); + status_t status = request.AddInt32("user", getuid()); + if (status == B_OK) + status = request.AddString("name", name); + if (status == B_OK) + status = request.AddBool("enable", enable); + if (status != B_OK) + return status; + + return _SendRequest(request); +} + + status_t BLaunchRoster::StartSession(const char* login) { diff --git a/src/servers/launch/LaunchDaemon.cpp b/src/servers/launch/LaunchDaemon.cpp index b8e029f065..6e9cc8d411 100644 --- a/src/servers/launch/LaunchDaemon.cpp +++ b/src/servers/launch/LaunchDaemon.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2015, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2015-2016, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. */ @@ -154,6 +154,7 @@ private: void _HandleGetLaunchData(BMessage* message); void _HandleLaunchTarget(BMessage* message); void _HandleLaunchJob(BMessage* message); + void _HandleEnableLaunchJob(BMessage* message); void _HandleStopLaunchJob(BMessage* message); void _HandleLaunchSession(BMessage* message); void _HandleRegisterSessionDaemon(BMessage* message); @@ -555,6 +556,9 @@ LaunchDaemon::MessageReceived(BMessage* message) case B_LAUNCH_JOB: _HandleLaunchJob(message); break; + case B_ENABLE_LAUNCH_JOB: + _HandleEnableLaunchJob(message); + break; case B_STOP_LAUNCH_JOB: _HandleStopLaunchJob(message); break; @@ -765,6 +769,37 @@ LaunchDaemon::_HandleLaunchJob(BMessage* message) } +void +LaunchDaemon::_HandleEnableLaunchJob(BMessage* message) +{ + uid_t user = _GetUserID(message); + if (user < 0) + return; + + const char* name = message->GetString("name"); + bool enable = message->GetBool("enable"); + + Job* job = FindJob(name); + if (job == NULL) { + Session* session = FindSession(user); + if (session != NULL) { + // Forward request to user launch_daemon + if (session->Daemon().SendMessage(message) == B_OK) + return; + } + + BMessage reply(B_NAME_NOT_FOUND); + message->SendReply(&reply); + return; + } + + job->SetEnabled(enable); + + BMessage reply((uint32)B_OK); + message->SendReply(&reply); +} + + void LaunchDaemon::_HandleStopLaunchJob(BMessage* message) {