xref: /haiku/src/tests/servers/registrar/RosterShell.cpp (revision 9e54316c528c34ee76f4d0d21150ceadd031c4de)
1 // RosterShell.cpp
2 
3 #include <iostream>
4 #include <sstream>
5 #include <stdio.h>
6 #include <string>
7 #include <string.h>
8 #include <vector>
9 #include <iostream>
10 
11 #include <List.h>
12 #include <Path.h>
13 #include <Roster.h>
14 
15 using std::string;
16 using std::vector;
17 
18 const char kShellUsage[] =
19 "Commands       Parameters     Description\n"
20 "---------------------------------------------------------------------------\n"
21 "activate, a    [ <team> ]     activates the application specified by <team>\n"
22 "exit, e                       exits the roster shell\n"
23 "help, h                       prints this help\n"
24 "launch         [ <program> ]  Executes <program> via BRoster::Launch()\n"
25 "list, l        [ <teams> ]    lists the applications specified by <teams>\n"
26 "                              or all registered applications\n"
27 "list-long, ll  [ <teams> ]    lists the applications specified by <teams>\n"
28 "                              or all registered applications (long format)\n"
29 "quit, q        [ <teams> ]    quits the applications specified by <teams>\n"
30 "\n"
31 ;
32 
33 class Shell {
34 public:
Shell()35 	Shell()
36 		:
37 		fTerminating(false)
38 	{
39 	}
40 
IsTerminating() const41 	bool IsTerminating() const { return fTerminating; }
42 
43 	void
DoCommand(vector<string> & cmdLine)44 	DoCommand(vector<string>& cmdLine)
45 	{
46 		if (cmdLine.size() > 0) {
47 			string command = cmdLine[0];
48 			if (command == "activate" || command == "a")
49 				CmdActivate(cmdLine);
50 			else if (command == "exit" || command == "e")
51 				CmdExit(cmdLine);
52 			else if (command == "help" || command == "h")
53 				Usage(string(" "));
54 			else if (command == "launch")
55 				CmdLaunch(cmdLine);
56 			else if (command == "list" || command == "l")
57 				CmdList(cmdLine);
58 			else if (command == "list-long" || command == "ll")
59 				CmdListLong(cmdLine);
60 			else if (command == "quit" || command == "q")
61 				CmdQuit(cmdLine);
62 			else
63 				Usage(string("Unknown command `") + command + "'");
64 		}
65 	}
66 
67 	void
Usage(string error)68 	Usage(string error)
69 	{
70 		if (error.length() > 0)
71 			std::cout << error << std::endl;
72 		std::cout << kShellUsage;
73 	}
74 
75 	void
CmdActivate(vector<string> & args)76 	CmdActivate(vector<string>& args)
77 	{
78 		BRoster roster;
79 
80 		// get a list of team IDs
81 		BList teamList;
82 		if (args.size() <= 1) {
83 			printf("activate: requires exactly one argument\n");
84 			return;
85 		}
86 
87 		ParseTeamList(args, &teamList);
88 		int32 count = teamList.CountItems();
89 		if (count != 1) {
90 			printf("activate: requires exactly one argument\n");
91 			return;
92 		}
93 
94 		// activate the team
95 		team_id team = (team_id)(uintptr_t)teamList.ItemAt(0);
96 		status_t error = roster.ActivateApp(team);
97 		if (error != B_OK) {
98 			printf("activate: failed to activate application %" B_PRId32
99 				": %s\n", team, strerror(error));
100 		}
101 	}
102 
103 	void
CmdExit(vector<string> &)104 	CmdExit(vector<string>&)
105 	{
106 		fTerminating = true;
107 	}
108 
109 	void
CmdLaunch(vector<string> & args)110 	CmdLaunch(vector<string>& args)
111 	{
112 		// check args
113 		if (args.size() != 2) {
114 			printf("launch: requires exactly one argument\n");
115 			return;
116 		}
117 
118 		string program = args[1];
119 
120 		// get an app ref
121 		entry_ref ref;
122 		status_t error = get_ref_for_path(program.c_str(), &ref);
123 		if (error != B_OK) {
124 			printf("launch: Failed to get entry ref for \"%s\": %s\n",
125 				program.c_str(), strerror(error));
126 			return;
127 		}
128 
129 		// launch the app
130 		BRoster roster;
131 		team_id teamID;
132 		error = roster.Launch(&ref, (const BMessage*)NULL, &teamID);
133 		if (error == B_OK) {
134 			printf("launched \"%s\", team id: %" B_PRId32 "\n", program.c_str(),
135 				teamID);
136 		} else {
137 			printf("launch: Failed to launch \"%s\": %s\n",
138 				program.c_str(), strerror(error));
139 		}
140 	}
141 
142 	static void
ParseTeamList(vector<string> & args,BList * teamList)143 	ParseTeamList(vector<string>& args, BList* teamList)
144 	{
145 		for (int32 i = 1; i < (int32)args.size(); i++) {
146 			string arg = args[i];
147 			team_id team = -1;
148 			if (sscanf(arg.c_str(), "%" B_PRId32, &team) > 0)
149 				teamList->AddItem((void*)(addr_t)team);
150 		}
151 	}
152 
153 	void
CmdList(vector<string> & args)154 	CmdList(vector<string>& args)
155 	{
156 		BRoster roster;
157 
158 		// get a list of team IDs
159 		BList teamList;
160 		if (args.size() > 1)
161 			ParseTeamList(args, &teamList);
162 		else
163 			roster.GetAppList(&teamList);
164 
165 		// print an info for each team
166 		int32 count = teamList.CountItems();
167 		printf("%-8s%-40s\n", "team", "signature");
168 		printf("---------------------------------------------------------\n");
169 		for (int32 i = 0; i < count; i++) {
170 			team_id team = (team_id)(uintptr_t)teamList.ItemAt(i);
171 			app_info info;
172 			status_t error = roster.GetRunningAppInfo(team, &info);
173 			if (error == B_OK)
174 				printf("%-8" B_PRId32 "%-40s\n", team, info.signature);
175 			else {
176 				printf("%-8" B_PRId32 "failed to get the app_info: %s\n", team,
177 					   strerror(error));
178 			}
179 		}
180 		printf("\n");
181 	}
182 
183 	void
CmdListLong(vector<string> & args)184 	CmdListLong(vector<string>& args)
185 	{
186 		BRoster roster;
187 
188 		// get a list of team IDs
189 		BList teamList;
190 		if (args.size() > 1)
191 			ParseTeamList(args, &teamList);
192 		else
193 			roster.GetAppList(&teamList);
194 
195 		// print an info for each team
196 		int32 count = teamList.CountItems();
197 		for (int32 i = 0; i < count; i++) {
198 			team_id team = (team_id)(uintptr_t)teamList.ItemAt(i);
199 			printf("team %8" B_PRId32 "\n", team);
200 			printf("-------------\n");
201 			app_info info;
202 			status_t error = roster.GetRunningAppInfo(team, &info);
203 			if (error == B_OK) {
204 				printf("signature: %s\n", info.signature);
205 				printf("thread:    %" B_PRId32 "\n", info.thread);
206 				printf("port:      %" B_PRId32 "\n", info.port);
207 				printf("flags:     0x%" B_PRIx32 "\n", info.flags);
208 				printf("file:      %s\n", BPath(&info.ref).Path());
209 			} else
210 				printf("failed to get the app_info: %s\n", strerror(error));
211 			printf("\n");
212 		}
213 	}
214 
215 	void
CmdQuit(vector<string> & args)216 	CmdQuit(vector<string>& args)
217 	{
218 		BRoster roster;
219 		// get a list of team IDs
220 		BList teamList;
221 		if (args.size() <= 1) {
222 			printf("quit: requires at least one argument\n");
223 			return;
224 		}
225 
226 		ParseTeamList(args, &teamList);
227 		int32 count = teamList.CountItems();
228 		if (count < 1) {
229 			printf("quit: requires at least one argument\n");
230 			return;
231 		}
232 
233 		// send a B_QUIT_REQUESTED message to each team
234 		for (int32 i = 0; i < count; i++) {
235 			team_id team = (team_id)(uintptr_t)teamList.ItemAt(i);
236 			status_t error = B_OK;
237 			BMessenger messenger(NULL, team, &error);
238 			if (messenger.IsValid()) {
239 				error = messenger.SendMessage(B_QUIT_REQUESTED);
240 				if (error != B_OK) {
241 					printf("quit: failed to deliver the B_QUIT_REQUESTED "
242 						   "message to team %" B_PRId32 "\n", team);
243 					printf("      %s\n", strerror(error));
244 				}
245 			} else {
246 				printf("quit: failed to create a messenger for team %" B_PRId32
247 					"\n", team);
248 				printf("      %s\n", strerror(error));
249 			}
250 		}
251 	}
252 
253 private:
254 	bool	fTerminating;
255 };
256 
257 
258 // read_line
259 bool
read_line(char * line,size_t size)260 read_line(char* line, size_t size)
261 {
262 	std::cout << "roster> ";
263 	std::cout.flush();
264 
265 	try {
266 		std::cin.getline(line, size);
267 	} catch (const std::exception &ex) {
268 		return false;
269 	}
270 
271 	return true;
272 }
273 
274 // main
275 int
main()276 main()
277 {
278 	Shell shell;
279 
280 	// main input loop
281 	char line[10240];
282 	while (!shell.IsTerminating() && read_line(line, sizeof(line))) {
283 		// parse args
284 		std::istringstream in(line);
285 		vector<string> args;
286 		string arg;
287 		while (in >> arg)
288 			args.push_back(arg);
289 		// invoke command
290 		shell.DoCommand(args);
291 	}
292 
293 	return 0;
294 }
295 
296