From aced405b7b5cee4504db4a07b6b381189e937bc5 Mon Sep 17 00:00:00 2001 From: "Aggin!2.0" Date: Sun, 20 Jan 2008 16:18:45 +0100 Subject: [PATCH] allgemeiner commit --- src/client/client.cpp | 32 +++++++++++++++++++++ src/client/client.hpp | 27 +++++++++++------ src/client/reverse_client.cpp | 4 +-- src/client/session.cpp | 25 ++++++++++++++++ src/client/session.hpp | 22 ++++++++++---- src/command.hpp | 11 +++++++ src/connection.cpp | 62 ++++++++++++++++++++++++++++------------ src/connection.hpp | 33 ++++++++++++++++----- src/server/command_processor.cpp | 6 +++- src/server/session.cpp | 12 ++------ src/session_base.cpp | 13 ++++++--- src/session_base.hpp | 12 ++------ 12 files changed, 194 insertions(+), 65 deletions(-) create mode 100644 src/client/client.cpp diff --git a/src/client/client.cpp b/src/client/client.cpp new file mode 100644 index 0000000..aefd65a --- /dev/null +++ b/src/client/client.cpp @@ -0,0 +1,32 @@ +#include "client.hpp" +#include "../command.hpp" +#include +#include + + +using namespace std; +using namespace boost; +using namespace boost::asio::ip; + + +ssftp::client::client::client() + :work(io_service) +{ + thread thread(boost::bind(&boost::asio::io_service::run, &io_service)); +} + +bool ssftp::client::client::connect(string ip, unsigned short port) +{ + session_ptr_.reset(new session(io_service)); + tcp::endpoint ep(address::from_string(ip), port); + boost::system::error_code error; + session_ptr_->socket().connect(ep, error); + if(!error) + session_ptr_->start(); + return error ? false : true; +} + +void ssftp::client::client::async_login(string username, string password, response_callback callback) +{ + session_ptr_->async_login(username, password, callback); +} \ No newline at end of file diff --git a/src/client/client.hpp b/src/client/client.hpp index fd844b9..6adcccc 100644 --- a/src/client/client.hpp +++ b/src/client/client.hpp @@ -1,7 +1,14 @@ +#include +class session; +typedef boost::shared_ptr session_ptr; + #ifndef __client_hpp__ #define __client_hpp__ #include +#include +#include "session.hpp" +#include "../connection.hpp" namespace ssftp @@ -10,17 +17,21 @@ namespace ssftp { class client { + boost::asio::io_service io_service; + boost::asio::io_service::work work; + session_ptr session_ptr_; + + void user_cmd_handler(); + public: - /** Verbindet zu einem Server. - * @return bei erfolg true, sonst false - */ - bool connect(std::string ip, unsigned short port); + client(); + + session_ptr session_ptr() { return session_ptr_; } - bool login(std::string username, std::string password); + bool connect(std::string ip, unsigned short port); - /** Fordert Datei&Ordner-Liste vom Server an. - */ - std::vector list(); + //proxies + void async_login(std::string username, std::string password, response_callback callback); }; } } diff --git a/src/client/reverse_client.cpp b/src/client/reverse_client.cpp index a6cc8a8..fad0113 100644 --- a/src/client/reverse_client.cpp +++ b/src/client/reverse_client.cpp @@ -27,11 +27,11 @@ asio::io_service& ssftp::client::reverse_client::get_io_service() void ssftp::client::reverse_client::start_accept_servers(unsigned short port) { acceptor_ptr.reset(new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), port))); - session::ptr session_ptr(new session(this->get_io_service())); + session_ptr session_ptr(new session(this->get_io_service())); acceptor_ptr->async_accept(session_ptr->socket(), bind(&reverse_client::handle_async_accept, this, _1, session_ptr)); } -void ssftp::client::reverse_client::handle_async_accept(const boost::system::error_code& error, session::ptr session_ptr) +void ssftp::client::reverse_client::handle_async_accept(const boost::system::error_code& error, session_ptr session_ptr) { if(!error) { diff --git a/src/client/session.cpp b/src/client/session.cpp index d0cbb42..ab069a7 100644 --- a/src/client/session.cpp +++ b/src/client/session.cpp @@ -1,3 +1,28 @@ #include "session.hpp" +#include +using namespace std; using namespace boost; + + +void ssftp::client::session::async_login(string username, string password, bool_handler handler) +{ + conn.async_write_command(commands::user(username), + boost::bind(&session::handle_user_command, this, _1, handler)); +} + +void ssftp::client::session::handle_user_command(response resp, bool_handler login_handler) +{ + +} + + +void ssftp::client::session::handle_read_response(const boost::system::error_code&, response resp) +{ + conn.async_read_response(boost::bind(&session::handle_read_response, this, _1, _2)); +} + +void ssftp::client::session::start() +{ + conn.async_read_response(boost::bind(&session::handle_read_response, this, _1, _2)); +} diff --git a/src/client/session.hpp b/src/client/session.hpp index 0b2e377..879fe04 100644 --- a/src/client/session.hpp +++ b/src/client/session.hpp @@ -1,31 +1,43 @@ #ifndef __session_hpp__ #define __session_hpp__ +#include +#include #include #include #include "client.hpp" #include "../connection.hpp" #include "../session_base.hpp" +#include "../response.hpp" namespace ssftp { namespace client { + typedef boost::function bool_handler; + class session : public session_base { - public: - typedef boost::shared_ptr ptr; + void handle_user_command(response resp); + + void handle_read_response(const boost::system::error_code&, response resp); + public: session(boost::asio::io_service& io_service) :session_base(io_service) {} - virtual void start() - { + void async_login(std::string username, std::string password, bool_handler handler); + + /** Fordert Datei&Ordner-Liste vom Server an. + */ + std::vector list(); - } + virtual void start(); }; + + typedef boost::shared_ptr session_ptr; } } diff --git a/src/command.hpp b/src/command.hpp index 9c52d36..b5c7d05 100644 --- a/src/command.hpp +++ b/src/command.hpp @@ -9,7 +9,18 @@ namespace ssftp struct command { std::string cmd, args; + //ctor + command(std::string cmd="", std::string args="") : cmd(cmd), args(args) {} }; + + namespace commands + { + struct user : command + { + user() : command("user") {} + user(std::string args) : command("user", args) {} + }; + } } diff --git a/src/connection.cpp b/src/connection.cpp index 8fe50e8..ec7c09f 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -13,26 +13,30 @@ using namespace boost; ssftp::connection::connection(asio::io_service& io_service) :socket(io_service) { + resp_callbacks.push(boost::bind(&connection::handle_greeting, this, _1)); } -void ssftp::connection::async_read_command(read_command_handler_t handler) +void ssftp::connection::async_read_command(read_command_handler handler) { asio::async_read_until(socket, data_, '\0', boost::bind(&connection::handle_read_until_command, this, _1, _2, handler)); } -void ssftp::connection::async_write_command(command command) +void ssftp::connection::async_write_command(command command, response_callback callback) { + resp_callbacks.push(callback); + string str = command.cmd // + ((command.args.length()>0) ? (" " + command.args):"") // + '\0'; // asio::async_write(socket, shared_const_buffer(str), - boost::bind(&connection::handle_write_response, this, _1, _2)); + boost::bind(&connection::handle_write_command, this, _1, _2)); } -void ssftp::connection::async_read_response(read_response_handler_t handler) +void ssftp::connection::async_read_response(read_response_handler handler) { - + asio::async_read_until(socket, data_, '\0', + boost::bind(&connection::handle_read_until_response, this, _1, _2, handler)); } void ssftp::connection::async_write_response(response resp) @@ -41,11 +45,11 @@ void ssftp::connection::async_write_response(response resp) + (resp.message.length()>0 ? resp.message : "") // + '\0'; // asio::async_write(socket, shared_const_buffer(trim_copy(str)), - boost::bind(&connection::handle_write_command, this, _1, _2)); + boost::bind(&connection::handle_write_response, this, _1, _2)); } void ssftp::connection::handle_read_until_command( - const boost::system::error_code& error, size_t bytes_received, read_command_handler_t handler) + const boost::system::error_code& error, size_t, read_command_handler handler) { command command; istream is(&data_); @@ -64,26 +68,46 @@ void ssftp::connection::handle_read_until_command( } void ssftp::connection::handle_read_until_response( - const boost::system::error_code& error, size_t bytes_received, read_response_handler_t handler) + const boost::system::error_code& error, size_t, read_response_handler handler) { - response resp; - istream is(&data_); + if(error) + { + disconnected_signal(); + } + else + { + response resp; + istream is(&data_); - resp.code = is.get(); // - getline(is, resp.message); //message + resp.code = is.get(); // + getline(is, resp.message); //message - //Restliches Zeug lesen - while (is.good() && is.get()); + //Restliches Zeug lesen + while (is.good() && is.get()); - handler(error, resp); + resp_callbacks.front()(resp); + resp_callbacks.pop(); + handler(error, resp); + } } -void ssftp::connection::handle_write_response(const boost::system::error_code& e, size_t bytes) +void ssftp::connection::handle_write_response(const boost::system::error_code& error, size_t bytes) { - clog << "response written to socket. (" << bytes << " bytes sent)" << endl; + if(error) + disconnected_signal(); + else + clog << "response written to socket. (" << bytes << " bytes sent)" << endl; +} + +void ssftp::connection::handle_write_command(const boost::system::error_code& error, size_t bytes) +{ + if(error) + disconnected_signal(); + else + clog << "command written to socket. (" << bytes << " bytes sent)" << endl; } -void ssftp::connection::handle_write_command(const boost::system::error_code& e, size_t bytes) +void ssftp::connection::on_disconnected(void_handler handler) { - clog << "command written to socket. (" << bytes << " bytes sent)" << endl; + disconnected_signal.connect(handler); } \ No newline at end of file diff --git a/src/connection.hpp b/src/connection.hpp index b435a54..5e5e0e8 100644 --- a/src/connection.hpp +++ b/src/connection.hpp @@ -1,39 +1,58 @@ #ifndef __control_connection_hpp__ #define __control_connection_hpp__ +#include #include #include +#include #include "response.hpp" #include "command.hpp" namespace ssftp { - typedef boost::function read_command_handler_t; - typedef boost::function read_response_handler_t; + typedef boost::function void_handler; + typedef boost::function read_command_handler; + typedef boost::function read_response_handler; + typedef boost::function read_command_handler; + typedef boost::function read_response_handler; + + typedef boost::function response_callback; class connection { boost::asio::streambuf data_; + std::queue resp_callbacks; + boost::signal disconnected_signal; void handle_read_until_command( - const boost::system::error_code& e, std::size_t size, read_command_handler_t handler); + const boost::system::error_code& e, std::size_t, read_command_handler handler); void handle_read_until_response( - const boost::system::error_code& e, std::size_t size, read_response_handler_t handler); + const boost::system::error_code& e, std::size_t, read_response_handler handler); void handle_write_command(const boost::system::error_code& e, std::size_t bytes); void handle_write_response(const boost::system::error_code& e, std::size_t bytes); + void handle_greeting(response resp) + { + //TODO auf +/- pruefen + } + public: boost::asio::ip::tcp::socket socket; connection(boost::asio::io_service& io_service); - void async_read_command(read_command_handler_t handler); - void async_write_command(command command); + void on_disconnected(void_handler handler); + + void async_read_command(read_command_handler handler); + /** . + * @param callback Funktion, die bei einer response auf den command aufgerufen wird. + */ + void async_write_command(command command, response_callback callback); - void async_read_response(read_response_handler_t handler); + void async_read_response(read_response_handler handler); void async_write_response(response resp); }; } diff --git a/src/server/command_processor.cpp b/src/server/command_processor.cpp index 45b4b43..4554ac7 100644 --- a/src/server/command_processor.cpp +++ b/src/server/command_processor.cpp @@ -20,6 +20,7 @@ ssftp::server::command_processor::command_processor(ssftp::server::session& sess ,file_sys_helper(session.file_sys_helper) ,login_state(login_states::none) ,rename_state(rename_states::none) + ,retr_state(retr_states::none) { command_fun_map["user"] = boost::bind(&command_processor::user, this, _1); command_fun_map["pass"] = boost::bind(&command_processor::pass, this, _1); @@ -29,6 +30,9 @@ ssftp::server::command_processor::command_processor(ssftp::server::session& sess command_fun_map["name"] = boost::bind(&command_processor::name, this, _1); command_fun_map["tobe"] = boost::bind(&command_processor::tobe, this, _1); command_fun_map["done"] = boost::bind(&command_processor::done, this, _1); + command_fun_map["retr"] = boost::bind(&command_processor::retr, this, _1); + command_fun_map["send"] = boost::bind(&command_processor::send, this, _1); + command_fun_map["stop"] = boost::bind(&command_processor::stop, this, _1); } /** Behandelt einen command und gibt den reply zurueck. @@ -212,7 +216,7 @@ ssftp::response ssftp::server::command_processor::send(string /*args*/) else if(retr_state != retr_states::intermediate) { retr_state = retr_states::none; - return error_response("Unknown internal state; try again") + return error_response("Unknown internal state; try again"); } //Sonst Datei senden else diff --git a/src/server/session.cpp b/src/server/session.cpp index 8bda8f0..89fd3c6 100644 --- a/src/server/session.cpp +++ b/src/server/session.cpp @@ -31,15 +31,7 @@ asio::ip::tcp::socket& ssftp::server::session::socket() void ssftp::server::session::handle_read_command(const boost::system::error_code& error, command cmd) { - if(error) - { - cerr << error.message() << endl; - disconnected_signal(); - } - else - { - process_command(cmd); - } + process_command(cmd); } void ssftp::server::session::process_command(command command) @@ -50,7 +42,7 @@ void ssftp::server::session::process_command(command command) { response resp = cmd_processor.process(command); if(typeid(resp) != typeid(no_response)) - conn.async_write_response(resp); + conn.async_write_response(resp); } catch(done_exception&) { diff --git a/src/session_base.cpp b/src/session_base.cpp index 523107a..d2a7e97 100644 --- a/src/session_base.cpp +++ b/src/session_base.cpp @@ -5,17 +5,22 @@ using namespace boost::asio; ssftp::session_base::session_base(io_service& io_service) - :strand(io_service) - ,conn(io_service) + ://strand(io_service) + conn(io_service) { } -void ssftp::session_base::on_disconnected(void_handler_type handler) +void ssftp::session_base::on_disconnected(void_handler handler) { - disconnected_signal.connect(handler); + conn.on_disconnected(handler); } asio::ip::tcp::socket& ssftp::session_base::socket() { return conn.socket; } + +ssftp::connection& ssftp::session_base::connection() +{ + return conn; +} \ No newline at end of file diff --git a/src/session_base.hpp b/src/session_base.hpp index 99747cd..9669184 100644 --- a/src/session_base.hpp +++ b/src/session_base.hpp @@ -10,26 +10,20 @@ namespace ssftp { - typedef boost::function void_handler_type; - class session_base { - typedef boost::signal void_signal_type; - protected: - boost::asio::io_service::strand strand; + //boost::asio::io_service::strand strand; connection conn; - void_signal_type disconnected_signal; public: - //typedef boost::shared_ptr ptr; - session_base(boost::asio::io_service& io_service); - void on_disconnected(void_handler_type handler); + void on_disconnected(void_handler handler); virtual void start()=0; + ssftp::connection& connection(); boost::asio::ip::tcp::socket& socket(); }; } -- 2.11.4.GIT