xref: /haiku/src/bin/launch_roster.cpp (revision 385ee03ba83b7a40d315e17b03031b3ca37820c0)
1 /*
2  * Copyright 2015-2016, Axel Dörfler, axeld@pinc-software.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 /*!	The launch_daemon's companion command line tool. */
8 
9 
10 #include <LaunchRoster.h>
11 #include <StringList.h>
12 
13 #include <getopt.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <errno.h>
18 
19 
20 static struct option const kLongOptions[] = {
21 	{"verbose", no_argument, 0, 'v'},
22 	{"help", no_argument, 0, 'h'},
23 	{NULL}
24 };
25 
26 extern const char *__progname;
27 static const char *kProgramName = __progname;
28 
29 
30 static void
31 list_jobs(bool verbose)
32 {
33 	BLaunchRoster roster;
34 	BStringList jobs;
35 	status_t status = roster.GetJobs(NULL, jobs);
36 	if (status != B_OK) {
37 		fprintf(stderr, "%s: Could not get job listing: %s\n", kProgramName,
38 			strerror(status));
39 		exit(EXIT_FAILURE);
40 	}
41 
42 	for (int32 i = 0; i < jobs.CountStrings(); i++)
43 		puts(jobs.StringAt(i).String());
44 }
45 
46 
47 static void
48 list_targets(bool verbose)
49 {
50 	BLaunchRoster roster;
51 	BStringList targets;
52 	status_t status = roster.GetTargets(targets);
53 	if (status != B_OK) {
54 		fprintf(stderr, "%s: Could not get target listing: %s\n", kProgramName,
55 			strerror(status));
56 		exit(EXIT_FAILURE);
57 	}
58 
59 	for (int32 i = 0; i < targets.CountStrings(); i++)
60 		puts(targets.StringAt(i).String());
61 }
62 
63 
64 static void
65 get_info(const char* name)
66 {
67 	BLaunchRoster roster;
68 	BMessage info;
69 	status_t targetStatus = roster.GetTargetInfo(name, info);
70 	if (targetStatus == B_OK) {
71 		printf("Target: %s\n", name);
72 		info.PrintToStream();
73 	}
74 
75 	info.MakeEmpty();
76 	status_t jobStatus = roster.GetJobInfo(name, info);
77 	if (jobStatus == B_OK) {
78 		printf("Job: %s\n", name);
79 		info.PrintToStream();
80 	}
81 
82 	if (jobStatus != B_OK && targetStatus != B_OK) {
83 		fprintf(stderr, "%s: Could not get target or job info for \"%s\": "
84 			"%s\n", kProgramName, name, strerror(jobStatus));
85 		exit(EXIT_FAILURE);
86 	}
87 }
88 
89 
90 static void
91 start_job(const char* name)
92 {
93 	BLaunchRoster roster;
94 	status_t status = roster.Start(name);
95 	if (status != B_OK) {
96 		fprintf(stderr, "%s: Starting job \"%s\" failed: %s\n", kProgramName,
97 			name, strerror(status));
98 		exit(EXIT_FAILURE);
99 	}
100 }
101 
102 
103 static void
104 stop_job(const char* name)
105 {
106 	BLaunchRoster roster;
107 	status_t status = roster.Stop(name);
108 	if (status != B_OK) {
109 		fprintf(stderr, "%s: Stopping job \"%s\" failed: %s\n", kProgramName,
110 			name, strerror(status));
111 		exit(EXIT_FAILURE);
112 	}
113 }
114 
115 
116 static void
117 enable_job(const char* name, bool enable)
118 {
119 	BLaunchRoster roster;
120 	status_t status = roster.SetEnabled(name, enable);
121 	if (status != B_OK) {
122 		fprintf(stderr, "%s: %s job \"%s\" failed: %s\n", kProgramName,
123 			enable ? "Enabling" : "Disabling", name, strerror(status));
124 		exit(EXIT_FAILURE);
125 	}
126 }
127 
128 
129 static void
130 usage(int status)
131 {
132 	fprintf(stderr, "Usage: %s <command>\n"
133 		"Where <command> is one of:\n"
134 		"  list - Lists all jobs (the default command)\n"
135 		"  list-targets - Lists all targets\n"
136 		"The following <command>s have a <name> argument:\n"
137 		"  start - Starts a job\n"
138 		"  stop - Stops a running job\n"
139 		"  info - Shows info for a job/target\n",
140 		kProgramName);
141 
142 	exit(status);
143 }
144 
145 
146 int
147 main(int argc, char** argv)
148 {
149 	const char* command = "list";
150 	bool verbose = false;
151 
152 	int c;
153 	while ((c = getopt_long(argc, argv, "hv", kLongOptions, NULL)) != -1) {
154 		switch (c) {
155 			case 0:
156 				break;
157 			case 'h':
158 				usage(0);
159 				break;
160 			case 'v':
161 				verbose = true;
162 				break;
163 			default:
164 				usage(1);
165 				break;
166 		}
167 	}
168 
169 	if (argc - optind >= 1)
170 		command = argv[optind];
171 
172 	if (strcmp(command, "list") == 0) {
173 		list_jobs(verbose);
174 	} else if (strcmp(command, "list-targets") == 0) {
175 		list_targets(verbose);
176 	} else if (argc == optind + 1) {
177 		// For convenience (the "info" command can be omitted)
178 		get_info(command);
179 	} else {
180 		// All commands that need a name following
181 
182 		const char* name = argv[argc - 1];
183 
184 		if (strcmp(command, "info") == 0) {
185 			get_info(name);
186 		} else if (strcmp(command, "start") == 0) {
187 			start_job(name);
188 		} else if (strcmp(command, "stop") == 0) {
189 			stop_job(name);
190 		} else if (strcmp(command, "enable") == 0) {
191 			enable_job(name, true);
192 		} else if (strcmp(command, "disable") == 0) {
193 			enable_job(name, false);
194 		} else {
195 			fprintf(stderr, "%s: Unknown command \"%s\".\n", kProgramName,
196 				command);
197 		}
198 	}
199 	return 0;
200 }
201