diff options
Diffstat (limited to 'src/Client/CommandParser.cpp')
-rw-r--r-- | src/Client/CommandParser.cpp | 331 |
1 files changed, 297 insertions, 34 deletions
diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp index 4c395b7..2a67dab 100644 --- a/src/Client/CommandParser.cpp +++ b/src/Client/CommandParser.cpp @@ -116,18 +116,138 @@ std::map<std::string, Common::HostInfo> CommandParser::parseHostList(const std:: } +void CommandParser::printFSInfo(boost::shared_ptr<const Common::XmlPacket> &packet) { + const std::string units[] = { + "kB", "MB", "GB", "TB", "" + }; + + for(size_t i = 0; i < (*packet)["filesystems"].getSize(); ++i) { + const Common::XmlPacket::Entry &fs = (*packet)["filesystems"][i]; + + unsigned usedUnit = 0, totalUnit = 0; + + float used = fs["usedSize"]; + float total = fs["totalSize"]; + float available = fs["availableSize"]; + + while(used >= 1024 && !units[usedUnit+1].empty()) { + ++usedUnit; + used /= 1024; + available /= 1024; + } + + while(total >= 1024 && !units[totalUnit+1].empty()) { + ++totalUnit; + total /= 1024; + } + + + std::string name = fs["name"]; + std::string mountedOn = fs["mountedOn"]; + + std::string nameString = mountedOn + " (" + name + ")"; + + if(nameString.length() < 32) { + nameString.resize(32, ' '); + } + else { + nameString += "\n\t"; + nameString.resize(nameString.length() + 32, ' '); + } + + std::printf("\t%s%.*f%s", nameString.c_str(), (used < 10) ? 2 : 1, used, (usedUnit == totalUnit) ? "" : (" " + units[usedUnit]).c_str()); + std::printf("/%.*f %s (%.1f%%)\n", (total < 10) ? 2 : 1, total, units[totalUnit].c_str(), std::min(100*used/(used+available), 100.0f)); + } + + std::printf("\n"); +} + +void CommandParser::printHostStatus(boost::shared_ptr<const Common::XmlPacket> &packet) { + unsigned long uptime = (*packet)["uptime"]; + + if(uptime) { + unsigned long uptime = (*packet)["uptime"]; + + unsigned long days = uptime/86400; + unsigned long hours = (uptime%86400)/3600; + unsigned long minutes = (uptime%3600)/60; + + std::printf("\tUptime:\t\t"); + + if(days) std::printf("%lu days ", days); + + std::printf("%lu:%02lu", hours, minutes); + + std::printf(" (load average: %.2f %.2f %.2f, %lu processes)", (float)(*packet)["loadAvg1"], (float)(*packet)["loadAvg5"], (float)(*packet)["loadAvg15"], (unsigned long)(*packet)["nProcesses"]); + + std::printf("\n\n"); + } + + if((unsigned long)(*packet)["totalMem"] && (unsigned long)(*packet)["freeMem"]) { + const std::string units[] = { + "kB", "MB", "GB", "TB", "" + }; + + unsigned unit = 0; + float totalMem = (*packet)["totalMem"], usedMem = totalMem-(float)(*packet)["freeMem"]; + + while(totalMem >= 1024 && !units[unit+1].empty()) { + ++unit; + totalMem /= 1024; + usedMem /= 1024; + } + + std::printf("\tMemory usage:\t%.*f/%.*f %s", (usedMem < 10) ? 2 : 1, usedMem, (totalMem < 10) ? 2 : 1, totalMem, units[unit].c_str()); + std::printf(" (%.1f%%)\n", usedMem*100.0f/totalMem); + + if((unsigned long)(*packet)["totalSwap"] && (unsigned long)(*packet)["freeSwap"]) { + unit = 0; + totalMem = (*packet)["totalSwap"]; usedMem = totalMem-(float)(*packet)["freeSwap"]; + + while(totalMem >= 1024 && !units[unit+1].empty()) { + ++unit; + totalMem /= 1024; + usedMem /= 1024; + } + + std::printf("\tSwap usage:\t%.*f/%.*f %s", (usedMem < 10) ? 2 : 1, usedMem, (totalMem < 10) ? 2 : 1, totalMem, units[unit].c_str()); + std::printf(" (%.1f%%)\n", usedMem*100.0f/totalMem); + } + + std::printf("\n"); + } +} + + void CommandParser::fsinfoCommand(const std::vector<std::string> &args) { + boost::shared_ptr<Common::Request> request; + if(args.size() == 1) - Common::RequestManager::get()->sendRequest0<Common::Requests::FSInfoRequest>(connection, boost::bind(&CommandManager::fsInfoRequestFinished, CommandManager::get(), _1)); + request = boost::shared_ptr<Common::Requests::FSInfoRequest>(new Common::Requests::FSInfoRequest); else if(args.size() == 2) - Common::RequestManager::get()->sendRequest1<Requests::DaemonFSInfoRequest>(connection, args[1], boost::bind(&CommandManager::daemonFSInfoRequestFinished, CommandManager::get(), _1)); + request = boost::shared_ptr<Requests::DaemonFSInfoRequest>(new Requests::DaemonFSInfoRequest(args[1])); else { Common::Logger::logf(Common::Logger::ERROR, "%s: Too many arguments.", args[0].c_str()); printUsage("fsinfo"); return; } - ++CommandManager::get()->activeRequests; + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); + + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(!result.first || result.second) { + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + } + else { + if(args.size() == 1) + std::cout << "Server file system usage:" << std::endl; + else + std::cout << "Host file system usage:" << std::endl; + + printFSInfo(result.first); + } } void CommandParser::helpCommand(const std::vector<std::string> &args) { @@ -220,12 +340,23 @@ void CommandParser::rebootCommand(const std::vector<std::string> &args) { std::map<std::string, Common::HostInfo> hosts = parseHostList(std::vector<std::string>(args.begin()+1, args.end()), true); + std::vector<boost::shared_ptr<Requests::DaemonCommandRequest> > requests; + for(std::map<std::string, Common::HostInfo>::iterator host = hosts.begin(); host != hosts.end(); ++host) { - Common::RequestManager::get()->sendRequest2<Requests::DaemonCommandRequest>(connection, - host->first, true, boost::bind(&CommandManager::daemonCommandRequestFinished, CommandManager::get(), _1) - ); + boost::shared_ptr<Requests::DaemonCommandRequest> request(new Requests::DaemonCommandRequest(host->first, true)); + Common::RequestManager::get()->sendRequest(connection, request); + + requests.push_back(request); + } + + for(std::vector<boost::shared_ptr<Requests::DaemonCommandRequest> >::iterator request = requests.begin(); request != requests.end(); ++request) + (*request)->wait(); - ++CommandManager::get()->activeRequests; + for(std::vector<boost::shared_ptr<Requests::DaemonCommandRequest> >::iterator request = requests.begin(); request != requests.end(); ++request) { + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = (*request)->getResult(); + + if(result.second) + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); } } @@ -238,29 +369,55 @@ void CommandParser::shutdownCommand(const std::vector<std::string> &args) { std::map<std::string, Common::HostInfo> hosts = parseHostList(std::vector<std::string>(args.begin()+1, args.end()), true); + std::vector<boost::shared_ptr<Requests::DaemonCommandRequest> > requests; + for(std::map<std::string, Common::HostInfo>::iterator host = hosts.begin(); host != hosts.end(); ++host) { - Common::RequestManager::get()->sendRequest2<Requests::DaemonCommandRequest>(connection, - host->first, false, boost::bind(&CommandManager::daemonCommandRequestFinished, CommandManager::get(), _1) - ); + boost::shared_ptr<Requests::DaemonCommandRequest> request(new Requests::DaemonCommandRequest(host->first, false)); + Common::RequestManager::get()->sendRequest(connection, request); - ++CommandManager::get()->activeRequests; + requests.push_back(request); + } + + for(std::vector<boost::shared_ptr<Requests::DaemonCommandRequest> >::iterator request = requests.begin(); request != requests.end(); ++request) + (*request)->wait(); + + for(std::vector<boost::shared_ptr<Requests::DaemonCommandRequest> >::iterator request = requests.begin(); request != requests.end(); ++request) { + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = (*request)->getResult(); + + if(result.second) + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); } } void CommandParser::statusCommand(const std::vector<std::string> &args) { + boost::shared_ptr<Common::Request> request; + if(args.size() == 1) - Common::RequestManager::get()->sendRequest0<Common::Requests::StatusRequest>(connection, - boost::bind(&CommandManager::statusRequestFinished, CommandManager::get(), _1)); + request = boost::shared_ptr<Common::Requests::StatusRequest>(new Common::Requests::StatusRequest); else if(args.size() == 2) - Common::RequestManager::get()->sendRequest1<Requests::DaemonStatusRequest>(connection, - args[1], boost::bind(&CommandManager::daemonStatusRequestFinished, CommandManager::get(), _1)); + request = boost::shared_ptr<Requests::DaemonStatusRequest>(new Requests::DaemonStatusRequest(args[1])); else { Common::Logger::logf(Common::Logger::ERROR, "%s: Too many arguments.", args[0].c_str()); printUsage("status"); return; } - ++CommandManager::get()->activeRequests; + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); + + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(!result.first || result.second) { + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + } + else { + if(args.size() == 1) + std::cout << "Server status:" << std::endl; + else + std::cout << "Host status:" << std::endl; + + printHostStatus(result.first); + } } void CommandParser::userInfoCommand(const std::vector<std::string> &args) { @@ -283,17 +440,50 @@ void CommandParser::userInfoCommand(const std::vector<std::string> &args) { return; } - ++CommandManager::get()->activeRequests; + boost::shared_ptr<Common::Requests::UserInfoRequest> request(new Common::Requests::UserInfoRequest(uid)); + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); + + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(!result.first || result.second) { + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + } + else { + const Common::XmlPacket &packet = *result.first; - Common::RequestManager::get()->sendRequest1<Common::Requests::UserInfoRequest>(connection, - uid, boost::bind(&CommandManager::userInfoRequestFinished, CommandManager::get(), _1)); + std::cout << " " << (unsigned long)packet["uid"] << ", " << (unsigned long)packet["gid"] << ", " << (const std::string&)packet["username"] << ", " + << (const std::string&)packet["fullName"] << std::endl << std::endl; + } } void CommandParser::listUsersCommand(const std::vector<std::string>&) { - ++CommandManager::get()->activeRequests; + boost::shared_ptr<Common::Requests::UserListRequest> request(new Common::Requests::UserListRequest); + + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); + + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(!result.first || result.second) { + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + } + else { + const Common::XmlPacket::Element &users = (*result.first)["users"]; + + if(users.isEmpty()) { + std::cout << "User list is empty." << std::endl; + } + else { + std::cout << "Found " << users.getSize() << " user" << (users.getSize()==1 ? "" : "s") << ":" << std::endl; + + + for(size_t i = 0; i < users.getSize(); ++i) + std::cout << " " << (unsigned long)users[i]["uid"] << ", " << (unsigned long)users[i]["gid"] << ", " << (const std::string&)users[i]["username"] << ", " << (const std::string&)users[i]["fullName"] << std::endl; + } - Common::RequestManager::get()->sendRequest0<Common::Requests::UserListRequest>(connection, - boost::bind(&CommandManager::userListRequestFinished, CommandManager::get(), _1)); + std::cout << std::endl; + } } void CommandParser::listUserGroupsCommand(const std::vector<std::string> &args) { @@ -316,17 +506,61 @@ void CommandParser::listUserGroupsCommand(const std::vector<std::string> &args) return; } - ++CommandManager::get()->activeRequests; + boost::shared_ptr<Common::Requests::UserGroupListRequest> request(new Common::Requests::UserGroupListRequest(uid)); + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); + + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(!result.first || result.second) { + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + } + else { + const Common::XmlPacket::Element &groups = (*result.first)["groups"]; + + if(groups.isEmpty()) { + std::cout << "The user isn't member of any group." << std::endl; + } + else { + + std::cout << "User is member of " << groups.getSize() << " group" << (groups.getSize()==1 ? "" : "s") << ":" << std::endl; + + + for(size_t i = 0; i < groups.getSize(); ++i) + std::cout << " " << (unsigned long)groups[i]["gid"] << std::endl; + } - Common::RequestManager::get()->sendRequest1<Common::Requests::UserGroupListRequest>(connection, - uid, boost::bind(&CommandManager::userGroupListRequestFinished, CommandManager::get(), _1)); + std::cout << std::endl; + } } void CommandParser::listGroupsCommand(const std::vector<std::string>&) { - ++CommandManager::get()->activeRequests; + boost::shared_ptr<Common::Requests::GroupListRequest> request(new Common::Requests::GroupListRequest); + + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); + + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(!result.first || result.second) { + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + } + else { + const Common::XmlPacket::Element &groups = (*result.first)["groups"]; - Common::RequestManager::get()->sendRequest0<Common::Requests::GroupListRequest>(connection, - boost::bind(&CommandManager::groupListRequestFinished, CommandManager::get(), _1)); + if(groups.isEmpty()) { + std::cout << "Group list is empty." << std::endl; + } + else { + std::cout << "Found " << groups.getSize() << " group" << (groups.getSize()==1 ? "" : "s") << ":" << std::endl; + + + for(size_t i = 0; i < groups.getSize(); ++i) + std::cout << " " << (unsigned long)groups[i]["gid"] << ", " << (const std::string&)groups[i]["name"] << std::endl; + } + + std::cout << std::endl; + } } void CommandParser::listGroupUsersCommand(const std::vector<std::string> &args) { @@ -349,17 +583,46 @@ void CommandParser::listGroupUsersCommand(const std::vector<std::string> &args) return; } - ++CommandManager::get()->activeRequests; + boost::shared_ptr<Common::Requests::GroupUserListRequest> request(new Common::Requests::GroupUserListRequest(gid)); + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); - Common::RequestManager::get()->sendRequest1<Common::Requests::GroupUserListRequest>(connection, - gid, boost::bind(&CommandManager::groupUserListRequestFinished, CommandManager::get(), _1)); + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(!result.first || result.second) { + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + } + else { + const Common::XmlPacket::Element &users = (*result.first)["users"]; + + if(users.isEmpty()) { + std::cout << "The group doesn't have any members." << std::endl; + } + else { + + std::cout << "The group has " << users.getSize() << " member" << (users.getSize()==1 ? "" : "s") << ":" << std::endl; + + + for(size_t i = 0; i < users.getSize(); ++i) + std::cout << " " << (unsigned long)users[i]["uid"] << std::endl; + } + + std::cout << std::endl; + } } void CommandParser::exitCommand(const std::vector<std::string>&) { - ++CommandManager::get()->activeRequests; + boost::shared_ptr<Common::Requests::DisconnectRequest> request(new Common::Requests::DisconnectRequest); + + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); - Common::RequestManager::get()->sendRequest0<Common::Requests::DisconnectRequest>(connection, - boost::bind(&CommandManager::disconnectRequestFinished, CommandManager::get(), _1)); + std::pair<boost::shared_ptr<const Common::XmlPacket>, Net::Exception> result = request->getResult(); + + if(result.second) + Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", result.second.strerror().c_str()); + else + disconnect = true; } bool CommandParser::parse(const std::string &cmd) { |