#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void handleServer(Block &commands); // handler for server mode void handleClient(Block &commands); // handler for client mode bool registerSignalHandler(void); // registers a Control-c handler void signalHandler(int signal); // The Control-C handler class SSTP; SmartPointer sstp; class SSTP { public: SSTP(); ~SSTP(); void handleServer(Block& arguments); void handleClient(Block& arguments); private: SmartPointer mSocketServer; SmartPointer mClientSocketSender; }; inline SSTP::SSTP() { } inline SSTP::~SSTP() { mSocketServer.destroy(); mClientSocketSender.destroy(); } /// @brief [0]=program [1]=SERVERMODE [2]={port} /// @Note Currently this method will never return. The application is terminate with CTRL-C. Ideally, we would exit is some cleaner fashion /// perhaps by implementing a CTRL-C hook and then destroying the SocketServer properly by calling it's destructor. See SocketServer::~SocketServer() /// @param commands inline void SSTP::handleServer(Block& commands) { Profiler profiler; if(commands.size()!=3) { std::cout << "Missing required parameters" << std::endl; return; } int port = commands[2].toInt(); std::cout << commands[1] << ":" << commands[2] << std::endl; SocketServer socketServer(commands[2].toInt()); socketServer.listen(); std::cout << "Done, total took " << Utility::formatNumber(profiler.end()) << "(ms)" << std::endl; } /// @brief [0]=program, [1]=CLIENTMODE, [2]=serveripaddress, [3]=serverport, [4]=pathfilename /// @param commands inline void SSTP::handleClient(Block& arguments) { Profiler profiler; if(arguments.size()!=5) { std::cout << "Missing required parameters" << std::endl; return; } mClientSocketSender.destroy(); mClientSocketSender = new ClientSocketSender(arguments[2],arguments[3].toInt()); bool returnCode = mClientSocketSender->sendFile(arguments[4]); if(!returnCode) { std::cout << "The transfer failed." << std::endl; } else { std::cout << "Transfer complete" << std::endl; } std::cout << "Done, total took " << Utility::formatNumber(profiler.end()) << "(ms)" << std::endl; } // **************************************************************************************************************************************************************** /// @brief /// @param argc /// @param argv [0] program. [1] SERVERMODE {port} [2] CLIENTMODE {serveripaddress} {serverport} SEND {FileName} /// @return -1:Error 1:Success int main(int argc, char **argv) { int returnCode(0); Profiler profiler; String version = "0.1.0.3"; // major version, minor version, patch, build std::cout << "sstp version " << version.str() << std::endl; if(!registerSignalHandler()) { std::cout << "Unable to register CTRL-C handler" << std::endl; return -1; } try { if(argc<2) { std::cout << "sstp SERVERMODE {port} | CLIENTMODE {serveripaddress} {serverport} {pathfileName}." << std::endl; std::cout << "SERVERMODE will listen on the specified port for a connection and receive the specified file." << std::endl; std::cout << "CLIENTMODE willl connect to the specified address and port and send the specfied file." << std::endl; return 1; } Block arguments; for(int index=0;indexhandleServer(arguments); // handleServer(arguments); } else if(arguments[1]=="CLIENTMODE") { sstp->handleClient(arguments); // handleClient(arguments); } else { std::cout << "Unknown command " << arguments[1] << std::endl; returnCode=-1; } } catch(Exception& exception) { std::cout << exception.toString() << std::endl; returnCode=-1; } catch(...) { std::cout << "An unhandled exception was encountered" << std::endl; returnCode=-1; } std::cout << "Done, total took " << Utility::formatNumber(profiler.end()) << "(ms)" << std::endl; return returnCode; } /// @brief The signal handler /// TODO: If we are sending then we need to destroy the sender, if we are listening then we need to destroy the listener /// Currently we exit the app without cleaning anything up. void signalHandler(int signal) { std::cout << "SSTP Received signal " << signal << std::endl; if(sstp.isOkay())sstp.destroy(); exit(signal); } /// @brief Method that registers the signal handler /// @param bool registerSignalHandler(void) { struct sigaction sa; sa.sa_handler = signalHandler; sigemptyset(&sa.sa_mask); // Clear the mask of blocked signals sa.sa_flags = 0; // No special flags if (-1==sigaction(SIGINT, &sa, nullptr)) { std::cerr << "Error registering SIGINT handler." << std::endl; return false; } return true; } /// @brief [0]=program [1]=SERVERMODE [2]={port} /// @Note Currently this method will never return. The application is terminate with CTRL-C. Ideally, we would exit is some cleaner fashion /// perhaps by implementing a CTRL-C hook and then destroying the SocketServer properly by calling it's destructor. See SocketServer::~SocketServer() /// @param commands // void handleServer(Block &commands) // { // Profiler profiler; // if(commands.size()!=3) // { // std::cout << "Missing required parameters" << std::endl; // return; // } // int port = commands[2].toInt(); // std::cout << commands[1] << ":" << commands[2] << std::endl; // SocketServer socketServer(commands[2].toInt()); // socketServer.listen(); // std::cout << "Done, total took " << Utility::formatNumber(profiler.end()) << "(ms)" << std::endl; // } /// @brief [0]=program, [1]=CLIENTMODE, [2]=serveripaddress, [3]=serverport, [4]=pathfilename /// @param commands // void handleClient(Block &commands) // { // Profiler profiler; // if(commands.size()!=5) // { // std::cout << "Missing required parameters" << std::endl; // return; // } // ClientSocketSender clientSocketSender(commands[2],commands[3].toInt()); // bool returnCode = clientSocketSender.sendFile(commands[4]); // if(!returnCode) // { // std::cout << "The transfer failed." << std::endl; // } // else // { // std::cout << "Transfer complete" << std::endl; // } // std::cout << "Done, total took " << Utility::formatNumber(profiler.end()) << "(ms)" << std::endl; // }