// -*- c++ -*- // Generated by assa-genesis //------------------------------------------------------------------------------ // $Id: echos.cpp,v 1.5 2005/10/08 02:42:01 vlg Exp $ //------------------------------------------------------------------------------ // EchoSvr.cpp //------------------------------------------------------------------------------ // Copyright (c) 2002,2005 by Vladislav Grinchenko // // 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 // 2 of the License, or (at your option) any later version. //------------------------------------------------------------------------------ // // Date : Wed Dec 11 11:43:20 2002 // //------------------------------------------------------------------------------ static const char help_msg[]= " \n" " NAME: \n" " \n" " echos - simple echo server \n" " \n" " DESCRIPTION: \n" " \n" " echos replaces UNIX echo service. All input is reflected back to the \n" " sender as-is. \n" " \n" " USAGE: \n" " \n" " shell> echos [OPTIONS] \n" " \n" " OPTIONS: \n" " \n" " -b, --daemon - Run process as true UNIX daemon \n" " -l, --pidfile PATH - The process ID is written to the lockfile PATH \n" " instead of default ~/.{procname}.pid \n" " -L, --no-pidfile - Do not create PID lockfile \n" " \n" " -D, --log-file NAME - Write debug to NAME file \n" " -d, --log-stdout - Write debug to standard output \n" " -z, --log-size NUM - Maximum size debug file can reach (dfl: is 10Mb) \n" " \n" " -m, --mask MASK - Mask (default: ALL = 0x7fffffff) \n" " -p, --port NAME - The tcp/ip port NAME (default - procname) \n" " -n, --instance NUM - Process instance NUM (default - none) \n" " \n" " -h, --help - Print this messag \n" " -v, --version - Print version number \n"; //------------------------------------------------------------------------------ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include using std::string; #include #include #include #include #include #include #include using namespace ASSA; /******************************************************************************/ class Reflector : public ServiceHandler { public: Reflector (IPv4Socket* s_) : ServiceHandler (s_) { /* no-op */ } virtual int open (); virtual int handle_read (int fd_); virtual int handle_close (int /* fd */) { delete (this); return 0; } }; /******************************************************************************/ class EchoSvr : public ASSA::GenServer, public ASSA::Singleton { public: EchoSvr (); virtual void init_service (); virtual void process_events (); int get_exit_value () const { return m_exit_value; } void set_exit_value (int v_) { m_exit_value = v_; } private: int m_exit_value; // Return status of the process Acceptor* m_acceptor; }; /* Useful definitions */ #define ECHOSVR EchoSvr::get_instance() #define REACTOR ECHOSVR->get_reactor() // Static declarations mandated by Singleton class ASSA_DECL_SINGLETON(EchoSvr); /******************************************************************************/ /******************************************************************************* Reflector member functions ******************************************************************************/ int Reflector:: open () { REACTOR->registerIOHandler (this, get_stream ().getHandler (), READ_EVENT); return 0; } int Reflector:: handle_read (int fd_) { IPv4Socket& s = *this; if (s.getHandler () != fd_) { return -1; } char c; int ret; while ((ret = s.read (&c, 1) == 1)) { if (s.write (&c, 1) != 1) { break; } } s << ASSA::flush; return BYTES_LEFT_IN_SOCKBUF(s); } /******************************************************************************* EchoSvr member functions ******************************************************************************/ EchoSvr:: EchoSvr () : m_exit_value (0) { // ---Configuration--- rm_opt ('f', "config-file" ); /*--- * By defauil disable all debugging *---*/ m_mask = ASSA::APP; m_log_file = "echos.log"; } void EchoSvr:: init_service () { trace("EchoSvr::init_service"); m_acceptor = new Acceptor (&m_reactor); ASSA::INETAddress address (get_port ().c_str ()); Assure_exit (!address.bad ()); Assure_exit (m_acceptor->open (address) == 0); DL((ASSA::APP,"Service has been initialized\n")); } void EchoSvr:: process_events () { trace("EchoSvr::process_events"); while (service_is_active ()) { m_reactor.waitForEvents (); } // Shut the service down m_reactor.stopReactor (); DL((ASSA::APP,"Service stopped!\n")); } int main (int argc, char* argv[]) { static const char release[] = "1.0"; int patch_level = 0; ECHOSVR->set_version (release, patch_level); ECHOSVR->set_author ("Vladislav Grinchenko"); ECHOSVR->set_flags (ASSA::GenServer::RMLOG); ECHOSVR->init (&argc, argv, help_msg); ECHOSVR->init_service (); ECHOSVR->process_events (); return ECHOSVR->get_exit_value (); }