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