diff -uNr ircservices-5.0.28/Changes ircservices-5.0.29/Changes --- ircservices-5.0.28/Changes 2004-02-05 20:54:46 +0900 +++ ircservices-5.0.29/Changes 2004-03-24 19:14:20 +0900 @@ -1,5 +1,15 @@ Version 5.0 ----------- +2004/03/24 .29 Added support for extended ban types, new channel mode +f + format, and other feeping creaturism in Unreal 3.2. +2004/03/24 Fixed PTlink channel database reading, and added workaround + for PTlink bug causing inconsistent data to be stored. + Reported by +2004/03/17 Added experimental support for Hybrid 7 servers. Thanks to + Jon Christopherson for assistance. +2004/03/06 Updated tr-ircd protocol module to support version 5.7. + Support for versions before 5.5 has been dropped at the + tr-ircd author's request. 2004/02/05 .28 The OperServ AKILL/EXCLUDE/EXCEPTION/SLINE LIST and VIEW commands now only display the first 50 entries matching the given mask. Note that no notice is given if the @@ -247,11 +257,10 @@ (this avoids "make ; make install" incrementing the value twice). Reported by Craig McLure 2003/03/03 Users are no longer collided if they have identified but - need to set an E-mail address. Reported by Andrew - Kempe + need to set an E-mail address. Reported by Andrew Kempe. 2003/03/03 Nicknames awaiting E-mail authorization now always use the regular 60-second timeout regardless of the KILL - setting. Suggested by Andrew Kempe + setting. Suggested by Andrew Kempe. 2003/03/03 Added new section (3-1-2) on netsplit recovery to the manual. 2003/03/03 Added workaround for broken browsers that don't handle backslashes properly. Reported by @@ -293,7 +302,7 @@ Yusuf Iskenderoglu 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 + 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 @@ -1086,7 +1095,7 @@ 2001/11/22 Added SMTP mail sending module. 2001/11/22 Added MemoServ FORWARD module. 2001/11/21 Fixed bug with SENDAUTH command response. Reported by - Andrew Kempe + Andrew Kempe. 2001/11/21 Fixed crash when an unregistered nick enters a channel. 2001/11/21 Added OperMaxExpiry directive to autokill module. Suggested by Finny Merrill @@ -1130,7 +1139,7 @@ 2001/11/07 Fixed failure to start up when databases did not exist. Last 3 reported by Finny Merrill 2001/11/07 Fixed compilation problem on FreeBSD. Reported by Andrew - Kempe + Kempe. 2001/11/07 Changed configure's default data directory selection to be slightly more intelligent, and fixed a bug with spaces in target directory names. diff -uNr ircservices-5.0.28/channels.c ircservices-5.0.29/channels.c --- ircservices-5.0.28/channels.c 2004-02-05 21:00:49 +0900 +++ ircservices-5.0.29/channels.c 2004-03-24 19:23:25 +0900 @@ -250,7 +250,7 @@ } if (!NoBouncyModes) { - /* Count identical server mode changes per second (mode bounce check) */ + /* Count identical server mode changes per second (mode bounce check)*/ /* Doesn't trigger on +/-[bov] or other multiply-settable modes */ static char multimodes[BUFSIZE]; if (!*multimodes) { diff -uNr ircservices-5.0.28/channels.h ircservices-5.0.29/channels.h --- ircservices-5.0.28/channels.h 2004-02-05 21:00:49 +0900 +++ ircservices-5.0.29/channels.h 2004-03-24 19:23:25 +0900 @@ -26,8 +26,9 @@ int32 mode; /* CMODE_* (binary) channel modes */ int32 limit; /* 0 if none */ char *key; /* NULL if none */ - char *link; /* +L (Unreal) */ - char *flood; /* +f (Unreal) */ + char *link; /* +L (Unreal, trircd) */ + char *flood; /* +f (Unreal, etc.) */ + int32 joindelay; /* +J (trircd) */ char **bans; int32 bans_count; diff -uNr ircservices-5.0.28/configure ircservices-5.0.29/configure --- ircservices-5.0.28/configure 2004-01-22 09:31:31 +0900 +++ ircservices-5.0.29/configure 2004-02-18 23:03:25 +0900 @@ -1192,7 +1192,7 @@ fi if [ "$OK" ] ; then if run $CONFTMP/test ; then - a=`$CONFTMP/test` + a=`$CONFTMP/test 2>/dev/null` log "missing-symbol test: $CONFTMP/test => $a" if [ "x$a" = "x0" ] ; then log "missing-symbol test succeeded" diff -uNr ircservices-5.0.28/data/example-ircservices.conf ircservices-5.0.29/data/example-ircservices.conf --- ircservices-5.0.28/data/example-ircservices.conf 2004-02-05 21:00:38 +0900 +++ ircservices-5.0.29/data/example-ircservices.conf 2004-03-24 19:23:24 +0900 @@ -485,12 +485,13 @@ # Select the module which matches the IRC server you are using: # protocol/bahamut DALnet Bahamut server, versions 1.4.25+ # protocol/dalnet DALnet server, version 4.4.13 and earlier -# protocol/dreamforge DALnet Dreamforge server (version 4.4.15+) +# protocol/dreamforge DALnet Dreamforge server, versions 4.4.15+ +# [*]protocol/hybrid Hybrid server, version 7.0 # protocol/monkey Chunky Monkey IRCD, version 1.0 and later # [*]protocol/ptlink PTlink IRC server, version 6.0 and later # protocol/rfc1459 RFC1459-compliant servers # protocol/trircd Trircd server, version 4.0 and later -# protocol/ts8 RFC1459 with TS8 extensions +# protocol/ts8 RFC1459 with TS8 extensions # protocol/undernet-p9 Undernet server, version 2.9.x only # protocol/unreal Unreal server, version 3.1.0 and later # Modules marked with [*] are still in an experimental stage and may @@ -805,8 +806,8 @@ ########################################################################### -# HTTP server modules [OPTIONAL] -# These are modules which do not fit easily into any other category; +# Miscellaneous modules [OPTIONAL] +# These are modules which do not fit easily into any other category: # # misc/xml-export # Provides the ability to export the Services database in XML diff -uNr ircservices-5.0.28/docs/2.html ircservices-5.0.29/docs/2.html --- ircservices-5.0.28/docs/2.html 2003-12-03 18:49:03 +0900 +++ ircservices-5.0.29/docs/2.html 2004-03-24 19:15:35 +0900 @@ -32,6 +32,19 @@ (or nearly so) operating system; it is known to work on FreeBSD and Solaris. +

Notice: Services will not work on OpenBSD 3.4, as the +version of GCC included in that release (2.95.3) has an OpenBSD-specific +bug which causes Services to crash, and OpenBSD 3.4 is not yet supported by +more recent versions of GCC due to an executable file format change. An +enhancement request +(#13891) +has been filed with the GCC development team, and the OpenBSD developers +are apparently working on importing GCC 3.3.2 into OpenBSD, but until one +or the other is complete, you will need to use either an older version of +OpenBSD or a different operating system to run Services. (It may be +possible to compile Services on an OpenBSD 3.3 or earlier system and use +the resulting executable on OpenBSD 3.4; this has not been tested.) +

  • A supported IRC server (IRCD). Services supports several different types of IRC servers, as listed in Table 2-1 below. Your IRC network must be using one of these servers in order to use Services (the @@ -56,7 +69,7 @@ removed completely in a future version. Also note that early versions in the 3.x series were reported to have problems, and should not be used. -

    Warning: GCC version 2.96, provided in some Red Hat and related +

    Warning: GCC version 2.96, provided in some Red Hat and related Linux distributions, has bugs which cause Services to be compiled incorrectly (see FAQ B.1 for details). Do not use this compiler to compile Services in any circumstances. @@ -99,6 +112,11 @@ dreamforge Dreamforge (ircd.dal 4.6.x) dreamforge +Hybrid + [ircd-hybrid.com] 7.0 + (**) + (experimental) + hybrid ircd-2.8.x rfc1459 ircd-2.8.x+TS8 @@ -108,11 +126,11 @@ undernet-p9 PTlink IRCd [www.ptlink.net] 6.10.0 and above - <(experimental) + (experimental) ptlink tr-ircd - [tr-ircd.sourceforge.net] 5.1 and - above + [tr-ircd.sourceforge.net] 5.5 and + above
    (5.7 recommended) trircd UltimateIRCD 2.8.1 dreamforge @@ -131,12 +149,23 @@ code when the DEBUGMODE compile-time constant is defined. If you use this server, make certain you either do not define DEBUGMODE, or change the following line in src/s_debug.c: -

    syslog(LOG_ERR, debugbuf);
    -to: -
    syslog(LOG_ERR, "%s", debugbuf);
    -See this +
        syslog(LOG_ERR, debugbuf); +
    to: +
        syslog(LOG_ERR, "%s", debugbuf); +
    See
    this advisory [0xbadc0ded.org] for details. +

    (**) To use Hybrid with Services, you must +compile and install the TBURST module, found in the +contrib directory of the Hybrid distribution. After compiling and +installing Hybrid, execute the following command from the top-level +directory of the distribution: +
        make m_tburst.so ; cp m_tburst.so prefix/modules/autoload +
    where prefix is the installation prefix you specified +to the Hybrid configure script (default /usr/local/ircd). +If the TBURST module is not properly installed, Services will +refuse to connect to the server. +

    Back to top


    @@ -303,7 +332,7 @@ all of the possible modules; select which ones you want to load or not load. In particular, make sure you select the correct protocol module and enter its name in the line which reads -
    LoadModule protocol/(insert protocol name here) + "LoadModule protocol/(insert protocol name here)" or Services will not be able to start. modules.conf diff -uNr ircservices-5.0.28/docs/5.html ircservices-5.0.29/docs/5.html --- ircservices-5.0.28/docs/5.html 2003-11-26 13:11:23 +0900 +++ ircservices-5.0.29/docs/5.html 2004-03-24 01:29:49 +0900 @@ -458,6 +458,9 @@ authentication code (2.22.0 and later) for nicknames
  • maximum number of users and time of maximum for channels +
  • An apparent bug in PTlink causes the successor field of some channels + to be corrupted; this will result in warnings when loading the + channel database.

    SirvNET diff -uNr ircservices-5.0.28/lang/de.l ircservices-5.0.29/lang/de.l --- ircservices-5.0.28/lang/de.l 2004-01-22 09:31:32 +0900 +++ ircservices-5.0.29/lang/de.l 2004-03-06 08:50:32 +0900 @@ -985,8 +985,8 @@ Modusliste muss mit + (plus) oder - (minus) beginnen. CHAN_SET_MLOCK_NEED_PARAM MLOCK +%c benötigt einen Parameter. -CHAN_SET_MLOCK_LIMIT_POSITIVE - Der Parameter für MLOCK +l muss eine positive Zahl sein. +CHAN_SET_MLOCK_NEED_POSITIVE + Der Parameter für MLOCK +%c muss eine positive Zahl sein. CHAN_SET_MLOCK_MODE_REG_BAD Modus +%c kann mit MLOCK nicht benutzt werden (wird immer bei registrierten Räumen gesetzt). CHAN_SET_MLOCK_LINK_BAD diff -uNr ircservices-5.0.28/lang/en_us.l ircservices-5.0.29/lang/en_us.l --- ircservices-5.0.28/lang/en_us.l 2004-01-22 09:32:31 +0900 +++ ircservices-5.0.29/lang/en_us.l 2004-03-17 20:33:41 +0900 @@ -1020,8 +1020,8 @@ Mode list must begin with a + (plus) or - (minus). CHAN_SET_MLOCK_NEED_PARAM Parameter required for MLOCK +%c. -CHAN_SET_MLOCK_LIMIT_POSITIVE - Parameter for MLOCK +l must be a positive number. +CHAN_SET_MLOCK_NEED_POSITIVE + Parameter for MLOCK +%c must be a positive number. CHAN_SET_MLOCK_MODE_REG_BAD Mode +%c is always set on registered channels, and cannot be used with MLOCK. CHAN_SET_MLOCK_LINK_BAD @@ -5076,4 +5076,4 @@ # version of the master (English) language file was used to create a # translated file. -# CVS: $Revision: 2.218 $ +# CVS: $Revision: 2.219 $ diff -uNr ircservices-5.0.28/lang/es.l ircservices-5.0.29/lang/es.l --- ircservices-5.0.28/lang/es.l 2004-01-22 09:31:32 +0900 +++ ircservices-5.0.29/lang/es.l 2004-03-06 08:50:55 +0900 @@ -1022,8 +1022,8 @@ Lista de Modos debe comenzar con un + (más) o - (menos). CHAN_SET_MLOCK_NEED_PARAM Parámetro requerido para MLOCK +%c. -CHAN_SET_MLOCK_LIMIT_POSITIVE - Parámetro para MLOCK +l debe ser un número positivo. +CHAN_SET_MLOCK_NEED_POSITIVE + Parámetro para MLOCK +%c debe ser un número positivo. CHAN_SET_MLOCK_MODE_REG_BAD Modo +%c es siempre establecido en canales registrados, y no puede ser usado con MLOCK (Opción Candado). CHAN_SET_MLOCK_LINK_BAD diff -uNr ircservices-5.0.28/lang/fr.l ircservices-5.0.29/lang/fr.l --- ircservices-5.0.28/lang/fr.l 2004-01-22 09:31:32 +0900 +++ ircservices-5.0.29/lang/fr.l 2004-03-06 08:51:04 +0900 @@ -1005,8 +1005,8 @@ La liste des modes doit commencer par un + (plus) ou un - (moins). CHAN_SET_MLOCK_NEED_PARAM Paramêtre +%c requis pour le mode vérouillé (MLOCK). -CHAN_SET_MLOCK_LIMIT_POSITIVE - Le paramêtre pour le mode de vérouillage MLOCK +l doit être un nombre positif. +CHAN_SET_MLOCK_NEED_POSITIVE + Le paramêtre pour le mode de vérouillage MLOCK +%c doit être un nombre positif. CHAN_SET_MLOCK_MODE_REG_BAD Le mode +%c est toujours présent sur un canal enregistré, et ne peut pas être utilisé avec MLOCK. CHAN_SET_MLOCK_LINK_BAD diff -uNr ircservices-5.0.28/lang/hu.l ircservices-5.0.29/lang/hu.l --- ircservices-5.0.28/lang/hu.l 2004-01-22 09:31:33 +0900 +++ ircservices-5.0.29/lang/hu.l 2004-03-06 08:51:19 +0900 @@ -1031,8 +1031,8 @@ A lockolni kívánt módokat tartalmazó lista + (plus) vagy - (minus) jelekkel kell, hogy kezdõdjön. CHAN_SET_MLOCK_NEED_PARAM A megadott flaghez (+%c) paraméter szükséges. -CHAN_SET_MLOCK_LIMIT_POSITIVE - A paraméter az MLOCK +l esetében pozitív szám kell, hogy legyen. +CHAN_SET_MLOCK_NEED_POSITIVE + A paraméter az MLOCK +%c esetében pozitív szám kell, hogy legyen. CHAN_SET_MLOCK_MODE_REG_BAD A megadott flag (+%c) mindig be lesz állítva a regisztrált csatornán, és nem használható az MLOCK paranccsal. CHAN_SET_MLOCK_LINK_BAD diff -uNr ircservices-5.0.28/lang/index ircservices-5.0.29/lang/index --- ircservices-5.0.28/lang/index 2004-02-02 12:25:56 +0900 +++ ircservices-5.0.29/lang/index 2004-03-17 21:07:41 +0900 @@ -360,7 +360,7 @@ CHAN_ENTRY_MSG_CHANGED CHAN_SET_MLOCK_NEED_PLUS_MINUS CHAN_SET_MLOCK_NEED_PARAM -CHAN_SET_MLOCK_LIMIT_POSITIVE +CHAN_SET_MLOCK_NEED_POSITIVE CHAN_SET_MLOCK_MODE_REG_BAD CHAN_SET_MLOCK_LINK_BAD CHAN_SET_MLOCK_LINK_SAME diff -uNr ircservices-5.0.28/lang/it.l ircservices-5.0.29/lang/it.l --- ircservices-5.0.28/lang/it.l 2004-01-22 09:31:33 +0900 +++ ircservices-5.0.29/lang/it.l 2004-03-06 08:51:35 +0900 @@ -638,12 +638,12 @@ # SET MLOCK responses CHAN_SET_MLOCK_NEED_PARAM Parametro richiesto per MLOCK +%c. -CHAN_SET_MLOCK_LIMIT_POSITIVE - Il parametro per MLOCK +l deve essere un numero positivo. +CHAN_SET_MLOCK_NEED_POSITIVE + Il parametro per MLOCK +%c deve essere un numero positivo. CHAN_SET_MLOCK_UNKNOWN_CHAR Sconosciuta modalita' %c ignorata. CHAN_MLOCK_CHANGED - Modalita' di chiusura di %s cambiata a %s. + Modalita' di chiusura di %s cambiata a %s. CHAN_MLOCK_REMOVED Modalita' di chiusura di %s rimossa. diff -uNr ircservices-5.0.28/lang/ja_euc.l ircservices-5.0.29/lang/ja_euc.l --- ircservices-5.0.28/lang/ja_euc.l 2004-01-22 09:31:33 +0900 +++ ircservices-5.0.29/lang/ja_euc.l 2004-03-06 08:52:16 +0900 @@ -966,8 +966,8 @@ ¥â¡¼¥É¥ê¥¹¥È¤ÎÀèƬ¤Ë¤Ï¡Ö+¡×¤«¡Ö-¡×¤¬É¬ÍפǤ¹¡£ CHAN_SET_MLOCK_NEED_PARAM ¥â¡¼¥É¡Ö+%c¡×¤Ë¤Ï¥Ñ¥é¥á¡¼¥¿¤¬É¬ÍפǤ¹¡£ -CHAN_SET_MLOCK_LIMIT_POSITIVE - ¥â¡¼¥É¡Ö+l¡×¤Ë¤ÏÀµ¿ô¥Ñ¥é¥á¡¼¥¿¤¬É¬ÍפǤ¹¡£ +CHAN_SET_MLOCK_NEED_POSITIVE + ¥â¡¼¥É¡Ö+%c¡×¤Ë¤ÏÀµ¿ô¥Ñ¥é¥á¡¼¥¿¤¬É¬ÍפǤ¹¡£ CHAN_SET_MLOCK_MODE_REG_BAD ¥â¡¼¥É¡Ö+%c¡×¤Ï¡¢ÅÐÏ¿¤µ¤ì¤¿¥Á¥ã¥ó¥Í¥ë¤Ë¤Ï¾ï¤ËÀßÄꤵ¤ì¡¢SET MLOCK¤Ç¤Ï»È¤¨¤Þ¤»¤ó¡£ CHAN_SET_MLOCK_LINK_BAD diff -uNr ircservices-5.0.28/lang/ja_sjis.l ircservices-5.0.29/lang/ja_sjis.l --- ircservices-5.0.28/lang/ja_sjis.l 2004-01-22 09:31:33 +0900 +++ ircservices-5.0.29/lang/ja_sjis.l 2004-03-06 09:05:23 +0900 @@ -966,8 +966,8 @@ ƒ‚[ƒhƒŠƒXƒg‚Ì擪‚É‚Íu+v‚©u-v‚ª•K—v‚Å‚·B CHAN_SET_MLOCK_NEED_PARAM ƒ‚[ƒhu+%cv‚ɂ̓pƒ‰ƒ[ƒ^‚ª•K—v‚Å‚·B -CHAN_SET_MLOCK_LIMIT_POSITIVE - ƒ‚[ƒhu+lv‚ɂͳ”ƒpƒ‰ƒ[ƒ^‚ª•K—v‚Å‚·B +CHAN_SET_MLOCK_NEED_POSITIVE + ƒ‚[ƒhu+%cv‚ɂͳ”ƒpƒ‰ƒ[ƒ^‚ª•K—v‚Å‚·B CHAN_SET_MLOCK_MODE_REG_BAD ƒ‚[ƒhu+%cv‚ÍA“o˜^‚³‚ꂽƒ`ƒƒƒ“ƒlƒ‹‚É‚Íí‚Éݒ肳‚êASET MLOCK‚Å‚ÍŽg‚¦‚Ü‚¹‚ñB CHAN_SET_MLOCK_LINK_BAD diff -uNr ircservices-5.0.28/lang/langstrs.h ircservices-5.0.29/lang/langstrs.h --- ircservices-5.0.28/lang/langstrs.h 2004-02-05 21:00:49 +0900 +++ ircservices-5.0.29/lang/langstrs.h 2004-03-24 19:23:26 +0900 @@ -360,7 +360,7 @@ #define CHAN_ENTRY_MSG_CHANGED 359 #define CHAN_SET_MLOCK_NEED_PLUS_MINUS 360 #define CHAN_SET_MLOCK_NEED_PARAM 361 -#define CHAN_SET_MLOCK_LIMIT_POSITIVE 362 +#define CHAN_SET_MLOCK_NEED_POSITIVE 362 #define CHAN_SET_MLOCK_MODE_REG_BAD 363 #define CHAN_SET_MLOCK_LINK_BAD 364 #define CHAN_SET_MLOCK_LINK_SAME 365 diff -uNr ircservices-5.0.28/lang/nl.l ircservices-5.0.29/lang/nl.l --- ircservices-5.0.28/lang/nl.l 2004-01-22 09:31:33 +0900 +++ ircservices-5.0.29/lang/nl.l 2004-03-06 08:52:33 +0900 @@ -1033,8 +1033,8 @@ Mode lijst dient te beginnen met een + (plus) of - (min). CHAN_SET_MLOCK_NEED_PARAM Parameter vereist voor MLOCK +%c. -CHAN_SET_MLOCK_LIMIT_POSITIVE - Parameter voor MLOCK +l dient een positief nummer te zijn. +CHAN_SET_MLOCK_NEED_POSITIVE + Parameter voor MLOCK +%c dient een positief nummer te zijn. CHAN_SET_MLOCK_MODE_REG_BAD Mode +%c is is altijd aanwezig in geregistreerde kamers, en kan niet gebruikt worden met MLOCK. diff -uNr ircservices-5.0.28/lang/pt.l ircservices-5.0.29/lang/pt.l --- ircservices-5.0.28/lang/pt.l 2004-01-22 09:31:33 +0900 +++ ircservices-5.0.29/lang/pt.l 2004-03-06 08:52:41 +0900 @@ -722,8 +722,8 @@ # SET MLOCK responses CHAN_SET_MLOCK_NEED_PARAM Parametro requerido para MLOCK +%c. -CHAN_SET_MLOCK_LIMIT_POSITIVE - Parametro para MLOCK +l deve ser um numero positivo. +CHAN_SET_MLOCK_NEED_POSITIVE + Parametro para MLOCK +%c deve ser um numero positivo. CHAN_SET_MLOCK_MODE_REG_BAD Modo +%c sempre eh colocado em canais registrados, e nao pode ser usado com MLOCK. CHAN_SET_MLOCK_UNKNOWN_CHAR diff -uNr ircservices-5.0.28/lang/tr.l ircservices-5.0.29/lang/tr.l --- ircservices-5.0.28/lang/tr.l 2004-01-22 09:31:33 +0900 +++ ircservices-5.0.29/lang/tr.l 2004-03-06 08:52:45 +0900 @@ -984,8 +984,8 @@ Mode belirtirken + ve ya - isaretleri kullanmak gerekmektedir. CHAN_SET_MLOCK_NEED_PARAM +%c modu icin parametre gerekiyor. -CHAN_SET_MLOCK_LIMIT_POSITIVE - MLOCK +l olarak pozitif bir sayi kullanmalisiniz. +CHAN_SET_MLOCK_NEED_POSITIVE + MLOCK +%c olarak pozitif bir sayi kullanmalisiniz. CHAN_SET_MLOCK_MODE_REG_BAD Mode +%c daima kayitli kanallar icin kullanilir, MLOCK ile tanimlanamaz. CHAN_SET_MLOCK_LINK_BAD diff -uNr ircservices-5.0.28/modules/chanserv/chanserv.h ircservices-5.0.29/modules/chanserv/chanserv.h --- ircservices-5.0.28/modules/chanserv/chanserv.h 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/chanserv/chanserv.h 2004-03-24 19:23:26 +0900 @@ -94,8 +94,9 @@ #endif int32 mlock_limit; /* 0 if no limit */ char *mlock_key; /* NULL if no key */ - char *mlock_link; /* +L (Unreal) */ - char *mlock_flood; /* +f (Unreal) */ + char *mlock_link; /* +L (Unreal, trircd) */ + char *mlock_flood; /* +f (Unreal, etc.) */ + int32 mlock_joindelay; /* +J (trircd) */ char *entry_message; /* Notice sent on entering channel */ diff -uNr ircservices-5.0.28/modules/chanserv/set.c ircservices-5.0.29/modules/chanserv/set.c --- ircservices-5.0.28/modules/chanserv/set.c 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/chanserv/set.c 2004-03-24 19:23:26 +0900 @@ -364,7 +364,7 @@ int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */ int32 flag; int params; - int32 oldlock_on, oldlock_off, oldlock_limit; + int32 oldlock_on, oldlock_off, oldlock_limit, oldlock_joindelay; char *oldlock_key, *oldlock_link, *oldlock_flood; oldlock_on = ci->mlock_on; @@ -373,12 +373,14 @@ oldlock_key = ci->mlock_key; oldlock_link = ci->mlock_link; oldlock_flood = ci->mlock_flood; + oldlock_joindelay = ci->mlock_joindelay; ci->mlock_on = 0; ci->mlock_off = 0; ci->mlock_limit = 0; ci->mlock_key = NULL; ci->mlock_link = NULL; ci->mlock_flood = NULL; + ci->mlock_joindelay = 0; while (ac < MAX_MLOCK_PARAMS && (s = strtok(NULL, " ")) != NULL) av[ac++] = s; @@ -433,7 +435,8 @@ if (add) { ci->mlock_limit = atol(avptr[0]); if (ci->mlock_limit <= 0) { - notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_LIMIT_POSITIVE); + notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_NEED_POSITIVE, + 'l'); goto fail; } } else { @@ -483,6 +486,7 @@ ci->mlock_key = oldlock_key; ci->mlock_link = oldlock_link; ci->mlock_flood = oldlock_flood; + ci->mlock_joindelay = oldlock_joindelay; } /*************************************************************************/ diff -uNr ircservices-5.0.28/modules/database/version4.c ircservices-5.0.29/modules/database/version4.c --- ircservices-5.0.28/modules/database/version4.c 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/database/version4.c 2004-03-24 19:23:26 +0900 @@ -51,9 +51,10 @@ /*************************************************************************/ #define FILE_VERSION 11 /* Must remain constant */ -#define LOCAL_VERSION 24 /* For extensions to database files */ +#define LOCAL_VERSION 25 /* For extensions to database files */ /* LOCAL_VERSION change history: + * 25: Added trircd +J handling (ci->mlock_joindelay field) * 24: Moved nickname authentication reason into its own field (no * longer stored as part of authentication code) * 23: Added count to autokick entries in channel extension data @@ -1081,6 +1082,8 @@ SAFE(read_string(&ci->mlock_link, f)); SAFE(read_string(&ci->mlock_flood, f)); } + if (ver >= 25) + SAFE(read_int32(&ci->mlock_joindelay, f)); if (ver >= 20) { int16 lev; SAFE(read_int16(&count, f)); @@ -1349,6 +1352,7 @@ } SAFE(write_string(ci->mlock_link, f)); SAFE(write_string(ci->mlock_flood, f)); + SAFE(write_int32(ci->mlock_joindelay, f)); if (ci->levels) { SAFE(write_int16(CA_SIZE, f)); for (i = 0; i < CA_SIZE; i++) diff -uNr ircservices-5.0.28/modules/misc/xml-export.c ircservices-5.0.29/modules/misc/xml-export.c --- ircservices-5.0.28/modules/misc/xml-export.c 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/misc/xml-export.c 2004-03-24 19:23:26 +0900 @@ -345,6 +345,7 @@ XML_PUT_STRING("\t\t", *ci, mlock_key); XML_PUT_STRING("\t\t", *ci, mlock_link); XML_PUT_STRING("\t\t", *ci, mlock_flood); + XML_PUT_LONG ("\t\t", *ci, mlock_joindelay); XML_PUT_STRING("\t\t", *ci, entry_message); write_memoinfo(writefunc, data, &ci->memos); writefunc(data, "\t\n"); diff -uNr ircservices-5.0.28/modules/misc/xml-import.c ircservices-5.0.29/modules/misc/xml-import.c --- ircservices-5.0.28/modules/misc/xml-import.c 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/misc/xml-import.c 2004-03-24 19:23:26 +0900 @@ -238,6 +238,7 @@ { "mlock_key", th_text }, { "mlock_link", th_text }, { "mlock_flood", th_text }, + { "mlock_joindelay", th_int32 }, { "entry_message", th_text }, { "news", th_news }, @@ -1506,6 +1507,8 @@ ci->mlock_link = ((TextInfo *)result)->text; } else if (stricmp(tag2, "mlock_flood") == 0) { ci->mlock_flood = ((TextInfo *)result)->text; + } else if (stricmp(tag2, "mlock_joindelay") == 0) { + ci->mlock_joindelay = *(int32 *)result; } else if (stricmp(tag2, "entry_message") == 0) { ci->entry_message = ((TextInfo *)result)->text; } else if (stricmp(tag2, "memoinfo") == 0) { diff -uNr ircservices-5.0.28/modules/protocol/Makefile ircservices-5.0.29/modules/protocol/Makefile --- ircservices-5.0.28/modules/protocol/Makefile 2004-02-05 21:00:49 +0900 +++ ircservices-5.0.29/modules/protocol/Makefile 2004-03-24 19:23:25 +0900 @@ -10,11 +10,13 @@ include ../../Makefile.inc -MODULES = bahamut.so dalnet.so dreamforge.so monkey.so ptlink.so \ +MODULES = bahamut.so dalnet.so dreamforge.so hybrid.so monkey.so ptlink.so \ rfc1459.so trircd.so ts8.so undernet-p9.so unreal.so OBJECTS-bahamut.so = banexcept.o svsnick.o OTHEROBJ-bahamut.so = sjoin-bahamut.o OBJECTS-dreamforge.so = svsnick.o +OBJECTS-hybrid.so = banexcept.o svsnick.o +OTHEROBJ-hybrid.so = sjoin-bahamut.o OBJECTS-monkey.so = halfop.o sjoin.o OBJECTS-ptlink.so = banexcept.o sjoin.o svsnick.o OBJECTS-trircd.so = banexcept.o chanprot.o halfop.o sjoin.o svsnick.o \ diff -uNr ircservices-5.0.28/modules/protocol/hybrid.c ircservices-5.0.29/modules/protocol/hybrid.c --- ircservices-5.0.28/modules/protocol/hybrid.c 1970-01-01 09:00:00 +0900 +++ ircservices-5.0.29/modules/protocol/hybrid.c 2004-03-24 19:23:26 +0900 @@ -0,0 +1,447 @@ +/* Hybrid 7 protocol module for IRC Services. + * + * IRC Services is copyright (c) 1996-2004 Andrew Church. + * E-mail: + * Parts written by Andrew Kempe and others. + * This program is free but copyrighted software; see the file COPYING for + * details. + */ + +#include "services.h" +#include "modules.h" +#include "conffile.h" +#include "messages.h" + +#define BAHAMUT_HACK +#include "sjoin.h" +#include "banexcept.h" +#include "svsnick.h" + +/*************************************************************************/ + +static Module *module; +static Module *module_operserv; + +static char **p_s_OperServ = &ServerName; +#define s_OperServ (*p_s_OperServ) + +static char *NetworkDomain = NULL; + +/*************************************************************************/ +/************************** User/channel modes ***************************/ +/*************************************************************************/ + +struct modedata_init { + uint8 mode; + ModeData data; +}; + +static const struct modedata_init new_usermodes[] = { + {'a', {0x00000008,0,0}}, /* Server admin */ +}; + +static const struct modedata_init new_chanmodes[] = { + {'a', {0x00000100,0,0}}, /* Hide ops */ + {'e', {0x80000000,1,1,0,MI_MULTIPLE}}, + /* Ban exceptions */ + {'I', {0x80000000,1,1,0,MI_MULTIPLE}}, + /* Auto-invite masks (Hybrid calls these "invite exceptions") */ +}; + +static const struct modedata_init new_chanusermodes[] = { +}; + +static void init_modes(void) +{ + int i; + + for (i = 0; i < lenof(new_usermodes); i++) + usermodes[new_usermodes[i].mode] = new_usermodes[i].data; + for (i = 0; i < lenof(new_chanmodes); i++) + chanmodes[new_chanmodes[i].mode] = new_chanmodes[i].data; + for (i = 0; i < lenof(new_chanusermodes); i++) + chanusermodes[new_chanusermodes[i].mode] = new_chanusermodes[i].data; + + mode_setup(); +}; + +/*************************************************************************/ +/************************* IRC message receiving *************************/ +/*************************************************************************/ + +static void m_nick(char *source, int ac, char **av) +{ + char *newmodes; + + if (*source) { + /* Old user changing nicks. */ + if (ac != 2) { + if (debug) + module_log("debug: NICK message: wrong number of parameters" + " (%d) for source `%s'", ac, source); + } else { + do_nick(source, ac, av); + } + return; + } + + if (ac != 8) { + if (debug) + module_log("debug: NICK message: wrong number of parameters (%d)" + " for new user", ac); + return; + } + + /* Save usermode and strip out from av[] */ + newmodes = av[3]; + memmove(&av[3], &av[4], sizeof(*av)*4); + ac--; + + if (do_nick(source, ac, av)) { + av[1] = newmodes; + do_umode(av[0], 2, av); + } +} + +/*************************************************************************/ + +static void m_capab(char *source, int ac, char **av) +{ + char *s; + int has_tburst = 0; + + if (ac != 1) + return; + for (s = strtok(av[0]," "); s; s = strtok(NULL," ")) { + if (stricmp(s, "EX") == 0) { + protocol_features |= PF_BANEXCEPT; + init_banexcept(module); + } else if (stricmp(s, "QS") == 0) { + protocol_features |= PF_NOQUIT; + } else if (stricmp(s, "TBURST") == 0) { + has_tburst = 1; + } + } + if (!has_tburst) { + send_error("TBURST support required"); + strscpy(quitmsg, "Remote server does not support TBURST (see the" + " manual)", sizeof(quitmsg)); + quitting = 1; + } +} + +/*************************************************************************/ + +static void m_sjoin(char *source, int ac, char **av) +{ + if (ac < 4) { + if (debug) + module_log("debug: SJOIN: expected >=4 params, got %d", ac); + return; + } + do_sjoin(source, ac, av); +} + +/*************************************************************************/ + +static void m_tburst(char *source, int ac, char **av) +{ + if (ac != 5) + return; + av[0] = av[1]; + av[1] = av[3]; + av[3] = av[4]; + do_topic(source, 4, av); +} + +/*************************************************************************/ + +static void m_hybrid_topic(char *source, int ac, char **av) +{ + char *newav[4]; + char timebuf[32]; + + if (ac != 2) + return; + newav[0] = av[0]; + newav[1] = source; + snprintf(timebuf, sizeof(timebuf), "%ld", (long)time(NULL)); + newav[2] = timebuf; + newav[3] = av[1]; + do_topic(source, 4, newav); +} + +/*************************************************************************/ + +static Message hybrid_messages[] = { + { "CAPAB", m_capab }, + { "GLINE", NULL }, + { "NICK", m_nick }, + { "SJOIN", m_sjoin }, + { "SVINFO", NULL }, + { "TBURST", m_tburst }, + { "TOPIC", m_hybrid_topic }, + { NULL } +}; + +/*************************************************************************/ +/************************** IRC message sending **************************/ +/*************************************************************************/ + +/* Send a NICK command for a new user. */ + +static void do_send_nick(const char *nick, const char *user, const char *host, + const char *server, const char *name, + const char *modes) +{ + /* NICK : */ + send_cmd(NULL, "NICK %s 1 %ld +%s %s %s %s :%s", nick, + (long)time(NULL), modes, user, host, server, name); +} + +/*************************************************************************/ + +/* Send a NICK command to change an existing user's nick. */ + +static void do_send_nickchange(const char *nick, const char *newnick) +{ + send_cmd(nick, "NICK %s %ld", newnick, (long)time(NULL)); +} + +/*************************************************************************/ + +/* Send a command to change a user's "real name". */ + +static void do_send_namechange(const char *nick, const char *newname) +{ + /* Not supported by this protocol. */ +} + +/*************************************************************************/ + +/* Send a SERVER command, and anything else needed at the beginning of the + * connection. + */ + +static void do_send_server(void) +{ + send_cmd(NULL, "PASS %s :TS", RemotePassword); + send_cmd(NULL, "CAPAB :EX IE KLN UNKLN HUB TBURST"); + send_cmd(NULL, "SERVER %s 1 :%s", ServerName, ServerDesc); + send_cmd(NULL, "SVINFO 5 3 0 :%ld", (long)time(NULL)); +} + +/*************************************************************************/ + +/* Send a SERVER command for a remote (juped) server. */ + +static void do_send_server_remote(const char *server, const char *reason) +{ + send_cmd(NULL, "SERVER %s 2 :%s", server, reason); +} + +/*************************************************************************/ + +/* Send a WALLOPS. */ + +static void do_wallops(const char *source, const char *fmt, ...) +{ + va_list args; + char buf[BUFSIZE]; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + send_cmd(source ? source : ServerName, "OPERWALL :%s", buf); +} + +/*************************************************************************/ + +/* Send a NOTICE to all users on the network. */ + +static void do_notice_all(const char *source, const char *fmt, ...) +{ + va_list args; + char msgbuf[BUFSIZE]; + + va_start(args, fmt); + vsnprintf(msgbuf, sizeof(msgbuf), fmt, args); + va_end(args); + if (NetworkDomain) { + send_cmd(source, "NOTICE $$*.%s :%s", NetworkDomain, msgbuf); + } else { + /* Go through all common top-level domains. If you have others, + * add them here. */ + send_cmd(source, "NOTICE $$*.com :%s", msgbuf); + send_cmd(source, "NOTICE $$*.net :%s", msgbuf); + send_cmd(source, "NOTICE $$*.org :%s", msgbuf); + send_cmd(source, "NOTICE $$*.edu :%s", msgbuf); + } +} + +/*************************************************************************/ + +/* Send a command which modifies channel status. */ + +static void do_send_channel_cmd(const char *source, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vsend_cmd(source, fmt, args); + va_end(args); +} + +/*************************************************************************/ +/******************************* Callbacks *******************************/ +/*************************************************************************/ + +static int do_set_topic(const char *source, Channel *c, const char *topic, + const char *setter, time_t t) +{ + if (setter) + return 0; + c->topic_time = t; + send_cmd(source, "TBURST %ld %s %ld %s :%s", (long)c->creation_time, + c->name, (long)c->topic_time, c->topic_setter, + c->topic ? c->topic : ""); + return 1; +} + +/*************************************************************************/ + +static int do_send_akill(const char *username, const char *host, + time_t expires, const char *who, const char *reason) +{ + if (expires) { + expires -= time(NULL); + if (expires < 1) + expires = 1; + } + send_cmd(s_OperServ, "KLINE * %ld %s %s :%s", (long)expires, username, + host, reason); + return 1; +} + +/*************************************************************************/ + +static int do_cancel_akill(const char *username, const char *host) +{ + send_cmd(s_OperServ, "UNKLINE * %s %s", username, host); + return 1; +} + +/*************************************************************************/ +/***************************** Module stuff ******************************/ +/*************************************************************************/ + +const int32 module_version = MODULE_VERSION_CODE; + +ConfigDirective module_config[] = { + { "NetworkDomain", { { CD_STRING, 0, &NetworkDomain } } }, + SJOIN_CONFIG, + { NULL } +}; + +/*************************************************************************/ + +static int do_load_module(Module *mod, const char *modname) +{ + if (strcmp(modname, "operserv/main") == 0) { + module_operserv = mod; + p_s_OperServ = get_module_symbol(mod, "s_OperServ"); + if (!p_s_OperServ) { + module_log("Unable to resolve symbol `s_OperServ' in module" + " `operserv/main'"); + p_s_OperServ = &ServerName; + } + } else if (strcmp(modname, "operserv/akill") == 0) { + if (!add_callback(mod, "send_akill", do_send_akill)) + module_log("Unable to add send_akill callback"); + if (!add_callback(mod, "cancel_akill", do_cancel_akill)) + module_log("Unable to add cancel_akill callback"); + } + return 0; +} + +/*************************************************************************/ + +static int do_unload_module(Module *mod) +{ + if (mod == module_operserv) { + module_operserv = NULL; + p_s_OperServ = &ServerName; + } + return 0; +} + +/*************************************************************************/ + +int init_module(Module *module_) +{ + module = module_; + + protocol_name = "Hybrid"; + protocol_version = "7.0"; + protocol_features = 0; + protocol_nickmax = 30; + + if (!register_messages(hybrid_messages)) { + module_log("Unable to register messages"); + exit_module(1); + return 0; + } + + if (!add_callback(NULL, "load module", do_load_module) + || !add_callback(NULL, "unload module", do_unload_module) + || !add_callback(NULL, "set topic", do_set_topic) + ) { + module_log("Unable to add callbacks"); + exit_module(1); + return 0; + } + + if (!init_sjoin(module)) { + return 0; + } + + init_modes(); + + irc_lowertable['^'] = '~'; + + send_nick = do_send_nick; + send_nickchange = do_send_nickchange; + send_namechange = do_send_namechange; + send_server = do_send_server; + send_server_remote = do_send_server_remote; + wallops = do_wallops; + notice_all = do_notice_all; + send_channel_cmd = do_send_channel_cmd; + pseudoclient_modes = "+i"; + enforcer_modes = "+i"; + + return 1; +} + +/*************************************************************************/ + +int exit_module(int shutdown) +{ + if (!shutdown) { + /* Do not allow removal */ + return 0; + } + + if (protocol_features & PF_BANEXCEPT) + exit_banexcept(); + exit_sjoin(); + + remove_callback(NULL, "set topic", do_set_topic); + remove_callback(NULL, "unload module", do_unload_module); + remove_callback(NULL, "load module", do_load_module); + + unregister_messages(hybrid_messages); + return 1; +} + +/*************************************************************************/ diff -uNr ircservices-5.0.28/modules/protocol/sjoin.c ircservices-5.0.29/modules/protocol/sjoin.c --- ircservices-5.0.28/modules/protocol/sjoin.c 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/protocol/sjoin.c 2004-03-24 19:23:26 +0900 @@ -41,7 +41,7 @@ * av[4] = limit / key (depends on modes in av[3]) * av[5] = limit / key (depends on modes in av[3]) * av[ac-1] = nickname(s), with modes, joining channel - * Bahamut SSJOIN (server source) / PTlink / Unreal SJOIN2/SJ3 format: + * Bahamut SSJOIN (server source) / Hybrid / PTlink / Unreal SJOIN2/SJ3 format: * av[0] = TS3 timestamp - channel creation time * av[1] = channel * av[2] = modes (limit/key in av[3]/av[4] as needed) diff -uNr ircservices-5.0.28/modules/protocol/trircd.c ircservices-5.0.29/modules/protocol/trircd.c --- ircservices-5.0.28/modules/protocol/trircd.c 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/protocol/trircd.c 2004-03-24 19:23:26 +0900 @@ -84,8 +84,6 @@ ModeData data; }; -#define MI_5_5 0x80000000 /* Mode available only in version 5.5+ */ - static const struct modedata_init new_usermodes[] = { {'g', {0x00000008}}, /* Receive globops */ {'h', {0x00000010}}, /* Helpop */ @@ -96,20 +94,13 @@ {'x', {0x00000100}}, /* Mask hostname */ {'R', {0x00000200}}, /* Do not receive text from unregged nicks */ {'L', {0x00000400}}, /* Nick language has been set */ - {'c', {0x00000800,0,0,0,MI_5_5}}, - /* No color in private messages */ - {'C', {0x00001000,0,0,0,MI_5_5}}, - /* No CTCPs in private messages */ - {'H', {0x00002000,0,0,0,MI_5_5}}, - /* User can see realhost, secret channels */ - {'p', {0x00004000,0,0,0,MI_5_5}}, - /* Hide idle time in /whois */ - {'P', {0x00008000,0,0,0,MI_5_5}}, - /* Do not receive private messages */ - {'t', {0x00010000,0,0,0,MI_5_5}}, - /* Greek->Greeklish translation active */ - {'z', {0x00020000,0,0,0,MI_5_5}}, - /* Dccallow all users */ + {'c', {0x00000800}}, /* No color in private messages */ + {'C', {0x00001000}}, /* No CTCPs in private messages */ + {'H', {0x00002000}}, /* User can see realhost, secret channels */ + {'p', {0x00004000}}, /* Hide idle time in /whois */ + {'P', {0x00008000}}, /* Do not receive private messages */ + {'t', {0x00010000}}, /* Greek->Greeklish translation active */ + {'z', {0x00020000}}, /* Dccallow all users */ }; static const struct modedata_init new_chanmodes[] = { @@ -124,14 +115,12 @@ {'N', {0x00004000,0,0}}, /* No clients with unresolved hostnames */ {'d', {0x00008000,0,0}}, /* Hide part/quit reasons */ {'f', {0x00010000,1,0}}, /* Flood limit */ - {'C', {0x00020000,0,0,0,MI_5_5}}, - /* No CTCP in channel */ - {'g', {0x00040000,0,0,0,MI_5_5}}, - /* Only registered nicks can talk */ - {'j', {0x00080000,0,0,0,MI_5_5}}, - /* /names only by members */ - {'L', {0x00100000,1,0,0,MI_5_5}}, - /* Channel link */ + {'C', {0x00020000,0,0}}, /* No CTCP in channel */ + {'g', {0x00040000,0,0}}, /* Only registered nicks can talk */ + {'j', {0x00080000,0,0}}, /* /names only by members */ + {'L', {0x00100000,1,0}}, /* Channel link */ + {'K', {0x00200000,0,0}}, /* No knock */ + {'J', {0x00400000,1,0}}, /* /join delay */ {'I', {0x80000000,1,1,0,MI_MULTIPLE}}, /* INVITE hosts */ {'e', {0x80000000,1,1,0,MI_MULTIPLE}}, /* ban exceptions */ {'M', {0x80000000,1,1,0,MI_MULTIPLE}}, /* moderated hosts */ @@ -145,23 +134,16 @@ /* Channel owner */ }; -static void init_modes(int do_5_5) +static void init_modes(void) { int i; - for (i = 0; i < lenof(new_usermodes); i++) { - if ((do_5_5 != 0) == ((new_usermodes[i].data.info & MI_5_5) != 0)) - usermodes[new_usermodes[i].mode] = new_usermodes[i].data; - } - for (i = 0; i < lenof(new_chanmodes); i++) { - if ((do_5_5 != 0) == ((new_chanmodes[i].data.info & MI_5_5) != 0)) - chanmodes[new_chanmodes[i].mode] = new_chanmodes[i].data; - } - for (i = 0; i < lenof(new_chanusermodes); i++) { - if ((do_5_5 != 0) == ((new_chanusermodes[i].data.info & MI_5_5) != 0)) - chanusermodes[new_chanusermodes[i].mode] = - new_chanusermodes[i].data; - } + for (i = 0; i < lenof(new_usermodes); i++) + usermodes[new_usermodes[i].mode] = new_usermodes[i].data; + for (i = 0; i < lenof(new_chanmodes); i++) + chanmodes[new_chanmodes[i].mode] = new_chanmodes[i].data; + for (i = 0; i < lenof(new_chanusermodes); i++) + chanusermodes[new_chanusermodes[i].mode] = new_chanusermodes[i].data; mode_setup(); }; @@ -317,40 +299,22 @@ static void m_capab(char *source, int ac, char **av) { - int got_dtone = 0, got_nickip = 0, got_trircd5 = 0; + int got_trircd5 = 0, got_excap = 0; int i; for (i = 0; i < ac; i++) { - if (stricmp(av[i], "NOQUIT") == 0) { - protocol_features |= PF_NOQUIT; - } else if (stricmp(av[i], "DT1") == 0) { - got_dtone = 1; - } else if (stricmp(av[i], "NICKIP") == 0) { - got_nickip = 1; - } else if (stricmp(av[i], "TRIRCD5") == 0) { + if (stricmp(av[i], "TRIRCD5") == 0) { got_trircd5 = 1; } else if (stricmp(av[i], "EXCAP") == 0) { - /* This is a 5.5 server */ - init_modes(1); + got_excap = 1; } } - if (!got_trircd5) { - send_error("Only trircd 5.1 and later are supported"); - strscpy(quitmsg, "Remote server version is not 5.1 or later", + if (!got_trircd5 || !got_excap) { + send_error("Only trircd 5.5 and later are supported"); + strscpy(quitmsg, "Remote server version is not 5.5 or later", sizeof(quitmsg)); quitting = 1; } - if (!got_dtone) { - send_error("Need DT1 protocol"); - strscpy(quitmsg, "Remote server doesn't support DT1", sizeof(quitmsg)); - quitting = 1; - } - if (!got_dtone) { - send_error("Need NICKIP protocol"); - strscpy(quitmsg, "Remote server doesn't support NICKIP", - sizeof(quitmsg)); - quitting = 1; - } } static void m_excap(char *source, int ac, char **av) @@ -410,6 +374,7 @@ { "GOPER", NULL }, { "HASH", NULL }, { "JUPITER", NULL }, + { "KNOCK", NULL }, { "MYID", NULL }, { "NETHTM", NULL }, { "NETSET", NULL }, @@ -539,7 +504,7 @@ { "x", "SQLINE" }, { "y", "UNGLINE" }, { "z", "SVINFO" }, - { "{", NULL }, + { "{", "KNOCK" }, { "|", "REXCOM" }, { "}", NULL }, { "~", "TMODE" }, @@ -590,6 +555,7 @@ static void do_send_server(void) { send_cmd(NULL, "PASS %s :TS7", RemotePassword); + /* for 5.7 only: send_cmd(NULL, "CAPAB NICKIP TOKEN1 EXCAP"); */ send_cmd(NULL, "CAPAB TS3 NOQUIT SSJOIN NICKIP DT1 EX-REX TOKEN1 TMODE EXCAP"); send_cmd(NULL, "EXCAP :CHANLINK"); send_cmd(NULL, "SERVER %s 1 :%s", ServerName, ServerDesc); @@ -699,7 +665,7 @@ ChannelInfo *ci; int add; int modeL; /* status of +/-L wrt this message (1:on, 0:off, -1:not seen) */ - int lockL; /* status of MLOCK +/-l (1:+L, 0:-L) */ + int lockL; /* status of MLOCK +/-L (1:+L, 0:-L) */ if (stricmp(cmd,"MODE") != 0 || ac < 2 || av[0][0] != '#' || get_channel(av[0]) /* existing channels will get handled normally */ @@ -834,6 +800,16 @@ channel->flood = NULL; } return 1; + + case 'J': + if (add) { + channel->mode |= flag; + channel->joindelay = strtol(av[0], NULL, 0); + } else { + channel->mode &= ~flag; + channel->joindelay = 0; + } + return 1; } return 0; } @@ -903,7 +879,18 @@ if (!c->flood || irc_stricmp(ci->mlock_flood, c->flood) != 0) set_cmode(s_ChanServ, c, "+f", ci->mlock_flood); } - return 1; + return 1; + case 'J': + if (ci->mlock_joindelay <= 0) { + module_log("warning: removing +J from channel %s mode lock" + " (invalid parameter: %d)", ci->name, + ci->mlock_joindelay); + ci->mlock_on &= ~mode_char_to_flag('J', MODE_CHANNEL); + ci->mlock_joindelay = 0; + } else { + if (c->joindelay != ci->mlock_joindelay) + set_cmode(s_ChanServ, c, "+J", ci->mlock_joindelay); + } } } else { /* remove */ switch (mode_flag_to_char(flag, MODE_CHANNEL)) { @@ -927,7 +914,9 @@ } /* Single mode set/clear */ + if (add) { + switch (mode) { case 'L': if (!valid_chan(av[0])) { @@ -963,9 +952,19 @@ /* String is invalid */ notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_FLOOD_BAD, mode); return 1; - } - } + } /* case 'f' */ + + case 'J': + ci->mlock_joindelay = atol(av[0]); + if (ci->mlock_joindelay <= 0) { + notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_NEED_POSITIVE, 'J'); + return 1; + } + break; + } /* switch (mode) */ + } else { /* !add -> lock off */ + switch (mode) { case 'L': { /* The channel should not exist here; check anyway just to be @@ -975,9 +974,20 @@ set_cmode(s_ChanServ, c, "-L"); else send_cmd(s_ChanServ, "MODE %s -L", ci->name); - } - } - } + } /* case 'L' */ + + case 'f': + free(ci->mlock_flood); + ci->mlock_flood = NULL; + break; + + case 'J': + ci->mlock_joindelay = 0; + break; + } /* switch (mode) */ + + } /* if (add) */ + return 0; } @@ -1166,7 +1176,8 @@ protocol_name = "trircd"; protocol_version = "5.5+"; - protocol_features = PF_SZLINE | PF_SVSJOIN | PF_AKILL_EXCL | PF_HALFOP; + protocol_features = PF_SZLINE | PF_SVSJOIN | PF_AKILL_EXCL | PF_HALFOP + | PF_NOQUIT; protocol_nickmax = 30; if (!register_messages(trircd_messages)) { @@ -1202,7 +1213,7 @@ return 0; } - init_modes(0); + init_modes(); init_langhash(); irc_lowertable['['] = '['; diff -uNr ircservices-5.0.28/modules/protocol/unreal.c ircservices-5.0.29/modules/protocol/unreal.c --- ircservices-5.0.28/modules/protocol/unreal.c 2004-02-05 21:00:50 +0900 +++ ircservices-5.0.29/modules/protocol/unreal.c 2004-03-24 19:23:26 +0900 @@ -196,6 +196,7 @@ {'f', {0x00800000,1,0}}, /* Flood limit */ {'L', {0x01000000,1,0}}, /* Channel link */ {'M', {0x02000000,0,0}}, /* Moderated to unregged nicks */ + {'T', {0x04000000,0,0}}, /* Disable notices to channel */ {'e', {0x80000000,1,1,0,MI_MULTIPLE}}, /* Ban exceptions */ }; @@ -445,8 +446,7 @@ /*************************************************************************/ /* 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()). + * UNREAL_HACK, so the routine actually called is do_sjoin_unreal()). */ static void m_sjoin(char *source, int ac, char **av) @@ -456,7 +456,7 @@ module_log("debug: SJOIN: expected >=3 params, got %d", ac); return; } - do_sjoin_unreal(source, ac, av); + do_sjoin(source, ac, av); } /*************************************************************************/ @@ -1012,6 +1012,96 @@ /*************************************************************************/ +/* Callback to handle clearing bans and exceptions for clear_channel(). + * Normally, the versions in actions.c and modules/protocol/banexcept.c + * will do the job, but Unreal has "extended ban types" which confuse the + * usermask comparison, so we need to write our own versions of the + * routines. Hooray for feeping creaturism... */ + +static void unreal_clear_bans_excepts(const char *sender, Channel *chan, + const User *u); +static int do_clear_channel(const char *sender, Channel *chan, int what, + const void *param) +{ + if (what & (CLEAR_USERS | CLEAR_BANS)) { + unreal_clear_bans_excepts(sender, chan, + (what & CLEAR_BANS) ? param : NULL); + } + return 0; +} + + +static void unreal_clear_bans_excepts(const char *sender, Channel *chan, + const User *u) +{ + int i, count; + char **list; + + if (chan->bans_count) { + count = chan->bans_count; + list = smalloc(sizeof(char *) * count); + memcpy(list, chan->bans, sizeof(char *) * count); + for (i = 0; i < count; i++) { + char *s = list[i]; + if (*s == '~' + && ((s[1] == '!' && s[2] && s[3] == ':') + || (s[1] && s[2] == ':')) + ) { + if (s[1] == '!') + s += 4; + else + s += 3; + } + if (!u || match_usermask(s, u)) + set_cmode(sender, chan, "-b", list[i]); + if (u && u->ipaddr) { + char tmpbuf[BUFSIZE]; + int nicklen = snprintf(tmpbuf, sizeof(tmpbuf), "%s!", u->nick); + snprintf(tmpbuf+nicklen, sizeof(tmpbuf)-nicklen, "%s@%s", + u->username, u->ipaddr); + if (match_wild_nocase(s, tmpbuf)) + set_cmode(sender, chan, "-b", list[i]); + if (match_wild_nocase(s, tmpbuf+nicklen)) + set_cmode(sender, chan, "-b", list[i]); + } + } + free(list); + } + + if (chan->excepts_count) { + count = chan->excepts_count; + list = smalloc(sizeof(char *) * count); + memcpy(list, chan->excepts, sizeof(char *) * count); + for (i = 0; i < count; i++) { + char *s = list[i]; + if (*s == '~' + && ((s[1] == '!' && s[2] && s[3] == ':') + || (s[1] && s[3] == ':')) + ) { + if (s[1] == '!') + s += 4; + else + s += 3; + } + if (!u || match_usermask(s, u)) + set_cmode(sender, chan, "-e", list[i]); + if (u && u->ipaddr) { + char tmpbuf[BUFSIZE]; + int nicklen = snprintf(tmpbuf, sizeof(tmpbuf), "%s!", u->nick); + snprintf(tmpbuf+nicklen, sizeof(tmpbuf)-nicklen, "%s@%s", + u->username, u->ipaddr); + if (match_wild_nocase(s, tmpbuf)) + set_cmode(sender, chan, "-e", list[i]); + if (match_wild_nocase(s, tmpbuf+nicklen)) + set_cmode(sender, chan, "-e", list[i]); + } + } + free(list); + } +} + +/*************************************************************************/ + /* * NickServ post-IDENTIFY callback; we set user mode +a for Services * admins if they're opered. @@ -1169,20 +1259,68 @@ case 'f': { char *s, *t; - /* Legal format for flood mode is "[*]digits:digits" */ + /* Legal format for flood mode is: + * "digits:digits" + * or "*digits:digits" + * or "[TYPE,TYPE...]:digits" + * where TYPE is 1-999 followed by one of cjkmnt possibly + * followed by # and (a letter possibly followed by digits) */ s = av[0]; - if (*s == '*') + if (*s == '[') { + int ok = 1; + char c; s++; - t = strchr(s, ':'); - if (t) { - t++; - if (s[strspn(s,"0123456789")] == ':' - && t[strspn(t,"0123456789")] == 0 - ) { + do { + if (!strchr("0123456789", *s)) { + ok = 0; + break; + } + t = s; + s += strspn(s, "0123456789"); + c = *s; + *s = 0; + if (atoi(t) < 1 || atoi(t) > 999) { + ok = 0; + break; + } + *s = c; + if (!strchr("cjkmnt", *s++)) { + ok = 0; + break; + } + if (*s == '#') { + s++; + if (!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", *s++)) { + ok = 0; + break; + } + s += strspn(s, "0123456789"); + } + if (*s != ',' && *s != ']') + ok = 0; + s++; + } while (ok && s[-1] != ']'); + if (ok && *s++ != ':') + ok = 0; + if (ok && s[strspn(s,"0123456789")] == 0) { /* String is valid */ ci->mlock_flood = sstrdup(av[0]); break; } + } else { + if (*s == '*') + s++; + t = strchr(s, ':'); + if (t) { + t++; + if (s[strspn(s,"0123456789")] == ':' + && t[strspn(t,"0123456789")] == 0 + ) { + /* String is valid */ + ci->mlock_flood = sstrdup(av[0]); + break; + } + } } /* String is invalid */ notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_FLOOD_BAD, mode); @@ -1406,7 +1544,7 @@ /* Set protocol information variables. */ protocol_name = "Unreal"; - protocol_version = "3.1.1"; + protocol_version = "3.1.1+"; protocol_features = PF_SZLINE | PF_SVSJOIN; protocol_nickmax = 30; @@ -1437,6 +1575,7 @@ do_user_servicestamp_change) || !add_callback(NULL, "user MODE", do_user_mode) || !add_callback(NULL, "channel MODE", do_channel_mode) + || !add_callback(NULL, "clear channel", do_clear_channel) || !add_callback(NULL, "set topic", do_set_topic) ) { module_log("Unable to add callbacks"); @@ -1525,6 +1664,7 @@ exit_banexcept(); remove_callback(NULL, "set topic", do_set_topic); + remove_callback(NULL, "clear channel", do_clear_channel); remove_callback(NULL, "channel MODE", do_channel_mode); remove_callback(NULL, "user MODE", do_user_mode); remove_callback(NULL, "user servicestamp change", diff -uNr ircservices-5.0.28/tools/convert-ptlink.c ircservices-5.0.29/tools/convert-ptlink.c --- ircservices-5.0.28/tools/convert-ptlink.c 2004-02-05 21:00:49 +0900 +++ ircservices-5.0.29/tools/convert-ptlink.c 2004-03-24 19:23:26 +0900 @@ -207,9 +207,11 @@ } /* for (i) */ close_db(f); if (count != total) { - fprintf(stderr, "%s: error: expected %d nicks, got %d\n", + fprintf(stderr, "%s: warning: expected %d nicks, got %d\n", filename, total, count); - exit(1); + fprintf(stderr, " This means that your data files may be corrupt." + " It may also be the\n" + " result of a bug in some versions of PTlink Services.\n"); } /* Resolve links */ @@ -287,7 +289,7 @@ NickInfo *ni; signed char ch; int16 tmp16, ver; - int32 tmp32, mlock_on, mlock_off; + int32 tmp32, total, count, mlock_on, mlock_off; char *on, *off; snprintf(filename, sizeof(filename), "%s/chan.db", sourcedir); @@ -301,9 +303,10 @@ } if (ver >= 9) - SAFE(read_int32(&tmp32, f)); /* some DayStats thing */ + SAFE(read_int32(&total, f)); + count = 0; - for (i = 0; i < 256; i++) { + for (i = 0; i < 65535; i++) { char *s; while ((c = getc_db(f)) == 1) { @@ -486,6 +489,8 @@ if ((ci->flags & CI_VERBOTEN) || ci->founder) add_channelinfo(ci); + count++; + } /* while (getc_db(f) == 1) */ if (c != 0) { fprintf(stderr, "%s is corrupt, aborting.\n", f->filename); @@ -493,6 +498,14 @@ } } /* for (i) */ close_db(f); + + if (ver >= 9 && count != total) { + fprintf(stderr, "%s: warning: expected %d channels, got %d\n", + filename, total, count); + fprintf(stderr, " This means that your data files may be corrupt." + " It may also be the\n" + " result of a bug in some versions of PTlink Services.\n"); + } } /*************************************************************************/ diff -uNr ircservices-5.0.28/version.sh ircservices-5.0.29/version.sh --- ircservices-5.0.28/version.sh 2004-02-05 20:54:51 +0900 +++ ircservices-5.0.29/version.sh 2004-03-24 19:14:06 +0900 @@ -6,7 +6,7 @@ # $PROGRAM is the string returned as the first part of a /VERSION reply, # and must not contain spaces. It is not used anywhere else. PROGRAM=ircservices -VERSION=5.0.28 +VERSION=5.0.29 # Increment Services build number if [ -f version.c ] ; then