445 lines
8.7 KiB
C++
445 lines
8.7 KiB
C++
/*
|
|
* 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 <LaunchRoster.h>
|
|
|
|
#include <Application.h>
|
|
#include <String.h>
|
|
#include <StringList.h>
|
|
|
|
#include <launch.h>
|
|
#include <LaunchDaemonDefs.h>
|
|
#include <LaunchRosterPrivate.h>
|
|
#include <MessengerPrivate.h>
|
|
|
|
|
|
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);
|
|
}
|