/* * Copyright 2015-2017 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de */ #include #include #include #include #include #include #include #include using namespace BPrivate; BLaunchRoster::Private::Private(BLaunchRoster* roster) : fRoster(roster) { } BLaunchRoster::Private::Private(BLaunchRoster& roster) : fRoster(&roster) { } status_t BLaunchRoster::Private::RegisterSessionDaemon(const BMessenger& daemon) { BMessage request(B_REGISTER_SESSION_DAEMON); status_t status = request.AddInt32("user", getuid()); if (status == B_OK) status = request.AddMessenger("daemon", daemon); if (status != B_OK) return status; // send the request BMessage result; status = fRoster->fMessenger.SendMessage(&request, &result); // evaluate the reply if (status == B_OK) status = result.what; return status; } // #pragma mark - BLaunchRoster::BLaunchRoster() { _InitMessenger(); } BLaunchRoster::~BLaunchRoster() { } status_t BLaunchRoster::InitCheck() const { return fMessenger.Team() >= 0 ? B_OK : B_ERROR; } status_t BLaunchRoster::GetData(BMessage& data) { if (be_app == NULL) return B_BAD_VALUE; return GetData(be_app->Signature(), data); } status_t BLaunchRoster::GetData(const char* signature, BMessage& data) { if (signature == NULL || signature[0] == '\0') return B_BAD_VALUE; BMessage request(B_GET_LAUNCH_DATA); status_t status = request.AddString("name", signature); if (status == B_OK) status = request.AddInt32("user", getuid()); if (status != B_OK) return status; return _SendRequest(request, data); } port_id BLaunchRoster::GetPort(const char* name) { if (be_app == NULL) return B_BAD_VALUE; return GetPort(be_app->Signature(), name); } port_id BLaunchRoster::GetPort(const char* signature, const char* name) { BMessage data; status_t status = GetData(signature, data); if (status == B_OK) { BString fieldName; if (name != NULL) fieldName << name << "_"; fieldName << "port"; port_id port = data.GetInt32(fieldName.String(), B_NAME_NOT_FOUND); if (port >= 0) return port; } return -1; } status_t BLaunchRoster::Target(const char* name, const BMessage& data, const char* baseName) { return Target(name, &data, baseName); } status_t BLaunchRoster::Target(const char* name, const BMessage* data, const char* baseName) { if (name == NULL) return B_BAD_VALUE; BMessage request(B_LAUNCH_TARGET); status_t status = request.AddInt32("user", getuid()); if (status == B_OK) status = request.AddString("target", name); if (status == B_OK && data != NULL && !data->IsEmpty()) status = request.AddMessage("data", data); if (status == B_OK && baseName != NULL) status = request.AddString("base target", baseName); if (status != B_OK) return status; return _SendRequest(request); } status_t BLaunchRoster::StopTarget(const char* name, bool force) { if (name == NULL) return B_BAD_VALUE; BMessage request(B_STOP_LAUNCH_TARGET); status_t status = request.AddInt32("user", getuid()); if (status == B_OK) status = request.AddString("target", name); if (status == B_OK) status = request.AddBool("force", force); if (status != B_OK) return status; return _SendRequest(request); } status_t BLaunchRoster::Start(const char* name) { if (name == NULL) return B_BAD_VALUE; BMessage request(B_LAUNCH_JOB); status_t status = request.AddInt32("user", getuid()); if (status == B_OK) status = request.AddString("name", name); if (status != B_OK) return status; return _SendRequest(request); } status_t BLaunchRoster::Stop(const char* name, bool force) { if (name == NULL) return B_BAD_VALUE; BMessage request(B_STOP_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("force", force); if (status != B_OK) return status; return _SendRequest(request); } 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) { if (login == NULL) return B_BAD_VALUE; BMessage request(B_LAUNCH_SESSION); status_t status = request.AddInt32("user", getuid()); if (status == B_OK) status = request.AddString("login", login); if (status != B_OK) return status; return _SendRequest(request); } status_t BLaunchRoster::RegisterEvent(const BMessenger& source, const char* name, uint32 flags) { return _UpdateEvent(B_REGISTER_LAUNCH_EVENT, source, name, flags); } status_t BLaunchRoster::UnregisterEvent(const BMessenger& source, const char* name) { return _UpdateEvent(B_UNREGISTER_LAUNCH_EVENT, source, name); } status_t BLaunchRoster::NotifyEvent(const BMessenger& source, const char* name) { return _UpdateEvent(B_NOTIFY_LAUNCH_EVENT, source, name); } status_t BLaunchRoster::ResetStickyEvent(const BMessenger& source, const char* name) { return _UpdateEvent(B_RESET_STICKY_LAUNCH_EVENT, source, name); } status_t BLaunchRoster::GetTargets(BStringList& targets) { BMessage request(B_GET_LAUNCH_TARGETS); status_t status = request.AddInt32("user", getuid()); if (status != B_OK) return status; // send the request BMessage result; status = _SendRequest(request, result); if (status == B_OK) status = result.FindStrings("target", &targets); return status; } status_t BLaunchRoster::GetTargetInfo(const char* name, BMessage& info) { return _GetInfo(B_GET_LAUNCH_TARGET_INFO, name, info); } status_t BLaunchRoster::GetJobs(const char* target, BStringList& jobs) { BMessage request(B_GET_LAUNCH_JOBS); status_t status = request.AddInt32("user", getuid()); if (status == B_OK && target != NULL) status = request.AddString("target", target); if (status != B_OK) return status; // send the request BMessage result; status = _SendRequest(request, result); if (status == B_OK) status = result.FindStrings("job", &jobs); return status; } status_t BLaunchRoster::GetJobInfo(const char* name, BMessage& info) { return _GetInfo(B_GET_LAUNCH_JOB_INFO, name, info); } status_t BLaunchRoster::GetLog(BMessage& info) { return _GetLog(NULL, info); } status_t BLaunchRoster::GetLog(const BMessage& filter, BMessage& info) { return _GetLog(&filter, info); } void BLaunchRoster::_InitMessenger() { #ifdef TEST_MODE port_id daemonPort = find_port(B_LAUNCH_DAEMON_PORT_NAME); #else // find the launch_daemon port port_id daemonPort = BPrivate::get_launch_daemon_port(); #endif port_info info; if (daemonPort >= 0 && get_port_info(daemonPort, &info) == B_OK) { BMessenger::Private(fMessenger).SetTo(info.team, daemonPort, B_PREFERRED_TOKEN); } } status_t BLaunchRoster::_SendRequest(BMessage& request) { BMessage result; return _SendRequest(request, result); } status_t BLaunchRoster::_SendRequest(BMessage& request, BMessage& result) { // Send the request, and evaluate the reply status_t status = fMessenger.SendMessage(&request, &result); if (status == B_OK) status = result.what; return status; } status_t BLaunchRoster::_UpdateEvent(uint32 what, const BMessenger& source, const char* name, uint32 flags) { if (be_app == NULL || name == NULL || name[0] == '\0') return B_BAD_VALUE; BMessage request(what); status_t status = request.AddInt32("user", getuid()); if (status == B_OK) status = request.AddMessenger("source", source); if (status == B_OK) status = request.AddString("owner", be_app->Signature()); if (status == B_OK) status = request.AddString("name", name); if (status == B_OK && flags != 0) status = request.AddUInt32("flags", flags); if (status != B_OK) return status; return _SendRequest(request); } status_t BLaunchRoster::_GetInfo(uint32 what, const char* name, BMessage& info) { if (name == NULL || name[0] == '\0') return B_BAD_VALUE; BMessage request(what); status_t status = request.AddInt32("user", getuid()); if (status == B_OK) status = request.AddString("name", name); if (status != B_OK) return status; return _SendRequest(request, info); } status_t BLaunchRoster::_GetLog(const BMessage* filter, BMessage& info) { BMessage request(B_GET_LAUNCH_LOG); status_t status = request.AddInt32("user", getuid()); if (status == B_OK && filter != NULL) status = request.AddMessage("filter", filter); if (status != B_OK) return status; return _SendRequest(request, info); }