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