00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef USE_PCH
00017 #include "sys.h"
00018 #include <libxml/xmlmemory.h>
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <unistd.h>
00022 #include "debug.h"
00023 #endif
00024
00025 #include "Application.h"
00026 #include "ProxyListenSocket.h"
00027 #include "PersistXML.h"
00028 #include "Network.h"
00029 #include "Identity.h"
00030 #include "ClientSession.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 Application::Application(void) :
00045 M_listen_port(0),
00046 #ifdef CWDEBUG
00047 M_suppress_ping(false),
00048 M_suppress_who(false),
00049 #endif
00050 M_memory_block_dummy(memory_block_st::create(0)),
00051 M_msg_block_dummy(M_memory_block_dummy->block_start(), 0, M_memory_block_dummy),
00052 M_terminating(false)
00053 {
00054 add_option(&Application::command_line_option_listen_port,
00055 "listen-port", 'p', "<port>", "Port to listen on for new connections.");
00056 #ifdef CWDEBUG
00057 add_option(&Application::command_line_option_suppress_ping,
00058 "suppress-ping", 0, NULL, "Suppress debug output regarding PING/PONG messages.");
00059 add_option(&Application::command_line_option_suppress_who,
00060 "suppress-who", 0, NULL, "Suppress debug output regarding WHO messages.");
00061 #endif
00062 }
00063
00064
00065
00066
00067
00068 Application::~Application() throw()
00069 {
00070
00071 M_identities.clear();
00072
00073
00074 M_memory_block_dummy->release();
00075 }
00076
00077 void Application::last_server_session_destroyed(void)
00078 {
00079 if (M_terminating)
00080 fd_dct::return_when_done(-1);
00081 }
00082
00083 #ifdef CWDEBUG
00084
00085
00086
00087
00088
00089 void Application::main_entered(int*, char* const**)
00090 {
00091 Debug(debug::init());
00092 }
00093 #endif
00094
00095
00096
00097
00098
00099
00100
00101
00102 void Application::start(void)
00103 {
00104 #ifdef CWDEBUG
00105
00106 static std::ofstream debug_file;
00107 debug_file.open("debug.out");
00108 static debug::TeeStream debug_stream(std::cout, debug_file);
00109 libcwd::libcw_do.set_ostream(&debug_stream);
00110 #endif
00111
00112 Dout(dc::notice, "Called Application::start()");
00113
00114
00115 PersistXML xml;
00116
00117 unsigned int commandline_listen_port = M_listen_port;
00118
00119
00120 struct stat statbuf;
00121 if (stat("ircproxy.xml", &statbuf) != -1)
00122 {
00123 xml.open("ircproxy.xml", PersistXML::load);
00124 xml.serialize("Application", *this);
00125 xml.close();
00126 }
00127
00128
00129 signalRequest(SignalRequestData(SIGINT, sigOneShot|sigReplace),
00130 Application::instance(), &Application::handle_signal);
00131
00132 signalRequest(SignalRequestData(SIGHUP),
00133 Application::instance(), &Application::handle_signal);
00134
00135
00136 if (commandline_listen_port)
00137 M_listen_port = commandline_listen_port;
00138 else if (M_listen_port == 0)
00139 M_listen_port = 6667;
00140
00141
00142 NEW(ProxyListenSocket(M_listen_port));
00143
00144 mainloop();
00145
00146
00147 xml.open("ircproxy.xml", PersistXML::store);
00148 xml.serialize("Application", *this);
00149 xml.close();
00150
00151
00152 xmlCleanupParser();
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 void Application::command_line_option_listen_port(char const* argument)
00165 {
00166 M_listen_port = atoi(optarg);
00167 if (M_listen_port <= 1024)
00168 {
00169 std::cerr << application_name << ": " << argument << " : out of range" << std::endl;
00170 libcw_exit(-1);
00171 }
00172 }
00173
00174 #ifdef CWDEBUG
00175 void Application::command_line_option_suppress_ping(char const* LIBCW_UNUSED(argument))
00176 {
00177 M_suppress_ping = true;
00178 }
00179
00180 void Application::command_line_option_suppress_who(char const* LIBCW_UNUSED(argument))
00181 {
00182 M_suppress_who = true;
00183 }
00184 #endif
00185
00186
00187
00188
00189
00190
00191
00192
00193 void Application::finish_options(void)
00194 {
00195 if (errflg)
00196 {
00197 print_usage(std::cerr);
00198 libcw_exit(2);
00199 }
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 void Application::print_version(std::ostream& os) const
00209 {
00210 os << PACKAGE_NAME << " " << VERSION << " by Carlo Wood <carlo@alinoe.com>\n";
00211 }
00212
00213 void Application::handle_signal(SignalType const& signal_type)
00214 {
00215 DoutEntering(dc::debug, "Application::handle_signal(" << signal_type << ")");
00216
00217 switch(signal_type.get_signal())
00218 {
00219 case SIGHUP:
00220 Dout( dc::notice, "Received SIGHUP " << signal_type.get_count() << " times." );
00221 break;
00222 case SIGINT:
00223 {
00224
00225 for (identities_type::iterator iter = identities().begin(); iter != identities().end(); ++iter)
00226 {
00227 if (iter->second.has_secondary_server_connection())
00228 iter->second.secondary_server_connection()->disconnect();
00229 if (iter->second.has_server_session())
00230 iter->second.server_connection().quit("ircproxy received SIGINT");
00231 }
00232
00233 M_terminating = true;
00234 break;
00235 }
00236 }
00237 }
00238
00239
00240 void Application::serialize(PersistXML& xml)
00241 {
00242 xml.serialize("M_listen_port", M_listen_port);
00243 xml.serialize("M_networks", M_networks);
00244 xml.serialize("M_identities", M_identities);
00245 }
00246
00247 namespace {
00248
00249 SingletonInstance<Application> app_instance __attribute__ ((unused));
00250 }
00251