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