diff -uNr ircservices-5.0.31/Changes ircservices-5.0.32/Changes --- ircservices-5.0.31/Changes 2004-04-29 08:54:48 +0900 +++ ircservices-5.0.32/Changes 2004-06-07 19:37:13 +0900 @@ -1,5 +1,19 @@ Version 5.0 ----------- +2004/06/07 .32 Updated Unreal protocol module for Unreal 3.2.1. +2004/05/24 get_access() (which returns a user's access level on a + channel) is now exported by the chanserv/main module. +2004/05/18 -z (insecure) users can no longer enter channels locked to + +z on Unreal. Reported by Dionisios K. + +2004/05/14 Fixed failure to clear ban exceptions on autokick. + Reported by Eric Murphy +2004/05/12 Updated Bahamut protocol module for Bahamut 1.8.0. Support + for 1.4.x has been removed. +2004/05/07 Fixed errors in OperServ SESSIONS and EXCEPTIONS help text. + Reported by Elijah +2004/05/04 Fixed harmless compilation warning in database/version4 + module. Reported by Craig McLure 2004/04/29 .31 Fixed crash with MLOCK +J when using trircd protocol. Reported by 2004/04/28 Added stricter checks on module loading order. @@ -52,7 +66,7 @@ 2004/01/05 + in channel names no longer confuses the httpd/dbaccess module. Reported by 2004/01/05 Channel entry messages are now prefixed with the channel - name. Suggested by Medice + name. Suggested by Medice. 2004/01/05 Fixed a bug in calculating session memory usage for OperServ STATS ALL. Reported by Ali Sor 2003/12/09 Added slightly more verbose logging when a fatal signal is diff -uNr ircservices-5.0.31/actions.c ircservices-5.0.32/actions.c --- ircservices-5.0.31/actions.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/actions.c 2004-06-07 19:44:06 +0900 @@ -671,7 +671,7 @@ } /* Actually send the command */ - send_cmd(md->sender, "MODE %s %s", md->channel->name, buf); + send_cmode_cmd(md->sender, md->channel->name, "%s", buf); /* Split buffer back up into individual parameters for do_cmode(). * This is inefficient, but taking the faster route of setting modes diff -uNr ircservices-5.0.31/channels.c ircservices-5.0.32/channels.c --- ircservices-5.0.31/channels.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/channels.c 2004-06-07 19:44:06 +0900 @@ -240,7 +240,7 @@ Channel *chan; char *s; int add = 1; /* 1 if adding modes, 0 if deleting */ - char *modestr = av[1]; + char *modestr; chan = get_channel(av[0]); if (!chan) { @@ -248,6 +248,11 @@ merge_args(ac-1, av+1), av[0]); return; } + if ((protocol_features & PF_MODETS_FIRST) && isdigit(av[1][0])) { + ac--; + av++; + } + modestr = av[1]; if (!NoBouncyModes) { /* Count identical server mode changes per second (mode bounce check)*/ diff -uNr ircservices-5.0.31/channels.h ircservices-5.0.32/channels.h --- ircservices-5.0.31/channels.h 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/channels.h 2004-06-07 19:44:06 +0900 @@ -29,6 +29,7 @@ char *link; /* +L (Unreal, trircd) */ char *flood; /* +f (Unreal, etc.) */ int32 joindelay; /* +J (trircd) */ + int32 joinrate1, joinrate2; /* +j (Bahamut) */ char **bans; int32 bans_count; diff -uNr ircservices-5.0.31/docs/1.html ircservices-5.0.32/docs/1.html --- ircservices-5.0.31/docs/1.html 2003-05-28 15:31:04 +0900 +++ ircservices-5.0.32/docs/1.html 2004-05-07 13:14:57 +0900 @@ -298,6 +298,7 @@
  • ftp://ftp.ircd.com.br/ircservices/ (Brazil)
  • http://www.irc.gr/ircservices/ (Greece)
  • http://ircservices.swissirc.ch/ (Switzerland) +
  • http://ircservices.pagefault.net/ (Netherlands)

    Back to top @@ -389,7 +390,8 @@ Michael Haardt, Andre Arruda, Sotiris Tsimbonis, -and Marcel Stutz. +Marcel Stutz, +and dik@zirc.org.

    Back to top diff -uNr ircservices-5.0.31/docs/2.html ircservices-5.0.32/docs/2.html --- ircservices-5.0.31/docs/2.html 2004-04-09 14:35:47 +0900 +++ ircservices-5.0.32/docs/2.html 2004-05-13 18:06:42 +0900 @@ -109,9 +109,8 @@
    IRC server (IRCD) nameServices module
    Bahamut - [bahamut.dal.net] 1.4.25 through 1.4.33 + [bahamut.dal.net] 1.8.0 and above (*) -
    Note: versions 1.4.34 and above are not supported.
    bahamut
    Chunky Monkey IRCD 1.0 and above monkey @@ -153,16 +152,12 @@
    (servers listed in italics are listed based on user reports, but are not supported) -

    (*) Bahamut (version 1.4.35 and earlier) has a -vulnerability which can lead to server crashes or execution of malicious -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 -advisory [0xbadc0ded.org] for details. +

    (*) When using Bahamut, do not configure +your server as a "services hub" ("servtype serviceshub" in the +ircd.conf file); this setting causes Bahamut to not send certain +information needed by Services to work correctly. If Services detects that +Bahamut is configured as a services hub, it will log a message to that +effect and abort.

    (**) To use Hybrid with Services, you must compile and install the TBURST module, found in the diff -uNr ircservices-5.0.31/docs/4.html ircservices-5.0.32/docs/4.html --- ircservices-5.0.31/docs/4.html 2004-04-02 12:19:41 +0900 +++ ircservices-5.0.32/docs/4.html 2004-05-07 14:29:47 +0900 @@ -2767,7 +2767,7 @@
    EXCEPTION VIEW [mask | list]

    -Allows Services admins to manipulate the list of hosts that +Allows Services operators to manipulate the list of hosts that have specific session limits, allowing certain machines, such as shell servers, to carry more than the default number of clients at a time. Once a host reaches its session limit, @@ -2820,7 +2820,7 @@ their host matches. Large exception lists and widely matching exception masks are likely to degrade Services' performance.

    -Limited to Services admins. +Limited to Services operators.


    @@ -2833,7 +2833,7 @@
    SESSION VIEW host

    -Allows Services admins to view the session list. +Allows Services operators to view the session list.

    SESSION LIST lists hosts with at least threshold sessions. The threshold must be a number greater than 1, to prevent @@ -2848,7 +2848,7 @@ limiting and how to set session limits specific to certain hosts and groups thereof.

    -Limited to Services admins. +Limited to Services operators.


    diff -uNr ircservices-5.0.31/extern.h ircservices-5.0.32/extern.h --- ircservices-5.0.31/extern.h 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/extern.h 2004-06-07 19:44:06 +0900 @@ -229,11 +229,16 @@ E uint8 *pack_ip(const char *ipaddr); E char *unpack_ip(const uint8 *ip); +E uint8 *pack_ip6(const char *ipaddr); +E char *unpack_ip6(const uint8 *ip); E int lock_data(void); E int is_data_locked(void); E int unlock_data(void); +int encode_base64(const void *in, int insize, char *out, int outsize); +E int decode_base64(const char *in, void *out, int outsize); + /**** process.c ****/ @@ -263,6 +268,8 @@ E void vsend_cmd(const char *source, const char *fmt, va_list args) FORMAT(printf,2,0); E void send_error(const char *fmt, ...) FORMAT(printf,1,2); +E void send_cmode_cmd(const char *source, const char *channel, + const char *fmt, ...); E void notice(const char *source, const char *dest, const char *fmt, ...) FORMAT(printf,3,4); E void notice_list(const char *source, const char *dest, const char **text); diff -uNr ircservices-5.0.31/lang/de.l ircservices-5.0.32/lang/de.l --- ircservices-5.0.31/lang/de.l 2004-03-06 08:50:32 +0900 +++ ircservices-5.0.32/lang/de.l 2004-05-18 11:53:54 +0900 @@ -995,7 +995,7 @@ Der Parameter für MLOCK +%c muss ein anderer Raum sein. CHAN_SET_MLOCK_LINK_NO_LIMIT Beim MLOCK +%c muss ebenfalls MLOCK +l gesetzt sein. -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM Der Parameter für MLOCK +%c ist nicht gültig. CHAN_SET_MLOCK_UNKNOWN_CHAR Unbekanntes Modus-Zeichen %c wird ignoriert. @@ -4695,7 +4695,7 @@ EXCEPTION LIST [Maske | Liste] EXCEPTION VIEW [Mask | Liste] - Erlaubt Services-Administratoren die Liste der Hosts mit spezifischen + Erlaubt Services-Operatoren die Liste der Hosts mit spezifischen Sitzungslimits zu bearbeiten (z.B. Shell Servers) um einigen Rechnern, wie z.B. Shell-Provider, eine größere anzahl der Client-Verbindungen zu erlauben, als die Standardeinstellung. @@ -4737,13 +4737,13 @@ aus der Liste benutzt. Lange Ausnahme-Listen beeinflußen die Performance der Services. - Dieser Befehl steht nur den Services-Administratoren zur Verfügung. + Dieser Befehl steht nur den Services-Operatoren zur Verfügung. OPER_HELP_SESSION Syntax: SESSION LIST Grenzwert SESSION VIEW Host - Zeigt den Services-Administratoren die Sitzungs-Liste. + Zeigt den Services-Operatoren die Sitzungs-Liste. SESSION LIST zeigt Hosts mit mindestens Grenzwert Sitzungen. Der Grenzwert ist eine Zahl gröser als 1. Dies @@ -4757,7 +4757,7 @@ Konsultieren Sie Hilfe für EXCEPTION für weitere Informationen über Sitzungslimits und deren Bearbeitung. - Dieser Befehl steht nur den Services-Administratoren zur Verfügung. + Dieser Befehl steht nur den Services-Operatoren zur Verfügung. OPER_HELP_SU Syntax: SU Passwort diff -uNr ircservices-5.0.31/lang/en_us.l ircservices-5.0.32/lang/en_us.l --- ircservices-5.0.31/lang/en_us.l 2004-03-17 20:33:41 +0900 +++ ircservices-5.0.32/lang/en_us.l 2004-05-18 12:04:39 +0900 @@ -1030,7 +1030,7 @@ Parameter for MLOCK +%c must be a different channel. CHAN_SET_MLOCK_LINK_NO_LIMIT MLOCK +%c requires MLOCK +l to be set as well. -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM Invalid parameter for MLOCK +%c. CHAN_SET_MLOCK_UNKNOWN_CHAR Unknown mode character %c ignored. @@ -4757,8 +4757,8 @@ EXCEPTION LIST [mask | list] EXCEPTION VIEW [mask | list] - Allows Services admins to manipulate the list of hosts that - have specific session limits, allowing certain machines, + Allows Services operators to manipulate the list of hosts + that have specific session limits, allowing certain machines, such as shell servers, to carry more than the default number of clients at a time. Once a host reaches its session limit, all clients attempting to connect from that host will be @@ -4814,7 +4814,7 @@ Syntax: SESSION LIST threshold SESSION VIEW host - Allows Services admins to view the session list. + Allows Services operatorss to view the session list. SESSION LIST lists hosts with at least threshold sessions. The threshold must be a number greater than 1, to prevent @@ -4829,7 +4829,7 @@ limiting and how to set session limits specific to certain hosts and groups thereof. - Limited to Services admins. + Limited to Services operators. OPER_HELP_SU Syntax: SU password @@ -5076,4 +5076,4 @@ # version of the master (English) language file was used to create a # translated file. -# CVS: $Revision: 2.219 $ +# CVS: $Revision: 2.221 $ diff -uNr ircservices-5.0.31/lang/es.l ircservices-5.0.32/lang/es.l --- ircservices-5.0.31/lang/es.l 2004-03-06 08:50:55 +0900 +++ ircservices-5.0.32/lang/es.l 2004-05-18 11:54:06 +0900 @@ -1032,7 +1032,7 @@ Parámetro para MLOCK +%c debe ser canal diferente. CHAN_SET_MLOCK_LINK_NO_LIMIT MLOCK +%c requiere que se fije MLOCK +l tambien. -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM Parámetro inválido para MLOCK +%c. CHAN_SET_MLOCK_UNKNOWN_CHAR Modo con caractér %c es desconocido e ignorado. @@ -4791,7 +4791,7 @@ EXCEPTION LIST [Máscara | List] EXCEPTION VIEW [Máscara | List] - Permite a los administradores de Servicios manipular la lista de las + Permite a los Operadores de Servicios manipular la lista de las máquinas (hosts) que tienen límite de sesiones específicas - permitiendo a ciertas máquinas, como los servidores de shell, a que carguen más del número permitido de clientes al mismo tiempo. Cuando una máquina @@ -4839,13 +4839,13 @@ grandes junto a máscaras de excepción que concuerden apliamente afectarán negativamente en la eficiencia de los servicios. - Limitado a los Administradores De Servicios. + Limitado a los Operadores De Servicios. OPER_HELP_SESSION Sintaxis: SESSION LIST Núm-Límite SESSION VIEW Máscara - Permite a Administradores de Servicios ver lista de sesión. + Permite a Operadores de Servicios ver lista de sesión. SESSION LIST lista máscaras con al menos sesiones límites. El límite debe ser un número mayor que 1. Esto es para @@ -4860,7 +4860,7 @@ de sesiones y sobre como fijar límites de sesiones específicos a ciertas máquinas y grupos de esas máquinas. - Limitado a los Administradores De Servicios. + Limitado a los Operadores De Servicios. OPER_HELP_SU Sintaxis: SU Contraseña diff -uNr ircservices-5.0.31/lang/fr.l ircservices-5.0.32/lang/fr.l --- ircservices-5.0.31/lang/fr.l 2004-03-06 08:51:04 +0900 +++ ircservices-5.0.32/lang/fr.l 2004-05-18 11:54:11 +0900 @@ -1015,7 +1015,7 @@ Le paramêtre +%c pour MLOCK doit être un canal différent. CHAN_SET_MLOCK_LINK_NO_LIMIT Le mode MLOCK +%c requiert que MLOCK +l soit sélectionné comme il faut. -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM Paramêtre invalide pour MLOCK +%c. CHAN_SET_MLOCK_UNKNOWN_CHAR Caractère de mode inconnu %c ignoré. @@ -4954,29 +4954,29 @@ # # Limité aux Opérateurs des Services. -OPER_HELP_SESSION - Syntaxe: SESSION LIST seuil (threshold) - SESSION VIEW hôte - - Permet aux Administrateurs des Services de voir la liste des - sessions. - - SESSION LIST présente les hôtes qui ont au minimum le seuil - des sessions. Le seuil doit être un nombre plus grand que - 1, pour prévenir l'affichage accidentel d'un nombre trop - large de hôtes de session simples. - - SESSION VIEW présente l'information détaillée relative à un - hôte spécifique, incluant le nombre actuel de - comptes-session et la limitation de sessions. La valeur - hôte ne doit pas inclure de frimes. - - Voir l'assistance (HELP) d'EXCEPTION pour plus d'information - à propos de la limitation de session et comment déterminer - une limitation de session spécifique pour certains hôtes et - groupes d'hôtes. - - Limité à l'usage des Administrateurs des Services. +#OPER_HELP_SESSION +# Syntaxe: SESSION LIST seuil (threshold) +# SESSION VIEW hôte +# +# Permet aux Administrateurs des Services de voir la liste des +# sessions. +# +# SESSION LIST présente les hôtes qui ont au minimum le seuil +# des sessions. Le seuil doit être un nombre plus grand que +# 1, pour prévenir l'affichage accidentel d'un nombre trop +# large de hôtes de session simples. +# +# SESSION VIEW présente l'information détaillée relative à un +# hôte spécifique, incluant le nombre actuel de +# comptes-session et la limitation de sessions. La valeur +# hôte ne doit pas inclure de frimes. +# +# Voir l'assistance (HELP) d'EXCEPTION pour plus d'information +# à propos de la limitation de session et comment déterminer +# une limitation de session spécifique pour certains hôtes et +# groupes d'hôtes. +# +# Limité à l'usage des Administrateurs des Services. OPER_HELP_SU Syntaxe: SU mot-de-passe diff -uNr ircservices-5.0.31/lang/hu.l ircservices-5.0.32/lang/hu.l --- ircservices-5.0.31/lang/hu.l 2004-03-06 08:51:19 +0900 +++ ircservices-5.0.32/lang/hu.l 2004-05-18 11:54:18 +0900 @@ -1041,7 +1041,7 @@ Az MLOCK +%c paraméternél egy másik szobát kell megadni. CHAN_SET_MLOCK_LINK_NO_LIMIT A megadott flag (+%c) jó beállításához +l flag is szükséges. -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM A megdott flag (+%c) érvénytelen. CHAN_SET_MLOCK_UNKNOWN_CHAR %c: ismeretlen karakter, elutasitva. @@ -4718,7 +4718,7 @@ EXCEPTION LIST [mask | lista] EXCEPTION VIEW [mask | lista] - Lehetõséget nyújt a Services adminisztrátoroknak, hogy + Lehetõséget nyújt a Services operátoroknak, hogy karbantartsák azon hostok listáját, amelyeknek meghatározott session korlátozásuk van, engedélyezve bizonyos gépeket, úgymint a shell szervereket, hogy egyidõben felvigyenek @@ -4776,7 +4776,7 @@ Syntax: SESSION LIST határérték SESSION VIEW host - Lehetõséget nyújt a Services adminisztrátoroknak, hogy megtekintsék + Lehetõséget nyújt a Services operátoroknak, hogy megtekintsék a session listát. SESSION LIST kilistázza azokat a hostokat, amelyeknek legalább @@ -4791,7 +4791,7 @@ korlátozással és azzal kapcsolatban, hogy hogyan állíts be különleges session korlátokat bizonyos hostokra és csoportokra. - Korlátozva Services adminisztrátorokra. + Korlátozva Services operátoroknak. OPER_HELP_SU Syntax: SU jelszó diff -uNr ircservices-5.0.31/lang/index ircservices-5.0.32/lang/index --- ircservices-5.0.31/lang/index 2004-03-17 21:07:41 +0900 +++ ircservices-5.0.32/lang/index 2004-05-19 16:16:17 +0900 @@ -365,7 +365,7 @@ CHAN_SET_MLOCK_LINK_BAD CHAN_SET_MLOCK_LINK_SAME CHAN_SET_MLOCK_LINK_NO_LIMIT -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM CHAN_SET_MLOCK_UNKNOWN_CHAR CHAN_SET_MLOCK_CANNOT_LOCK CHAN_MLOCK_CHANGED diff -uNr ircservices-5.0.31/lang/it.l ircservices-5.0.32/lang/it.l --- ircservices-5.0.31/lang/it.l 2004-03-06 08:51:35 +0900 +++ ircservices-5.0.32/lang/it.l 2004-05-07 14:33:03 +0900 @@ -2703,26 +2703,26 @@ # # Limitato ai Services admins. -OPER_HELP_SESSION - Syntax: SESSION LIST numero - SESSION VIEW host - - Fa in modo che i Services admins vedano la session list. - - SESSION LIST mostra gli hosts con almeno numero - sessioni. - Il numero deve essere maggiore di 1. Questo per prevenire - acciedentali liste di un grande numero di persone. - SESSION VIEW mostra specifiche informazioni su un host - specifico, includendo il numero di sessioni corrente e il - limite. Il parametro host non deve includere delle - wildcards (* oppure ?). - - Guarda l'help di EXCEPTION per informazioni piu' - dettagliate sulla limitazione di sessioni e su come - settare delle specifiche limitazioni. - - Limitato ai Services admins. +#OPER_HELP_SESSION +# Syntax: SESSION LIST numero +# SESSION VIEW host +# +# Fa in modo che i Services admins vedano la session list. +# +# SESSION LIST mostra gli hosts con almeno numero +# sessioni. +# Il numero deve essere maggiore di 1. Questo per prevenire +# acciedentali liste di un grande numero di persone. +# SESSION VIEW mostra specifiche informazioni su un host +# specifico, includendo il numero di sessioni corrente e il +# limite. Il parametro host non deve includere delle +# wildcards (* oppure ?). +# +# Guarda l'help di EXCEPTION per informazioni piu' +# dettagliate sulla limitazione di sessioni e su come +# settare delle specifiche limitazioni. +# +# Limitato ai Services admins. NICK_OPER_HELP_INFO diff -uNr ircservices-5.0.31/lang/ja_euc.l ircservices-5.0.32/lang/ja_euc.l --- ircservices-5.0.31/lang/ja_euc.l 2004-03-06 08:52:16 +0900 +++ ircservices-5.0.32/lang/ja_euc.l 2004-05-18 11:54:28 +0900 @@ -976,7 +976,7 @@ ¥â¡¼¥É¡Ö+%c¡×¤Î¥Ñ¥é¥á¡¼¥¿¤Ë¡¢Æ±¤¸¥Á¥ã¥ó¥Í¥ë¤ò»ØÄꤹ¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¡£ CHAN_SET_MLOCK_LINK_NO_LIMIT ¥â¡¼¥É¡Ö+%c¡×¤ò¥í¥Ã¥¯¤¹¤ë¤Ë¤Ï¡¢¥â¡¼¥É¡Ö+l¡×¤òƱ»þ¤Ë¥í¥Ã¥¯¤·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£ -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM ¥â¡¼¥É¡Ö+%c¡×¤Î¥Ñ¥é¥á¡¼¥¿¤Ï̵¸ú¤Ç¤¹¡£ CHAN_SET_MLOCK_UNKNOWN_CHAR ¡Ö%c¡×¡§¥â¡¼¥Éʸ»ú¤¬Ìµ¸ú¤Ç¤¹¡£ @@ -4506,7 +4506,7 @@ ¤Ê¤ª¡¢Æ±¤¸¥Û¥¹¥È¤ËŬÍѤǤ­¤ë¥¨¥ó¥È¥ê¤¬Ê£¿ô¤¢¤ë¾ì¹ç¡¢¥ê¥¹¥È¤Î °ìÈÖ¾å¡ÊÈֹ椬°ìÈּ㤤¡Ë¤â¤Î¤¬Å¬ÍѤµ¤ì¤Þ¤¹¡£ - ¤³¤Î¥³¥Þ¥ó¥É¤Î»ÈÍѤÏServices¥¢¥É¥ß¥ó¤ËÀ©¸Â¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¥³¥Þ¥ó¥É¤Î»ÈÍѤÏServices¥ª¥Ú¥ì¡¼¥¿¤ËÀ©¸Â¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ OPER_HELP_SESSION ÍÑË¡¡§SESSION LIST ²¼¸Â @@ -4526,7 +4526,7 @@ ¥»¥Ã¥·¥ç¥óÀ©¸Âµ¡Ç½¤Î¾Ü¤·¤¤ÀâÌÀ¤Ë¤Ä¤¤¤Æ¤Ï¡¢EXCEPTION¥³¥Þ¥ó¥É ¤Î¥Ø¥ë¥×¾ðÊó¤ò¤´Í÷¤¯¤À¤µ¤¤¡£ - ¤³¤Î¥³¥Þ¥ó¥É¤Î»ÈÍѤÏServices¥¢¥É¥ß¥ó¤ËÀ©¸Â¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ + ¤³¤Î¥³¥Þ¥ó¥É¤Î»ÈÍѤÏServices¥ª¥Ú¥ì¡¼¥¿¤ËÀ©¸Â¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ OPER_HELP_SU ÍÑË¡¡§SU ¥Ñ¥¹¥ï¡¼¥É diff -uNr ircservices-5.0.31/lang/ja_sjis.l ircservices-5.0.32/lang/ja_sjis.l --- ircservices-5.0.31/lang/ja_sjis.l 2004-03-06 09:05:23 +0900 +++ ircservices-5.0.32/lang/ja_sjis.l 2004-05-18 11:57:51 +0900 @@ -976,7 +976,7 @@ ƒ‚[ƒhu+%cv‚̃pƒ‰ƒ[ƒ^‚ÉA“¯‚¶ƒ`ƒƒƒ“ƒlƒ‹‚ðŽw’è‚·‚邱‚Æ‚Í‚Å‚«‚Ü‚¹‚ñB CHAN_SET_MLOCK_LINK_NO_LIMIT ƒ‚[ƒhu+%cv‚ðƒƒbƒN‚·‚é‚É‚ÍAƒ‚[ƒhu+lv‚𓯎ž‚ɃƒbƒN‚µ‚È‚¯‚ê‚΂Ȃè‚Ü‚¹‚ñB -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM ƒ‚[ƒhu+%cv‚̃pƒ‰ƒ[ƒ^‚Í–³Œø‚Å‚·B CHAN_SET_MLOCK_UNKNOWN_CHAR u%cvFƒ‚[ƒh•¶Žš‚ª–³Œø‚Å‚·B @@ -4506,7 +4506,7 @@ ‚È‚¨A“¯‚¶ƒzƒXƒg‚É“K—p‚Å‚«‚éƒGƒ“ƒgƒŠ‚ª•¡”‚ ‚éê‡AƒŠƒXƒg‚Ì ˆê”Ôãi”Ô†‚ªˆê”ÔŽá‚¢j‚à‚Ì‚ª“K—p‚³‚ê‚Ü‚·B - ‚±‚̃Rƒ}ƒ“ƒh‚ÌŽg—p‚ÍServicesƒAƒhƒ~ƒ“‚ɧŒÀ‚³‚ê‚Ä‚¢‚Ü‚·B + ‚±‚̃Rƒ}ƒ“ƒh‚ÌŽg—p‚ÍServicesƒIƒyƒŒ[ƒ^‚ɧŒÀ‚³‚ê‚Ä‚¢‚Ü‚·B OPER_HELP_SESSION —p–@FSESSION LIST ‰ºŒÀ @@ -4526,7 +4526,7 @@ ƒZƒbƒVƒ‡ƒ“§ŒÀ‹@”\‚ÌÚ‚µ‚¢à–¾‚ɂ‚¢‚Ä‚ÍAEXCEPTIONƒRƒ}ƒ“ƒh ‚̃wƒ‹ƒvî•ñ‚ð‚²——‚­‚¾‚³‚¢B - ‚±‚̃Rƒ}ƒ“ƒh‚ÌŽg—p‚ÍServicesƒAƒhƒ~ƒ“‚ɧŒÀ‚³‚ê‚Ä‚¢‚Ü‚·B + ‚±‚̃Rƒ}ƒ“ƒh‚ÌŽg—p‚ÍServicesƒIƒyƒŒ[ƒ^‚ɧŒÀ‚³‚ê‚Ä‚¢‚Ü‚·B OPER_HELP_SU —p–@FSU ƒpƒXƒ[ƒh diff -uNr ircservices-5.0.31/lang/langstrs.h ircservices-5.0.32/lang/langstrs.h --- ircservices-5.0.31/lang/langstrs.h 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/lang/langstrs.h 2004-06-07 19:44:06 +0900 @@ -365,7 +365,7 @@ #define CHAN_SET_MLOCK_LINK_BAD 364 #define CHAN_SET_MLOCK_LINK_SAME 365 #define CHAN_SET_MLOCK_LINK_NO_LIMIT 366 -#define CHAN_SET_MLOCK_FLOOD_BAD 367 +#define CHAN_SET_MLOCK_BAD_PARAM 367 #define CHAN_SET_MLOCK_UNKNOWN_CHAR 368 #define CHAN_SET_MLOCK_CANNOT_LOCK 369 #define CHAN_MLOCK_CHANGED 370 diff -uNr ircservices-5.0.31/lang/nl.l ircservices-5.0.32/lang/nl.l --- ircservices-5.0.31/lang/nl.l 2004-03-06 08:52:33 +0900 +++ ircservices-5.0.32/lang/nl.l 2004-05-18 11:54:46 +0900 @@ -1044,7 +1044,7 @@ Parameter voor MLOCK +%c dient een andere kamer te zijn. CHAN_SET_MLOCK_LINK_NO_LIMIT MLOCK +%c vereist dat MLOCK +l is ingesteld. -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM Ongeldige parameter voor MLOCK +%c. CHAN_SET_MLOCK_UNKNOWN_CHAR Onbekend mode karakter %c genegeerd. @@ -4872,7 +4872,7 @@ EXCEPTION LIST [masker | list] EXCEPTION VIEW [masker | list] - Geeft Services Admins de mogelijkheid de lijst van + Geeft Services operators de mogelijkheid de lijst van hostmaskers die specifieke sessie limieten hebben te bewerken. Doormiddel van deze lijt kunnen bepaalde computers meer inloggen dan het standaard aantal. Wanneer de limiet @@ -4931,7 +4931,7 @@ Syntax: SESSION LIST drempel SESSION VIEW host - Geeft Services Admins de mogelijkheid de sessie lijst te + Geeft Services operators de mogelijkheid de sessie lijst te bekijken. SESSION LIST toont host maskers met minimaal drempel @@ -4948,7 +4948,7 @@ limitering en hoe sessie limieten te specificeren voor bepaalde hosts of groepen hosts. - Beperkt tot Services Admins. + Beperkt tot Services operators. OPER_HELP_SU Syntax: SU wachtwoord diff -uNr ircservices-5.0.31/lang/pt.l ircservices-5.0.32/lang/pt.l --- ircservices-5.0.31/lang/pt.l 2004-03-06 08:52:41 +0900 +++ ircservices-5.0.32/lang/pt.l 2004-05-07 14:35:32 +0900 @@ -3372,28 +3372,28 @@ # # Limitado aos Administradores dos Services. -OPER_HELP_SESSION - Syntax: SESSION LIST numero - SESSION VIEW host - - Perimite que os Administradores dos Services vejam a lista de - conexoes. - - SESSION LIST lista mascaras de hosts com pelo menos - -numero- conexoes permitidas. - O limite deve ser um numero maior que 1. Isto deve previnir - a listagem de muitos hosts com um limite de conexoes - limitado a 1. - SESSION VIEW mostra informacoes detalhadas sobre um host - especifico, incluindo o numero de conexoes atual e o limite - de conexoes permitidas. - A mascara dada em -host- nao deve incluir coringas ("wildcards"). - - Veja a ajuda sobre EXCEPTION para mais informacoes sobre - o limite de conexoes e como especificar limites de conexoes - para certos hosts e grupos de hosts. - - Limitado aos Administradores dos Services. +#OPER_HELP_SESSION +# Syntax: SESSION LIST numero +# SESSION VIEW host +# +# Perimite que os Administradores dos Services vejam a lista de +# conexoes. +# +# SESSION LIST lista mascaras de hosts com pelo menos +# -numero- conexoes permitidas. +# O limite deve ser um numero maior que 1. Isto deve previnir +# a listagem de muitos hosts com um limite de conexoes +# limitado a 1. +# SESSION VIEW mostra informacoes detalhadas sobre um host +# especifico, incluindo o numero de conexoes atual e o limite +# de conexoes permitidas. +# A mascara dada em -host- nao deve incluir coringas ("wildcards"). +# +# Veja a ajuda sobre EXCEPTION para mais informacoes sobre +# o limite de conexoes e como especificar limites de conexoes +# para certos hosts e grupos de hosts. +# +# Limitado aos Administradores dos Services. #OPER_HELP_SU # Sintaxe: SU senha diff -uNr ircservices-5.0.31/lang/tr.l ircservices-5.0.32/lang/tr.l --- ircservices-5.0.31/lang/tr.l 2004-03-06 08:52:45 +0900 +++ ircservices-5.0.32/lang/tr.l 2004-05-18 11:55:06 +0900 @@ -13,6 +13,7 @@ ######################################################## # Translated by TimeMr14C (uhc0@stud.uni-karlsruhe.de) # # Former translations by mikado (mikado@holyfire.com) # +# Typos fixed by |SaMaN| (saman@ttnet.net.tr) # ######################################################## ########################################################################### @@ -994,7 +995,7 @@ MLOCK icin +%c farkli bir kanal olmak zorunda. CHAN_SET_MLOCK_LINK_NO_LIMIT +%c icin belirtilen mod kilidinde ayrica +l de bulunmalidir. -CHAN_SET_MLOCK_FLOOD_BAD +CHAN_SET_MLOCK_BAD_PARAM +%c modu icin hatali parametre verildi. CHAN_SET_MLOCK_UNKNOWN_CHAR Varolmayan mode %c dikkate alinmadi. @@ -1274,7 +1275,7 @@ CHAN_INFO_DESCRIPTION Aciklama: %s CHAN_INFO_ENTRYMSG - Gisis mesaji: %s + Giris mesaji: %s CHAN_INFO_TIME_REGGED Kayit zamani: %s CHAN_INFO_LAST_USED @@ -2393,7 +2394,7 @@ NICK_HELP_COMMANDS_IDENTIFY IDENTIFY Sizi nick'in sahibi olarak tanitir. NICK_HELP_COMMANDS_SENDPASS - SENDPASS Kayip sifreinizi email ile gönderir. + SENDPASS Kayip sifrenizi email ile gönderir. NICK_HELP_COMMANDS_DROP DROP Nick'inizin kaydini siler. NICK_HELP_COMMANDS_LINK @@ -2818,7 +2819,7 @@ vs.) listeler. NICK_HELP_INFO_AUTH - Eger nickin mail adresi henüz AUTH komudu ile + Eger nickin mail adresi henüz AUTH komutu ile onaylanmamissa SET HIDE EMAIL özelliginden bagimsiz olarak, nickin sahibi ve services adminleri disinda kimse tarafindan görüntülenemez. @@ -3183,7 +3184,7 @@ CHAN_HELP %S size bir kanali kendi adiniza kaydetme ve onu - cesitli yonetme imkani saglar. %S cogu zaman kotu + yonetme imkani saglar. %S cogu zaman kotu niyetli kullanicilarin kanalinizi elegecirmelerini (takeover) , ornegin kanalda sadece belirli bir listedeki kisilerin op olmalarina izin vererek engeller.Mevcut @@ -3193,7 +3194,7 @@ /msg %S HELP komut yazmaniz yeterlidir. CHAN_HELP_EXPIRES - Unutulmamalidir ki %s gun suresince kullanilmayan kanallar otomatik + Unutulmamalidir ki %s suresince kullanilmayan kanallar otomatik olarak silinirler.(ornegin access list'indeki kimsenin bu sure icerisinde kanala girmemesi durumunda) @@ -3204,7 +3205,7 @@ REGISTER Kanali sizin adiniza %S veritabanina kaydeder. IDENTIFY Sifreniz ile birlikte sizi kanal sahibi olarak tanitir. CHAN_HELP_COMMANDS_SENDPASS - SENDPASS Kayip olan kanal sifresini founder email adresine gönderir. + SENDPASS Kayip olan kanal sifresini founder'in email adresine gönderir. CHAN_HELP_COMMANDS_DROP DROP Bir kanalin kaydini siler. SET Cesitli kanal ozelliklerini ve kanal bilgisinini ayarlar. @@ -3275,7 +3276,7 @@ Sizi %S'e belirtilen kanalin founder'i olarak tanitir. Pek cok komutu kullanabilmek icin once kendinizi founder olarak tanitmaniz gerekir.Sifre kismi kanali register - ederken kullanilan + ederken kullanilan sifre ile ayni olmalidir. CHAN_HELP_DROP Kullanimi: DROP kanal @@ -3303,7 +3304,7 @@ PASSWORD Founder sifresini degistirir. DESC Kanal hakkindaki aciklamayi degistirir. URL Bir internet adresini kanal ile iliskilendirir. - EMAIL Bir E-Mail adresini kanal ile iliskilendirir. + EMAIL Bir E-posta adresini kanal ile iliskilendirir. ENTRYMSG Kanala girince gönderilecek bir mesaj belirler. MLOCK Kanal modlarini kilitler/acar. KEEPTOPIC Kanal kullanilmadigi zaman topici hafizada @@ -3328,7 +3329,7 @@ Kullanimi: SET kanal FOUNDER nick Belirtilen kanalin founder'ini (sahibini) degistirir. - Yeni nick te %S'e kaydedilmis olmalidir. + Yeni nick de %S'e kaydedilmis olmalidir. CHAN_HELP_SET_SUCCESSOR Kullanimi: SET kanal SUCCESSOR nick @@ -3393,7 +3394,7 @@ Kanalin mod-kilidi (mode-lock) parametresini acar/kapar. %S size bazi kanal modlarinin daimi olarak aktif veya kapali tutma imkani saglar.Sozkonusu modlar i, k, l, m, n, - p, s, ve t arasindan bir veya birkaci olabilir.modlar + p, s ve t arasindan bir veya birkaci olabilir.modlar parametresinin sekli /MODE komutundaki kullanimi ile aynidir.(Ornegin +nt , -isp gibi.) MLOCK ile kilitlenen modlar, ayni MODE komutu kullanildigindaki @@ -3411,11 +3412,11 @@ SET #kanal MLOCK +nt-iklps Kanalda +nt modlari surekli aktif (+) iken, i, k, l, - p, ve s off surekli devre disi (-) kalacaktir.Kanal + p ve s surekli devre disi (-) kalacaktir.Kanal kodu m ise serbest birakilmistir. SET #kanal MLOCK +knst-ilmp anahtarim - k, n, s, and t modlari surekli aktifken i, l, m, ve + k, n, s ve t modlari surekli aktifken i, l, m, ve p modlari surekli devre disidir.Ayrica kanalin anahtari da (KEY) "anahtarim" seklinde sabit tutulur. @@ -3460,7 +3461,7 @@ kanala ilk girmek sureti ile op olmus kisileri deoplamayacaktir. Öte yandan, SECUREOPS normal calismaya devam edecek, erisimi olmadan op olan kisiler deoplanacaktir. - DIKKAT: Bu özellik, netsplit esnasinda op olmayi ´olaylastirabilir. + DIKKAT: Bu özellik, netsplit esnasinda op olmayi kolaylastirabilir. CHAN_HELP_SET_OPNOTICE Kullanimi: SET kanal OPNOTICE {ON | OFF} @@ -3505,8 +3506,8 @@ kimlerin erisebilecegi gibi bilgileri saklar.Degisik erisim haklari icin farkli erisim seviyeleri (access level) belirlenmistir.Standart olan bu seviyelerin buyuk bir kismi - kanal sahibi tarafindan degistirilebilir.(bkz. - /msg %S HELP ACCESS LEVELS) Bir kanalin kullanici + kanal sahibi tarafindan degistirilebilir(bkz. + /msg %S HELP ACCESS LEVELS). Bir kanalin kullanici listesinde (access list) bulunmayan her nick'in seviyesi varsayilan deger olarak 0'dir. @@ -3725,24 +3726,24 @@ listesinde bulunan bir kullanici kanala girmeye calisirsa, %S tarafindan kanaldan banlanir ve atilir. - AKICK ADD komudu verilen user@host veya + AKICK ADD komutu verilen user@host veya nick!user@hostu autokick listesine ekler. Eger bir aciklama verilmis ise bu kullanilir aksi takdirde kullanici atilirken "You have been banned from the channel" mesaji kullanilir. - AKICK DEL komudu verilen mask i autokick listesindan cikarir. + AKICK DEL komutu verilen mask i autokick listesindan cikarir. Ancak bu veriye uyan mevcut banlari kaldirmaz, bunlar elle kaldirilmalidir. - AKICK LIST komudu autokick listesini veya verilen maska uygun + AKICK LIST komutu autokick listesini veya verilen maska uygun olan verileri görüntüler. AKICK VIEW benzerdir ancak daha ayrintili bilgi verir. - AKICK ENFORCE komudu ile %S e o anda kanalda bulunan ve + AKICK ENFORCE komutu ile %S e o anda kanalda bulunan ve autokick listesindeki verilere uyan kisileri uzaklastirir. - AKICK COUNT komudu ile listede kac adet verinin bulundugu + AKICK COUNT komutu ile listede kac adet verinin bulundugu görüntülenebilir. Standart ayar olarak kanalda %s ve üzeri access bulunan @@ -3753,7 +3754,7 @@ Belirtilen kanalin bilgilerini goruntuler.Kanal bilgileri icinde bazi kisimlar saklanmis veya yazilmamis olabilir. - Bu bilgiler, sahipin nicki, kayit tarihi, son kullanilma + Bu bilgiler, sahibin nicki, kayit tarihi, son kullanilma tarihi ve de mod kilidi gibi bilgilerdir. Kanal sahibi ayrica ALL parametresini kullanarak, giris mesaji ve ya successor bilgilerini de görebilir. @@ -3785,7 +3786,7 @@ CHAN_HELP_VOICE Kullanimi: VOICE kanal nick - Belirtilen nicke süz konusu kanalda op verir. Varsayilan deger + Belirtilen nicke söz konusu kanalda op verir. Varsayilan deger olarak erisim seviyesi %s ve de üstünde olan kisiler bu komutu kullanabilir. @@ -3843,14 +3844,14 @@ %S 'un kanala topic atmasini saglar.Ozellikle TOPICLOCK ozelliginin aktif oldugu zamanlarda - kullanislidir. Standard olarak, erisim seviyesi %s ve de üzeri + kullanislidir. Standart olarak, erisim seviyesi %s ve de üzeri olan kullanicilar bu komutu kullanabilir. CHAN_HELP_KICK Kullanimi: KICK kanal nick [sebep] %S, belirtilen kullaniciyi, belirtilen kanaldan atacaktir. - Sebep verilmis ise bu kullanilacak, ya da standard bir sebep + Sebep verilmis ise bu kullanilacak, ya da standart bir sebep gösterilecektir. Varsayilan deger olarak, erisim seviyesi en az %s olan kullanicilar bu komutu kullanabilirler. @@ -4613,7 +4614,7 @@ EXCEPTION LIST [mask | liste] EXCEPTION VIEW [mask | liste] - Services Adminlerin kimi hostlar icin özel baglanti limitleri tanimlayabilmeleri + Services operatorlerin kimi hostlar icin özel baglanti limitleri tanimlayabilmeleri icindir. Mesela shell server larin, normalden daha fazla baglantiyi kaldirabilmeleri gibi. Bir host limitine erismis ise, limiti asan her bir baglantiya kill komutu gönderilir ve de %S den bir NOTICE ile o hosttan @@ -4656,7 +4657,7 @@ Kullanimi: SESSION LIST threshold SESSION VIEW host - Services Adminlerin oturum listesini görmelerini saglar. + Services operatorlerin oturum listesini görmelerini saglar. SESSION LIST ile en az threshold baglantili hostlar görüntülenir. Flood sorunu olmamasi icin bu rakam en az 1 olmalidir. @@ -4668,7 +4669,7 @@ EXCEPTION helpini kullanarak daha fazla bilgi alabilirsiniz. - Bu komutu sadece Services admin'ler kullanabilir. + Bu komutu sadece Services operatorler kullanabilir. OPER_HELP_SU Kullanimi: SU password diff -uNr ircservices-5.0.31/misc.c ircservices-5.0.32/misc.c --- ircservices-5.0.31/misc.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/misc.c 2004-06-07 19:44:06 +0900 @@ -712,8 +712,10 @@ /*************************************************************************/ /*************************************************************************/ -/* Translate an IPv4 dotted-quad address to a 4-byte string. Return NULL - * if the given string is not in dotted-quad format or `ipaddr' is NULL. +/* Translate an IPv4 dotted-quad address into binary (4 bytes). Returns + * NULL if the given string is not in dotted-quad format or `ipaddr' is + * NULL. The returned buffer is static and will be overwritten on + * subsequent calls. */ uint8 *pack_ip(const char *ipaddr) @@ -744,9 +746,11 @@ /*************************************************************************/ -/* Translate a 4-byte character string to a dotted-quad IPv4 address. - * Always succeeds and always returns a string <= 15 characters in length, - * unless `ip' is NULL, in which case the function returns NULL. +/* Translate a 4-byte binary IPv4 to its dotted-quad (ASCII) representation. + * Always succeeds and always returns a null-terminated string <= 15 + * characters in length, unless `ip' is NULL, in which case the function + * returns NULL. The returned buffer is static and will be overwritten on + * subsequent calls. */ char *unpack_ip(const uint8 *ip) @@ -762,6 +766,139 @@ } /*************************************************************************/ + +/* Translate an IPv6 ASCII address into binary (16 bytes). Return NULL if + * the given string is not in IPv6 format or `ipaddr' is NULL. The + * returned buffer is static and will be overwritten on subsequent calls. + */ + +uint8 *pack_ip6(const char *ipaddr) +{ + static uint8 ipbuf[16]; + int words[8]; + int wordnum; + const char *s, *t; + int i; + + if (!ipaddr) + return NULL; + + /* Parse the address into 16-bit words */ + s = ipaddr; + wordnum = 0; + if (*s == ':') { + words[wordnum++] = 0; + s++; + } + while (*s) { + if (wordnum >= 8) { + /* too many words, abort */ + return NULL; + } + if (*s == ':') { + /* mark "::" with a -1 */ + words[wordnum++] = -1; + s++; + } else { + words[wordnum++] = (int)strtol(s, (char **)&t, 16); + if (*t && *t != ':') { + /* invalid syntax */ + return NULL; + } + if (*t) { + t++; /* skip past delimiter */ + if (!*t) { + /* trailing ":", convert to :0000 */ + if (wordnum >= 8) + return NULL; + words[wordnum++] = 0; + } + } + s = t; + } + } + + /* Expand "::" into as many zeros as needed, and make sure there + * aren't multiple occurrences of "::" */ + for (i = 0; i < wordnum; i++) { + if (words[i] == -1) + break; + } + if (i < wordnum) { /* found a "::" */ + int j, offset; + for (j = i+1; j < wordnum; j++) { + if (words[j] == -1) { + /* multiple "::" */ + return NULL; + } + } + offset = 8-wordnum; + for (j = 7; j >= i; j--) { + if (j-offset > i) + words[j] = words[j-offset]; + else + words[j] = 0; + } + wordnum = 8; + } + + /* Make sure we have exactly 8 words */ + if (wordnum != 8) + return NULL; + + /* Convert to binary and return */ + for (i = 0; i < 8; i++) { + ipbuf[i*2 ] = words[i] >> 8; + ipbuf[i*2+1] = words[i] & 255; + } + return ipbuf; +} + +/*************************************************************************/ + +/* Translate a 16-byte binary IPv6 address to its ASCII representation. + * Always succeeds and always returns a null-terminated string <= 39 + * characters in length, unless `ip' is NULL, in which case the function + * returns NULL. The returned buffer is static and will be overwritten on + * subsequent calls. + * + * The address string returned by this function will always use 4-digit + * hexadecimal numbers for each word in the address, but will omit all-zero + * words when possible. + */ + +char *unpack_ip6(const uint8 *ip) +{ + static char ipbuf[41]; /* 1 byte extra to catch overflow (paranoia) */ + char *out, *s; + int i; + + if (!ip) + return NULL; + + out = ipbuf; + for (i = 0; i < 8; i++) { + /* Skip 0000 at beginning or end */ + if ((i != 0 && i != 7) || ip[i*2] || ip[i*2+1]) { + out += snprintf(out, sizeof(ipbuf)-(out-ipbuf), "%02X%02X", + ip[i*2], ip[i*2+1]); + } + if (i != 7) + *out++ = ':'; + } + if (strlen(ipbuf) > 39) + fatal("BUG: unpack_ip6(): result too long (%s)", ipbuf); + if ((s = strstr(ipbuf,":0000:")) != NULL) { + /* Compress zeros */ + memmove(s+1, s+5, strlen(s+5)+1); + s++; + while (strncmp(s,":0000:",6) == 0) + memmove(s, s+5, strlen(s+5)+1); + } + return ipbuf; +} + +/*************************************************************************/ /*************************************************************************/ /* Lock the data directory if possible; return nonzero on success, zero on @@ -824,3 +961,167 @@ } /*************************************************************************/ +/*************************************************************************/ + +/* Encode buffer `in' of size `insize' to buffer `out' of size `outsize' + * using base64, appending a trailing null. Returns the number of bytes + * required by the encoded string. (The amount of space needed to store + * the encoded string can be found with encode_base64(...,NULL,0).) + * Returns -1 if the input or output buffer is NULL (except when the + * corresponding size is zero) or if the input or output size is negative. + * If `out' is too small to hold the entire encoded string, it will contain + * the first `outsize'-1 bytes of the encoded string followed by a null. + */ + +static const char base64_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +int encode_base64(const void *in, int insize, char *out, int outsize) +{ + int required = ((insize+2)/3*4)+1; + const uint8 *inp = in; + int inpos, outpos; + + if (insize < 0 || outsize < 0) + return -1; + if (outsize == 0) + return required; + if (!out) + return -1; + if (insize == 0) { + /* outsize is at least 1 */ + *out = 0; + return 1; + } + if (!in) + return -1; + + outsize--; /* leave room for trailing \0 */ + + /* Actually do the encoding */ + outpos = 0; + for (inpos = 0; inpos < insize; inpos += 3) { + uint8 i0, i1, i2; + char o0, o1, o2, o3; + i0 = inp[inpos]; + o0 = base64_chars[i0>>2]; + if (inpos+1 < insize) { + i1 = inp[inpos+1]; + o1 = base64_chars[(i0&3)<<4 | i1>>4]; + if (inpos+2 < insize) { + i2 = inp[inpos+2]; + o2 = base64_chars[(i1&15)<<2 | i2>>6]; + o3 = base64_chars[i2&63]; + } else { + o2 = base64_chars[(i1&15)<<2]; + o3 = '='; + } + } else { + o1 = base64_chars[(i0&3)<<4]; + o2 = '='; + o3 = '='; + } + if (outpos < outsize) + out[outpos++] = o0; + if (outpos < outsize) + out[outpos++] = o1; + if (outpos < outsize) + out[outpos++] = o2; + if (outpos < outsize) + out[outpos++] = o3; + } + + /* Terminate the string and return; outpos is constrained above to + * still be within the buffer (remember that outsize was decremented + * before the loop) */ + out[outpos] = 0; + return required; +} + +/*************************************************************************/ + +/* Decode base64-encoded string `in' (null-terminated) to buffer `out' of + * size `outsize'. Returns the number of bytes required by the decoded + * data. (The amount of space needed to store the decoded data can be + * found with decode_base64(...,NULL,0).) Returns -1 if the input string + * is NULL, or if the output buffer is NULL (except when the size is zero) + * or the size is negative. If `out' is too small to hold all of the + * decoded data, it will contain the first `outsize' bytes. + */ + +static const char base64_array[256] = { + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x00 */ + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, + 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, /* 0x40 */ + 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, + -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0x80 */ + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 0xC0 */ + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, +}; + +int decode_base64(const char *in, void *out, int outsize) +{ + uint8 *outp = out; + int outpos; + + if (!in || outsize < 0) + return -1; + + outpos = 0; + while (*in) { + int i0, i1, i2, i3; + i0 = *in++; + if (*in) { + i1 = *in++; + if (*in) { + i2 = *in++; + if (*in) { + i3 = *in++; + } else { + i3 = 0; + } + } else { + i2 = 0; + i3 = 0; + } + } else { + i1 = 0; + i2 = 0; + i3 = 0; + } + i0 = base64_array[(int)i0 & 255]; + i1 = base64_array[(int)i1 & 255]; + i2 = base64_array[(int)i2 & 255]; + i3 = base64_array[(int)i3 & 255]; + if (i0 < 0 || i1 < 0) + break; + /* Only store if buffer space is available; increment outpos anyway + * to keep track of total space required (for return value) */ + if (outpos < outsize) + outp[outpos] = i0<<2 | i1>>4; + outpos++; + if (i2 < 0) + break; + if (outpos < outsize) + outp[outpos] = (i1&15)<<4 | i2>>2; + outpos++; + if (i3 < 0) + break; + if (outpos < outsize) + outp[outpos] = (i2&3)<<6 | i3; + outpos++; + } + + return outpos; +} + +/*************************************************************************/ diff -uNr ircservices-5.0.31/modules/chanserv/access.c ircservices-5.0.32/modules/chanserv/access.c --- ircservices-5.0.31/modules/chanserv/access.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/chanserv/access.c 2004-06-07 19:44:06 +0900 @@ -113,6 +113,33 @@ /*************************************************************************/ +/* Return the access level the given user has on the channel. If the + * channel doesn't exist, the user isn't on the access list, or the channel + * is CS_SECURE and the user hasn't IDENTIFY'd with NickServ, return 0. + */ + +EXPORT_FUNC(get_access) +int get_access(User *user, ChannelInfo *ci) +{ + if (is_founder(user, ci)) + return ACCLEV_FOUNDER; + if (!ci || !valid_ngi(user) || (ci->flags&CI_VERBOTEN) || ci->suspendinfo) + return 0; + if (user_identified(user) + || (user_recognized(user) && !(ci->flags & CI_SECURE)) + ) { + int32 id = user->ngi->id; + int i; + ARRAY_FOREACH (i, ci->access) { + if (ci->access[i].nickgroup == id) + return ci->access[i].level; + } + } + return 0; +} + +/*************************************************************************/ + /* Return 1 if the user's access level on the given channel falls into the * given category, 0 otherwise. Note that this may seem slightly confusing * in some cases: for example, check_access(..., CA_NOJOIN) returns true if @@ -214,6 +241,33 @@ } /*************************************************************************/ +/************************** Local-use routines ***************************/ +/*************************************************************************/ + +/* Return the access level the given user has on the channel, supposing the + * user was identified for their current nick (if it's registered). + */ + +static int get_access_if_idented(User *user, ChannelInfo *ci) +{ + int i; + int32 id; + + if (is_identified(user, ci)) + return ACCLEV_FOUNDER; + if (!ci || !valid_ngi(user) || (ci->flags&CI_VERBOTEN) || ci->suspendinfo) + return 0; + if (user->ngi->id == ci->founder) + return ACCLEV_FOUNDER; + id = user->ngi->id; + ARRAY_FOREACH (i, ci->access) { + if (ci->access[i].nickgroup == id) + return ci->access[i].level; + } + return 0; +} + +/*************************************************************************/ /* Check a channel user mode change, and return the mask of mode flags * which should be changed (i.e. should be the reverse of the new flags @@ -230,7 +284,6 @@ * (i.e. "setting CUMODE_o is incorrect" -> send a MODE -o) */ -EXPORT_FUNC(check_access_cumode) int check_access_cumode(User *user, ChannelInfo *ci, int32 newmodes, int32 changemask) { @@ -259,59 +312,6 @@ } /*************************************************************************/ -/************************** Local-use routines ***************************/ -/*************************************************************************/ - -/* Return the access level the given user has on the channel. If the - * channel doesn't exist, the user isn't on the access list, or the channel - * is CS_SECURE and the user hasn't IDENTIFY'd with NickServ, return 0. - */ - -int get_access(User *user, ChannelInfo *ci) -{ - if (is_founder(user, ci)) - return ACCLEV_FOUNDER; - if (!ci || !valid_ngi(user) || (ci->flags&CI_VERBOTEN) || ci->suspendinfo) - return 0; - if (user_identified(user) - || (user_recognized(user) && !(ci->flags & CI_SECURE)) - ) { - int32 id = user->ngi->id; - int i; - ARRAY_FOREACH (i, ci->access) { - if (ci->access[i].nickgroup == id) - return ci->access[i].level; - } - } - return 0; -} - -/*************************************************************************/ - -/* Return the access level the given user has on the channel, supposing the - * user was identified for their current nick (if it's registered). - */ - -static int get_access_if_idented(User *user, ChannelInfo *ci) -{ - int i; - int32 id; - - if (is_identified(user, ci)) - return ACCLEV_FOUNDER; - if (!ci || !valid_ngi(user) || (ci->flags&CI_VERBOTEN) || ci->suspendinfo) - return 0; - if (user->ngi->id == ci->founder) - return ACCLEV_FOUNDER; - id = user->ngi->id; - ARRAY_FOREACH (i, ci->access) { - if (ci->access[i].nickgroup == id) - return ci->access[i].level; - } - return 0; -} - -/*************************************************************************/ /* Add an entry `nick' (at `level') to the access list by a user with * access `uacc'. diff -uNr ircservices-5.0.31/modules/chanserv/chanserv.h ircservices-5.0.32/modules/chanserv/chanserv.h --- ircservices-5.0.31/modules/chanserv/chanserv.h 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/chanserv/chanserv.h 2004-06-07 19:44:06 +0900 @@ -97,6 +97,8 @@ char *mlock_link; /* +L (Unreal, trircd) */ char *mlock_flood; /* +f (Unreal, etc.) */ int32 mlock_joindelay; /* +J (trircd) */ + int32 mlock_joinrate1; /* +j (Bahamut) */ + int32 mlock_joinrate2; /* +j (Bahamut) */ char *entry_message; /* Notice sent on entering channel */ @@ -200,12 +202,11 @@ E2 void free_channelinfo(ChannelInfo *ci); #undef E2 E int check_expire_channel(ChannelInfo *ci); +E int get_access(User *user, ChannelInfo *ci); E int check_access(User *user, ChannelInfo *ci, int what); E int check_access_if_idented(User *user, ChannelInfo *ci, int what); E int check_access_cmd(User *user, ChannelInfo *ci, const char *command, const char *subcommand); -E int check_access_cumode(User *user, ChannelInfo *ci, int32 newmodes, - int32 changemask); E int check_channel_limit(NickGroupInfo *ngi, int *max_ret); E void reset_levels(ChannelInfo *ci, int set); diff -uNr ircservices-5.0.31/modules/chanserv/check.c ircservices-5.0.32/modules/chanserv/check.c --- ircservices-5.0.31/modules/chanserv/check.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/chanserv/check.c 2004-06-07 19:44:06 +0900 @@ -387,7 +387,7 @@ clear_channel(c, CLEAR_EXCEPTS, user); /* Apparently invites can get around bans, so check for ban first */ if (!chan_has_ban(chan, mask)) { - send_channel_cmd(s_ChanServ, "MODE %s +b %s", chan, mask); + send_cmode_cmd(s_ChanServ, chan, "+b %s", mask); if (c) { char *av[3]; av[0] = (char *)chan; diff -uNr ircservices-5.0.31/modules/chanserv/cs-local.h ircservices-5.0.32/modules/chanserv/cs-local.h --- ircservices-5.0.31/modules/chanserv/cs-local.h 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/chanserv/cs-local.h 2004-06-07 19:44:06 +0900 @@ -55,7 +55,8 @@ E int16 def_levels[CA_SIZE]; -E int get_access(User *user, ChannelInfo *ci); +E int check_access_cumode(User *user, ChannelInfo *ci, int32 newmodes, + int32 changemask); E int access_add(ChannelInfo *ci, const char *nick, int level, int uacc); E int init_access(Module *mod_unused); E void exit_access(void); diff -uNr ircservices-5.0.31/modules/chanserv/main.c ircservices-5.0.32/modules/chanserv/main.c --- ircservices-5.0.31/modules/chanserv/main.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/chanserv/main.c 2004-06-07 19:44:06 +0900 @@ -817,7 +817,7 @@ delchan(ci); if (chanmode_reg && (c = get_channel(chan))) { c->mode &= ~chanmode_reg; - send_cmd(s_ChanServ, "MODE %s -%s", chan, + send_cmode_cmd(s_ChanServ, chan, "-%s", mode_flags_to_string(chanmode_reg, MODE_CHANNEL)); } notice_lang(s_ChanServ, u, CHAN_DROPPED, chan); diff -uNr ircservices-5.0.31/modules/chanserv/util.c ircservices-5.0.32/modules/chanserv/util.c --- ircservices-5.0.31/modules/chanserv/util.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/chanserv/util.c 2004-06-07 19:44:06 +0900 @@ -118,7 +118,7 @@ if (chanmode_reg && (c = get_channel(ci->name))) { c->mode &= ~chanmode_reg; /* Send this out immediately, no set_cmode() delay */ - send_cmd(s_ChanServ, "MODE %s -%s", ci->name, + send_cmode_cmd(s_ChanServ, ci->name, "-%s", mode_flags_to_string(chanmode_reg, MODE_CHANNEL)); } delchan(ci); diff -uNr ircservices-5.0.31/modules/database/version4.c ircservices-5.0.32/modules/database/version4.c --- ircservices-5.0.31/modules/database/version4.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/database/version4.c 2004-06-07 19:44:06 +0900 @@ -51,9 +51,10 @@ /*************************************************************************/ #define FILE_VERSION 11 /* Must remain constant */ -#define LOCAL_VERSION 26 /* For extensions to database files */ +#define LOCAL_VERSION 27 /* For extensions to database files */ /* LOCAL_VERSION change history: + * 27: Added Bahamut +j handling (ci->mlock_joinrate{1,2} fields) * 26: Forced AUTODEOP and NOJOIN to default values * 25: Added trircd +J handling (ci->mlock_joindelay field) * 24: Moved nickname authentication reason into its own field (no @@ -1085,6 +1086,10 @@ } if (ver >= 25) SAFE(read_int32(&ci->mlock_joindelay, f)); + if (ver >= 27) { + SAFE(read_int32(&ci->mlock_joinrate1, f)); + SAFE(read_int32(&ci->mlock_joinrate2, f)); + } if (ver >= 20) { int16 lev; SAFE(read_int16(&count, f)); @@ -1365,6 +1370,8 @@ SAFE(write_string(ci->mlock_link, f)); SAFE(write_string(ci->mlock_flood, f)); SAFE(write_int32(ci->mlock_joindelay, f)); + SAFE(write_int32(ci->mlock_joinrate1, f)); + SAFE(write_int32(ci->mlock_joinrate2, f)); if (ci->levels) { SAFE(write_int16(CA_SIZE, f)); for (i = 0; i < CA_SIZE; i++) @@ -2753,9 +2760,6 @@ int init_module(Module *module_) { - Module *mod; - - module = module_; /* Ensure a protocol module has already been loaded--this is a bit of a diff -uNr ircservices-5.0.31/modules/httpd/auth-password.c ircservices-5.0.32/modules/httpd/auth-password.c --- ircservices-5.0.31/modules/httpd/auth-password.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/httpd/auth-password.c 2004-06-07 19:44:06 +0900 @@ -118,9 +118,8 @@ static int do_Protect2(const char *filename, int linenum, char *param) { DirInfo di; - char *s, *d; - static const char *base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char *s; + int bufsize = 0; static DirInfo *new_protected = NULL; static int new_protected_count = 0; @@ -171,29 +170,26 @@ } /* base64-encode and store in di.userpass */ - di.userpass = malloc((strlen(param)+2)/3*4+1); + bufsize = encode_base64(param, strlen(param), NULL, 0); + if (bufsize <= 0) { + config_error(filename, linenum, "Internal error: base64 encoding" + " failed"); + free(di.path); + return 0; + } + di.userpass = malloc(bufsize); if (!di.userpass) { config_error(filename, linenum, "Out of memory"); free(di.path); return 0; } - s = param; - d = di.userpass; - do { - *d++ = base64_chars[*s>>2 & 63]; - *d++ = base64_chars[(*s<<4 | s[1]>>4) & 63]; - if (s[1]) { - *d++ = base64_chars[(s[1]<<2 | s[2]>>6) & 63]; - if (s[2]) - *d++ = base64_chars[s[2] & 63]; - else - *d++ = '='; - } else { - *d++ = '='; - *d++ = '='; - } - } while (s[1] && s[2] && s[3] && (s += 3)); /* s+=3 will never be false */ - *d = 0; + if (encode_base64(param, strlen(param), NULL, 0) != bufsize) { + config_error(filename, linenum, "Internal error: base64 encoding" + " failed"); + free(di.userpass); + free(di.path); + return 0; + } /* Store new record in array and return success */ ARRAY_EXTEND(new_protected); diff -uNr ircservices-5.0.31/modules/misc/xml-export.c ircservices-5.0.32/modules/misc/xml-export.c --- ircservices-5.0.31/modules/misc/xml-export.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules/misc/xml-export.c 2004-06-07 19:44:07 +0900 @@ -346,6 +346,8 @@ 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_LONG ("\t\t", *ci, mlock_joinrate1); + XML_PUT_LONG ("\t\t", *ci, mlock_joinrate2); XML_PUT_STRING("\t\t", *ci, entry_message); write_memoinfo(writefunc, data, &ci->memos); writefunc(data, "\t\n"); diff -uNr ircservices-5.0.31/modules/misc/xml-import.c ircservices-5.0.32/modules/misc/xml-import.c --- ircservices-5.0.31/modules/misc/xml-import.c 2004-04-29 09:00:53 +0900 +++ ircservices-5.0.32/modules/misc/xml-import.c 2004-06-07 19:44:07 +0900 @@ -239,6 +239,8 @@ { "mlock_link", th_text }, { "mlock_flood", th_text }, { "mlock_joindelay", th_int32 }, + { "mlock_joinrate1", th_int32 }, + { "mlock_joinrate2", th_int32 }, { "entry_message", th_text }, { "news", th_news }, @@ -1509,6 +1511,10 @@ ci->mlock_flood = ((TextInfo *)result)->text; } else if (stricmp(tag2, "mlock_joindelay") == 0) { ci->mlock_joindelay = *(int32 *)result; + } else if (stricmp(tag2, "mlock_joinrate1") == 0) { + ci->mlock_joinrate1 = *(int32 *)result; + } else if (stricmp(tag2, "mlock_joinrate2") == 0) { + ci->mlock_joinrate2 = *(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.31/modules/operserv/main.c ircservices-5.0.32/modules/operserv/main.c --- ircservices-5.0.31/modules/operserv/main.c 2004-04-29 09:00:53 +0900 +++ ircservices-5.0.32/modules/operserv/main.c 2004-06-07 19:44:07 +0900 @@ -796,10 +796,10 @@ u->nick, all ? " ALL" : "", chan); if (all) { clear_channel(c, CLEAR_UMODES, (void *)MODE_ALL); - clear_channel(c, CLEAR_MODES | CLEAR_BANS, NULL); + clear_channel(c, CLEAR_MODES | CLEAR_BANS | CLEAR_EXCEPTS, NULL); notice_lang(s_OperServ, u, OPER_CLEARMODES_ALL_DONE, chan); } else { - clear_channel(c, CLEAR_MODES | CLEAR_BANS, NULL); + clear_channel(c, CLEAR_MODES | CLEAR_BANS | CLEAR_EXCEPTS, NULL); notice_lang(s_OperServ, u, OPER_CLEARMODES_DONE, chan); } } diff -uNr ircservices-5.0.31/modules/protocol/bahamut.c ircservices-5.0.32/modules/protocol/bahamut.c --- ircservices-5.0.31/modules/protocol/bahamut.c 2004-04-29 09:00:53 +0900 +++ ircservices-5.0.32/modules/protocol/bahamut.c 2004-06-07 19:44:07 +0900 @@ -14,6 +14,7 @@ #include "messages.h" #include "modules/operserv/operserv.h" #include "modules/nickserv/nickserv.h" +#include "modules/chanserv/chanserv.h" #define BAHAMUT_HACK /* For SJOIN; see comments in sjoin.c */ #include "banexcept.h" @@ -24,6 +25,7 @@ static Module *module; static Module *module_operserv; +static Module *module_chanserv; static char *NetworkDomain = NULL; @@ -39,6 +41,9 @@ } #define is_services_admin local_is_services_admin +static char **p_s_ChanServ = &ServerName; +#define s_ChanServ (*p_s_ChanServ) + /*************************************************************************/ /************************** User/channel modes ***************************/ /*************************************************************************/ @@ -66,8 +71,11 @@ /* Only opers can join channel */ /* Note: Flags in this range are used by Unreal */ {'M', {0x02000000,0,0}}, /* Moderated to unregged nicks */ + {'j', {0x04000000,1,0}}, /* /join rate limit */ {'e', {0x80000000,1,1,0,MI_MULTIPLE}}, /* Ban exceptions */ + {'I', {0x80000000,1,1,0,MI_MULTIPLE}}, + /* INVITE hosts */ }; static const struct modedata_init new_chanusermodes[] = { @@ -135,10 +143,8 @@ } else if (!ip && find_module("operserv/sline")) { static int warned_no_nickip = 0; if (!warned_no_nickip) { - wallops(NULL, - "\2WARNING\2: missing IP address for new nick %s. Make" - " sure you have no pre-1.4.25 servers on your network," - " or SZLINEs will not work correctly.", av[0]); + wallops(NULL, "\2WARNING\2: missing IP address for new nick %s", + av[0]); warned_no_nickip = 1; } module_log("WARNING: missing IP address for new nick %s", av[0]); @@ -230,20 +236,100 @@ /*************************************************************************/ +/* Abbreviated message handlers. + * We do not allow Bahamut to run in SERVICESHUB mode because it cuts out + * both the topic burst (causing temporary desynch) and AWAY messages + * (causing MemoServ unaway checking to break). + */ + +#ifdef ALLOW_BAHAMUT_SERVICESHUB /* not defined anywhere */ + +static void expand_to_privmsg(char *source, const char *cmdname, + const char *targetsym, char *msg) +{ + char **targetnick = NULL; + + if (targetsym) + targetnick = get_module_symbol(NULL, targetsym); + if (targetnick) { + Message *m = find_message("PRIVMSG"); + if (m) { + char *av[2]; + av[0] = *targetnick; + av[1] = msg; + m->func(source, 2, av); + } else { + module_log("expand_to_privmsg(): BUG: PRIVMSG message entry not" + " found"); + send_cmd(ServerName, "421 %s %s :Internal error", source, msg); + } + } else { + /* We don't know what command/nick the user originally used, so + * this is about the best we can do... */ + send_cmd(ServerName, "421 %s %s :Command not available", source, msg); + } +} + +static void m_ns(char *source, int ac, char **av) { + expand_to_privmsg(source, "NS", "s_NickServ", av[0]); } +static void m_cs(char *source, int ac, char **av) { + expand_to_privmsg(source, "CS", "s_ChanServ", av[0]); } +static void m_ms(char *source, int ac, char **av) { + expand_to_privmsg(source, "MS", "s_MemoServ", av[0]); } +static void m_rs(char *source, int ac, char **av) { + expand_to_privmsg(source, "RS", NULL /*"s_RootServ"*/, av[0]); } +static void m_os(char *source, int ac, char **av) { + expand_to_privmsg(source, "OS", "s_OperServ", av[0]); } +static void m_ss(char *source, int ac, char **av) { + expand_to_privmsg(source, "SS", "s_StatServ", av[0]); } +static void m_hs(char *source, int ac, char **av) { + expand_to_privmsg(source, "HS", "s_HelpServ", av[0]); } + +#else + +static void no_serviceshub(char *source, int ac, char **av) +{ + fatal("IRC Services will not function correctly when Bahamut is" + " configured as a SERVICESHUB. Please reconfigure Bahamut as a" + " regular hub and restart Services."); +} + +#define m_ns no_serviceshub +#define m_cs no_serviceshub +#define m_ms no_serviceshub +#define m_rs no_serviceshub +#define m_os no_serviceshub +#define m_ss no_serviceshub +#define m_hs no_serviceshub + +#endif + +/*************************************************************************/ + static Message bahamut_messages[] = { { "AKILL", NULL }, { "CAPAB", m_capab }, + { "CS", m_cs }, { "GLOBOPS", NULL }, { "GNOTICE", NULL }, { "GOPER", NULL }, + { "HS", m_hs }, + { "LOCKLUSERS",NULL }, + { "MS", m_ms }, { "NICK", m_nick }, + { "NS", m_ns }, + { "OS", m_os }, { "RAKILL", NULL }, + { "RS", m_rs }, { "SILENCE", NULL }, { "SJOIN", m_sjoin }, { "SQLINE", NULL }, + { "SS", m_ss }, { "SVINFO", NULL }, { "SVSMODE", m_svsmode }, { "SZLINE", NULL }, + { "UNSQLINE", NULL }, + { "UNSZLINE", NULL }, { NULL } }; @@ -290,7 +376,9 @@ static void do_send_server(void) { send_cmd(NULL, "PASS %s :TS", RemotePassword); - send_cmd(NULL, "CAPAB TS3 SSJOIN NICKIP NOQUIT"); + /* Note that we don't actually support UNCONNECT (remote SQUITs) but + * Bahamut will throw us off if we don't claim to */ + send_cmd(NULL, "CAPAB TS3 SSJOIN NICKIP NOQUIT TSMODE UNCONNECT"); send_cmd(NULL, "SERVER %s 1 :%s", ServerName, ServerDesc); send_cmd(NULL, "SVINFO 3 3 0 :%ld", (long)time(NULL)); } @@ -352,7 +440,7 @@ va_list args; va_start(args, fmt); - vsend_cmd(ServerName, fmt, args); + vsend_cmd(source, fmt, args); va_end(args); } @@ -413,6 +501,54 @@ /*************************************************************************/ +static int do_channel_mode(const char *source, Channel *channel, + int modechar, int add, char **av) +{ + int32 flag = mode_char_to_flag(modechar, MODE_CHANNEL); + + switch (modechar) { + case 'j': + if (add) { + int ok = 0; + char *s; + int joinrate1 = strtol(av[0], &s, 0); + if (*s == ':') { + int joinrate2 = strtol(s+1, &s, 0); + if (!*s) { + if (joinrate1 && joinrate2) { + channel->mode |= flag; + channel->joinrate1 = joinrate1; + channel->joinrate2 = joinrate2; + } else { + channel->mode &= ~flag; + channel->joinrate1 = 0; + channel->joinrate2 = 0; + ok = 1; + } + ok = 1; + } + } else if (joinrate1 == 0) { + channel->mode &= ~flag; + channel->joinrate1 = 0; + channel->joinrate2 = 0; + ok = 1; + } + if (!ok) { + module_log("warning: invalid MODE +j %s for %s", av[0], + channel->name); + } + } else { + channel->mode &= ~flag; + channel->joinrate1 = 0; + channel->joinrate2 = 0; + } + return 1; + } + return 0; +} + +/*************************************************************************/ + static int do_nick_identified(User *u, int old_status) { if (is_oper(u) && is_services_admin(u)) @@ -435,14 +571,94 @@ /*************************************************************************/ +static int do_check_modes(Channel *c, ChannelInfo *ci, int add, int32 flag) +{ + if (add) { + switch (mode_flag_to_char(flag, MODE_CHANNEL)) { + case 'j': + if (ci->mlock_joinrate1 <= 0 || ci->mlock_joinrate2 <= 0) { + module_log("warning: removing +j from channel %s mode lock" + " (invalid parameter: %d:%d)", ci->name, + ci->mlock_joinrate1, ci->mlock_joinrate2); + ci->mlock_on &= ~mode_char_to_flag('j', MODE_CHANNEL); + ci->mlock_joinrate1 = ci->mlock_joinrate2 = 0; + } else { + if (c->joinrate1 != ci->mlock_joinrate1 + || c->joinrate2 != ci->mlock_joinrate2 + ) { + char buf[BUFSIZE]; + snprintf(buf, sizeof(buf), "%d:%d", + ci->mlock_joinrate1, ci->mlock_joinrate2); + set_cmode(s_ChanServ, c, "+j", buf); + } + } + return 1; + } + } + return 0; +} + +/*************************************************************************/ + +static int do_set_mlock(User *u, ChannelInfo *ci, int mode, int add, char **av) +{ + if (!mode) { + /* Final check of new mode lock--nothing to do */ + return 0; + } + + /* Single mode set/clear */ + + if (add) { + + switch (mode) { + case 'j': { + int ok = 0; + char *s; + ci->mlock_joinrate1 = strtol(av[0], &s, 0); + if (ci->mlock_joinrate1 > 0 && *s == ':') { + ci->mlock_joinrate2 = strtol(s+1, &s, 0); + if (ci->mlock_joinrate2 > 0 && !*s) + ok = 1; + } + if (!ok) { + notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_BAD_PARAM, mode); + return 1; + } + break; + } /* case 'j' */ + } /* switch (mode) */ + + } else { /* !add -> lock off */ + + switch (mode) { + case 'j': + ci->mlock_joindelay = 0; + break; + } /* switch (mode) */ + + } /* if (add) */ + + return 0; +} + +/*************************************************************************/ + static int do_send_akill(const char *username, const char *host, time_t expires, const char *who, const char *reason) { time_t now = time(NULL); + /* Bahamut 1.8.0 has a "feature" which converts an expiration delay of + * zero (supposedly "unlimited") into a delay of one week. Therefore, + * we have a "feature" which sends an unlimited expiration time as + * many years in the future. */ + time_t length = ((expires && expires > now) ? expires - now : 0); + if (length == 0 && now < 0x7FFFFFFF) + length = 0x7FFFFFFF - now; + send_cmd(ServerName, "AKILL %s %s %ld %s %ld :%s", host, username, - (long)((expires && expires > now) ? expires - now : 0), - who ? who : "", (long)now, reason); + (long)length, who ? who : "", (long)now, reason); return 1; } @@ -473,8 +689,7 @@ static int do_send_szline(const char *mask, time_t expires, const char *who, const char *reason) { - send_cmd(ServerName, "SZLINE %s :%s", mask, reason); - return 1; + return do_send_akill("*", mask, expires, who, reason); } /*************************************************************************/ @@ -493,7 +708,7 @@ static int do_cancel_szline(const char *mask) { - send_cmd(ServerName, "UNSZLINE %s", mask); + return do_cancel_akill("*", mask); return 1; } @@ -541,6 +756,18 @@ } else if (strcmp(modname, "nickserv/main") == 0) { if (!add_callback(mod, "identified", do_nick_identified)) module_log("Unable to add NickServ identified callback"); + } else if (strcmp(modname, "chanserv/main") == 0) { + module_chanserv = mod; + p_s_ChanServ = get_module_symbol(mod, "s_ChanServ"); + if (!p_s_ChanServ) { + module_log("Unable to resolve symbol `s_ChanServ' in module" + " `chanserv/main'"); + p_s_ChanServ = &ServerName; + } + if (!add_callback(mod, "check_modes", do_check_modes)) + module_log("Unable to add ChanServ check_modes callback"); + if (!add_callback(mod, "SET MLOCK", do_set_mlock)) + module_log("Unable to add ChanServ SET MLOCK callback"); } return 0; } @@ -552,6 +779,11 @@ if (mod == module_operserv) { module_operserv = NULL; p_is_services_admin = NULL; + } else if (mod == module_chanserv) { + module_chanserv = NULL; + p_s_ChanServ = &ServerName; + remove_callback(mod, "SET MLOCK", do_set_mlock); + remove_callback(mod, "check_modes", do_check_modes); } return 0; } @@ -565,8 +797,8 @@ module = module_; protocol_name = "Bahamut"; - protocol_version = "1.4.25+"; - protocol_features = PF_SZLINE; + protocol_version = "1.8.0+"; + protocol_features = PF_SZLINE | PF_MODETS_FIRST; protocol_nickmax = 30; if (!register_messages(bahamut_messages)) { @@ -579,6 +811,7 @@ || !add_callback(NULL, "unload module", do_unload_module) || !add_callback(NULL, "user servicestamp change", do_user_servicestamp_change) + || !add_callback(NULL, "channel MODE", do_channel_mode) || !add_callback(NULL, "user MODE", do_user_mode) || !add_callback(NULL, "set topic", do_set_topic) ) { @@ -635,6 +868,7 @@ exit_banexcept(); remove_callback(NULL, "set topic", do_set_topic); remove_callback(NULL, "user MODE", do_user_mode); + remove_callback(NULL, "channel MODE", do_channel_mode); remove_callback(NULL, "user servicestamp change", do_user_servicestamp_change); remove_callback(NULL, "unload module", do_unload_module); diff -uNr ircservices-5.0.31/modules/protocol/banexcept.c ircservices-5.0.32/modules/protocol/banexcept.c --- ircservices-5.0.31/modules/protocol/banexcept.c 2004-04-29 09:00:53 +0900 +++ ircservices-5.0.32/modules/protocol/banexcept.c 2004-06-07 19:44:07 +0900 @@ -58,8 +58,8 @@ static int do_clear_channel(const char *sender, Channel *chan, int what, const void *param) { - if (what & (CLEAR_USERS | CLEAR_BANS)) - clear_excepts(sender, chan, (what & CLEAR_BANS) ? param : NULL); + if (what & (CLEAR_USERS | CLEAR_EXCEPTS)) + clear_excepts(sender, chan, (what & CLEAR_EXCEPTS) ? param : NULL); return 0; } @@ -75,16 +75,16 @@ excepts = smalloc(sizeof(char *) * count); memcpy(excepts, chan->excepts, sizeof(char *) * count); for (i = 0; i < count; i++) { - if (!u || match_usermask(excepts[i], u)) + if (!u || match_usermask(excepts[i], u)) { set_cmode(sender, chan, "-e", excepts[i]); - if (u && u->ipaddr) { + } else 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(excepts[i], tmpbuf)) set_cmode(sender, chan, "-e", excepts[i]); - if (match_wild_nocase(excepts[i], tmpbuf+nicklen)) + else if (match_wild_nocase(excepts[i], tmpbuf+nicklen)) set_cmode(sender, chan, "-e", excepts[i]); } } diff -uNr ircservices-5.0.31/modules/protocol/sjoin.c ircservices-5.0.32/modules/protocol/sjoin.c --- ircservices-5.0.31/modules/protocol/sjoin.c 2004-04-29 09:00:53 +0900 +++ ircservices-5.0.32/modules/protocol/sjoin.c 2004-06-07 19:44:07 +0900 @@ -174,7 +174,7 @@ * or behind the server sending the SJOIN, so we need an * extra MODE to explicitly give ops back to the initial * joining user. */ - send_cmd(ServerName, "MODE %s +o :%s", c->name, u->nick); + send_cmode_cmd(ServerName, c->name, "+o :%s", u->nick); } #endif } diff -uNr ircservices-5.0.31/modules/protocol/trircd.c ircservices-5.0.32/modules/protocol/trircd.c --- ircservices-5.0.31/modules/protocol/trircd.c 2004-04-29 09:00:53 +0900 +++ ircservices-5.0.32/modules/protocol/trircd.c 2004-06-07 19:44:07 +0900 @@ -954,7 +954,7 @@ } } /* String is invalid */ - notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_FLOOD_BAD, mode); + notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_BAD_PARAM, mode); return 1; } /* case 'f' */ @@ -1265,6 +1265,7 @@ remove_callback(NULL, "user MODE", do_user_mode); remove_callback(NULL, "user servicestamp change", do_user_servicestamp_change); + remove_callback(NULL, "channel MODE", do_channel_mode); remove_callback(NULL, "user create", do_user_create); remove_callback(NULL, "receive message", do_receive_message); remove_callback(NULL, "connect", do_connect); diff -uNr ircservices-5.0.31/modules/protocol/unreal.c ircservices-5.0.32/modules/protocol/unreal.c --- ircservices-5.0.31/modules/protocol/unreal.c 2004-04-29 09:00:53 +0900 +++ ircservices-5.0.32/modules/protocol/unreal.c 2004-06-07 19:44:07 +0900 @@ -53,14 +53,19 @@ * to make sure these values are synchronized with the list of modes * below). */ static int32 usermode_admin = 0; /* +aANT */ +static int32 usermode_secure = 0; /* +z */ static int32 usermode_hiding = 0; /* +I */ static int32 chanmode_admins_only = 0; /* +A */ +static int32 chanmode_secure_only = 0; /* +z */ static int32 chanmode_no_hiding = 0; /* +H */ /* This variable holds the version of the Unreal protocol the remote server * is using, extracted from its SERVER message. */ static int unreal_version = 0; +/* Does the remote server support NICKIP? */ +static int has_nickip = 0; + /*************************************************************************/ /****************** Local interface to external symbols ******************/ /*************************************************************************/ @@ -132,9 +137,11 @@ */ #define MI_ADMIN 0x01000000 /* Usermode given to admins */ -#define MI_HIDING 0x02000000 /* Usermode for hiding users */ +#define MI_SECURE 0x02000000 /* Usermode for users on secure conn's */ +#define MI_HIDING 0x04000000 /* Usermode for hiding users */ #define MI_ADMINS_ONLY 0x01000000 /* Chanmode for admin-only channels */ -#define MI_NO_HIDING 0x02000000 /* Chanmode for no-hiding channels */ +#define MI_SECURE_ONLY 0x02000000 /* Chanmode for secure-user-only chans */ +#define MI_NO_HIDING 0x04000000 /* Chanmode for no-hiding channels */ /*************************************************************************/ @@ -159,6 +166,8 @@ {'I', {0x00002000,0,0,0,MI_HIDING}}, /* Completely invisible (joins etc) */ {'d', {0x00004000}}, /* Deaf */ + {'z', {0x00008000,0,0,0,MI_SECURE}}, + /* Using secure connection */ }; /*************************************************************************/ @@ -182,7 +191,8 @@ /* Only opers can join channel */ {'A', {0x00001000,0,0,0,MI_OPERS_ONLY|MI_ADMINS_ONLY}}, /* Only admins can join channel */ - {'z', {0x00002000,0,0}}, /* Only secure (+z) users allowed */ + {'z', {0x00002000,0,0,0,MI_SECURE_ONLY}}, + /* Only secure (+z) users allowed */ {'Q', {0x00004000,0,0}}, /* No kicks */ {'K', {0x00008000,0,0}}, /* No knocks */ {'V', {0x00010000,0,0}}, /* No invites */ @@ -228,6 +238,8 @@ usermodes[new_usermodes[i].mode] = new_usermodes[i].data; if (new_usermodes[i].data.info & MI_ADMIN) usermode_admin |= new_usermodes[i].data.flag; + if (new_usermodes[i].data.info & MI_SECURE) + usermode_secure |= new_usermodes[i].data.flag; if (new_usermodes[i].data.info & MI_HIDING) usermode_hiding |= new_usermodes[i].data.flag; } @@ -235,6 +247,8 @@ chanmodes[new_chanmodes[i].mode] = new_chanmodes[i].data; if (new_chanmodes[i].data.info & MI_ADMINS_ONLY) chanmode_admins_only |= new_chanmodes[i].data.flag; + if (new_chanmodes[i].data.info & MI_SECURE_ONLY) + chanmode_secure_only |= new_chanmodes[i].data.flag; if (new_chanmodes[i].data.info & MI_NO_HIDING) chanmode_no_hiding |= new_chanmodes[i].data.flag; } @@ -252,8 +266,12 @@ static void m_nick(char *source, int ac, char **av) { - char *tmp; - char *newmodes; + char *ipaddr; + char *newav[10]; + +#ifdef CLEAN_COMPILE + ipaddr = NULL; +#endif if (*source) { /* Old user changing nicks. */ @@ -268,10 +286,11 @@ } /* - * New user. Unreal's NICK message takes 10 parameters: + * New user. Unreal's NICK message takes 10 parameters (11 for servers + * supporting NICKIP): * * NICK - * : + * [] : * * Processing consists of: * - Making sure the message has the right number of parameters @@ -287,30 +306,80 @@ * we got from the server for now. */ - if (ac != 10) { + if (ac != (has_nickip ? 11 : 10)) { if (debug) module_log("debug: NICK message: wrong number of parameters (%d)" " for new user", ac); return; } - /* Save the new user's modes modes and strip the parameter out. */ - newmodes = av[7]; - av[7] = av[9]; - /* We keep ac as is because we insert a NULL (IP address) later. */ - - /* Swap parameters so the Services timestamp is in the right place. */ - tmp = av[6]; - av[6] = av[7]; - av[7] = tmp; - - /* Move fakehost into user argument area. */ - av[9] = av[8]; - av[8] = NULL; - if (do_nick(source, ac, av)) { + /* If this is a NICKIP server, decode and save the IP address, then + * strip it out of the parameter list so that the code below sees a + * standard set of parameters regardless of NICKIP support. */ + if (has_nickip) { + if (strcmp(av[9],"*") == 0) { + ipaddr = "0.0.0.0"; + } else { + unsigned char tmpbuf[16]; + const char *badip = NULL; /* error message, or NULL if no error */ + int len = decode_base64(av[9], tmpbuf, sizeof(tmpbuf)); + if (len < 0 || len > sizeof(tmpbuf)) { + badip = "Corrupt IP address"; + } else if (len == 4) { + ipaddr = unpack_ip(tmpbuf); + if (!ipaddr) + badip = "Internal error decoding IPv4 address"; + } else if (len == 16) { + ipaddr = unpack_ip6(tmpbuf); + if (!ipaddr) + badip = "Internal error decoding IPv6 address"; + } else { + badip = "Unrecognized IP address format"; + } + if (badip) { + static int warned_no_nickip = 0; + if (!warned_no_nickip) { + wallops(NULL, "\2WARNING\2: %s for new nick %s", badip, + av[0]); + warned_no_nickip = 1; + } + module_log("WARNING: %s for new nick %s", badip, av[0]); + ipaddr = "0.0.0.0"; + } + av[9] = av[10]; + } + } else { + ipaddr = NULL; + } + + /* Set up parameter list for do_nick(): + * (current) (desired) + * 0: nick nick + * 1: hopcount hopcount + * 2: timestamp timestamp + * 3: username username + * 4: hostname hostname + * 5: server server + * 6: servicestamp realname + * 7: modes servicestamp + * 8: fakehost ipaddr + * 9: realname fakehost + */ + newav[0] = av[0]; + newav[1] = av[1]; + newav[2] = av[2]; + newav[3] = av[3]; + newav[4] = av[4]; + newav[5] = av[5]; + newav[6] = av[9]; + newav[7] = av[6]; + newav[8] = ipaddr; + newav[9] = av[8]; + + if (do_nick(source, 10, newav)) { /* The user was accepted; set modes. */ - av[1] = newmodes; - do_umode(av[0], 2, av); + newav[1] = av[7]; + do_umode(newav[0], 2, newav); } } @@ -328,6 +397,8 @@ got_nickv2 = 1; if (stricmp(av[i], "NOQUIT") == 0) protocol_features |= PF_NOQUIT; + if (stricmp(av[i], "NICKIP") == 0) + has_nickip = 1; } /* Make sure we got a NICKv2 from the remote server; if not, abort. */ if (!got_nickv2) { @@ -752,12 +823,17 @@ const char *modes) { /* NICK - * : */ - /* Note that if SETHOST has not been used, is for VHP + * [] : + * The parameter is only included if the remote server specified + * NICKIP in its PROTOCTL line. + * + * Note that if SETHOST has not been used, is for VHP * servers but "*" for others. We send because that works in - * both cases. */ - send_cmd(NULL, "NICK %s 1 %ld %s %s %s 0 +%s %s :%s", nick, - (long)time(NULL), user, host, server, modes, host, name); + * both cases. + */ + send_cmd(NULL, "NICK %s 1 %ld %s %s %s 0 +%s %s%s :%s", nick, + (long)time(NULL), user, host, server, modes, host, + has_nickip ? " *" : "", name); } /*************************************************************************/ @@ -786,8 +862,8 @@ static void do_send_server(void) { - send_cmd(NULL, - "PROTOCTL SJOIN SJOIN2 SJ3 NICKv2 VHP VL NOQUIT UMODE2 TOKEN"); + send_cmd(NULL, "PROTOCTL SJOIN SJOIN2 SJ3 NICKv2 VHP VL NOQUIT UMODE2" + " TOKEN NICKIP"); send_cmd(NULL, "PASS :%s", RemotePassword); /* Syntax: * SERVER servername hopcount :U-flags-numeric serverdesc @@ -1021,84 +1097,88 @@ * routines. Hooray for feeping creaturism... */ static void unreal_clear_bans_excepts(const char *sender, Channel *chan, - const User *u); + int what, 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); + if (what & (CLEAR_USERS | CLEAR_BANS | CLEAR_EXCEPTS)) { + unreal_clear_bans_excepts(sender, chan, what, + (what & CLEAR_USERS) ? NULL : param); } return 0; } static void unreal_clear_bans_excepts(const char *sender, Channel *chan, - const User *u) + int what, 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)) + if (what & (CLEAR_USERS | CLEAR_BANS)) { + 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); } - 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)) + if (what & (CLEAR_USERS | CLEAR_EXCEPTS)) { + 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); } - free(list); } } @@ -1195,8 +1275,8 @@ /*************************************************************************/ /* - * Callback for ChanServ channel entrance checking; we enforce admin-only - * and no-hiding channel modes here. + * Callback for ChanServ channel entrance checking; we enforce admin-only, + * secure-only, and no-hiding channel modes here. */ static int do_check_kick(User *user, ChannelInfo *ci, char **mask_ret, @@ -1214,6 +1294,14 @@ *reason_ret = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN); return 1; } + /* Don't let users not on secure connections (-z) into +z channels */ + if ((ci->mlock_on & chanmode_secure_only) + && !(user->mode & usermode_secure) + ) { + *mask_ret = create_mask(user, 1); + *reason_ret = getstring(user->ngi, CHAN_NOT_ALLOWED_TO_JOIN); + return 1; + } /* Don't let hiding users into no-hiding channels */ if ((ci->mlock_on & chanmode_no_hiding) && (user->mode & usermode_hiding)){ *mask_ret = create_mask(user, 1); @@ -1325,7 +1413,7 @@ } } /* String is invalid */ - notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_FLOOD_BAD, mode); + notice_lang(s_ChanServ, u, CHAN_SET_MLOCK_BAD_PARAM, mode); return 1; } } diff -uNr ircservices-5.0.31/modules.h ircservices-5.0.32/modules.h --- ircservices-5.0.31/modules.h 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/modules.h 2004-06-07 19:44:06 +0900 @@ -16,7 +16,7 @@ * program (structures, etc.) makes existing binary modules incompatible. * All modules MUST export a variable `module_version' which is initialized * to this constant! */ -#define MODULE_VERSION_CODE 0x05001A /* 5.0.26 */ +#define MODULE_VERSION_CODE 0x050020 /* 5.0.32 */ /*************************************************************************/ diff -uNr ircservices-5.0.31/send.c ircservices-5.0.32/send.c --- ircservices-5.0.31/send.c 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/send.c 2004-06-07 19:44:06 +0900 @@ -176,6 +176,28 @@ /*************************************************************************/ +/* Send a command to change channel modes. (Needed to handle various + * varieties of timestamping. We currently cheat and use a timestamp of + * zero to force our modes through.) + */ + +void send_cmode_cmd(const char *source, const char *channel, + const char *fmt, ...) +{ + va_list args; + char buf[BUFSIZE]; + + va_start(args, fmt); + vsnprintf(buf, sizeof(buf), fmt, args); + va_end(args); + if (protocol_features & PF_MODETS_FIRST) + send_channel_cmd(source, "MODE %s 0 %s", channel, buf); + else + send_channel_cmd(source, "MODE %s %s", channel, buf); +} + +/*************************************************************************/ + /* Send a NOTICE from the given source to the given nick. */ void notice(const char *source, const char *dest, const char *fmt, ...) diff -uNr ircservices-5.0.31/services.h ircservices-5.0.32/services.h --- ircservices-5.0.31/services.h 2004-04-29 09:00:52 +0900 +++ ircservices-5.0.32/services.h 2004-06-07 19:44:06 +0900 @@ -83,6 +83,8 @@ #define PF_CHANGENICK 0x00000040 /* Supports autokill exclusions */ #define PF_AKILL_EXCL 0x00000080 +/* Timestamp in MODE message comes right after channel name */ +#define PF_MODETS_FIRST 0x00000100 /* Invalid flag, used to check whether protocol_features was set */ #define PF_UNSET 0x80000000 diff -uNr ircservices-5.0.31/version.sh ircservices-5.0.32/version.sh --- ircservices-5.0.31/version.sh 2004-04-29 08:55:26 +0900 +++ ircservices-5.0.32/version.sh 2004-06-07 19:37:58 +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.31 +VERSION=5.0.32 # Increment Services build number if [ -f version.c ] ; then