xref: /haiku/src/kits/app/LaunchRoster.cpp (revision a77aa747eaf779898d401614a11b98fe58dddf35)
1 /*
2  * Copyright 2015-2017 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  */
8 
9 
10 #include <LaunchRoster.h>
11 
12 #include <Application.h>
13 #include <String.h>
14 #include <StringList.h>
15 
16 #include <launch.h>
17 #include <LaunchDaemonDefs.h>
18 #include <LaunchRosterPrivate.h>
19 #include <MessengerPrivate.h>
20 
21 
22 using namespace BPrivate;
23 
24 
Private(BLaunchRoster * roster)25 BLaunchRoster::Private::Private(BLaunchRoster* roster)
26 	:
27 	fRoster(roster)
28 {
29 }
30 
31 
Private(BLaunchRoster & roster)32 BLaunchRoster::Private::Private(BLaunchRoster& roster)
33 	:
34 	fRoster(&roster)
35 {
36 }
37 
38 
39 status_t
RegisterSessionDaemon(const BMessenger & daemon)40 BLaunchRoster::Private::RegisterSessionDaemon(const BMessenger& daemon)
41 {
42 	BMessage request(B_REGISTER_SESSION_DAEMON);
43 	status_t status = request.AddInt32("user", getuid());
44 	if (status == B_OK)
45 		status = request.AddMessenger("daemon", daemon);
46 	if (status != B_OK)
47 		return status;
48 
49 	// send the request
50 	BMessage result;
51 	status = fRoster->fMessenger.SendMessage(&request, &result);
52 
53 	// evaluate the reply
54 	if (status == B_OK)
55 		status = result.what;
56 
57 	return status;
58 }
59 
60 
61 // #pragma mark -
62 
63 
BLaunchRoster()64 BLaunchRoster::BLaunchRoster()
65 {
66 	_InitMessenger();
67 }
68 
69 
~BLaunchRoster()70 BLaunchRoster::~BLaunchRoster()
71 {
72 }
73 
74 
75 status_t
InitCheck() const76 BLaunchRoster::InitCheck() const
77 {
78 	return fMessenger.Team() >= 0 ? B_OK : B_ERROR;
79 }
80 
81 
82 status_t
GetData(BMessage & data)83 BLaunchRoster::GetData(BMessage& data)
84 {
85 	if (be_app == NULL)
86 		return B_BAD_VALUE;
87 
88 	return GetData(be_app->Signature(), data);
89 }
90 
91 
92 status_t
GetData(const char * signature,BMessage & data)93 BLaunchRoster::GetData(const char* signature, BMessage& data)
94 {
95 	if (signature == NULL || signature[0] == '\0')
96 		return B_BAD_VALUE;
97 
98 	BMessage request(B_GET_LAUNCH_DATA);
99 	status_t status = request.AddString("name", signature);
100 	if (status == B_OK)
101 		status = request.AddInt32("user", getuid());
102 	if (status != B_OK)
103 		return status;
104 
105 	return _SendRequest(request, data);
106 }
107 
108 
109 port_id
GetPort(const char * name)110 BLaunchRoster::GetPort(const char* name)
111 {
112 	if (be_app == NULL)
113 		return B_BAD_VALUE;
114 
115 	return GetPort(be_app->Signature(), name);
116 }
117 
118 
119 port_id
GetPort(const char * signature,const char * name)120 BLaunchRoster::GetPort(const char* signature, const char* name)
121 {
122 	BMessage data;
123 	status_t status = GetData(signature, data);
124 	if (status == B_OK) {
125 		BString fieldName;
126 		if (name != NULL)
127 			fieldName << name << "_";
128 		fieldName << "port";
129 
130 		port_id port = data.GetInt32(fieldName.String(), B_NAME_NOT_FOUND);
131 		if (port >= 0)
132 			return port;
133 	}
134 
135 	return -1;
136 }
137 
138 
139 status_t
Target(const char * name,const BMessage & data,const char * baseName)140 BLaunchRoster::Target(const char* name, const BMessage& data,
141 	const char* baseName)
142 {
143 	return Target(name, &data, baseName);
144 }
145 
146 
147 status_t
Target(const char * name,const BMessage * data,const char * baseName)148 BLaunchRoster::Target(const char* name, const BMessage* data,
149 	const char* baseName)
150 {
151 	if (name == NULL)
152 		return B_BAD_VALUE;
153 
154 	BMessage request(B_LAUNCH_TARGET);
155 	status_t status = request.AddInt32("user", getuid());
156 	if (status == B_OK)
157 		status = request.AddString("target", name);
158 	if (status == B_OK && data != NULL && !data->IsEmpty())
159 		status = request.AddMessage("data", data);
160 	if (status == B_OK && baseName != NULL)
161 		status = request.AddString("base target", baseName);
162 	if (status != B_OK)
163 		return status;
164 
165 	return _SendRequest(request);
166 }
167 
168 
169 status_t
StopTarget(const char * name,bool force)170 BLaunchRoster::StopTarget(const char* name, bool force)
171 {
172 	if (name == NULL)
173 		return B_BAD_VALUE;
174 
175 	BMessage request(B_STOP_LAUNCH_TARGET);
176 	status_t status = request.AddInt32("user", getuid());
177 	if (status == B_OK)
178 		status = request.AddString("target", name);
179 	if (status == B_OK)
180 		status = request.AddBool("force", force);
181 	if (status != B_OK)
182 		return status;
183 
184 	return _SendRequest(request);
185 }
186 
187 
188 status_t
Start(const char * name)189 BLaunchRoster::Start(const char* name)
190 {
191 	if (name == NULL)
192 		return B_BAD_VALUE;
193 
194 	BMessage request(B_LAUNCH_JOB);
195 	status_t status = request.AddInt32("user", getuid());
196 	if (status == B_OK)
197 		status = request.AddString("name", name);
198 	if (status != B_OK)
199 		return status;
200 
201 	return _SendRequest(request);
202 }
203 
204 
205 status_t
Stop(const char * name,bool force)206 BLaunchRoster::Stop(const char* name, bool force)
207 {
208 	if (name == NULL)
209 		return B_BAD_VALUE;
210 
211 	BMessage request(B_STOP_LAUNCH_JOB);
212 	status_t status = request.AddInt32("user", getuid());
213 	if (status == B_OK)
214 		status = request.AddString("name", name);
215 	if (status == B_OK)
216 		status = request.AddBool("force", force);
217 	if (status != B_OK)
218 		return status;
219 
220 	return _SendRequest(request);
221 }
222 
223 
224 status_t
SetEnabled(const char * name,bool enable)225 BLaunchRoster::SetEnabled(const char* name, bool enable)
226 {
227 	if (name == NULL)
228 		return B_BAD_VALUE;
229 
230 	BMessage request(B_ENABLE_LAUNCH_JOB);
231 	status_t status = request.AddInt32("user", getuid());
232 	if (status == B_OK)
233 		status = request.AddString("name", name);
234 	if (status == B_OK)
235 		status = request.AddBool("enable", enable);
236 	if (status != B_OK)
237 		return status;
238 
239 	return _SendRequest(request);
240 }
241 
242 
243 status_t
StartSession(const char * login)244 BLaunchRoster::StartSession(const char* login)
245 {
246 	if (login == NULL)
247 		return B_BAD_VALUE;
248 
249 	BMessage request(B_LAUNCH_SESSION);
250 	status_t status = request.AddInt32("user", getuid());
251 	if (status == B_OK)
252 		status = request.AddString("login", login);
253 	if (status != B_OK)
254 		return status;
255 
256 	return _SendRequest(request);
257 }
258 
259 
260 status_t
RegisterEvent(const BMessenger & source,const char * name,uint32 flags)261 BLaunchRoster::RegisterEvent(const BMessenger& source, const char* name,
262 	uint32 flags)
263 {
264 	return _UpdateEvent(B_REGISTER_LAUNCH_EVENT, source, name, flags);
265 }
266 
267 
268 status_t
UnregisterEvent(const BMessenger & source,const char * name)269 BLaunchRoster::UnregisterEvent(const BMessenger& source, const char* name)
270 {
271 	return _UpdateEvent(B_UNREGISTER_LAUNCH_EVENT, source, name);
272 }
273 
274 
275 status_t
NotifyEvent(const BMessenger & source,const char * name)276 BLaunchRoster::NotifyEvent(const BMessenger& source, const char* name)
277 {
278 	return _UpdateEvent(B_NOTIFY_LAUNCH_EVENT, source, name);
279 }
280 
281 
282 status_t
ResetStickyEvent(const BMessenger & source,const char * name)283 BLaunchRoster::ResetStickyEvent(const BMessenger& source, const char* name)
284 {
285 	return _UpdateEvent(B_RESET_STICKY_LAUNCH_EVENT, source, name);
286 }
287 
288 
289 status_t
GetTargets(BStringList & targets)290 BLaunchRoster::GetTargets(BStringList& targets)
291 {
292 	BMessage request(B_GET_LAUNCH_TARGETS);
293 	status_t status = request.AddInt32("user", getuid());
294 	if (status != B_OK)
295 		return status;
296 
297 	// send the request
298 	BMessage result;
299 	status = _SendRequest(request, result);
300 	if (status == B_OK)
301 		status = result.FindStrings("target", &targets);
302 
303 	return status;
304 }
305 
306 
307 status_t
GetTargetInfo(const char * name,BMessage & info)308 BLaunchRoster::GetTargetInfo(const char* name, BMessage& info)
309 {
310 	return _GetInfo(B_GET_LAUNCH_TARGET_INFO, name, info);
311 }
312 
313 
314 status_t
GetJobs(const char * target,BStringList & jobs)315 BLaunchRoster::GetJobs(const char* target, BStringList& jobs)
316 {
317 	BMessage request(B_GET_LAUNCH_JOBS);
318 	status_t status = request.AddInt32("user", getuid());
319 	if (status == B_OK && target != NULL)
320 		status = request.AddString("target", target);
321 	if (status != B_OK)
322 		return status;
323 
324 	// send the request
325 	BMessage result;
326 	status = _SendRequest(request, result);
327 	if (status == B_OK)
328 		status = result.FindStrings("job", &jobs);
329 
330 	return status;
331 }
332 
333 
334 status_t
GetJobInfo(const char * name,BMessage & info)335 BLaunchRoster::GetJobInfo(const char* name, BMessage& info)
336 {
337 	return _GetInfo(B_GET_LAUNCH_JOB_INFO, name, info);
338 }
339 
340 
341 status_t
GetLog(BMessage & info)342 BLaunchRoster::GetLog(BMessage& info)
343 {
344 	return _GetLog(NULL, info);
345 }
346 
347 
348 status_t
GetLog(const BMessage & filter,BMessage & info)349 BLaunchRoster::GetLog(const BMessage& filter, BMessage& info)
350 {
351 	return _GetLog(&filter, info);
352 }
353 
354 
355 void
_InitMessenger()356 BLaunchRoster::_InitMessenger()
357 {
358 #ifdef TEST_MODE
359 	port_id daemonPort = find_port(B_LAUNCH_DAEMON_PORT_NAME);
360 #else
361 	// find the launch_daemon port
362 	port_id daemonPort = BPrivate::get_launch_daemon_port();
363 #endif
364 	port_info info;
365 	if (daemonPort >= 0 && get_port_info(daemonPort, &info) == B_OK) {
366 		BMessenger::Private(fMessenger).SetTo(info.team, daemonPort,
367 			B_PREFERRED_TOKEN);
368 	}
369 }
370 
371 
372 status_t
_SendRequest(BMessage & request)373 BLaunchRoster::_SendRequest(BMessage& request)
374 {
375 	BMessage result;
376 	return _SendRequest(request, result);
377 }
378 
379 
380 status_t
_SendRequest(BMessage & request,BMessage & result)381 BLaunchRoster::_SendRequest(BMessage& request, BMessage& result)
382 {
383 	// Send the request, and evaluate the reply
384 	status_t status = fMessenger.SendMessage(&request, &result);
385 	if (status == B_OK)
386 		status = result.what;
387 
388 	return status;
389 }
390 
391 
392 status_t
_UpdateEvent(uint32 what,const BMessenger & source,const char * name,uint32 flags)393 BLaunchRoster::_UpdateEvent(uint32 what, const BMessenger& source,
394 	const char* name, uint32 flags)
395 {
396 	if (be_app == NULL || name == NULL || name[0] == '\0')
397 		return B_BAD_VALUE;
398 
399 	BMessage request(what);
400 	status_t status = request.AddInt32("user", getuid());
401 	if (status == B_OK)
402 		status = request.AddMessenger("source", source);
403 	if (status == B_OK)
404 		status = request.AddString("owner", be_app->Signature());
405 	if (status == B_OK)
406 		status = request.AddString("name", name);
407 	if (status == B_OK && flags != 0)
408 		status = request.AddUInt32("flags", flags);
409 	if (status != B_OK)
410 		return status;
411 
412 	return _SendRequest(request);
413 }
414 
415 
416 status_t
_GetInfo(uint32 what,const char * name,BMessage & info)417 BLaunchRoster::_GetInfo(uint32 what, const char* name, BMessage& info)
418 {
419 	if (name == NULL || name[0] == '\0')
420 		return B_BAD_VALUE;
421 
422 	BMessage request(what);
423 	status_t status = request.AddInt32("user", getuid());
424 	if (status == B_OK)
425 		status = request.AddString("name", name);
426 	if (status != B_OK)
427 		return status;
428 
429 	return _SendRequest(request, info);
430 }
431 
432 
433 status_t
_GetLog(const BMessage * filter,BMessage & info)434 BLaunchRoster::_GetLog(const BMessage* filter, BMessage& info)
435 {
436 	BMessage request(B_GET_LAUNCH_LOG);
437 	status_t status = request.AddInt32("user", getuid());
438 	if (status == B_OK && filter != NULL)
439 		status = request.AddMessage("filter", filter);
440 	if (status != B_OK)
441 		return status;
442 
443 	return _SendRequest(request, info);
444 }
445