// RosterShell.cpp #include #include #include #include #include #include #include #include #include #include using std::string; using std::vector; const char kShellUsage[] = "Commands Parameters Description\n" "---------------------------------------------------------------------------\n" "activate, a [ ] activates the application specified by \n" "exit, e exits the roster shell\n" "help, h prints this help\n" "launch [ ] Executes via BRoster::Launch()\n" "list, l [ ] lists the applications specified by \n" " or all registered applications\n" "list-long, ll [ ] lists the applications specified by \n" " or all registered applications (long format)\n" "quit, q [ ] quits the applications specified by \n" "\n" ; class Shell { public: Shell() : fTerminating(false) { } bool IsTerminating() const { return fTerminating; } void DoCommand(vector& cmdLine) { if (cmdLine.size() > 0) { string command = cmdLine[0]; if (command == "activate" || command == "a") CmdActivate(cmdLine); else if (command == "exit" || command == "e") CmdExit(cmdLine); else if (command == "help" || command == "h") Usage(string(" ")); else if (command == "launch") CmdLaunch(cmdLine); else if (command == "list" || command == "l") CmdList(cmdLine); else if (command == "list-long" || command == "ll") CmdListLong(cmdLine); else if (command == "quit" || command == "q") CmdQuit(cmdLine); else Usage(string("Unknown command `") + command + "'"); } } void Usage(string error) { if (error.length() > 0) std::cout << error << std::endl; std::cout << kShellUsage; } void CmdActivate(vector& args) { BRoster roster; // get a list of team IDs BList teamList; if (args.size() <= 1) { printf("activate: requires exactly one argument\n"); return; } ParseTeamList(args, &teamList); int32 count = teamList.CountItems(); if (count != 1) { printf("activate: requires exactly one argument\n"); return; } // activate the team team_id team = (team_id)(uintptr_t)teamList.ItemAt(0); status_t error = roster.ActivateApp(team); if (error != B_OK) { printf("activate: failed to activate application %" B_PRId32 ": %s\n", team, strerror(error)); } } void CmdExit(vector&) { fTerminating = true; } void CmdLaunch(vector& args) { // check args if (args.size() != 2) { printf("launch: requires exactly one argument\n"); return; } string program = args[1]; // get an app ref entry_ref ref; status_t error = get_ref_for_path(program.c_str(), &ref); if (error != B_OK) { printf("launch: Failed to get entry ref for \"%s\": %s\n", program.c_str(), strerror(error)); return; } // launch the app BRoster roster; team_id teamID; error = roster.Launch(&ref, (const BMessage*)NULL, &teamID); if (error == B_OK) { printf("launched \"%s\", team id: %" B_PRId32 "\n", program.c_str(), teamID); } else { printf("launch: Failed to launch \"%s\": %s\n", program.c_str(), strerror(error)); } } static void ParseTeamList(vector& args, BList* teamList) { for (int32 i = 1; i < (int32)args.size(); i++) { string arg = args[i]; team_id team = -1; if (sscanf(arg.c_str(), "%" B_PRId32, &team) > 0) teamList->AddItem((void*)(addr_t)team); } } void CmdList(vector& args) { BRoster roster; // get a list of team IDs BList teamList; if (args.size() > 1) ParseTeamList(args, &teamList); else roster.GetAppList(&teamList); // print an info for each team int32 count = teamList.CountItems(); printf("%-8s%-40s\n", "team", "signature"); printf("---------------------------------------------------------\n"); for (int32 i = 0; i < count; i++) { team_id team = (team_id)(uintptr_t)teamList.ItemAt(i); app_info info; status_t error = roster.GetRunningAppInfo(team, &info); if (error == B_OK) printf("%-8" B_PRId32 "%-40s\n", team, info.signature); else { printf("%-8" B_PRId32 "failed to get the app_info: %s\n", team, strerror(error)); } } printf("\n"); } void CmdListLong(vector& args) { BRoster roster; // get a list of team IDs BList teamList; if (args.size() > 1) ParseTeamList(args, &teamList); else roster.GetAppList(&teamList); // print an info for each team int32 count = teamList.CountItems(); for (int32 i = 0; i < count; i++) { team_id team = (team_id)(uintptr_t)teamList.ItemAt(i); printf("team %8" B_PRId32 "\n", team); printf("-------------\n"); app_info info; status_t error = roster.GetRunningAppInfo(team, &info); if (error == B_OK) { printf("signature: %s\n", info.signature); printf("thread: %" B_PRId32 "\n", info.thread); printf("port: %" B_PRId32 "\n", info.port); printf("flags: 0x%" B_PRIx32 "\n", info.flags); printf("file: %s\n", BPath(&info.ref).Path()); } else printf("failed to get the app_info: %s\n", strerror(error)); printf("\n"); } } void CmdQuit(vector& args) { BRoster roster; // get a list of team IDs BList teamList; if (args.size() <= 1) { printf("quit: requires at least one argument\n"); return; } ParseTeamList(args, &teamList); int32 count = teamList.CountItems(); if (count < 1) { printf("quit: requires at least one argument\n"); return; } // send a B_QUIT_REQUESTED message to each team for (int32 i = 0; i < count; i++) { team_id team = (team_id)(uintptr_t)teamList.ItemAt(i); status_t error = B_OK; BMessenger messenger(NULL, team, &error); if (messenger.IsValid()) { error = messenger.SendMessage(B_QUIT_REQUESTED); if (error != B_OK) { printf("quit: failed to deliver the B_QUIT_REQUESTED " "message to team %" B_PRId32 "\n", team); printf(" %s\n", strerror(error)); } } else { printf("quit: failed to create a messenger for team %" B_PRId32 "\n", team); printf(" %s\n", strerror(error)); } } } private: bool fTerminating; }; // read_line bool read_line(char* line, size_t size) { std::cout << "roster> "; std::cout.flush(); try { std::cin.getline(line, size); } catch (const std::exception &ex) { return false; } return true; } // main int main() { Shell shell; // main input loop char line[10240]; while (!shell.IsTerminating() && read_line(line, sizeof(line))) { // parse args std::istringstream in(line); vector args; string arg; while (in >> arg) args.push_back(arg); // invoke command shell.DoCommand(args); } return 0; }