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