diff options
Diffstat (limited to 'src')
70 files changed, 715 insertions, 962 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) {} }; } diff --git a/src/Common/CMakeLists.txt b/src/Common/CMakeLists.txt index fe18760..de6dfc7 100644 --- a/src/Common/CMakeLists.txt +++ b/src/Common/CMakeLists.txt @@ -8,7 +8,7 @@ link_directories(${LTDL_LIBRARY_DIR}) add_library(Common Base64Encoder.cpp ClientConnection.cpp ConfigEntry.cpp ConfigManager.cpp Connection.cpp Initializable.cpp Logger.cpp LogManager.cpp - ModuleManager.cpp Request.cpp RequestManager.cpp SystemManager.cpp Tokenizer.cpp - XmlPacket.cpp + ModuleManager.cpp Request.cpp RequestHandler.cpp RequestManager.cpp SystemManager.cpp + Tokenizer.cpp XmlPacket.cpp ) target_link_libraries(Common RequestHandlers Requests Net ${LIBXML2_LIBRARIES} ${LTDL_LIBRARIES}) diff --git a/src/Common/Connection.cpp b/src/Common/Connection.cpp index db962ea..6afd5f0 100644 --- a/src/Common/Connection.cpp +++ b/src/Common/Connection.cpp @@ -24,7 +24,7 @@ namespace Mad { namespace Common { void Connection::receive(boost::shared_ptr<Net::Packet> packet) { - signalReceive.emit(XmlPacket(*packet), packet->getRequestId()); + signalReceive.emit(boost::shared_ptr<XmlPacket>(new XmlPacket(*packet)), packet->getRequestId()); } bool Connection::sendPacket(const XmlPacket &packet, uint16_t requestId) { diff --git a/src/Common/Connection.h b/src/Common/Connection.h index b794a88..6f1cffd 100644 --- a/src/Common/Connection.h +++ b/src/Common/Connection.h @@ -39,7 +39,7 @@ class Connection : private boost::noncopyable { private: bool authenticated; - Net::Signals::Signal2<const XmlPacket&, uint16_t> signalReceive; + Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, uint16_t> signalReceive; protected: Connection() : authenticated(0) {} @@ -53,9 +53,13 @@ class Connection : private boost::noncopyable { bool sendPacket(const XmlPacket &packet, uint16_t requestId); - Net::Signals::Connection connectSignalReceive(const Net::Signals::Signal2<const XmlPacket&, uint16_t>::slot_type &slot) { + Net::Signals::Connection2 connectSignalReceive(const Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, uint16_t>::slot_type &slot) { return signalReceive.connect(slot); } + void disconnectSignalReceive(const Net::Signals::Connection2 &con) { + signalReceive.disconnect(con); + } + virtual bool disconnect() = 0; //virtual void* getCertificate(size_t *size) const = 0; diff --git a/src/Common/Request.cpp b/src/Common/Request.cpp index e27c1b9..723039f 100644 --- a/src/Common/Request.cpp +++ b/src/Common/Request.cpp @@ -22,19 +22,17 @@ namespace Mad { namespace Common { -Request::slot_type Request::empty_slot(&Request::doNothing); - -void Request::handlePacket(const XmlPacket &packet) { - if(packet.getType() == "Error") { - finishWithError(Net::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"])); +void Request::handlePacket(boost::shared_ptr<const XmlPacket> packet) { + if(packet->getType() == "Error") { + signalFinished(Net::Exception((*packet)["Where"], (*packet)["ErrorCode"], (*packet)["SubCode"], (*packet)["SubSubCode"])); return; } - else if(packet.getType() != "OK") { - finishWithError(Net::Exception(Net::Exception::UNEXPECTED_PACKET)); + else if(packet->getType() != "OK") { + signalFinished(Net::Exception(Net::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } - finish(packet); + signalFinished(packet); } } diff --git a/src/Common/Request.h b/src/Common/Request.h index d351c2a..b8477f7 100644 --- a/src/Common/Request.h +++ b/src/Common/Request.h @@ -17,8 +17,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef MAD_COMMON_XMLREQUEST_H_ -#define MAD_COMMON_XMLREQUEST_H_ +#ifndef MAD_COMMON_REQUEST_H_ +#define MAD_COMMON_REQUEST_H_ #include "RequestHandler.h" #include <Net/Exception.h> @@ -37,80 +37,54 @@ class Request : public RequestHandler { private: friend class RequestManager; - Net::Signals::Signal1<Request&> finished; - - std::auto_ptr<XmlPacket> res; - Net::Exception exp; - boost::mutex mutex; boost::condition_variable finishCond; bool isFinished; - static void doNothing(Request&) {} + boost::shared_ptr<const XmlPacket> packet; + Net::Exception exception; - public: - typedef Net::Signals::Signal1<Request&>::slot_type slot_type; + Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, Net::Exception> finished; protected: - static slot_type empty_slot; - - Request(Connection *connection, uint16_t requestId, slot_type slot) - : RequestHandler(connection, requestId), exp(Net::Exception::NOT_FINISHED), isFinished(false) { - finished.connect(slot); - finished.connect(boost::bind(&Request::signalFinished, this)); - } - - virtual ~Request() { - wait(); - } + Request() : isFinished(false) {} - void finish(std::auto_ptr<XmlPacket> result) { + void signalFinished(boost::shared_ptr<const XmlPacket> pkt, Net::Exception exp) { { boost::lock_guard<boost::mutex> lock(mutex); - res = result; isFinished = true; + packet = pkt; + exception = exp; } + finished.emit(pkt, exp); finishCond.notify_all(); - finished.emit(*this); - } - void finish(const XmlPacket& result) { - { - boost::lock_guard<boost::mutex> lock(mutex); - - res.reset(new XmlPacket(result)); - isFinished = true; - } - - finishCond.notify_all(); - finished.emit(*this); + RequestHandler::signalFinished(); } - void finishWithError(const Net::Exception &e) { - { - boost::lock_guard<boost::mutex> lock(mutex); + void signalFinished(boost::shared_ptr<const XmlPacket> packet) { + signalFinished(packet, Net::Exception()); + } - exp = e; - isFinished = true; - } + void signalFinished(Net::Exception exp) { + signalFinished(boost::shared_ptr<const XmlPacket>(), exp); + } - finishCond.notify_all(); - finished.emit(*this); + void signalFinished() { + signalFinished(boost::shared_ptr<const XmlPacket>(), Net::Exception()); } virtual void sendRequest() = 0; - virtual void handlePacket(const XmlPacket &packet); + virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet); public: - const XmlPacket& getResult() throw(Net::Exception) { - boost::lock_guard<boost::mutex> lock(mutex); - - if(res.get()) - return *res; - - throw exp; + Net::Signals::Connection2 connectSignalFinished(const Net::Signals::Signal22<boost::shared_ptr<const XmlPacket>, Net::Exception>::slot_type &slot) { + return finished.connect(slot); + } + void disconnectSignalFinished(const Net::Signals::Connection2 &con) { + finished.disconnect(con); } void wait() { @@ -119,9 +93,18 @@ class Request : public RequestHandler { while(!isFinished) finishCond.wait(lock); } + + std::pair<boost::shared_ptr<const XmlPacket>, Net::Exception> getResult() { + boost::lock_guard<boost::mutex> lock(mutex); + + if(!isFinished) + return std::make_pair(boost::shared_ptr<const XmlPacket>(), Net::Exception(Net::Exception::NOT_FINISHED)); + else + return std::make_pair(packet, exception); + } }; } } -#endif /* MAD_COMMON_XMLREQUEST_H_ */ +#endif /* MAD_COMMON_REQUEST_H_ */ diff --git a/src/Common/RequestHandler.cpp b/src/Common/RequestHandler.cpp new file mode 100644 index 0000000..218155d --- /dev/null +++ b/src/Common/RequestHandler.cpp @@ -0,0 +1,40 @@ +/* + * RequestHandler.cpp + * + * Copyright (C) 2009 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 "RequestHandler.h" +#include "RequestManager.h" + +namespace Mad { +namespace Common { + +Connection* RequestHandler::getConnection() const { + return RequestManager::get()->requestMap.getRequestInfo(this).first; +} + +void RequestHandler::sendPacket(const XmlPacket &packet) { + std::pair<Connection*, boost::uint16_t> requestInfo = RequestManager::get()->requestMap.getRequestInfo(this); + + if(!requestInfo.first) + return; + + requestInfo.first->sendPacket(packet, requestInfo.second); +} + +} +} diff --git a/src/Common/RequestHandler.h b/src/Common/RequestHandler.h index d35ab1b..87fccba 100644 --- a/src/Common/RequestHandler.h +++ b/src/Common/RequestHandler.h @@ -17,8 +17,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef MAD_COMMON_XMLREQUESTHANDLER_H_ -#define MAD_COMMON_XMLREQUESTHANDLER_H_ +#ifndef MAD_COMMON_REQUESTHANDLER_H_ +#define MAD_COMMON_REQUESTHANDLER_H_ #include "Connection.h" #include "XmlPacket.h" @@ -26,6 +26,8 @@ #include <Net/Signals/Signals.h> #include <boost/cstdint.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/mutex.hpp> namespace Mad { namespace Common { @@ -35,43 +37,42 @@ class RequestManager; class RequestHandler : private boost::noncopyable { private: - Net::Signals::Signal0 finished; + friend class RequestManager; - Connection *connection; - boost::uint16_t requestId; + boost::mutex mutex; - protected: - RequestHandler(Connection *connection0, boost::uint16_t requestId0) : connection(connection0), requestId(requestId0) {} + Net::Signals::Signal20 finished; - void signalFinished() { - finished.emit(); + void callHandlePacket(boost::shared_ptr<const XmlPacket> packet) { + boost::lock_guard<boost::mutex> lock(mutex); + handlePacket(packet); } - Net::Signals::Connection connectSignalFinished(const Net::Signals::Signal0::slot_type &slot) { - return finished.connect(slot); - } + protected: + RequestHandler() {} - Connection* getConnection() const { - return connection; + void signalFinished() { + finished.emit(); } - boost::uint16_t getRequestId() const { - return requestId; - } + Connection* getConnection() const; - void sendPacket(const XmlPacket &packet) { - connection->sendPacket(packet, requestId); - } + void sendPacket(const XmlPacket &packet); - virtual void handlePacket(const XmlPacket &packet) = 0; + virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet) = 0; public: virtual ~RequestHandler() {} - friend class RequestManager; + Net::Signals::Connection2 connectSignalFinished(const Net::Signals::Signal20::slot_type &slot) { + return finished.connect(slot); + } + void disconnectSignalFinished(const Net::Signals::Connection2 &con) { + finished.disconnect(con); + } }; } } -#endif /* MAD_COMMON_XMLREQUESTHANDLER_H_ */ +#endif /* MAD_COMMON_REQUESTHANDLER_H_ */ diff --git a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp index ac8e7dc..942da0a 100644 --- a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp +++ b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp @@ -25,8 +25,8 @@ namespace Mad { namespace Common { namespace RequestHandlers { -void DisconnectRequestHandler::handlePacket(const XmlPacket &packet) { - if(packet.getType() != "Disconnect") { +void DisconnectRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packet) { + if(packet->getType() != "Disconnect") { Logger::log(Logger::ERROR, "Received an unexpected packet."); XmlPacket ret; diff --git a/src/Common/RequestHandlers/DisconnectRequestHandler.h b/src/Common/RequestHandlers/DisconnectRequestHandler.h index 05b9c50..963f603 100644 --- a/src/Common/RequestHandlers/DisconnectRequestHandler.h +++ b/src/Common/RequestHandlers/DisconnectRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class DisconnectRequestHandler : public RequestHandler { protected: - virtual void handlePacket(const XmlPacket &packet); - - public: - DisconnectRequestHandler(Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet); }; } diff --git a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp index 9044c68..845258b 100644 --- a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp +++ b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp @@ -27,8 +27,8 @@ namespace Mad { namespace Common { namespace RequestHandlers { -void FSInfoRequestHandler::handlePacket(const XmlPacket &packet) { - if(packet.getType() != "FSInfo") { +void FSInfoRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packet) { + if(packet->getType() != "FSInfo") { Logger::log(Logger::ERROR, "Received an unexpected packet."); XmlPacket ret; diff --git a/src/Common/RequestHandlers/FSInfoRequestHandler.h b/src/Common/RequestHandlers/FSInfoRequestHandler.h index 47fcbd8..6d21787 100644 --- a/src/Common/RequestHandlers/FSInfoRequestHandler.h +++ b/src/Common/RequestHandlers/FSInfoRequestHandler.h @@ -31,11 +31,7 @@ namespace RequestHandlers { class FSInfoRequestHandler : public RequestHandler { protected: - virtual void handlePacket(const XmlPacket &packet); - - public: - FSInfoRequestHandler(Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet); }; } diff --git a/src/Common/RequestHandlers/StatusRequestHandler.cpp b/src/Common/RequestHandlers/StatusRequestHandler.cpp index e766670..989ce7c 100644 --- a/src/Common/RequestHandlers/StatusRequestHandler.cpp +++ b/src/Common/RequestHandlers/StatusRequestHandler.cpp @@ -28,8 +28,8 @@ namespace Mad { namespace Common { namespace RequestHandlers { -void StatusRequestHandler::handlePacket(const XmlPacket &packet) { - if(packet.getType() != "GetStatus") { +void StatusRequestHandler::handlePacket(boost::shared_ptr<const XmlPacket> packet) { + if(packet->getType() != "GetStatus") { Logger::log(Logger::ERROR, "Received an unexpected packet."); XmlPacket ret; diff --git a/src/Common/RequestHandlers/StatusRequestHandler.h b/src/Common/RequestHandlers/StatusRequestHandler.h index 151852c..656a1a5 100644 --- a/src/Common/RequestHandlers/StatusRequestHandler.h +++ b/src/Common/RequestHandlers/StatusRequestHandler.h @@ -29,11 +29,7 @@ namespace RequestHandlers { class StatusRequestHandler : public RequestHandler { protected: - virtual void handlePacket(const XmlPacket &packet); - - public: - StatusRequestHandler(Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet); }; } diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index da9979a..3817ff5 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -29,71 +29,105 @@ namespace Common { RequestManager RequestManager::requestManager; -bool RequestManager::RequestMap::addRequest(boost::uint16_t id, boost::shared_ptr<RequestHandler> info) { - if(!insert(std::make_pair(id, info)).second) +void RequestManager::RequestMap::unregisterConnection(Connection *connection) { + std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(connection); + if(idMap == connectionMap.end()) + return; + + for(IdMap::iterator request = idMap->second.begin(); request != idMap->second.end(); ++request) + handlerMap.erase(request->second.get()); + + connectionMap.erase(idMap); +} + +bool RequestManager::RequestMap::addRequest(Connection *con, boost::uint16_t id, boost::shared_ptr<RequestHandler> request) { + std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(con); + if(idMap == connectionMap.end()) + return false; + + if(!idMap->second.insert(std::make_pair(id, request)).second) return false; - info->connectSignalFinished(boost::bind(&RequestManager::RequestMap::deleteRequest, this, id)); + if(!handlerMap.insert(std::make_pair(request.get(), std::make_pair(con, id))).second) { + idMap->second.erase(id); + return false; + } return true; } -boost::shared_ptr<RequestHandler> RequestManager::RequestMap::findRequest(boost::uint16_t id) { - iterator it = find(id); - if(it == end()) +boost::shared_ptr<RequestHandler> RequestManager::RequestMap::findRequest(Connection *con, boost::uint16_t id) { + std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(con); + if(idMap == connectionMap.end()) + return boost::shared_ptr<RequestHandler>(); + + IdMap::iterator it = idMap->second.find(id); + if(it == idMap->second.end()) return boost::shared_ptr<RequestHandler>(); return it->second; } -void RequestManager::RequestMap::deleteRequest(boost::uint16_t id) { - Net::ThreadManager::get()->pushWork(boost::bind(&RequestMap::doDeleteRequest, this, id)); +void RequestManager::RequestMap::deleteRequest(Connection *con, boost::uint16_t id) { + std::map<Connection*, IdMap>::iterator idMap = connectionMap.find(con); + if(idMap == connectionMap.end()) + return; + + IdMap::iterator it = idMap->second.find(id); + if(it == idMap->second.end()) + return; + + handlerMap.erase(it->second.get()); + idMap->second.erase(it); } -void RequestManager::RequestMap::doDeleteRequest(boost::uint16_t id) { - erase(id); +std::pair<Connection*, boost::uint16_t> RequestManager::RequestMap::getRequestInfo(const RequestHandler *requestHandler) { + HandlerMap::iterator it = handlerMap.find(requestHandler); + if(it == handlerMap.end()) + return std::pair<Connection*, boost::uint16_t>(0, 0); + else + return it->second; } -void RequestManager::receiveHandler(Connection *connection, const XmlPacket &packet, boost::uint16_t requestId) { +void RequestManager::receiveHandler(Connection *connection, boost::shared_ptr<const XmlPacket> packet, boost::uint16_t requestId) { boost::upgrade_lock<boost::shared_mutex> lock(mutex); - std::map<Connection*, boost::shared_ptr<RequestMap> >::iterator it = requestMaps.find(connection); - if(it == requestMaps.end()) { - // TODO: Error - Logger::log(Logger::ERROR, "Received a packet from an unregistered connection."); + boost::shared_ptr<RequestHandler> request = requestMap.findRequest(connection, requestId); + if(request) { + lock.unlock(); + request->callHandlePacket(packet); return; } - boost::shared_ptr<RequestMap> requestMap = it->second; - boost::shared_ptr<RequestHandler> request = requestMap->findRequest(requestId); - - if(request) { - lock.unlock(); - request->handlePacket(packet); + if(!requestMap.isConnectionRegistered(connection)) { + // TODO: Error + Logger::log(Logger::ERROR, "Received a packet from an unregistered connection."); return; } - std::map<std::string, boost::shared_ptr<RequestHandlerFactory> >::iterator factoryIt = requestHandlerFactories.find(packet.getType()); + std::map<std::string, boost::shared_ptr<RequestHandlerFactory> >::iterator factoryIt = requestHandlerFactories.find(packet->getType()); if(factoryIt != requestHandlerFactories.end()) { { boost::upgrade_to_unique_lock<boost::shared_mutex> upgradeLock(lock); - request = factoryIt->second->createRequestHandler(connection, requestId); - requestMap->addRequest(requestId, request); + request = factoryIt->second->createRequestHandler(); + requestMap.addRequest(connection, requestId, request); + request->connectSignalFinished(boost::bind(&RequestManager::handleRequestFinished, this, connection, requestId)); + } lock.unlock(); - request->handlePacket(packet); + request->callHandlePacket(packet); return; } lock.unlock(); - Logger::logf(Logger::ERROR, "Received an unexpected packet with type '%s'.", packet.getType().c_str()); + Logger::logf(Logger::ERROR, "Received an unexpected packet with type '%s'.", packet->getType().c_str()); XmlPacket ret; ret.setType("Error"); @@ -102,28 +136,37 @@ void RequestManager::receiveHandler(Connection *connection, const XmlPacket &pac connection->sendPacket(ret, requestId); } -boost::shared_ptr<RequestManager::RequestMap> RequestManager::_getUnusedRequestId(Connection *connection, boost::uint16_t *requestId) { - std::map<Connection*, boost::shared_ptr<RequestMap> >::iterator it = requestMaps.find(connection); +// XXX Error handling! +bool RequestManager::sendRequest(Connection *connection, boost::shared_ptr<Request> request) { + boost::unique_lock<boost::shared_mutex> lock(mutex); - if(it == requestMaps.end()) { + if(!requestMap.isConnectionRegistered(connection)) { Logger::log(Logger::CRITICAL, "Trying to send a request over an unregistered connecion."); - return boost::shared_ptr<RequestMap>(); + return false; } - boost::shared_ptr<RequestMap> requestMap = it->second; + uint16_t requestId = _getUnusedRequestId(connection); + requestMap.addRequest(connection, requestId, request); + request->connectSignalFinished(boost::bind(&RequestManager::handleRequestFinished, this, connection, requestId)); + lock.unlock(); + + Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request)); - do { - *requestId = _getRequestId(); - } while(requestMap->findRequest(*requestId)); + return true; +} - return requestMap; +boost::uint16_t RequestManager::_getUnusedRequestId(Connection *connection) { + while(true) { + boost::uint16_t requestId = _getRequestId(); + if(!requestMap.findRequest(connection, requestId)) + return requestId; + } } void RequestManager::registerConnection(Connection *connection) { boost::lock_guard<boost::shared_mutex> lock(mutex); - requestMaps.insert(std::make_pair(connection, new RequestMap())); - + requestMap.registerConnection(connection); connection->connectSignalReceive(boost::bind(&RequestManager::receiveHandler, this, connection, _1, _2)); } diff --git a/src/Common/RequestManager.h b/src/Common/RequestManager.h index bd1c12d..07a7c05 100644 --- a/src/Common/RequestManager.h +++ b/src/Common/RequestManager.h @@ -21,7 +21,6 @@ #define MAD_COMMON_REQUESTMANAGER_H_ #include "Request.h" -#include <Net/ThreadManager.h> #include <map> #include <memory> @@ -40,29 +39,49 @@ namespace Common { class RequestManager : boost::noncopyable { private: - class RequestMap : private std::map<boost::uint16_t, boost::shared_ptr<RequestHandler> >, boost::noncopyable { - public: - bool addRequest(boost::uint16_t id, boost::shared_ptr<RequestHandler> info); - boost::shared_ptr<RequestHandler> findRequest(boost::uint16_t id); - void deleteRequest(boost::uint16_t id); + friend class RequestHandler; + class RequestMap : private boost::noncopyable { private: - void doDeleteRequest(boost::uint16_t id); + typedef std::map<boost::uint16_t, boost::shared_ptr<RequestHandler> > IdMap; + typedef std::map<const RequestHandler*, std::pair<Connection*, boost::uint16_t> > HandlerMap; + + std::map<Connection*, IdMap> connectionMap; + HandlerMap handlerMap; + + public: + void registerConnection(Connection *connection) { + connectionMap.insert(std::make_pair(connection, IdMap())); + } + + void unregisterConnection(Connection *connection); + + bool isConnectionRegistered(Connection *connection) const { + return connectionMap.count(connection); + } + + bool addRequest(Connection *con, boost::uint16_t id, boost::shared_ptr<RequestHandler> info); + boost::shared_ptr<RequestHandler> findRequest(Connection *con, boost::uint16_t id); + void deleteRequest(Connection *con, boost::uint16_t id); + + std::pair<Connection*, boost::uint16_t> getRequestInfo(const RequestHandler *requestHandler); }; + + class RequestHandlerFactory { protected: RequestHandlerFactory() {} public: - virtual boost::shared_ptr<RequestHandler> createRequestHandler(Connection *connection, boost::uint16_t requestId) = 0; + virtual boost::shared_ptr<RequestHandler> createRequestHandler() = 0; virtual ~RequestHandlerFactory() {} }; template<class T> class SpecificRequestHandlerFactory : public RequestHandlerFactory { public: - virtual boost::shared_ptr<RequestHandler> createRequestHandler(Connection *connection, boost::uint16_t requestId) { - return boost::shared_ptr<RequestHandler>(new T(connection, requestId)); + virtual boost::shared_ptr<RequestHandler> createRequestHandler() { + return boost::shared_ptr<RequestHandler>(new T()); } }; @@ -70,7 +89,8 @@ class RequestManager : boost::noncopyable { boost::shared_mutex mutex; - std::map<Connection*, boost::shared_ptr<RequestMap> > requestMaps; + RequestMap requestMap; + bool server; boost::uint16_t lastRequestId; @@ -80,9 +100,14 @@ class RequestManager : boost::noncopyable { return lastRequestId+=2; } - void receiveHandler(Connection *connection, const XmlPacket &packet, boost::uint16_t requestId); + void receiveHandler(Connection *connection, boost::shared_ptr<const XmlPacket> packet, boost::uint16_t requestId); + + void handleRequestFinished(Connection *con, boost::uint16_t requestId) { + boost::lock_guard<boost::shared_mutex> lock(mutex); + requestMap.deleteRequest(con, requestId); + } - boost::shared_ptr<RequestMap> _getUnusedRequestId(Connection *connection, boost::uint16_t *requestId); + boost::uint16_t _getUnusedRequestId(Connection *connection); bool send(Request *request); @@ -113,7 +138,7 @@ class RequestManager : boost::noncopyable { void unregisterConnection(Connection *connection) { boost::lock_guard<boost::shared_mutex> lock(mutex); - requestMaps.erase(connection); + requestMap.unregisterConnection(connection); } template <class T> void registerPacketType(const std::string &type) { @@ -126,110 +151,7 @@ class RequestManager : boost::noncopyable { requestHandlerFactories.erase(type); } - template <class T> - boost::shared_ptr<Request> sendRequest0(Connection *connection, Request::slot_type slot = Request::empty_slot) { - boost::unique_lock<boost::shared_mutex> lock(mutex); - - boost::shared_ptr<RequestMap> requestMap; - boost::uint16_t requestId; - - requestMap = _getUnusedRequestId(connection, &requestId); - - if(!requestMap) - return boost::shared_ptr<Request>(); - - boost::shared_ptr<Request> request(new T(connection, requestId, slot)); - requestMap->addRequest(requestId, request); - lock.unlock(); - - Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request)); - - return request; - } - - template <class T, typename T1> - boost::shared_ptr<Request> sendRequest1(Connection *connection, T1 t1, Request::slot_type slot = Request::empty_slot) { - boost::unique_lock<boost::shared_mutex> lock(mutex); - - boost::shared_ptr<RequestMap> requestMap; - boost::uint16_t requestId; - - requestMap = _getUnusedRequestId(connection, &requestId); - - if(!requestMap) - return boost::shared_ptr<Request>(); - - boost::shared_ptr<Request> request(new T(connection, requestId, slot, t1)); - requestMap->addRequest(requestId, request); - lock.unlock(); - - Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request)); - - return request; - } - - template <class T, typename T1, typename T2> - boost::shared_ptr<Request> sendRequest2(Connection *connection, T1 t1, T2 t2, Request::slot_type slot = Request::empty_slot) { - boost::unique_lock<boost::shared_mutex> lock(mutex); - - boost::shared_ptr<RequestMap> requestMap; - boost::uint16_t requestId; - - requestMap = _getUnusedRequestId(connection, &requestId); - - if(!requestMap) - return boost::shared_ptr<Request>(); - - boost::shared_ptr<Request> request(new T(connection, requestId, slot, t1, t2)); - requestMap->addRequest(requestId, request); - lock.unlock(); - - Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request)); - - return request; - } - - template <class T, typename T1, typename T2, typename T3> - boost::shared_ptr<Request> sendRequest3(Connection *connection, T1 t1, T2 t2, T3 t3, Request::slot_type slot = Request::empty_slot) { - boost::unique_lock<boost::shared_mutex> lock(mutex); - - boost::shared_ptr<RequestMap> requestMap; - boost::uint16_t requestId; - - requestMap = _getUnusedRequestId(connection, &requestId); - - if(!requestMap) - return boost::shared_ptr<Request>(); - - boost::shared_ptr<T> request(new T(connection, requestId, slot, t1, t2, t3)); - requestMap->addRequest(requestId, request); - lock.unlock(); - - Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request)); - - return request; - } - - template <class T, typename T1, typename T2, typename T3, typename T4> - boost::shared_ptr<Request> sendRequest4(Connection *connection, T1 t1, T2 t2, T3 t3, T4 t4, Request::slot_type slot = Request::empty_slot) { - boost::unique_lock<boost::shared_mutex> lock(mutex); - - boost::shared_ptr<RequestMap> requestMap; - boost::uint16_t requestId; - - requestMap = _getUnusedRequestId(connection, &requestId); - - if(!requestMap) - return boost::shared_ptr<Request>(); - - boost::shared_ptr<Request> request(new T(connection, requestId, slot, t1, t2, t3, t4)); - requestMap->addRequest(requestId, request); - lock.unlock(); - - Net::ThreadManager::get()->pushWork(boost::bind(&Request::sendRequest, request)); - - return request; - } + bool sendRequest(Connection *connection, boost::shared_ptr<Request> request); }; } diff --git a/src/Common/Requests/DisconnectRequest.cpp b/src/Common/Requests/DisconnectRequest.cpp index 3fac25b..249bbc1 100644 --- a/src/Common/Requests/DisconnectRequest.cpp +++ b/src/Common/Requests/DisconnectRequest.cpp @@ -30,19 +30,19 @@ void DisconnectRequest::sendRequest() { sendPacket(packet); } -void DisconnectRequest::handlePacket(const XmlPacket &packet) { - if(packet.getType() == "Error") { - finishWithError(Net::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"])); +void DisconnectRequest::handlePacket(boost::shared_ptr<const XmlPacket> packet) { + if(packet->getType() == "Error") { + signalFinished(Net::Exception((*packet)["Where"], (*packet)["ErrorCode"], (*packet)["SubCode"], (*packet)["SubSubCode"])); return; } - else if(packet.getType() != "OK") { - finishWithError(Net::Exception(Net::Exception::UNEXPECTED_PACKET)); + else if(packet->getType() != "OK") { + signalFinished(Net::Exception(Net::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } getConnection()->disconnect(); - finish(packet); + signalFinished(packet); } } diff --git a/src/Common/Requests/DisconnectRequest.h b/src/Common/Requests/DisconnectRequest.h index b4fd4db..6da0ac9 100644 --- a/src/Common/Requests/DisconnectRequest.h +++ b/src/Common/Requests/DisconnectRequest.h @@ -29,11 +29,7 @@ namespace Requests { class DisconnectRequest : public Request { protected: virtual void sendRequest(); - virtual void handlePacket(const XmlPacket &packet); - - public: - DisconnectRequest(Connection *connection, uint16_t requestId, slot_type slot) - : Request(connection, requestId, slot) {} + virtual void handlePacket(boost::shared_ptr<const XmlPacket> packet); }; } diff --git a/src/Common/Requests/FSInfoRequest.h b/src/Common/Requests/FSInfoRequest.h index 1db7753..250889a 100644 --- a/src/Common/Requests/FSInfoRequest.h +++ b/src/Common/Requests/FSInfoRequest.h @@ -28,8 +28,7 @@ namespace Requests { class FSInfoRequest : public SimpleRequest { public: - FSInfoRequest(Connection *connection, uint16_t requestId, slot_type slot) - : SimpleRequest(connection, requestId, slot, "FSInfo") {} + FSInfoRequest() : SimpleRequest("FSInfo") {} }; } diff --git a/src/Common/Requests/GroupListRequest.h b/src/Common/Requests/GroupListRequest.h index 5aad003..b1e4115 100644 --- a/src/Common/Requests/GroupListRequest.h +++ b/src/Common/Requests/GroupListRequest.h @@ -28,8 +28,7 @@ namespace Requests { class GroupListRequest : public SimpleRequest { public: - GroupListRequest(Connection *connection, uint16_t requestId, slot_type slot) - : SimpleRequest(connection, requestId, slot, "ListGroups") {} + GroupListRequest() : SimpleRequest("ListGroups") {} }; } diff --git a/src/Common/Requests/GroupUserListRequest.h b/src/Common/Requests/GroupUserListRequest.h index fd56a2f..bb735f1 100644 --- a/src/Common/Requests/GroupUserListRequest.h +++ b/src/Common/Requests/GroupUserListRequest.h @@ -34,8 +34,7 @@ class GroupUserListRequest : public Request { virtual void sendRequest(); public: - GroupUserListRequest(Connection *connection, uint16_t requestId, slot_type slot, unsigned long gid0) - : Request(connection, requestId, slot), gid(gid0) {} + GroupUserListRequest(unsigned long gid0) : gid(gid0) {} }; } diff --git a/src/Common/Requests/IdentifyRequest.h b/src/Common/Requests/IdentifyRequest.h index 3798909..3084ce6 100644 --- a/src/Common/Requests/IdentifyRequest.h +++ b/src/Common/Requests/IdentifyRequest.h @@ -36,8 +36,7 @@ class IdentifyRequest : public Common::Request { virtual void sendRequest(); public: - IdentifyRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, const std::string &hostname0 = std::string()) - : Common::Request(connection, requestId, slot), hostname(hostname0) {} + IdentifyRequest(const std::string &hostname0 = std::string()) : hostname(hostname0) {} }; } diff --git a/src/Common/Requests/SimpleRequest.h b/src/Common/Requests/SimpleRequest.h index 2c3070a..d381ecf 100644 --- a/src/Common/Requests/SimpleRequest.h +++ b/src/Common/Requests/SimpleRequest.h @@ -34,8 +34,7 @@ class SimpleRequest : public Request { virtual void sendRequest(); - SimpleRequest(Connection *connection, uint16_t requestId, slot_type slot, const std::string &type0) - : Request(connection, requestId, slot), type(type0) {} + SimpleRequest(const std::string &type0) : type(type0) {} }; } diff --git a/src/Common/Requests/StatusRequest.h b/src/Common/Requests/StatusRequest.h index 0663fc4..b9b9f02 100644 --- a/src/Common/Requests/StatusRequest.h +++ b/src/Common/Requests/StatusRequest.h @@ -28,8 +28,7 @@ namespace Requests { class StatusRequest : public SimpleRequest { public: - StatusRequest(Connection *connection, uint16_t requestId, slot_type slot) - : SimpleRequest(connection, requestId, slot, "GetStatus") {} + StatusRequest() : SimpleRequest("GetStatus") {} }; } diff --git a/src/Common/Requests/UserGroupListRequest.h b/src/Common/Requests/UserGroupListRequest.h index 2ee33d9..82db411 100644 --- a/src/Common/Requests/UserGroupListRequest.h +++ b/src/Common/Requests/UserGroupListRequest.h @@ -34,8 +34,7 @@ class UserGroupListRequest : public Request { virtual void sendRequest(); public: - UserGroupListRequest(Connection *connection, uint16_t requestId, slot_type slot, unsigned long uid0) - : Request(connection, requestId, slot), uid(uid0) {} + UserGroupListRequest(unsigned long uid0) : uid(uid0) {} }; } diff --git a/src/Common/Requests/UserInfoRequest.h b/src/Common/Requests/UserInfoRequest.h index 27cf1af..c9ac89b 100644 --- a/src/Common/Requests/UserInfoRequest.h +++ b/src/Common/Requests/UserInfoRequest.h @@ -34,8 +34,8 @@ class UserInfoRequest : public Request { virtual void sendRequest(); public: - UserInfoRequest(Connection *connection, uint16_t requestId, slot_type slot, unsigned long uid0) - : Request(connection, requestId, slot), uid(uid0) {} + UserInfoRequest(unsigned long uid0) + : uid(uid0) {} }; } diff --git a/src/Common/Requests/UserListRequest.h b/src/Common/Requests/UserListRequest.h index 7ab3ec7..9b69564 100644 --- a/src/Common/Requests/UserListRequest.h +++ b/src/Common/Requests/UserListRequest.h @@ -28,8 +28,7 @@ namespace Requests { class UserListRequest : public SimpleRequest { public: - UserListRequest(Connection *connection, uint16_t requestId, slot_type slot) - : SimpleRequest(connection, requestId, slot, "ListUsers") {} + UserListRequest() : SimpleRequest("ListUsers") {} }; } diff --git a/src/Daemon/Backends/NetworkLogger.h b/src/Daemon/Backends/NetworkLogger.h index 1c5749d..10f5d25 100644 --- a/src/Daemon/Backends/NetworkLogger.h +++ b/src/Daemon/Backends/NetworkLogger.h @@ -34,8 +34,8 @@ class NetworkLogger : public Common::Logger { protected: virtual void logMessage(Common::Logger::MessageCategory category, Common::Logger::MessageLevel level, time_t messageTimestamp, const std::string &message) { - Common::RequestManager::get()->sendRequest4<Requests::LogRequest>(connection, - category, level, messageTimestamp, message); + boost::shared_ptr<Requests::LogRequest> request(new Requests::LogRequest(category, level, messageTimestamp, message)); + Common::RequestManager::get()->sendRequest(connection, request); } public: diff --git a/src/Daemon/RequestHandlers/CommandRequestHandler.cpp b/src/Daemon/RequestHandlers/CommandRequestHandler.cpp index 95e57f1..208d6e0 100644 --- a/src/Daemon/RequestHandlers/CommandRequestHandler.cpp +++ b/src/Daemon/RequestHandlers/CommandRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Daemon { namespace RequestHandlers { -void CommandRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "Command") { +void CommandRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "Command") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -43,7 +43,7 @@ void CommandRequestHandler::handlePacket(const Common::XmlPacket &packet) { // TODO Require authentication // TODO Error handling - std::string command = packet["command"]; + std::string command = (*packet)["command"]; Common::XmlPacket ret; diff --git a/src/Daemon/RequestHandlers/CommandRequestHandler.h b/src/Daemon/RequestHandlers/CommandRequestHandler.h index a033c75..be560f7 100644 --- a/src/Daemon/RequestHandlers/CommandRequestHandler.h +++ b/src/Daemon/RequestHandlers/CommandRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class CommandRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - CommandRequestHandler(Common::Connection *connection, boost::uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Daemon/Requests/LogRequest.h b/src/Daemon/Requests/LogRequest.h index cb8a111..bf675e3 100644 --- a/src/Daemon/Requests/LogRequest.h +++ b/src/Daemon/Requests/LogRequest.h @@ -39,8 +39,8 @@ class LogRequest : public Common::Request { virtual void sendRequest(); public: - LogRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, Common::Logger::MessageCategory category0, Common::Logger::MessageLevel level0, time_t messageTimestamp0, const std::string &message0) - : Common::Request(connection, requestId, slot), category(category0), level(level0), messageTimestamp(messageTimestamp0), message(message0) {} + LogRequest(Common::Logger::MessageCategory category0, Common::Logger::MessageLevel level0, time_t messageTimestamp0, const std::string &message0) + : category(category0), level(level0), messageTimestamp(messageTimestamp0), message(message0) {} }; } diff --git a/src/Net/Exception.h b/src/Net/Exception.h index 8522528..1ddf5f4 100644 --- a/src/Net/Exception.h +++ b/src/Net/Exception.h @@ -42,9 +42,9 @@ class Exception { long subSubCode; public: - Exception(const std::string &where0, ErrorCode errorCode0, long subCode0 = 0, long subSubCode0 = 0) + Exception(const std::string &where0, ErrorCode errorCode0 = SUCCESS, long subCode0 = 0, long subSubCode0 = 0) : where(where0), errorCode(errorCode0), subCode(subCode0), subSubCode(subSubCode0) {} - Exception(ErrorCode errorCode0, long subCode0 = 0, long subSubCode0 = 0) : errorCode(errorCode0), subCode(subCode0), subSubCode(subSubCode0) {} + Exception(ErrorCode errorCode0 = SUCCESS, long subCode0 = 0, long subSubCode0 = 0) : errorCode(errorCode0), subCode(subCode0), subSubCode(subSubCode0) {} virtual ~Exception() {} const std::string& getWhere() const {return where;} @@ -53,6 +53,10 @@ class Exception { long getSubSubCode() const {return subSubCode;} std::string strerror() const; + + operator bool() const { + return (errorCode != SUCCESS); + } }; } diff --git a/src/Server/ConnectionManager.cpp b/src/Server/ConnectionManager.cpp index cd02d21..3743e43 100644 --- a/src/Server/ConnectionManager.cpp +++ b/src/Server/ConnectionManager.cpp @@ -85,8 +85,10 @@ void ConnectionManager::updateState(Common::HostInfo *hostInfo, Common::HostInfo for(std::set<boost::shared_ptr<ServerConnection> >::iterator con = connections.begin(); con != connections.end(); ++con) { - if((*con)->getConnectionType() == ServerConnection::CLIENT) - Common::RequestManager::get()->sendRequest2<Requests::DaemonStateUpdateRequest>(con->get(), hostInfo->getName(), state, boost::bind(&ConnectionManager::updateStateFinished, this, _1)); + if((*con)->getConnectionType() == ServerConnection::CLIENT) { + boost::shared_ptr<Requests::DaemonStateUpdateRequest> request(new Requests::DaemonStateUpdateRequest(hostInfo->getName(), state)); + Common::RequestManager::get()->sendRequest(con->get(), request); + } } } diff --git a/src/Server/ConnectionManager.h b/src/Server/ConnectionManager.h index 710665d..92cce11 100644 --- a/src/Server/ConnectionManager.h +++ b/src/Server/ConnectionManager.h @@ -101,9 +101,6 @@ class ConnectionManager : public Common::Configurable, public Common::Initializa std::map<std::string,Common::HostInfo> daemonInfo; void updateState(Common::HostInfo *hostInfo, Common::HostInfo::State state); - void updateStateFinished(const Common::Request&) { - // TODO Error handling (updateStateFinished) - } ConnectionManager() {} diff --git a/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp b/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp index 0a7bd39..65592a1 100644 --- a/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp @@ -27,8 +27,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void DaemonCommandRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "DaemonCommand") { +void DaemonCommandRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "DaemonCommand") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -43,12 +43,14 @@ void DaemonCommandRequestHandler::handlePacket(const Common::XmlPacket &packet) // TODO Require authentication - std::string command = packet["command"]; + std::string command = (*packet)["command"]; try { - boost::shared_ptr<Common::Connection> daemonCon = ConnectionManager::get()->getDaemonConnection(packet["daemon"]); - Common::RequestManager::get()->sendRequest1<Requests::CommandRequest>(daemonCon.get(), - command == "reboot", boost::bind(&DaemonCommandRequestHandler::requestFinished, this, _1)); + boost::shared_ptr<Common::Connection> daemonCon = ConnectionManager::get()->getDaemonConnection((*packet)["daemon"]); + + boost::shared_ptr<Requests::CommandRequest> request(new Requests::CommandRequest(command == "reboot")); + request->connectSignalFinished(boost::bind(&DaemonCommandRequestHandler::requestFinished, this, _1, _2)); + Common::RequestManager::get()->sendRequest(daemonCon.get(), request); } catch(Net::Exception &e) { Common::XmlPacket ret; @@ -62,20 +64,20 @@ void DaemonCommandRequestHandler::handlePacket(const Common::XmlPacket &packet) } } -void DaemonCommandRequestHandler::requestFinished(Common::Request &request) { - try { - sendPacket(request.getResult()); - } - catch(Net::Exception &e) { +void DaemonCommandRequestHandler::requestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error) { + if(error) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", e.getErrorCode()); - ret.add("SubCode", e.getSubCode()); - ret.add("SubSubCode", e.getSubSubCode()); - ret.add("Where", e.getWhere()); + ret.add("ErrorCode", error.getErrorCode()); + ret.add("SubCode", error.getSubCode()); + ret.add("SubSubCode", error.getSubSubCode()); + ret.add("Where", error.getWhere()); sendPacket(ret); } + else { + sendPacket(*packet); + } signalFinished(); } diff --git a/src/Server/RequestHandlers/DaemonCommandRequestHandler.h b/src/Server/RequestHandlers/DaemonCommandRequestHandler.h index b0b49df..4595372 100644 --- a/src/Server/RequestHandlers/DaemonCommandRequestHandler.h +++ b/src/Server/RequestHandlers/DaemonCommandRequestHandler.h @@ -30,14 +30,10 @@ namespace RequestHandlers { class DaemonCommandRequestHandler : public Common::RequestHandler { private: - void requestFinished(Common::Request &request); + void requestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error); protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - DaemonCommandRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp b/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp index a9791b5..c66e3d3 100644 --- a/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp @@ -27,8 +27,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void DaemonFSInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "DaemonFSInfo") { +void DaemonFSInfoRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "DaemonFSInfo") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -44,9 +44,11 @@ void DaemonFSInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { // TODO Require authentication try { - boost::shared_ptr<Common::Connection> daemonCon = ConnectionManager::get()->getDaemonConnection(packet["daemon"]); - Common::RequestManager::get()->sendRequest0<Common::Requests::FSInfoRequest>(daemonCon.get(), - boost::bind(&DaemonFSInfoRequestHandler::requestFinished, this, _1)); + boost::shared_ptr<Common::Connection> daemonCon = ConnectionManager::get()->getDaemonConnection((*packet)["daemon"]); + + boost::shared_ptr<Common::Requests::FSInfoRequest> request(new Common::Requests::FSInfoRequest); + request->connectSignalFinished(boost::bind(&DaemonFSInfoRequestHandler::requestFinished, this, _1, _2)); + Common::RequestManager::get()->sendRequest(daemonCon.get(), request); } catch(Net::Exception &e) { Common::XmlPacket ret; @@ -60,20 +62,20 @@ void DaemonFSInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { } } -void DaemonFSInfoRequestHandler::requestFinished(Common::Request &request) { - try { - sendPacket(request.getResult()); - } - catch(Net::Exception &e) { +void DaemonFSInfoRequestHandler::requestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error) { + if(error) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", e.getErrorCode()); - ret.add("SubCode", e.getSubCode()); - ret.add("SubSubCode", e.getSubSubCode()); - ret.add("Where", e.getWhere()); + ret.add("ErrorCode", error.getErrorCode()); + ret.add("SubCode", error.getSubCode()); + ret.add("SubSubCode", error.getSubSubCode()); + ret.add("Where", error.getWhere()); sendPacket(ret); } + else { + sendPacket(*packet); + } signalFinished(); } diff --git a/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.h b/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.h index 5d2ae1c..baf60f7 100644 --- a/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.h +++ b/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.h @@ -30,14 +30,10 @@ namespace RequestHandlers { class DaemonFSInfoRequestHandler : public Common::RequestHandler { private: - void requestFinished(Common::Request &request); + void requestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error); protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - DaemonFSInfoRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/DaemonListRequestHandler.cpp b/src/Server/RequestHandlers/DaemonListRequestHandler.cpp index f960eaa..63d6bb3 100644 --- a/src/Server/RequestHandlers/DaemonListRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonListRequestHandler.cpp @@ -25,8 +25,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void DaemonListRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "ListHosts") { +void DaemonListRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "ListHosts") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; diff --git a/src/Server/RequestHandlers/DaemonListRequestHandler.h b/src/Server/RequestHandlers/DaemonListRequestHandler.h index 8726962..adbdabb 100644 --- a/src/Server/RequestHandlers/DaemonListRequestHandler.h +++ b/src/Server/RequestHandlers/DaemonListRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class DaemonListRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - DaemonListRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp b/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp index 94df846..114260d 100644 --- a/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp @@ -27,8 +27,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void DaemonStatusRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "GetDaemonStatus") { +void DaemonStatusRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "GetDaemonStatus") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -43,12 +43,12 @@ void DaemonStatusRequestHandler::handlePacket(const Common::XmlPacket &packet) { // TODO Require authentication - std::string daemonName = packet["daemonName"]; - try { - boost::shared_ptr<Common::Connection> daemonCon = ConnectionManager::get()->getDaemonConnection(daemonName); - Common::RequestManager::get()->sendRequest0<Common::Requests::StatusRequest>(daemonCon.get(), - boost::bind(&DaemonStatusRequestHandler::requestFinished, this, _1)); + boost::shared_ptr<Common::Connection> daemonCon = ConnectionManager::get()->getDaemonConnection((*packet)["daemonName"]); + + boost::shared_ptr<Common::Requests::StatusRequest> request(new Common::Requests::StatusRequest); + request->connectSignalFinished(boost::bind(&DaemonStatusRequestHandler::requestFinished, this, _1, _2)); + Common::RequestManager::get()->sendRequest(daemonCon.get(), request); } catch(Net::Exception &e) { Common::XmlPacket ret; @@ -62,20 +62,20 @@ void DaemonStatusRequestHandler::handlePacket(const Common::XmlPacket &packet) { } } -void DaemonStatusRequestHandler::requestFinished(Common::Request &request) { - try { - sendPacket(request.getResult()); - } - catch(Net::Exception &e) { +void DaemonStatusRequestHandler::requestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error) { + if(error) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", e.getErrorCode()); - ret.add("SubCode", e.getSubCode()); - ret.add("SubSubCode", e.getSubSubCode()); - ret.add("Where", e.getWhere()); + ret.add("ErrorCode", error.getErrorCode()); + ret.add("SubCode", error.getSubCode()); + ret.add("SubSubCode", error.getSubSubCode()); + ret.add("Where", error.getWhere()); sendPacket(ret); } + else { + sendPacket(*packet); + } signalFinished(); } diff --git a/src/Server/RequestHandlers/DaemonStatusRequestHandler.h b/src/Server/RequestHandlers/DaemonStatusRequestHandler.h index de7f83d..728be4a 100644 --- a/src/Server/RequestHandlers/DaemonStatusRequestHandler.h +++ b/src/Server/RequestHandlers/DaemonStatusRequestHandler.h @@ -30,14 +30,10 @@ namespace RequestHandlers { class DaemonStatusRequestHandler : public Common::RequestHandler { private: - void requestFinished(Common::Request &request); + void requestFinished(boost::shared_ptr<const Common::XmlPacket> packet, Net::Exception error); protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - DaemonStatusRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/GroupListRequestHandler.cpp b/src/Server/RequestHandlers/GroupListRequestHandler.cpp index 5d8c9be..453f4c2 100644 --- a/src/Server/RequestHandlers/GroupListRequestHandler.cpp +++ b/src/Server/RequestHandlers/GroupListRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void GroupListRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "ListGroups") { +void GroupListRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "ListGroups") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; diff --git a/src/Server/RequestHandlers/GroupListRequestHandler.h b/src/Server/RequestHandlers/GroupListRequestHandler.h index d7d6a9c..8654708 100644 --- a/src/Server/RequestHandlers/GroupListRequestHandler.h +++ b/src/Server/RequestHandlers/GroupListRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class GroupListRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - GroupListRequestHandler(Common::Connection *connection, boost::uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/GroupUserListRequestHandler.cpp b/src/Server/RequestHandlers/GroupUserListRequestHandler.cpp index 07ed446..f862e8b 100644 --- a/src/Server/RequestHandlers/GroupUserListRequestHandler.cpp +++ b/src/Server/RequestHandlers/GroupUserListRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void GroupUserListRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "ListGroupUsers") { +void GroupUserListRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "ListGroupUsers") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -45,7 +45,7 @@ void GroupUserListRequestHandler::handlePacket(const Common::XmlPacket &packet) Common::XmlPacket ret; try { - boost::shared_ptr<std::set<unsigned long> > users = UserManager::get()->getGroupUserList((unsigned long)packet["gid"]); + boost::shared_ptr<std::set<unsigned long> > users = UserManager::get()->getGroupUserList((unsigned long)(*packet)["gid"]); ret.setType("OK"); ret.addList("users"); diff --git a/src/Server/RequestHandlers/GroupUserListRequestHandler.h b/src/Server/RequestHandlers/GroupUserListRequestHandler.h index 5e50961..2220565 100644 --- a/src/Server/RequestHandlers/GroupUserListRequestHandler.h +++ b/src/Server/RequestHandlers/GroupUserListRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class GroupUserListRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - GroupUserListRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/IdentifyRequestHandler.cpp b/src/Server/RequestHandlers/IdentifyRequestHandler.cpp index 5300c19..1b94a52 100644 --- a/src/Server/RequestHandlers/IdentifyRequestHandler.cpp +++ b/src/Server/RequestHandlers/IdentifyRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void IdentifyRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "Identify") { +void IdentifyRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "Identify") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -42,10 +42,10 @@ void IdentifyRequestHandler::handlePacket(const Common::XmlPacket &packet) { // TODO Require authentication try { - if(packet["hostname"].isEmpty()) + if((*packet)["hostname"].isEmpty()) ConnectionManager::get()->identifyClientConnection(getConnection()); else - ConnectionManager::get()->identifyDaemonConnection(getConnection(), packet["hostname"]); + ConnectionManager::get()->identifyDaemonConnection(getConnection(), (*packet)["hostname"]); Common::XmlPacket ret; ret.setType("OK"); diff --git a/src/Server/RequestHandlers/IdentifyRequestHandler.h b/src/Server/RequestHandlers/IdentifyRequestHandler.h index 322bbab..9b2e6a9 100644 --- a/src/Server/RequestHandlers/IdentifyRequestHandler.h +++ b/src/Server/RequestHandlers/IdentifyRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class IdentifyRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - IdentifyRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/LogRequestHandler.cpp b/src/Server/RequestHandlers/LogRequestHandler.cpp index 019a7f2..0a615c5 100644 --- a/src/Server/RequestHandlers/LogRequestHandler.cpp +++ b/src/Server/RequestHandlers/LogRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void LogRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "Log") { +void LogRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "Log") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -43,7 +43,7 @@ void LogRequestHandler::handlePacket(const Common::XmlPacket &packet) { // TODO Require authentication try { - Common::LogManager::get()->log(packet["category"], packet["level"], packet["timestamp"], packet["message"], + Common::LogManager::get()->log((*packet)["category"], (*packet)["level"], (*packet)["timestamp"], (*packet)["message"], ConnectionManager::get()->getDaemonName(getConnection())); } catch(Net::Exception &e) { diff --git a/src/Server/RequestHandlers/LogRequestHandler.h b/src/Server/RequestHandlers/LogRequestHandler.h index d18a6d3..211b976 100644 --- a/src/Server/RequestHandlers/LogRequestHandler.h +++ b/src/Server/RequestHandlers/LogRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class LogRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - LogRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/UserGroupListRequestHandler.cpp b/src/Server/RequestHandlers/UserGroupListRequestHandler.cpp index 435a507..f5a3f7e 100644 --- a/src/Server/RequestHandlers/UserGroupListRequestHandler.cpp +++ b/src/Server/RequestHandlers/UserGroupListRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void UserGroupListRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "ListUserGroups") { +void UserGroupListRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "ListUserGroups") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -45,7 +45,7 @@ void UserGroupListRequestHandler::handlePacket(const Common::XmlPacket &packet) Common::XmlPacket ret; try { - boost::shared_ptr<std::set<unsigned long> > groups = UserManager::get()->getUserGroupList((unsigned long)packet["uid"]); + boost::shared_ptr<std::set<unsigned long> > groups = UserManager::get()->getUserGroupList((unsigned long)(*packet)["uid"]); ret.setType("OK"); ret.addList("groups"); diff --git a/src/Server/RequestHandlers/UserGroupListRequestHandler.h b/src/Server/RequestHandlers/UserGroupListRequestHandler.h index 8e2add0..35ff2eb 100644 --- a/src/Server/RequestHandlers/UserGroupListRequestHandler.h +++ b/src/Server/RequestHandlers/UserGroupListRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class UserGroupListRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - UserGroupListRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/UserInfoRequestHandler.cpp b/src/Server/RequestHandlers/UserInfoRequestHandler.cpp index 1773658..e9e0716 100644 --- a/src/Server/RequestHandlers/UserInfoRequestHandler.cpp +++ b/src/Server/RequestHandlers/UserInfoRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void UserInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "GetUserInfo") { +void UserInfoRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "GetUserInfo") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; @@ -45,7 +45,7 @@ void UserInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; try { - boost::shared_ptr<Common::UserInfo> info = UserManager::get()->getUserInfo(packet["uid"]); + boost::shared_ptr<Common::UserInfo> info = UserManager::get()->getUserInfo((*packet)["uid"]); ret.setType("OK"); diff --git a/src/Server/RequestHandlers/UserInfoRequestHandler.h b/src/Server/RequestHandlers/UserInfoRequestHandler.h index 90032f0..af11678 100644 --- a/src/Server/RequestHandlers/UserInfoRequestHandler.h +++ b/src/Server/RequestHandlers/UserInfoRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class UserInfoRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - UserInfoRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/RequestHandlers/UserListRequestHandler.cpp b/src/Server/RequestHandlers/UserListRequestHandler.cpp index 519ba6f..4164f22 100644 --- a/src/Server/RequestHandlers/UserListRequestHandler.cpp +++ b/src/Server/RequestHandlers/UserListRequestHandler.cpp @@ -26,8 +26,8 @@ namespace Mad { namespace Server { namespace RequestHandlers { -void UserListRequestHandler::handlePacket(const Common::XmlPacket &packet) { - if(packet.getType() != "ListUsers") { +void UserListRequestHandler::handlePacket(boost::shared_ptr<const Common::XmlPacket> packet) { + if(packet->getType() != "ListUsers") { Common::Logger::log(Common::Logger::ERROR, "Received an unexpected packet."); Common::XmlPacket ret; diff --git a/src/Server/RequestHandlers/UserListRequestHandler.h b/src/Server/RequestHandlers/UserListRequestHandler.h index 4b1a385..36cef00 100644 --- a/src/Server/RequestHandlers/UserListRequestHandler.h +++ b/src/Server/RequestHandlers/UserListRequestHandler.h @@ -28,11 +28,7 @@ namespace RequestHandlers { class UserListRequestHandler : public Common::RequestHandler { protected: - virtual void handlePacket(const Common::XmlPacket &packet); - - public: - UserListRequestHandler(Common::Connection *connection, uint16_t requestId) - : RequestHandler(connection, requestId) {} + virtual void handlePacket(boost::shared_ptr<const Common::XmlPacket> packet); }; } diff --git a/src/Server/Requests/CommandRequest.h b/src/Server/Requests/CommandRequest.h index feb33be..8221b14 100644 --- a/src/Server/Requests/CommandRequest.h +++ b/src/Server/Requests/CommandRequest.h @@ -34,8 +34,7 @@ class CommandRequest : public Common::Request { virtual void sendRequest(); public: - CommandRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, bool reboot0) - : Common::Request(connection, requestId, slot), reboot(reboot0) {} + CommandRequest(bool reboot0) : reboot(reboot0) {} }; } diff --git a/src/Server/Requests/DaemonStateUpdateRequest.h b/src/Server/Requests/DaemonStateUpdateRequest.h index 6debb06..c3ed792 100644 --- a/src/Server/Requests/DaemonStateUpdateRequest.h +++ b/src/Server/Requests/DaemonStateUpdateRequest.h @@ -36,8 +36,8 @@ class DaemonStateUpdateRequest : public Common::Request { virtual void sendRequest(); public: - DaemonStateUpdateRequest(Common::Connection *connection, uint16_t requestId, slot_type slot, const std::string &name0, Common::HostInfo::State state0) - : Common::Request(connection, requestId, slot), name(name0), state(state0) {} + DaemonStateUpdateRequest(const std::string &name0, Common::HostInfo::State state0) + : name(name0), state(state0) {} }; } diff --git a/src/mad.cpp b/src/mad.cpp index c89487b..42afc87 100644 --- a/src/mad.cpp +++ b/src/mad.cpp @@ -35,10 +35,6 @@ using namespace Mad; -static void requestFinished(Common::Request&) { - Common::Logger::log("Identified."); -} - int main() { Net::ThreadManager::get()->init(); @@ -69,7 +65,13 @@ int main() { //char hostname[256]; //gethostname(hostname, sizeof(hostname)); //Common::RequestManager::get()->sendRequest<Daemon::Requests::IdentifyRequest>(connection, sigc::ptr_fun(requestFinished), hostname); - Common::RequestManager::get()->sendRequest1<Common::Requests::IdentifyRequest>(connection, "test", &requestFinished); + //Common::RequestManager::get()->sendRequest1<Common::Requests::IdentifyRequest>(connection, "test")->wait(); + { + boost::shared_ptr<Common::Requests::IdentifyRequest> request(new Common::Requests::IdentifyRequest("test")); + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); + } + Common::Logger::log("Identified."); connection->waitWhileConnected(); diff --git a/src/madc.cpp b/src/madc.cpp index 40bd51c..64078c8 100644 --- a/src/madc.cpp +++ b/src/madc.cpp @@ -37,21 +37,10 @@ using namespace Mad; -static bool commandRunning = false; -static boost::mutex commandMutex; -static boost::condition_variable commandNotify; - static void usage(const std::string &cmd) { std::cerr << "Usage: " << cmd << " address" << std::endl; } -static void commandFinished() { - boost::lock_guard<boost::mutex> lock(commandMutex); - commandRunning = false; - - commandNotify.notify_one(); -} - int main(int argc, char *argv[]) { if(argc != 2) { usage(argv[0]); @@ -75,12 +64,9 @@ int main(int argc, char *argv[]) { Common::RequestManager::get()->registerConnection(connection); { - boost::unique_lock<boost::mutex> lock(commandMutex); - commandRunning = true; - Common::RequestManager::get()->sendRequest0<Common::Requests::IdentifyRequest>(connection, boost::bind(&commandFinished)); - while(commandRunning) { - commandNotify.wait(lock); - } + boost::shared_ptr<Common::Requests::IdentifyRequest> request(new Common::Requests::IdentifyRequest); + Common::RequestManager::get()->sendRequest(connection, request); + request->wait(); } std::cerr << " connected." << std::endl; @@ -92,13 +78,10 @@ int main(int argc, char *argv[]) { std::cerr << " done." << std::endl << std::endl; Client::CommandParser::get()->setConnection(connection); - Client::CommandManager::get()->connectSignalFinished(&commandFinished); - while(connection->isConnected() && !Client::CommandManager::get()->willDisconnect()) { + while(connection->isConnected() && !Client::CommandParser::get()->willDisconnect()) { char *cmd = readline("mad> "); - boost::unique_lock<boost::mutex> lock(commandMutex); - if(!cmd) { Client::CommandParser::get()->requestDisconnect(); } @@ -107,11 +90,6 @@ int main(int argc, char *argv[]) { add_history(cmd); } else continue; - - commandRunning = Client::CommandManager::get()->requestsActive(); - - while(commandRunning) - commandNotify.wait(lock); } connection->waitWhileConnected(); |