diff -uNr ircservices-5.0.9/Changes ircservices-5.0.10/Changes --- ircservices-5.0.9/Changes 2003-02-01 10:53:44.000000000 +0900 +++ ircservices-5.0.10/Changes 2003-02-19 11:08:45.000000000 +0900 @@ -1,14 +1,24 @@ Version 5.0 ----------- -2002/02/01 .9 Fixed a bug leading to desynchs. Reported by +2003/02/19 .10 Fixed bug causing Services to terminate with a fatal error + on receiving multiple KILL messages in quick succession. + Reported by Andrew Kempe +2003/02/17 SMTP traffic is now logged at debug level 1 instead of level 2. +2003/02/17 Added more debug log messages to the Unreal protocol module. +2003/02/14 Fixed bug causing Services to hang if disconnected from the + remote server. Reported by several people. +2003/02/14 Added checks to avoid "sockprintf() with NULL socket" errors + appearing in the logfile. +2003/02/14 Fixed trivial bug in calculating socket read timeout. +2003/02/01 .9 Fixed a bug leading to desynchs. Reported by -2002/01/31 .8 Fixed a number of compilation warnings. -2002/01/31 Fixed typo and thinko causing crashes on channel mode changes. -2002/01/30 .7 Fixed crash when opening a corrupt StatServ database. +2003/01/31 .8 Fixed a number of compilation warnings. +2003/01/31 Fixed typo and thinko causing crashes on channel mode changes. +2003/01/30 .7 Fixed crash when opening a corrupt StatServ database. Reported by Rob van Eijk -2002/01/30 Added robustness in clearing mode +r from users after +2003/01/30 Added robustness in clearing mode +r from users after nickname changes. -2002/01/30 Users now properly get mode +r upon successful AUTH after +2003/01/30 Users now properly get mode +r upon successful AUTH after registering a nick. Reported by 2003/01/23 SZlines are now properly added on startup when using Unreal. Reported by Aragon Gouveia @@ -17,6 +27,8 @@ 2003/01/22 OperServ KILLCLONES no longer adds a new autokill if an existing autokill matches the clones' user@host mask. Reported by Alexander Janssens +2003/01/16 Bahamut protocol support cut off for version 1.4.34+ due to + bugs in the Bahamut ircd. 2003/01/07 Experimental PTlink IRC server support added. 2003/01/06 Fixed bug causing -remote command-line option to not be recognized. diff -uNr ircservices-5.0.9/init.c ircservices-5.0.10/init.c --- ircservices-5.0.9/init.c 2003-02-01 11:02:13.000000000 +0900 +++ ircservices-5.0.10/init.c 2003-02-19 11:15:31.000000000 +0900 @@ -502,20 +502,25 @@ { int retval; + retval = call_callback_1(NULL, cb_introduce_user, user); + if (user == NULL) { + if (retval > 0) + log("introduce_user(): callback returned nonzero for user==NULL"); + retval = 1; + } + /* Watch out for infinite loops... */ + if (retval) { #define LTSIZE 20 - static int lasttimes[LTSIZE]; - if (lasttimes[0] >= time(NULL)-3) - fatal("introduce_user() loop detected"); - memmove(lasttimes, lasttimes+1, sizeof(lasttimes)-sizeof(int)); - lasttimes[LTSIZE-1] = time(NULL); + static int lasttimes[LTSIZE]; + if (lasttimes[0] >= time(NULL)-3) + fatal("introduce_user() loop detected"); + memmove(lasttimes, lasttimes+1, sizeof(lasttimes)-sizeof(*lasttimes)); + lasttimes[LTSIZE-1] = time(NULL); #undef LTSIZE + } - retval = call_callback_1(NULL, cb_introduce_user, user); - if (user == NULL && retval > 0) - log("introduce_user(): callback returned nonzero for user == NULL"); - - return user==NULL ? 1 : retval; + return retval; } #undef NICK diff -uNr ircservices-5.0.9/main.c ircservices-5.0.10/main.c --- ircservices-5.0.9/main.c 2003-02-01 11:02:13.000000000 +0900 +++ ircservices-5.0.10/main.c 2003-02-19 11:15:31.000000000 +0900 @@ -206,55 +206,55 @@ if (debug >= 2) log("debug: Top of main loop"); - if (sock_isconn(servsock)) { - if (!readonly && !noexpire - && (save_data || now-last_expire >= ExpireTimeout) - ) { - if (debug) - log("debug: Running expire routines"); - call_callback(NULL, cb_expire); - last_expire = now; - } - if (!readonly && (save_data || now-last_update >= UpdateTimeout)) { - if (!lock_data()) { - if (errno == EEXIST) { - wallops(NULL, - "\2Warning:\2 Data directory is locked;" - " databases will not be updated. Remove" - " the `%s' file to allow database updates.", - LockFilename); - log("warning: data directory is locked, not" - " updating databases"); - } else { - wallops(NULL, - "\2Warning:\2 Unable to lock data directory;" - " databases will not be updated."); - log_perror("warning: unable to lock data directory," - " not updating databases"); - } + if (!readonly + && !noexpire + && (save_data || now-last_expire >= ExpireTimeout) + ) { + if (debug) + log("debug: Running expire routines"); + call_callback(NULL, cb_expire); + last_expire = now; + } + if (!readonly && (save_data || now-last_update >= UpdateTimeout)) { + if (!lock_data()) { + if (errno == EEXIST) { + wallops(NULL, + "\2Warning:\2 Data directory is locked;" + " databases will not be updated. Remove" + " the `%s' file to allow database updates.", + LockFilename); + log("warning: data directory is locked, not updating" + " databases"); } else { - if (debug) - log("debug: Saving databases"); - call_callback(NULL, cb_save_data); - if (!unlock_data()) { - wallops(NULL, - "\2Warning:\2 Unable to unlock data" - " directory; future database updates may" - " fail until the `%s' file is removed.", - LockFilename); - log_perror("warning: unable to unlock data directory"); - } - if (save_data < 0) - break; /* out of main loop */ + wallops(NULL, + "\2Warning:\2 Unable to lock data directory;" + " databases will not be updated."); + log_perror("warning: unable to lock data directory," + " not updating databases"); + } + } else { + if (debug) + log("debug: Saving databases"); + call_callback(NULL, cb_save_data); + if (!unlock_data()) { + wallops(NULL, + "\2Warning:\2 Unable to unlock data" + " directory; future database updates may" + " fail until the `%s' file is removed.", + LockFilename); + log_perror("warning: unable to unlock data directory"); } - save_data = 0; - last_update = now; } - if (delayed_quit) - break; + save_data = 0; + last_update = now; + } + if (delayed_quit) + break; + + if (sock_isconn(servsock)) { if (PingFrequency && now-last_send >= PingFrequency) send_cmd(NULL, "PING :%s", ServerName); - } /* if (sock_isconn(servsock)) */ + } if (now_msec - last_check >= TimeoutCheck) { check_timeouts(); diff -uNr ircservices-5.0.9/modules/mail/smtp.c ircservices-5.0.10/modules/mail/smtp.c --- ircservices-5.0.9/modules/mail/smtp.c 2003-02-01 11:02:14.000000000 +0900 +++ ircservices-5.0.10/modules/mail/smtp.c 2003-02-19 11:15:32.000000000 +0900 @@ -66,6 +66,8 @@ module_log("send_smtp(): sock_new() failed"); return 1; } + if (debug) + module_log("debug: SMTP(%p) connecting", si->sock); si->from = strdup(from); si->fromname = strdup(fromname); si->to = strdup(to); @@ -169,8 +171,8 @@ if (*--s == '\r') have_eol++; *s = 0; - if (debug >= 2) - module_log("SMTP(%p) received: %s", sock, buf); + if (debug) + module_log("debug: SMTP(%p) received: %s", sock, buf); if (!si->replycode) { if (buf[0] < '1' || buf[0] > '5' || buf[1] < '0' || buf[1] > '9' @@ -247,14 +249,14 @@ static void smtp_writeline(Socket *sock, const char *fmt, ...) { va_list args; - char buf[4096]; /* space for creating log message */ + char buf[4096]; va_start(args, fmt); snprintf(buf, sizeof(buf), "%s\r\n", fmt); vsockprintf(sock, buf, args); - if (debug >= 2) { + if (debug) { char *s = buf; - s += snprintf(buf, sizeof(buf), "SMTP(%p) sent: ", sock); + s += snprintf(buf, sizeof(buf), "debug: SMTP(%p) sent: ", sock); vsnprintf(s, sizeof(buf)-(s-buf), fmt, args); module_log("%s", buf); } @@ -273,6 +275,11 @@ return; } + if (debug) { + module_log("debug: SMTP(%p) closed (%s)", sock, + why==DISCONN_LOCAL ? "local" : + why==DISCONN_CONNFAIL ? "connfail" : "remote"); + } if (why == DISCONN_LOCAL) /* we explicitly closed the socket */ return; if (why == DISCONN_CONNFAIL) diff -uNr ircservices-5.0.9/modules/nickserv/collide.c ircservices-5.0.10/modules/nickserv/collide.c --- ircservices-5.0.9/modules/nickserv/collide.c 2003-02-01 11:02:14.000000000 +0900 +++ ircservices-5.0.10/modules/nickserv/collide.c 2003-02-19 11:15:32.000000000 +0900 @@ -90,8 +90,15 @@ static void timeout_collide(Timeout *t) { NickInfo *ni = t->data; - NickGroupInfo *ngi = get_ngi(ni); + NickGroupInfo *ngi = NULL; + if (ni) { + if (ni->nickgroup != 0) + ngi = get_ngi(ni); + } else { + log("BUG: NULL NickInfo in timeout_collide"); + return; + } rem_ns_timeout(ni, TO_COLLIDE, 0); /* If they identified or don't exist anymore, don't kill them. */ if ((ngi && nick_identified(ni)) @@ -114,6 +121,10 @@ { NickInfo *ni = t->data; + if (!ni) { + log("BUG: NULL NickInfo in timeout_release"); + return; + } rem_ns_timeout(ni, TO_RELEASE, 0); release(ni, 1); } @@ -127,18 +138,23 @@ NickInfo *ni = t->data; User *u; + if (!ni) { + log("BUG: NULL NickInfo in timeout_send_433"); + return; + } rem_ns_timeout(ni, TO_SEND_433, 0); /* If they identified or don't exist anymore, don't send the 433. */ if (nick_identified(ni) || !(u = get_user(ni->nick)) || u->my_signon > t->settime) return; - if (ni->status & NS_VERBOTEN) + if (ni->status & NS_VERBOTEN) { send_cmd(ServerName, "433 %s %s :Nickname may not be used", ni->nick, ni->nick); - else + } else { send_cmd(ServerName, "433 %s %s :Nickname is registered to someone" " else", ni->nick, ni->nick); + } } /*************************************************************************/ @@ -151,6 +167,11 @@ struct my_timeout *t; void (*timeout_routine)(Timeout *); + if (!ni) { + log("BUG: NULL NickInfo in add_ns_timeout (type=%d delay=%ld)", + type, (long)delay); + return; + } if (type == TO_COLLIDE) timeout_routine = timeout_collide; else if (type == TO_RELEASE) @@ -158,8 +179,8 @@ else if (type == TO_SEND_433) timeout_routine = timeout_send_433; else { - module_log("unknown timeout type %d! ni=%p (%s), delay=%ld", - type, ni, ni->nick, delay); + module_log("BUG: unknown timeout type %d! ni=%p (%s), delay=%ld", + type, ni, ni->nick, (long)delay); return; } to = add_timeout(delay, timeout_routine, 0); @@ -182,6 +203,11 @@ { struct my_timeout *t, *t2; + if (!ni) { + log("BUG: NULL NickInfo in rem_ns_timeout (type=%d del_to=%d)", + type, del_to); + return; + } LIST_FOREACH_SAFE (t, my_timeouts, t2) { if (t->ni == ni && (type < 0 || t->type == type)) { LIST_REMOVE(t, my_timeouts); diff -uNr ircservices-5.0.9/modules/protocol/monkey.c ircservices-5.0.10/modules/protocol/monkey.c --- ircservices-5.0.9/modules/protocol/monkey.c 2003-02-01 11:02:14.000000000 +0900 +++ ircservices-5.0.10/modules/protocol/monkey.c 2003-02-19 11:15:32.000000000 +0900 @@ -228,7 +228,7 @@ static void do_send_server(void) { sleep(5); /* Hack, give monkeyircd time to resolve properly */ - send_cmd(NULL, "PASS %s :TS", RemotePassword); + send_cmd(NULL, "PASS %s 0280ircservices CMIRCD|Nothing", RemotePassword); send_cmd(NULL, "CAPAB :TS4"); send_cmd(NULL, "SERVER %s 1 :%s", ServerName, ServerDesc); send_cmd(NULL, "SVINFO 4 4 0 :%ld", (long)time(NULL)); diff -uNr ircservices-5.0.9/modules/protocol/unreal.c ircservices-5.0.10/modules/protocol/unreal.c --- ircservices-5.0.9/modules/protocol/unreal.c 2003-02-01 11:02:14.000000000 +0900 +++ ircservices-5.0.10/modules/protocol/unreal.c 2003-02-19 11:15:32.000000000 +0900 @@ -370,8 +370,13 @@ static void m_chghost(char *source, int ac, char **av) { - if (ac == 2) + if (ac == 2) { + if (debug) { + module_log("debug: m_chghost from %s calling m_sethost for %s", + source, av[0]); + } m_sethost(av[0], ac-1, av+1); + } } /*************************************************************************/ @@ -395,8 +400,13 @@ static void m_chgident(char *source, int ac, char **av) { - if (ac == 2) + if (ac == 2) { + if (debug) { + module_log("debug: m_chgident from %s calling m_setident for %s", + source, av[0]); + } m_setident(av[0], ac-1, av+1); + } } /*************************************************************************/ @@ -420,13 +430,21 @@ static void m_chgname(char *source, int ac, char **av) { - if (ac == 2) + if (ac == 2) { + if (debug) { + module_log("debug: m_chgname from %s calling m_setname for %s", + source, av[0]); + } m_setname(av[0], ac-1, av+1); + } } /*************************************************************************/ -/* SJOIN message handler. The actual code is in sjoin.c. Note */ +/* SJOIN message handler. The actual code is in sjoin.c (note that we use + * UNREAL_HACK, so the routine we call is do_sjoin_unreal() instead of + * do_sjoin()). + */ static void m_sjoin(char *source, int ac, char **av) { diff -uNr ircservices-5.0.9/send.c ircservices-5.0.10/send.c --- ircservices-5.0.9/send.c 2003-02-01 11:02:13.000000000 +0900 +++ ircservices-5.0.10/send.c 2003-02-19 11:15:31.000000000 +0900 @@ -131,11 +131,13 @@ vsnprintf(buf, sizeof(buf), fmt, args); if (source) { - sockprintf(servsock, ":%s %s\r\n", source, buf); + if (sock_isconn(servsock)) + sockprintf(servsock, ":%s %s\r\n", source, buf); if (debug) log("debug: Sent: :%s %s", source, buf); } else { - sockprintf(servsock, "%s\r\n", buf); + if (sock_isconn(servsock)) + sockprintf(servsock, "%s\r\n", buf); if (debug) log("debug: Sent: %s", buf); } diff -uNr ircservices-5.0.9/sockets.c ircservices-5.0.10/sockets.c --- ircservices-5.0.9/sockets.c 2003-02-01 11:02:13.000000000 +0900 +++ ircservices-5.0.10/sockets.c 2003-02-19 11:15:31.000000000 +0900 @@ -176,11 +176,13 @@ /*************************************************************************/ -/* Return whether the given socket is currently connected. */ +/* Return whether the given socket is currently connected (this includes + * sockets which are waiting for a connection to be completed). + */ int sock_isconn(const Socket *s) { - return s->flags & SF_CONNECTED ? 1 : 0; + return s->flags & (SF_CONNECTING|SF_CONNECTED) ? 1 : 0; } /*************************************************************************/ @@ -316,7 +318,7 @@ rfds = sock_fds; wfds = write_fds; tv.tv_sec = ReadTimeout/1000; - tv.tv_usec = ReadTimeout%1000; + tv.tv_usec = (ReadTimeout%1000) * 1000; enable_signals(); do { /* Note: On systems which don't return the time remaining in `tv', diff -uNr ircservices-5.0.9/version.sh ircservices-5.0.10/version.sh --- ircservices-5.0.9/version.sh 2003-02-01 10:53:53.000000000 +0900 +++ ircservices-5.0.10/version.sh 2003-02-19 11:11:36.000000000 +0900 @@ -3,7 +3,7 @@ # Build the version.c file which contains all the version related info and # needs to be updated on a per-build basis. -VERSION=5.0.9 +VERSION=5.0.10 # Increment Services build number if [ -f version.c ] ; then