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: 35 Shell() 36 : 37 fTerminating(false) 38 { 39 } 40 41 bool IsTerminating() const { return fTerminating; } 42 43 void 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 68 Usage(string error) 69 { 70 if (error.length() > 0) 71 std::cout << error << std::endl; 72 std::cout << kShellUsage; 73 } 74 75 void 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 104 CmdExit(vector<string>&) 105 { 106 fTerminating = true; 107 } 108 109 void 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 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 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 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 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 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 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