summaryrefslogtreecommitdiffstats
path: root/src/Client
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-06-04 22:23:07 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-06-04 22:23:07 +0200
commit0b27c37fe95c6aced613d51a3624f8930a96ad3f (patch)
tree5cb92568f70fe9789e99633ec71048389efb7fa4 /src/Client
parent50d92f64547c5c06851976ceab5ed631ec93f647 (diff)
downloadmad-0b27c37fe95c6aced613d51a3624f8930a96ad3f.tar
mad-0b27c37fe95c6aced613d51a3624f8930a96ad3f.zip
RequestHandler-Interface ?berarbeitet
Diffstat (limited to 'src/Client')
-rw-r--r--src/Client/CMakeLists.txt2
-rw-r--r--src/Client/CommandManager.cpp335
-rw-r--r--src/Client/CommandManager.h85
-rw-r--r--src/Client/CommandParser.cpp331
-rw-r--r--src/Client/CommandParser.h15
-rw-r--r--src/Client/InformationManager.cpp30
-rw-r--r--src/Client/InformationManager.h17
-rw-r--r--src/Client/Requests/DaemonCommandRequest.h4
-rw-r--r--src/Client/Requests/DaemonFSInfoRequest.h3
-rw-r--r--src/Client/Requests/DaemonListRequest.h3
-rw-r--r--src/Client/Requests/DaemonStatusRequest.h3
11 files changed, 338 insertions, 490 deletions
diff --git a/src/Client/CMakeLists.txt b/src/Client/CMakeLists.txt
index fd8922d..00b72c5 100644
--- a/src/Client/CMakeLists.txt
+++ b/src/Client/CMakeLists.txt
@@ -2,5 +2,5 @@ add_subdirectory(Requests)
include_directories(${INCLUDES})
-add_library(Client CommandManager.cpp CommandParser.cpp InformationManager.cpp)
+add_library(Client CommandParser.cpp InformationManager.cpp)
target_link_libraries(Client ClientRequests Common)
diff --git a/src/Client/CommandManager.cpp b/src/Client/CommandManager.cpp
deleted file mode 100644
index 6c643f2..0000000
--- a/src/Client/CommandManager.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * CommandManager.cpp
- *
- * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "CommandManager.h"
-#include <Common/HostInfo.h>
-#include <Common/Logger.h>
-#include <Common/Request.h>
-
-#include <cmath>
-#include <iostream>
-#include <vector>
-
-
-namespace Mad {
-namespace Client {
-
-CommandManager CommandManager::commandManager;
-
-
-void CommandManager::printFSInfo(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 CommandManager::printHostStatus(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 CommandManager::daemonCommandRequestFinished(Common::Request &request) {
- try {
- request.getResult();
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::daemonFSInfoRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
- std::cout << "Host file system usage:" << std::endl;
- printFSInfo(packet);
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::daemonStatusRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
- std::cout << "Host status:" << std::endl;
- printHostStatus(packet);
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::disconnectRequestFinished(Common::Request &request) {
- try {
- request.getResult();
- disconnect = true;
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::fsInfoRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
- std::cout << "Server file system usage:" << std::endl;
- printFSInfo(packet);
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::statusRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
- std::cout << "Server status:" << std::endl;
- printHostStatus(packet);
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::userInfoRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
-
- std::cout << " " << (unsigned long)packet["uid"] << ", " << (unsigned long)packet["gid"] << ", " << (const std::string&)packet["username"] << ", "
- << (const std::string&)packet["fullName"] << std::endl << std::endl;
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::userListRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
-
- const Common::XmlPacket::Element &users = packet["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;
- }
-
- std::cout << std::endl;
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::userGroupListRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
-
- const Common::XmlPacket::Element &groups = packet["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;
- }
-
- std::cout << std::endl;
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::groupListRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
-
- const Common::XmlPacket::Element &groups = packet["groups"];
-
- 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;
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-void CommandManager::groupUserListRequestFinished(Common::Request &request) {
- try {
- const Common::XmlPacket &packet = request.getResult();
-
- const Common::XmlPacket::Element &users = packet["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;
- }
- catch(Net::Exception &exception) {
- Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str());
- }
-
- requestFinished();
-}
-
-}
-}
diff --git a/src/Client/CommandManager.h b/src/Client/CommandManager.h
deleted file mode 100644
index 3c51bd3..0000000
--- a/src/Client/CommandManager.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * CommandManager.h
- *
- * Copyright (C) 2008 Matthias Schiffer <matthias@gamezock.de>
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MAD_CLIENT_COMMANDMANAGER_H_
-#define MAD_CLIENT_COMMANDMANAGER_H_
-
-#include <Net/Signals/Signals.h>
-
-namespace Mad {
-
-namespace Common {
-class XmlPacket;
-class Request;
-}
-
-namespace Client {
-
-class CommandManager {
- private:
- friend class CommandParser;
-
- static CommandManager commandManager;
-
- unsigned int activeRequests;
-
- Net::Signals::Signal0 finished;
-
- bool disconnect;
-
- void requestFinished() {
- activeRequests--;
-
- finished.emit();
- }
-
- void printFSInfo(const Common::XmlPacket &packet);
- void printHostStatus(const Common::XmlPacket &packet);
-
- void daemonCommandRequestFinished(Common::Request &request);
- void daemonFSInfoRequestFinished(Common::Request &request);
- void daemonStatusRequestFinished(Common::Request &request);
- void disconnectRequestFinished(Common::Request &request);
- void fsInfoRequestFinished(Common::Request &request);
- void statusRequestFinished(Common::Request &request);
- void userInfoRequestFinished(Common::Request &request);
- void userListRequestFinished(Common::Request &request);
- void userGroupListRequestFinished(Common::Request &request);
- void groupListRequestFinished(Common::Request &request);
- void groupUserListRequestFinished(Common::Request &request);
-
- CommandManager() : activeRequests(0), disconnect(false) {}
-
- public:
- static CommandManager *get() {
- return &commandManager;
- }
-
- bool requestsActive() {return (activeRequests > 0);}
- bool willDisconnect() {return disconnect;}
-
- Net::Signals::Connection connectSignalFinished(const Net::Signals::Signal0::slot_type &slot) {
- return finished.connect(slot);
- }
-};
-
-}
-}
-
-#endif /* MAD_CLIENT_COMMANDMANAGER_H_ */
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) {
diff --git a/src/Client/CommandParser.h b/src/Client/CommandParser.h
index 692eb7e..ca9b59e 100644
--- a/src/Client/CommandParser.h
+++ b/src/Client/CommandParser.h
@@ -20,8 +20,10 @@
#ifndef MAD_CLIENT_COMMANDPARSER_H_
#define MAD_CLIENT_COMMANDPARSER_H_
-#include "CommandManager.h"
#include <Common/HostInfo.h>
+#include <Common/XmlPacket.h>
+
+#include <boost/smart_ptr.hpp>
#include <map>
#include <string>
@@ -52,11 +54,16 @@ class CommandParser {
Common::Connection *connection;
+ bool disconnect;
+
const Command* findCommand(const std::string& command);
void printUsage(const std::string& command);
std::map<std::string, Common::HostInfo> parseHostList(const std::vector<std::string> &args, bool mustBeActive = false);
+ void printFSInfo(boost::shared_ptr<const Common::XmlPacket> &packet);
+ void printHostStatus(boost::shared_ptr<const Common::XmlPacket> &packet);
+
void fsinfoCommand(const std::vector<std::string> &args);
void helpCommand(const std::vector<std::string> &args);
void listHostsCommand(const std::vector<std::string> &args);
@@ -70,7 +77,7 @@ class CommandParser {
void listGroupUsersCommand(const std::vector<std::string> &args);
void exitCommand(const std::vector<std::string>&);
- CommandParser() : connection(0) {}
+ CommandParser() : connection(0), disconnect(false) {}
public:
static CommandParser *get() {
@@ -90,6 +97,10 @@ class CommandParser {
void requestDisconnect() {
exitCommand(std::vector<std::string>());
}
+
+ bool willDisconnect() const {
+ return disconnect;
+ }
};
}
diff --git a/src/Client/InformationManager.cpp b/src/Client/InformationManager.cpp
index 78a0cf7..03a71c6 100644
--- a/src/Client/InformationManager.cpp
+++ b/src/Client/InformationManager.cpp
@@ -29,8 +29,8 @@ namespace Client {
InformationManager InformationManager::informationManager;
-void InformationManager::DaemonStateUpdateRequestHandler::handlePacket(const Common::XmlPacket &packet) {
- if(packet.getType() != "UpdateHostState") {
+void InformationManager::DaemonStateUpdateRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) {
+ if(packet->getType() != "UpdateHostState") {
Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet.");
Common::XmlPacket ret;
@@ -48,9 +48,9 @@ void InformationManager::DaemonStateUpdateRequestHandler::handlePacket(const Com
{
boost::lock_guard<boost::mutex> lock(informationManager.mutex);
- std::map<std::string, Common::HostInfo>::iterator host = informationManager.daemons.find(packet["name"]);
+ std::map<std::string, Common::HostInfo>::iterator host = informationManager.daemons.find((*packet)["name"]);
if(host != informationManager.daemons.end())
- host->second.setState(packet["state"]);
+ host->second.setState((*packet)["state"]);
else
Common::Logger::log(Common::Logger::WARNING, "Received a state update for an unknown host.");
}
@@ -77,19 +77,22 @@ void InformationManager::updateDaemonList(Common::Connection *con) {
if(updating)
return;
- Common::RequestManager::get()->sendRequest0<Requests::DaemonListRequest>(con,
- boost::bind(&InformationManager::daemonListRequestFinished, this, _1));
+ updateRequest = boost::shared_ptr<Requests::DaemonListRequest>(new Requests::DaemonListRequest);
+ updateRequest->connectSignalFinished(boost::bind(&InformationManager::daemonListRequestFinished, this, _1, _2));
+
+ Common::RequestManager::get()->sendRequest(con, updateRequest);
updating = true;
}
-void InformationManager::daemonListRequestFinished(Common::Request &request) {
+void InformationManager::daemonListRequestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error) {
boost::lock_guard<boost::mutex> lock(mutex);
- try {
- const Common::XmlPacket &packet = request.getResult();
-
- const Common::XmlPacket::Element &hostInfo = packet["hosts"];
+ if(!packet || error) {
+ Common::Logger::logf(Common::Logger::CRITICAL, "Host list request failed: %s", error.strerror().c_str());
+ }
+ else {
+ const Common::XmlPacket::Element &hostInfo = (*packet)["hosts"];
daemons.clear();
@@ -102,13 +105,8 @@ void InformationManager::daemonListRequestFinished(Common::Request &request) {
daemons.insert(std::make_pair(info.getName(), info));
}
}
- catch(Net::Exception &e) {
- Common::Logger::logf(Common::Logger::CRITICAL, "Host list request failed: %s", e.strerror().c_str());
- }
updating = false;
-
- updateCond.notify_all();
}
}
diff --git a/src/Client/InformationManager.h b/src/Client/InformationManager.h
index 239b8d8..a7d2354 100644
--- a/src/Client/InformationManager.h
+++ b/src/Client/InformationManager.h
@@ -38,17 +38,14 @@ class InformationManager : public Common::Initializable, private boost::noncopya
private:
class DaemonStateUpdateRequestHandler : public Common::RequestHandler {
protected:
- virtual void handlePacket(const Common::XmlPacket &packet);
-
- public:
- DaemonStateUpdateRequestHandler(Common::Connection *connection, uint16_t requestId)
- : RequestHandler(connection, requestId) {}
+ virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet);
};
static InformationManager informationManager;
boost::mutex mutex;
- boost::condition_variable updateCond;
+
+ boost::shared_ptr<Common::Request> updateRequest;
std::map<std::string, Common::HostInfo> daemons;
@@ -56,7 +53,7 @@ class InformationManager : public Common::Initializable, private boost::noncopya
InformationManager() : updating(false) {}
- void daemonListRequestFinished(Common::Request &request);
+ void daemonListRequestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error);
protected:
virtual void doInit();
@@ -76,9 +73,11 @@ class InformationManager : public Common::Initializable, private boost::noncopya
void waitWhileUpdating() {
boost::unique_lock<boost::mutex> lock(mutex);
+ boost::shared_ptr<Common::Request> request = updateRequest;
+ lock.unlock();
- while(updating)
- updateCond.wait(lock);
+ if(request)
+ request->wait();
}
diff --git a/src/Client/Requests/DaemonCommandRequest.h b/src/Client/Requests/DaemonCommandRequest.h
index 2e421e8..8559f87 100644
--- a/src/Client/Requests/DaemonCommandRequest.h
+++ b/src/Client/Requests/DaemonCommandRequest.h
@@ -36,8 +36,8 @@ class DaemonCommandRequest : public Common::Request {
virtual void sendRequest();
public:
- DaemonCommandRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, const std::string &daemon0, bool reboot0)
- : Common::Request(connection, requestId, slot), daemon(daemon0), reboot(reboot0) {}
+ DaemonCommandRequest(const std::string &daemon0, bool reboot0)
+ : daemon(daemon0), reboot(reboot0) {}
};
}
diff --git a/src/Client/Requests/DaemonFSInfoRequest.h b/src/Client/Requests/DaemonFSInfoRequest.h
index 17d2aa0..58ca9a6 100644
--- a/src/Client/Requests/DaemonFSInfoRequest.h
+++ b/src/Client/Requests/DaemonFSInfoRequest.h
@@ -36,8 +36,7 @@ class DaemonFSInfoRequest : public Common::Request {
virtual void sendRequest();
public:
- DaemonFSInfoRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, const std::string &daemon0)
- : Common::Request(connection, requestId, slot), daemon(daemon0) {}
+ DaemonFSInfoRequest(const std::string &daemon0) : daemon(daemon0) {}
};
}
diff --git a/src/Client/Requests/DaemonListRequest.h b/src/Client/Requests/DaemonListRequest.h
index 27a025f..d10efab 100644
--- a/src/Client/Requests/DaemonListRequest.h
+++ b/src/Client/Requests/DaemonListRequest.h
@@ -28,8 +28,7 @@ namespace Requests {
class DaemonListRequest : public Common::Requests::SimpleRequest {
public:
- DaemonListRequest(Common::Connection *connection, uint16_t requestId, slot_type slot)
- : SimpleRequest(connection, requestId, slot, "ListHosts") {}
+ DaemonListRequest() : SimpleRequest("ListHosts") {}
};
}
diff --git a/src/Client/Requests/DaemonStatusRequest.h b/src/Client/Requests/DaemonStatusRequest.h
index 936692f..0642187 100644
--- a/src/Client/Requests/DaemonStatusRequest.h
+++ b/src/Client/Requests/DaemonStatusRequest.h
@@ -36,8 +36,7 @@ class DaemonStatusRequest : public Common::Request {
virtual void sendRequest();
public:
- DaemonStatusRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, const std::string &daemon0)
- : Common::Request(connection, requestId, slot), daemon(daemon0) {}
+ DaemonStatusRequest(const std::string &daemon0) : daemon(daemon0) {}
};
}