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