/* * madc.cpp * * Copyright (C) 2008 Matthias Schiffer * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along * with this program. If not, see . */ #include "config.h" #include "Core/ConfigManager.h" #include "Common/ClientConnection.h" #include "Common/UserManager.h" #include "Common/Backends/NetworkUserBackend.h" #include "Common/RequestManager.h" #include "Common/Requests/IdentifyRequest.h" #include "Client/Application.h" #include "Client/CommandParser.h" #include "Client/ConsoleUtil.h" #include "Client/InformationManager.h" #include "Client/Authenticators/ChallengeResponseAuthenticator.h" #include "Client/Authenticators/PasswordAuthenticator.h" #include #include #include #include using namespace Mad; static void usage(const std::string &cmd) { std::cerr << "Usage: " << cmd << " [host[:port]]" << std::endl; } static char* prompt(EditLine* /*e*/) { return const_cast("mad> "); } int main(int argc, char *argv[]) { if(argc > 2) { usage(argv[0]); std::exit(1); } Client::Application application; application.getConfigManager()->configure(); Common::ClientConnection *connection = new Common::ClientConnection(&application); application.getRequestManager()->registerConnection(connection); try { std::string server = "localhost", port = "6666"; if(argc == 2) { server = argv[1]; } static const boost::regex r("(.+):(\\d+)", boost::regex_constants::perl); boost::smatch match; if(boost::regex_match(server, match, r)) { server = match[1].str(); port = match[2].str(); } boost::asio::ip::tcp::resolver resolver(application.getIOService()); boost::asio::ip::tcp::resolver::query query(server, port); boost::asio::ip::tcp::resolver::iterator entry = resolver.resolve(query); connection->connect(entry->endpoint()); std::cerr << "Connecting to " << entry->host_name() << "..." << std::flush; connection->waitWhileConnecting(); std::cerr << " connected." << std::endl << std::endl; { std::cerr << "Login: " << std::flush; Core::String username = Core::String::getline(std::cin); Core::String password = Client::ConsoleUtil::readPassword("Password: "); try { Client::Authenticators::ChallengeResponseAuthenticator::authenticate(&application, connection, username, password); } catch(Core::Exception e) { if(e.getErrorCode() != Core::Exception::NOT_AVAILABLE) throw e; Client::Authenticators::PasswordAuthenticator::authenticate(&application, connection, username, password); } } std::cerr << "Login successful." << std::endl << std::endl; std::cerr << "Receiving host list..." << std::flush; application.getInformationManager()->updateDaemonList(connection); application.getInformationManager()->waitWhileUpdating(); std::cerr << " done." << std::endl << std::endl; boost::shared_ptr networkUserBackend(new Common::Backends::NetworkUserBackend(&application, connection)); application.getUserManager()->registerBackendCached(networkUserBackend); Client::CommandParser commandParser(&application, connection); EditLine *el = el_init(argv[0], stdin, stdout, stderr); el_set(el, EL_EDITOR, "vi"); el_set(el, EL_PROMPT, &prompt); HistEvent histEv; History *hist = history_init(); history(hist, &histEv, H_SETSIZE, 800); el_set(el, EL_HIST, history, hist); while(connection->isConnected() && !commandParser.willDisconnect()) { const char *cmd = el_gets(el, 0); if(!cmd) { commandParser.requestDisconnect(); } else if(*cmd) { commandParser.parse(Core::String::fromLocale(cmd)); history(hist, &histEv, H_ENTER, cmd); } else continue; } history_end(hist); el_end(el); connection->waitWhileConnected(); application.getUserManager()->unregisterBackend(networkUserBackend); } catch(Core::Exception &e) { application.log(Core::Logger::LOG_CRITICAL, Core::Format("Error: %1%") % e); } application.getRequestManager()->unregisterConnection(connection); delete connection; return 0; }