00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: server.c,v 1.68 2007-09-13 22:20:57 sven Exp $";
00022 #endif
00023
00024 #include "server.h"
00025
00026 current_server_t current_server = {0};
00027 server_config_t server_config = {0};
00028 event_owner_t server_owner = {
00029 "server", 0,
00030 0, 0,
00031 0
00032 };
00033
00034 int cycle_delay = 0;
00035
00036
00037 extern int server_script_init();
00038 extern int server_script_destroy();
00039
00040
00041 extern void connect_to_next_server();
00042
00043
00044 extern void dequeue_messages();
00045
00046
00047 extern bind_list_t server_raw_binds[];
00048
00049
00050 extern bind_list_t server_party_commands[];
00051
00052
00053 int server_support(const char *name, const char **value)
00054 {
00055 int i;
00056
00057 for (i = 0; i < current_server.nsupport; i++) {
00058 if (!strcasecmp(name, current_server.support[i].name)) {
00059 *value = current_server.support[i].value;
00060 return(0);
00061 }
00062 }
00063 *value = NULL;
00064 return(-1);
00065 }
00066
00067
00068
00069
00070
00071 static int server_secondly()
00072 {
00073 if (current_server.idx < 0 && cycle_delay >= 0) {
00074
00075
00076 cycle_delay--;
00077 if (cycle_delay <= 0) {
00078 cycle_delay = -1;
00079 connect_to_next_server();
00080 }
00081 return(0);
00082 }
00083
00084
00085 dequeue_messages();
00086
00087
00088 if (current_server.idx >= 0) {
00089 if (current_server.time_to_ping == 0) {
00090 egg_timeval_t now, diff;
00091
00092 timer_get_time(&now);
00093 timer_diff(¤t_server.last_ping_sent, &now, &diff);
00094
00095
00096
00097 if (diff.sec > current_server.last_ping_time.sec || (diff.sec <= current_server.last_ping_time.sec && diff.usec > current_server.last_ping_time.usec)) {
00098 current_server.last_ping_time = diff;
00099 }
00100 if (diff.sec >= server_config.ping_timeout) {
00101 kill_server("ping timeout");
00102 }
00103 }
00104 else if (current_server.time_to_ping > 0) {
00105 current_server.time_to_ping--;
00106 if (current_server.time_to_ping == 0) {
00107 current_server.ping_id = random();
00108 timer_get_time(¤t_server.last_ping_sent);
00109 printserv(SERVER_NOQUEUE, "PING :%d", current_server.ping_id);
00110 }
00111 }
00112 }
00113 return(0);
00114 }
00115
00116 static int server_status(partymember_t *p, const char *text)
00117 {
00118 int details = 0;
00119 channel_t *chan;
00120
00121 if (text) {
00122 if (!strcasecmp(text, "all") || !strcasecmp(text, "server")) details = 1;
00123 else if (*text) return(0);
00124 }
00125
00126 partymember_printf(p, "Server module:");
00127 if (!current_server.connected) {
00128 if (current_server.idx >= 0) partymember_printf(p, _(" Connecting to server %s/%d."), current_server.server_host, current_server.port);
00129 else partymember_printf(p, _(" Connecting to next server in %d seconds."), cycle_delay);
00130 return(0);
00131 }
00132
00133
00134 partymember_printf(p, _(" Connected to %s/%d."), current_server.server_self ? current_server.server_self : current_server.server_host, current_server.port);
00135
00136
00137 if (current_server.registered) {
00138 if (current_server.user) partymember_printf(p, _(" Online as %s!%s@%s (%s)."), current_server.nick, current_server.user, current_server.host, current_server.real_name);
00139 else partymember_printf(p, _(" Online as %s (still waiting for WHOIS result)."), current_server.nick);
00140 }
00141 else partymember_printf(p, _(" Still logging in."));
00142
00143
00144 if (current_server.time_to_ping >= 0 && current_server.npings > 0) {
00145 partymember_printf(p, _(" Last server ping %d.%03d seconds"), current_server.last_ping_time.sec, current_server.last_ping_time.usec / 1000);
00146 }
00147
00148
00149 for (chan = channel_head; chan; chan = chan->next) {
00150 partymember_printf(p, " %s : %d member%s", chan->name, chan->nmembers, chan->nmembers == 1 ? "" : "s");
00151 }
00152
00153
00154 if (details) {
00155 sockbuf_stats_t *stats;
00156
00157 sockbuf_get_stats(current_server.idx, &stats);
00158 partymember_printf(p, " Server traffic: %lld in / %lld out (raw), %lld in / %lld out (filtered)", stats->raw_bytes_in, stats->raw_bytes_out, stats->bytes_in, stats->bytes_out);
00159 }
00160 return(0);
00161 }
00162
00163 static int server_config_save(const char *handle)
00164 {
00165 server_t *server;
00166 void *root, *list, *node;
00167 int i;
00168
00169 putlog(LOG_MISC, "*", "Saving server config...");
00170 root = config_get_root("eggdrop");
00171
00172
00173 list = config_exists(root, "server.serverlist", 0, NULL);
00174 if (list) config_destroy(list);
00175
00176
00177 list = config_lookup_section(root, "server.serverlist", 0, NULL);
00178 i = 0;
00179 for (server = server_list; server; server = server->next) {
00180 node = config_lookup_section(list, "server", i, NULL);
00181 config_set_str(server->host, node, "host", 0, NULL);
00182 config_set_str(server->pass, node, "pass", 0, NULL);
00183 config_set_int(server->port, node, "port", 0, NULL);
00184 i++;
00185 }
00186
00187
00188 list = config_exists(root, "server.nicklist", 0, NULL);
00189 if (list) config_destroy(list);
00190
00191
00192 list = config_lookup_section(root, "server.nicklist", 0, NULL);
00193 for (i = 0; i < nick_list_len; i++) {
00194 config_set_str(nick_list[i], list, "nick", i, NULL);
00195 }
00196
00197
00198 putlog(LOG_MISC, "*", "Saving channels file...");
00199 channel_save(server_config.chanfile);
00200 return(0);
00201 }
00202
00203 static config_var_t server_config_vars[] = {
00204 {"chanfile", &server_config.chanfile, CONFIG_STRING},
00205
00206 {"user", &server_config.user, CONFIG_STRING},
00207 {"realname", &server_config.realname, CONFIG_STRING},
00208
00209
00210 {"connect_timeout", &server_config.connect_timeout, CONFIG_INT},
00211 {"ping_timeout", &server_config.ping_timeout, CONFIG_INT},
00212 {"dcc_timeout", &server_config.dcc_timeout, CONFIG_INT},
00213
00214 {"trigger_on_ignore", &server_config.trigger_on_ignore, CONFIG_INT},
00215 {"keepnick", &server_config.keepnick, CONFIG_INT},
00216 {"cycle_delay", &server_config.cycle_delay, CONFIG_INT},
00217 {"default_port", &server_config.default_port, CONFIG_INT},
00218 {"max_line_len", &server_config.max_line_len, CONFIG_INT},
00219
00220 {"chaninfo_items", &server_config.chaninfo_items, CONFIG_STRING},
00221
00222 {"fake005", &server_config.fake005, CONFIG_STRING},
00223
00224 {"raw_log", &server_config.raw_log, CONFIG_INT},
00225
00226 {"ip_lookup", &server_config.ip_lookup, CONFIG_INT},
00227 {0}
00228 };
00229
00230 static int server_close(int why)
00231 {
00232 void *config_root;
00233
00234 kill_server(_("server module unloading"));
00235 cycle_delay = 100;
00236
00237 config_root = config_get_root("eggdrop");
00238 config_unlink_table(server_config_vars, config_root, "server", 0, NULL);
00239
00240 bind_rem_list("raw", server_raw_binds);
00241
00242 bind_rem_simple("secondly", NULL, NULL, server_secondly);
00243 bind_rem_simple("status", NULL, NULL, server_status);
00244 bind_rem_simple("config_save", NULL, "eggdrop", server_config_save);
00245
00246
00247 server_clear();
00248 nick_clear();
00249
00250 server_binds_destroy();
00251
00252 channel_destroy();
00253 channel_events_destroy();
00254 uhost_cache_destroy();
00255
00256 server_script_destroy();
00257
00258 return(0);
00259 }
00260
00261 static void server_config_init()
00262 {
00263 int i;
00264 char *host, *pass, *nickstr;
00265 int port;
00266 void *config_root, *server, *nick, *list;
00267
00268
00269 server_config.chanfile = strdup("channels.xml");
00270 server_config.user = strdup("user");
00271 server_config.realname = strdup("real name");
00272 server_config.connect_timeout = 30;
00273 server_config.ping_timeout = 30;
00274 server_config.dcc_timeout = 30;
00275 server_config.trigger_on_ignore = 0;
00276 server_config.keepnick = 0;
00277 server_config.cycle_delay = 10;
00278 server_config.default_port = 6667;
00279 server_config.fake005 = NULL;
00280 server_config.max_line_len = 510;
00281 server_config.chaninfo_items = strdup("Inactive");
00282
00283
00284 config_root = config_get_root("eggdrop");
00285 config_link_table(server_config_vars, config_root, "server", 0, NULL);
00286 config_update_table(server_config_vars, config_root, "server", 0, NULL);
00287
00288
00289 list = config_exists(config_root, "server", 0, "serverlist", 0, NULL);
00290 for (i = 0; (server = config_exists(list, "server", i, NULL)); i++) {
00291 host = pass = NULL;
00292 port = 0;
00293 config_get_str(&host, server, "host", 0, NULL);
00294 config_get_str(&pass, server, "pass", 0, NULL);
00295 config_get_int(&port, server, "port", 0, NULL);
00296 if (host) server_add(host, port, pass);
00297 }
00298
00299
00300 list = config_exists(config_root, "server", 0, "nicklist", 0, NULL);
00301 for (i = 0; (nick = config_exists(list, "nick", i, NULL)); i++) {
00302 nickstr = NULL;
00303 config_get_str(&nickstr, nick, NULL);
00304 if (nickstr) nick_add(nickstr);
00305 }
00306 }
00307
00308 EXPORT_SCOPE int start(egg_module_t *modinfo);
00309
00310 int start(egg_module_t *modinfo)
00311 {
00312 server_owner.module = server_dcclistener_owner.module = modinfo;
00313
00314 modinfo->name = "server";
00315 modinfo->author = "eggdev";
00316 modinfo->version = "1.0.0";
00317 modinfo->description = "normal irc server support";
00318 modinfo->close_func = server_close;
00319 modinfo->major = EGG_SERVER_API_MAJOR;
00320 modinfo->minor = EGG_SERVER_API_MINOR;
00321 modinfo->module_api = server_get_api();
00322
00323 memset(¤t_server, 0, sizeof(current_server));
00324 current_server.idx = -1;
00325 cycle_delay = 0;
00326
00327 server_config_init();
00328
00329
00330 server_binds_init();
00331 bind_add_list("raw", server_raw_binds);
00332 bind_add_list("party", server_party_commands);
00333 bind_add_simple("secondly", NULL, NULL, server_secondly);
00334 bind_add_simple("status", NULL, NULL, server_status);
00335 bind_add_simple("config_save", NULL, "eggdrop", server_config_save);
00336
00337
00338 channel_init();
00339 channel_events_init();
00340 uhost_cache_init();
00341
00342
00343 server_script_init();
00344
00345 return(0);
00346 }