xref: /haiku/src/bin/launch_roster.cpp (revision 5e19679ea35a79a26477c6215c7abba9bb7c4d00)
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_NAME_NOT_FOUND)
96 		status = roster.Target(name);
97 
98 	if (status != B_OK) {
99 		fprintf(stderr, "%s: Starting job \"%s\" failed: %s\n", kProgramName,
100 			name, strerror(status));
101 		exit(EXIT_FAILURE);
102 	}
103 }
104 
105 
106 static void
107 stop_job(const char* name)
108 {
109 	BLaunchRoster roster;
110 	status_t status = roster.Stop(name);
111 	if (status == B_NAME_NOT_FOUND)
112 		status = roster.StopTarget(name);
113 
114 	if (status != B_OK) {
115 		fprintf(stderr, "%s: Stopping job \"%s\" failed: %s\n", kProgramName,
116 			name, strerror(status));
117 		exit(EXIT_FAILURE);
118 	}
119 }
120 
121 
122 static void
123 restart_job(const char* name)
124 {
125 	stop_job(name);
126 	start_job(name);
127 }
128 
129 
130 static void
131 enable_job(const char* name, bool enable)
132 {
133 	BLaunchRoster roster;
134 	status_t status = roster.SetEnabled(name, enable);
135 	if (status != B_OK) {
136 		fprintf(stderr, "%s: %s job \"%s\" failed: %s\n", kProgramName,
137 			enable ? "Enabling" : "Disabling", name, strerror(status));
138 		exit(EXIT_FAILURE);
139 	}
140 }
141 
142 
143 static void
144 usage(int status)
145 {
146 	fprintf(stderr, "Usage: %s <command>\n"
147 		"Where <command> is one of:\n"
148 		"  list - Lists all jobs (the default command)\n"
149 		"  list-targets - Lists all targets\n"
150 		"The following <command>s have a <name> argument:\n"
151 		"  start - Starts a job/target\n"
152 		"  stop - Stops a running job/target\n"
153 		"  restart - Restarts a running job/target\n"
154 		"  info - Shows info for a job/target\n",
155 		kProgramName);
156 
157 	exit(status);
158 }
159 
160 
161 int
162 main(int argc, char** argv)
163 {
164 	const char* command = "list";
165 	bool verbose = false;
166 
167 	int c;
168 	while ((c = getopt_long(argc, argv, "hv", kLongOptions, NULL)) != -1) {
169 		switch (c) {
170 			case 0:
171 				break;
172 			case 'h':
173 				usage(0);
174 				break;
175 			case 'v':
176 				verbose = true;
177 				break;
178 			default:
179 				usage(1);
180 				break;
181 		}
182 	}
183 
184 	if (argc - optind >= 1)
185 		command = argv[optind];
186 
187 	if (strcmp(command, "list") == 0) {
188 		list_jobs(verbose);
189 	} else if (strcmp(command, "list-targets") == 0) {
190 		list_targets(verbose);
191 	} else if (argc == optind + 1) {
192 		// For convenience (the "info" command can be omitted)
193 		get_info(command);
194 	} else {
195 		// All commands that need a name following
196 
197 		const char* name = argv[argc - 1];
198 
199 		if (strcmp(command, "info") == 0) {
200 			get_info(name);
201 		} else if (strcmp(command, "start") == 0) {
202 			start_job(name);
203 		} else if (strcmp(command, "stop") == 0) {
204 			stop_job(name);
205 		} else if (strcmp(command, "restart") == 0) {
206 			restart_job(name);
207 		} else if (strcmp(command, "enable") == 0) {
208 			enable_job(name, true);
209 		} else if (strcmp(command, "disable") == 0) {
210 			enable_job(name, false);
211 		} else {
212 			fprintf(stderr, "%s: Unknown command \"%s\".\n", kProgramName,
213 				command);
214 		}
215 	}
216 	return 0;
217 }
218