haiku/src/kits/app/LaunchRoster.cpp

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);
}