[IRC-Dev CVS] [CVS] Module ircd-ircdev: Change committed
Brought to you by:
zolty
From: Toni G. <zo...@us...> - 2004-11-24 16:07:04
|
CVSROOT : /cvsroot/irc-dev Module : ircd-ircdev Commit time: 2004-11-24 16:06:26 UTC Modified files: ircd/IPcheck.c ircd/Makefile.in ircd/channel.c ircd/class.c ircd/client.c ircd/crule.c ircd/dbuf.c ircd/destruct_event.c ircd/engine_devpoll.c ircd/engine_epoll.c ircd/engine_kqueue.c ircd/engine_poll.c ircd/engine_select.c ircd/fileio.c ircd/gline.c ircd/hash.c ircd/ircd.c ircd/ircd_lexer.l ircd/ircd_parser.y ircd/jupe.c ircd/list.c ircd/listener.c ircd/match.c ircd/motd.c ircd/msgq.c ircd/numnicks.c ircd/opercmds.c ircd/os_generic.c ircd/packet.c ircd/parse.c ircd/querycmds.c ircd/random.c ircd/send.c ircd/table_gen.c ircd/uping.c ircd/userload.c ircd/version.c.SH ircd/whocmds.c ircd/whowas.c Added files: ircd/memdebug.c ircd/umkpasswd.c Removed files: ircd/chkconf.c ircd/fda.c ircd/fda_t.c ircd/iauth.c ircd/ircd_xopen.c ircd/os_bsd.c ircd/os_linux.c ircd/os_openbsd.c ircd/os_solaris.c ircd/res_adns.c ircd/res_libresolv.c ircd/support.c Log message: Author: zoltan <zo...@ir...> Log message: 2004-11-24 Toni García <zo...@ir...> 1.0.alpha13 * Comentarios para Doxygen * Excepciones de Silences * Soporte total de IPv6 * Sincronizacion Undernet ---------------------- diff included ---------------------- Index: ircd-ircdev/ircd/IPcheck.c diff -u ircd-ircdev/ircd/IPcheck.c:1.4 ircd-ircdev/ircd/IPcheck.c:1.5 --- ircd-ircdev/ircd/IPcheck.c:1.4 Fri May 21 08:39:34 2004 +++ ircd-ircdev/ircd/IPcheck.c Wed Nov 24 08:06:14 2004 @@ -18,14 +18,17 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: IPcheck.c,v 1.4 2004/05/21 15:39:34 zolty Exp $ - * + */ +/** @file + * @brief Code to count users connected from particular IP addresses. + * @version $Id: IPcheck.c,v 1.5 2004/11/24 16:06:14 zolty Exp $ */ #include "config.h" #include "IPcheck.h" #include "client.h" #include "ircd.h" +#include "match.h" #include "msg.h" #include "numnicks.h" /* NumNick, NumServ (GODMODE) */ #include "ircd_alloc.h" @@ -38,67 +41,97 @@ #include <assert.h> #include <string.h> +/** Stores free target information for a particular user. */ struct IPTargetEntry { - int count; - unsigned char targets[MAXTARGETS]; + int count; /**< Number of free targets targets. */ + unsigned char targets[MAXTARGETS]; /**< Array of recent targets. */ }; +/** Stores recent information about a particular IP address. */ struct IPRegistryEntry { - struct IPRegistryEntry* next; - struct IPTargetEntry* target; - unsigned int addr; - int last_connect; - unsigned short connected; - unsigned char attempts; + struct IPRegistryEntry* next; /**< Next entry in the hash chain. */ + struct IPTargetEntry* target; /**< Recent targets, if any. */ + struct irc_in_addr addr; /**< IP address for this user. */ + int last_connect; /**< Last connection attempt timestamp. */ + unsigned short connected; /**< Number of currently connected clients. */ + unsigned char attempts; /**< Number of recent connection attempts. */ }; -/* - * Hash table for IPv4 address registry - * - * Hash table size must be a power of 2 - * Use 64K hash table to conserve memory - */ +/** Size of hash table (must be a power of two). */ #define IP_REGISTRY_TABLE_SIZE 0x10000 -#define MASK_16 0xffff - -#define NOW ((unsigned short)(CurrentTime & MASK_16)) +/** Report current time for tracking in IPRegistryEntry::last_connect. */ +#define NOW ((unsigned short)(CurrentTime & 0xffff)) +/** Time from \a x until now, in seconds. */ #define CONNECTED_SINCE(x) (NOW - (x)) +/** Macro for easy access to configured IPcheck clone limit. */ #define IPCHECK_CLONE_LIMIT feature_int(FEAT_IPCHECK_CLONE_LIMIT) +/** Macro for easy access to configured IPcheck clone period. */ #define IPCHECK_CLONE_PERIOD feature_int(FEAT_IPCHECK_CLONE_PERIOD) +/** Macro for easy access to configured IPcheck clone delay. */ #define IPCHECK_CLONE_DELAY feature_int(FEAT_IPCHECK_CLONE_DELAY) - +/** Hash table for storing IPRegistryEntry entries. */ static struct IPRegistryEntry* hashTable[IP_REGISTRY_TABLE_SIZE]; -static struct IPRegistryEntry* freeList = 0; - +/** List of allocated but unused IPRegistryEntry structs. */ +static struct IPRegistryEntry* freeList; +/** Periodic timer to look for too-old registry entries. */ static struct Timer expireTimer; -static unsigned int ip_registry_hash(unsigned int ip) -{ - return ((ip >> 16) ^ ip) & (IP_REGISTRY_TABLE_SIZE - 1); -} - -static struct IPRegistryEntry* ip_registry_find(unsigned int ip) +/** Calculate hash value for an IP address. + * If this looks like an IPv6 address, only consider the first 64 bits + * of the address. Otherwise, only consider the final 32 bits. + * @param[in] ip Address to hash. + * @return Hash value for address. + */ +static unsigned int ip_registry_hash(const struct irc_in_addr *ip) +{ + unsigned int res; + + if (ip->in6_16[0] || ip->in6_16[1] || ip->in6_16[2] || ip->in6_16[3] || ip->in6_16[4]) { + /* Only use the first 64 bits of address, since the last 64 bits + * tend to be under user control. */ + res = ip->in6_16[0] ^ ip->in6_16[1] ^ ip->in6_16[2] ^ ip->in6_16[3]; + } else { + /* Looks like an IPv4 address. */ + res = ip->in6_16[6] ^ ip->in6_16[7]; + } + return res & (IP_REGISTRY_TABLE_SIZE - 1); +} + +/** Find an IP registry entry if one exists for the IP address. + * If \a ip looks like an IPv6 address, only consider the first 64 bits + * of the address. Otherwise, only consider the final 32 bits. + * @param[in] ip IP address to search for. + * @return Matching registry entry, or NULL if none exists. + */ +static struct IPRegistryEntry* ip_registry_find(const struct irc_in_addr *ip) { struct IPRegistryEntry* entry = hashTable[ip_registry_hash(ip)]; for ( ; entry; entry = entry->next) { - if (entry->addr == ip) + int bits = (ip->in6_16[0] || ip->in6_16[1] || ip->in6_16[2] || ip->in6_16[3] || ip->in6_16[4]) ? 64 : 128; + if (ipmask_check(ip, &entry->addr, bits)) break; } return entry; } +/** Add an IP registry entry to the hash table. + * @param[in] entry Registry entry to add. + */ static void ip_registry_add(struct IPRegistryEntry* entry) { - unsigned int bucket = ip_registry_hash(entry->addr); + unsigned int bucket = ip_registry_hash(&entry->addr); entry->next = hashTable[bucket]; hashTable[bucket] = entry; } - + +/** Remove an IP registry entry from the hash table. + * @param[in] entry Registry entry to add. + */ static void ip_registry_remove(struct IPRegistryEntry* entry) { - unsigned int bucket = ip_registry_hash(entry->addr); + unsigned int bucket = ip_registry_hash(&entry->addr); if (hashTable[bucket] == entry) hashTable[bucket] = entry->next; else { @@ -111,7 +144,11 @@ } } } - + +/** Allocate a new IP registry entry. + * For members that have a sensible default value, that is used. + * @return Newly allocated registry entry. + */ static struct IPRegistryEntry* ip_registry_new_entry() { struct IPRegistryEntry* entry = freeList; @@ -128,6 +165,10 @@ return entry; } +/** Deallocate memory for \a entry. + * The entry itself is prepended to #freeList. + * @param[in] entry IP registry entry to release. + */ static void ip_registry_delete_entry(struct IPRegistryEntry* entry) { if (entry->target) @@ -136,6 +177,9 @@ freeList = entry; } +/** Update free target count for \a entry. + * @param[in,out] entry IP registry entry to update. + */ static unsigned int ip_registry_update_free_targets(struct IPRegistryEntry* entry) { unsigned int free_targets = STARTTARGETS; @@ -149,6 +193,11 @@ return free_targets; } +/** Check whether all or part of \a entry needs to be expired. + * If the entry is at least 600 seconds stale, free the entire thing. + * If it is at least 120 seconds stale, expire its free targets list. + * @param[in] entry Registry entry to check for expiration. + */ static void ip_registry_expire_entry(struct IPRegistryEntry* entry) { /* @@ -171,7 +220,9 @@ } } -/* Callback to run an expiry of the IPcheck registry */ +/** Periodic timer callback to check for expired registry entries. + * @param[in] ev Timer event (ignored). + */ static void ip_registry_expire(struct Event* ev) { int i; @@ -190,50 +241,28 @@ } } -/* - * IPcheck_init() - * - * Initializes the registry timer - */ +/** Initialize the IPcheck subsystem. */ void IPcheck_init(void) { timer_add(timer_init(&expireTimer), ip_registry_expire, 0, TT_PERIODIC, 60); } -/* - * IPcheck_local_connect - * - * Event: - * A new connection was accept()-ed with IP number `cptr->ip.s_addr'. - * - * Action: - * Update the IPcheck registry. - * Return: - * 1 : You're allowed to connect. - * 0 : You're not allowed to connect. - * - * Throttling: - * - * A connection should be rejected when a connection from the same IP number was - * received IPCHECK_CLONE_LIMIT times before this connect attempt, with - * reconnect intervals of IPCHECK_CLONE_PERIOD seconds or less. - * - * Free target inheritance: - * - * When the client is accepted, then the number of Free Targets - * of the cptr is set to the value stored in the found IPregistry - * structure, or left at STARTTARGETS. This can be done by changing - * cptr->nexttarget to be `now - (TARGET_DELAY * (FREE_TARGETS - 1))', - * where FREE_TARGETS may range from 0 till STARTTARGETS. +/** Check whether a new connection from a local client should be allowed. + * A connection is rejected if someone from the "same" address (see + * ip_registry_find()) connects IPCHECK_CLONE_LIMIT times, each time + * separated by no more than IPCHECK_CLONE_PERIOD seconds. + * @param[in] addr Address of client. + * @param[out] next_target_out Receives time to grant another free target. + * @return Non-zero if the connection is permitted, zero if denied. */ -int ip_registry_check_local(unsigned int addr, time_t* next_target_out) +int ip_registry_check_local(const struct irc_in_addr *addr, time_t* next_target_out) { struct IPRegistryEntry* entry = ip_registry_find(addr); unsigned int free_targets = STARTTARGETS; - + if (0 == entry) { entry = ip_registry_new_entry(); - entry->addr = addr; /* The IP number of registry entry */ + memcpy(&entry->addr, addr, sizeof(entry->addr)); ip_registry_add(entry); return 1; } @@ -276,20 +305,17 @@ return 1; } -/* - * IPcheck_remote_connect - * - * Event: - * A remote client connected to Undernet, with IP number `cptr->ip.s_addr' - * and hostname `hostname'. - * - * Action: - * Update the IPcheck registry. - * Return 0 on failure, 1 on success. +/** Check whether a connection from a remote client should be allowed. + * This is much more relaxed than ip_registry_check_local(): The only + * cause for rejection is when the IPRegistryEntry::connected counter + * would overflow. + * @param[in] cptr Client that has connected. + * @param[in] is_burst Non-zero if client was introduced during a burst. + * @return Non-zero if the client should be accepted, zero if they must be killed. */ int ip_registry_check_remote(struct Client* cptr, int is_burst) { - struct IPRegistryEntry* entry = ip_registry_find((cli_ip(cptr)).s_addr); + struct IPRegistryEntry* entry = ip_registry_find(&cli_ip(cptr)); /* * Mark that we did add/update an IPregistry entry @@ -297,7 +323,7 @@ SetIPChecked(cptr); if (0 == entry) { entry = ip_registry_new_entry(); - entry->addr = (cli_ip(cptr)).s_addr; + memcpy(&entry->addr, &cli_ip(cptr), sizeof(entry->addr)); if (is_burst) entry->attempts = 0; ip_registry_add(entry); @@ -325,40 +351,32 @@ return 1; } -/* - * IPcheck_connect_fail - * - * Event: - * This local client failed to connect due to legal reasons. - * - * Action: - * Neutralize the effect of calling IPcheck_local_connect, in such - * a way that the client won't be penalized when trying to reconnect - * again. +/** Handle a client being rejected during connection through no fault + * of their own. This "undoes" the effect of ip_registry_check_local() + * so the client's address is not penalized for the failure. + * @param[in] addr Address of rejected client. */ -void ip_registry_connect_fail(unsigned int addr) +void ip_registry_connect_fail(const struct irc_in_addr *addr) { struct IPRegistryEntry* entry = ip_registry_find(addr); - if (entry) + if (entry) { if (0 == --entry->attempts) - ++entry->attempts; /* check for overflow */ + ++entry->attempts; } } -/* - * IPcheck_connect_succeeded - * - * Event: - * A client succeeded to finish the registration. - * - * Finish IPcheck registration of a successfully, locally connected client. +/** Handle a client that has successfully connected. + * This copies free target information to \a cptr from his address's + * registry entry and sends him a NOTICE describing the parameters for + * the entry. + * @param[in,out] cptr Client that has successfully connected. */ void ip_registry_connect_succeeded(struct Client *cptr) { const char* tr = ""; unsigned int free_targets = STARTTARGETS; - struct IPRegistryEntry* entry = ip_registry_find((cli_ip(cptr)).s_addr); + struct IPRegistryEntry* entry = ip_registry_find(&cli_ip(cptr)); if (!entry) { Debug((DEBUG_ERROR, "Missing registry entry for: %s", cli_sock_ip(cptr))); @@ -374,20 +392,14 @@ free_targets, STARTTARGETS, tr); } -/* - * IPcheck_disconnect - * - * Event: - * A local client disconnected or a remote client left Undernet. - * - * Action: - * Update the IPcheck registry. - * Remove all expired IPregistry structures from the hash bucket - * that belongs to this clients IP number. +/** Handle a client that decided to disconnect (or was killed after + * completing his connection). This updates the free target + * information for his IP registry entry. + * @param[in] cptr Client that has exited. */ void ip_registry_disconnect(struct Client *cptr) { - struct IPRegistryEntry* entry = ip_registry_find((cli_ip(cptr)).s_addr); + struct IPRegistryEntry* entry = ip_registry_find(&cli_ip(cptr)); if (0 == entry) { /* * trying to find an entry for a server causes this to happen, @@ -458,59 +470,31 @@ } } -/* - * IPcheck_nr - * - * Returns number of clients with the same IP number +/** Find number of clients from a particular IP address. + * @param[in] addr Address to look up. + * @return Number of clients known to be connected from that address. */ -int ip_registry_count(unsigned int addr) +int ip_registry_count(const struct irc_in_addr *addr) { struct IPRegistryEntry* entry = ip_registry_find(addr); return (entry) ? entry->connected : 0; } -/* - * IPcheck_local_connect - * - * Event: - * A new connection was accept()-ed with IP number `cptr->ip.s_addr'. - * - * Action: - * Update the IPcheck registry. - * Return: - * 1 : You're allowed to connect. - * 0 : You're not allowed to connect. - * - * Throttling: - * - * A connection should be rejected when a connection from the same IP number was - * received IPCHECK_CLONE_LIMIT times before this connect attempt, with - * reconnect intervals of IPCHECK_CLONE_PERIOD seconds or less. - * - * Free target inheritance: - * - * When the client is accepted, then the number of Free Targets - * of the cptr is set to the value stored in the found IPregistry - * structure, or left at STARTTARGETS. This can be done by changing - * cptr->nexttarget to be `now - (TARGET_DELAY * (FREE_TARGETS - 1))', - * where FREE_TARGETS may range from 0 till STARTTARGETS. +/** Check whether a client is allowed to connect locally. + * @param[in] a Address of client. + * @param[out] next_target_out Receives time to grant another free target. + * @return Non-zero if the connection is permitted, zero if denied. */ -int IPcheck_local_connect(struct in_addr a, time_t* next_target_out) +int IPcheck_local_connect(const struct irc_in_addr *a, time_t* next_target_out) { assert(0 != next_target_out); - return ip_registry_check_local(a.s_addr, next_target_out); + return ip_registry_check_local(a, next_target_out); } -/* - * IPcheck_remote_connect - * - * Event: - * A remote client connected to Undernet, with IP number `cptr->ip.s_addr' - * and hostname `hostname'. - * - * Action: - * Update the IPcheck registry. - * Return 0 on failure, 1 on success. +/** Check whether a client is allowed to connect remotely. + * @param[in] cptr Client that has connected. + * @param[in] is_burst Non-zero if client was introduced during a burst. + * @return Non-zero if the client should be accepted, zero if they must be killed. */ int IPcheck_remote_connect(struct Client *cptr, int is_burst) { @@ -518,29 +502,21 @@ return ip_registry_check_remote(cptr, is_burst); } -/* - * IPcheck_connect_fail - * - * Event: - * This local client failed to connect due to legal reasons. - * - * Action: - * Neutralize the effect of calling IPcheck_local_connect, in such - * a way that the client won't be penalized when trying to reconnect - * again. - */ -void IPcheck_connect_fail(struct in_addr a) -{ - ip_registry_connect_fail(a.s_addr); -} - -/* - * IPcheck_connect_succeeded - * - * Event: - * A client succeeded to finish the registration. - * - * Finish IPcheck registration of a successfully, locally connected client. +/** Handle a client being rejected during connection through no fault + * of their own. This "undoes" the effect of ip_registry_check_local() + * so the client's address is not penalized for the failure. + * @param[in] a Address of rejected client. + */ +void IPcheck_connect_fail(const struct irc_in_addr *a) +{ + ip_registry_connect_fail(a); +} + +/** Handle a client that has successfully connected. + * This copies free target information to \a cptr from his address's + * registry entry and sends him a NOTICE describing the parameters for + * the entry. + * @param[in,out] cptr Client that has successfully connected. */ void IPcheck_connect_succeeded(struct Client *cptr) { @@ -548,16 +524,10 @@ ip_registry_connect_succeeded(cptr); } -/* - * IPcheck_disconnect - * - * Event: - * A local client disconnected or a remote client left Undernet. - * - * Action: - * Update the IPcheck registry. - * Remove all expired IPregistry structures from the hash bucket - * that belongs to this clients IP number. +/** Handle a client that decided to disconnect (or was killed after + * completing his connection). This updates the free target + * information for his IP registry entry. + * @param[in] cptr Client that has exited. */ void IPcheck_disconnect(struct Client *cptr) { @@ -565,13 +535,12 @@ ip_registry_disconnect(cptr); } -/* - * IPcheck_nr - * - * Returns number of clients with the same IP number +/** Find number of clones of a client. + * @param[in] cptr Client whose address to look up. + * @return Number of clients known to be connected from that address. */ unsigned short IPcheck_nr(struct Client *cptr) { assert(0 != cptr); - return ip_registry_count(cli_ip(cptr).s_addr); + return ip_registry_count(&cli_ip(cptr)); } Index: ircd-ircdev/ircd/Makefile.in diff -u ircd-ircdev/ircd/Makefile.in:1.12 ircd-ircdev/ircd/Makefile.in:1.13 --- ircd-ircdev/ircd/Makefile.in:1.12 Wed Nov 17 03:45:49 2004 +++ ircd-ircdev/ircd/Makefile.in Wed Nov 24 08:06:14 2004 @@ -18,7 +18,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA -# $Id: Makefile.in,v 1.12 2004/11/17 11:45:49 zolty Exp $ +# $Id: Makefile.in,v 1.13 2004/11/24 16:06:14 zolty Exp $ #### Start of system configuration section. #### @@ -35,8 +35,6 @@ RM = @RMPROG@ AWK = @AWK@ LN_S = @LN_S@ -LEX = @LEX@ -YACC = @YACC@ MV = mv CHMOD = chmod CHOWN = chown @@ -44,9 +42,9 @@ MKDIR = mkdir TOUCH = touch GREP = grep -OSDEP_C = @OSDEP_C@ +LEX = @LEX@ +YACC = @YACC@ ENGINE_C = @ENGINE_C@ -RES_C = @RES_C@ @SET_MAKE@ BINDIR = @bindir@ @@ -62,7 +60,6 @@ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = -I. -I.. -I${top_srcdir}/include @CPPFLAGS@ -#CPPFLAGS = -I. -I.. -I${top_srcdir}/include -I${top_srcdir}/libs/adns/src @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ @@ -70,13 +67,6 @@ PURIFY = RINGLOG_O = -OSDEP_SRC = \ - os_bsd.c \ - os_linux.c \ - os_openbsd.c \ - os_generic.c \ - os_solaris.c - ENGINE_SRC = \ engine_devpoll.c \ engine_epoll.c \ @@ -84,9 +74,16 @@ engine_kqueue.c \ engine_select.c -RES_SRC = \ - res_adns.c \ - res_libresolv.c +CRYPTO_SRC = \ + ircd_md5.c \ + ircd_crypt_plain.c \ + ircd_crypt_smd5.c \ + ircd_crypt_native.c + +UMKPASSWD_SRC = ${CRYPTO_SRC} \ + ircd_alloc.c \ + ircd_string.c \ + umkpasswd.c IRCD_SRC = \ IPcheck.c \ @@ -97,22 +94,24 @@ dbuf.c \ ddb.c \ destruct_event.c \ - fda.c \ fileio.c \ gline.c \ hash.c \ ircd.c \ ircd_alloc.c \ + ircd_auth.c \ + ircd_crypt.c \ ircd_events.c \ ircd_features.c \ ircd_log.c \ ircd_relay.c \ ircd_reply.c \ + ircd_res.c \ + ircd_reslib.c \ ircd_signal.c \ ircd_snprintf.c \ ircd_string.c \ ircd_tea.c \ - ircd_xopen.c \ jupe.c \ lex.yy.c \ list.c \ @@ -194,10 +193,12 @@ m_whois.c \ m_whowas.c \ match.c \ + memdebug.c \ motd.c \ msgq.c \ numnicks.c \ opercmds.c \ + os_generic.c \ packet.c \ parse.c \ querycmds.c \ @@ -213,7 +214,6 @@ s_stats.c \ s_user.c \ send.c \ - support.c \ uping.c \ userload.c \ watch.c \ @@ -221,13 +221,13 @@ whowas.c \ y.tab.c -CHKCONF_SRC = chkconf.c - -SRC = ${IRCD_SRC} ${OSDEP_C} ${ENGINE_C} ${RES_C} +SRC = ${IRCD_SRC} ${ENGINE_C} ${CRYPTO_SRC} OBJS = ${SRC:%.c=%.o} -DEP_SRC = ${IRCD_SRC} ${OSDEP_SRC} ${ENGINE_SRC} ${CHKCONF_SRC} +UMKPASSWD_OBJS = ${UMKPASSWD_SRC:%.c=%.o} + +DEP_SRC = ${IRCD_SRC} ${ENGINE_SRC} ${CRYPTO_SRC} all: ( cd ..; make -f Makefile ) @@ -240,7 +240,7 @@ build: ircd ircd: ${OBJS} ../include/patchlevel.h version.o - ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} ${OBJS} version.o ${RINGLOG_O} ${LDFLAGS} ${LIBS} \ + ${PURIFY} ${CC} ${OBJS} version.o ${RINGLOG_O} ${LDFLAGS} ${LIBS} \ -o ircd ${CHMOD} ${IRCDMODE} ircd @@ -254,14 +254,13 @@ # must be a better solution...perhaps sum all of the .c files and include # only that one sum? # -version.c: version.c.SH s_serv.c s_user.c channel.c s_bsd.c s_misc.c ircd.c \ - ../include/version.h ../include/patchlevel.h - ${SHELL} ${srcdir}/version.c.SH ${srcdir} +version.c: version.c.SH umkpasswd + ${SHELL} ${srcdir}/version.c.SH ${top_srcdir} ircd_string.o: ircd_string.c chattr.tab.c table_gen: table_gen.o - ${CC} ${CFLAGS} ${LDFLAGS} -o $@ table_gen.o + ${CC} ${LDFLAGS} -o $@ table_gen.o chattr.tab.c: table_gen ./table_gen > chattr.tab.c @@ -272,13 +271,8 @@ y.tab.c y.tab.h: ircd_parser.y ${YACC} -d ${srcdir}/ircd_parser.y -chkcrule.o: crule.c - ${CC} ${CFLAGS} ${CPPFLAGS} -DCR_CHKCONF -o chkcrule.o -c \ - ${srcdir}/crule.c - -chkconf: chkconf.o fda.o match.o chkcrule.o ircd_alloc.o fileio.o ircd_string.o - ${CC} chkconf.o fda.o match.o chkcrule.o ircd_alloc.o fileio.o \ - ircd_string.o ${CFLAGS} ${LDFLAGS} ${LIBS} -o chkconf +umkpasswd: ${UMKPASSWD_OBJS} + ${CC} ${LDFLAGS} ${UMKPASSWD_OBJS} ${LIBS} -o $@ mkbindir: @test -d ${BINDIR} || mkdir ${BINDIR} @@ -300,8 +294,9 @@ ${RM} -f ${SYMLINK}; \ ${LN_S} ircd.`cat /tmp/ircd.tag` ${SYMLINK}; ) @${RM} /tmp/ircd.tag -# ${INSTALL} -s -m 700 -o ${IRCDOWN} -g ${IRCDGRP} chkconf ${BINDIR} + ${INSTALL} -s -m 700 -o ${IRCDOWN} -g ${IRCDGRP} umkpasswd ${BINDIR} ${INSTALL} -m 600 -o ${IRCDOWN} -g ${IRCDGRP} ${top_srcdir}/doc/ircd.sample-en.conf ${DPATH} + ${INSTALL} -m 600 -o ${IRCDOWN} -g ${IRCDGRP} ${top_srcdir}/doc/ircd.sample-es.conf ${DPATH} # ( cd ${DPATH}; \ # ${TOUCH} ${MPATH}; \ # ${TOUCH} ${RPATH}; \ @@ -318,8 +313,8 @@ fi @echo "Installing new ircd as ${BINDIR}/ircd :" ${INSTALL} -m ${IRCDMODE} -o ${IRCDOWN} -g ${IRCDGRP} ircd ${BINDIR}/ircd -# ${INSTALL} -s -m 700 -o ${IRCDOWN} -g ${IRCDGRP} chkconf ${BINDIR} - ${INSTALL} -m 600 -o ${IRCDOWN} -g ${IRCDGRP} ${top_srcdir}/doc/en/ircd.sample-en.conf ${DPATH} + ${INSTALL} -m 600 -o ${IRCDOWN} -g ${IRCDGRP} ${top_srcdir}/doc/ircd.sample-en.conf ${DPATH} + ${INSTALL} -m 600 -o ${IRCDOWN} -g ${IRCDGRP} ${top_srcdir}/doc/ircd.sample-es.conf ${DPATH} # ( cd ${DPATH}; \ # ${TOUCH} ${MPATH}; \ # ${TOUCH} ${RPATH}; \ @@ -328,13 +323,13 @@ uninstall: @if [ "${BINDIR}" != "${DPATH}" ]; then \ - echo "${RM} -f ${BINDIR}/${SYMLINK} ${BINDIR}/ircd.9* ${BINDIR}/chkconf"; \ - ${RM} -f ${BINDIR}/${SYMLINK} ${BINDIR}/ircd.9* ${BINDIR}/chkconf; \ + echo "${RM} -f ${BINDIR}/${SYMLINK} ${BINDIR}/ircd.9*"; \ + ${RM} -f ${BINDIR}/${SYMLINK} ${BINDIR}/ircd.9*; \ fi @echo "Please remove the contents of ${DPATH} manually" clean: - ${RM} -f *.o *.bak ircd version.c chkconf ircd_osdep.c chattr.tab.c table_gen y.tab.* lex.yy.* + ${RM} -f *.o *.bak ircd version.c umkpasswd ircd_osdep.c chattr.tab.c table_gen y.tab.* lex.yy.* distclean: clean ${RM} -f Makefile stamp-m @@ -371,7 +366,7 @@ # ../config/config.h: # @cd ../config; ${MAKE} config.h -# DO NOT DELETE THIS LINE -- make depend depends on it. +# DO NOT DELETE THIS LINE (or the blank line after it) -- make depend depends on them. IPcheck.o: IPcheck.c ../config.h ../include/IPcheck.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ @@ -390,7 +385,7 @@ ../include/msg.h ../include/numeric.h ../include/numnicks.h \ ../include/querycmds.h ../include/s_bsd.h ../include/s_conf.h \ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \ - ../include/send.h ../include/support.h ../include/sys.h \ + ../include/send.h ../include/sys.h \ ../include/whowas.h class.o: class.c ../config.h ../include/class.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ @@ -430,7 +425,7 @@ ../include/ircd_snprintf.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/match.h ../include/numeric.h \ ../include/s_bsd.h ../include/s_debug.h ../include/s_misc.h \ - ../include/s_stats.h ../include/send.h ../include/support.h \ + ../include/s_stats.h ../include/send.h \ ../include/msg.h ../include/numnicks.h ../include/sys.h \ ../include/whocmds.h hash.o: hash.c ../config.h ../include/hash.h ../include/client.h \ @@ -438,7 +433,7 @@ ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \ ../include/ircd_chattr.h ../include/ircd_string.h ../include/ircd.h \ ../include/struct.h ../include/msg.h ../include/send.h \ - ../include/support.h ../include/sys.h ../include/watch.h + ../include/sys.h ../include/watch.h ircd.o: ircd.c ../config.h ../include/ircd.h ../include/struct.h \ ../include/ircd_defs.h ../include/IPcheck.h ../include/class.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ @@ -471,7 +466,7 @@ ../include/msg.h ../include/numeric.h ../include/numnicks.h \ ../include/random.h ../include/s_bsd.h ../include/s_debug.h \ ../include/s_misc.h ../include/s_stats.h ../include/send.h \ - ../include/support.h ../include/sys.h ../include/whowas.h + ../include/sys.h ../include/whowas.h ircd_log.o: ircd_log.c ../config.h ../include/ircd_log.h \ ../include/client.h ../include/ircd_defs.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ @@ -506,7 +501,6 @@ ../include/ircd_chattr.h ../include/ircd_defs.h ../include/ircd_log.h \ chattr.tab.c ircd_tea.o: ircd_tea.c ../config.h -ircd_xopen.o: ircd_xopen.c ../config.h ../include/ircd_xopen.h jupe.o: jupe.c ../config.h ../include/jupe.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/hash.h \ @@ -515,7 +509,7 @@ ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/s_bsd.h \ - ../include/s_misc.h ../include/send.h ../include/support.h \ + ../include/s_misc.h ../include/send.h \ ../include/sys.h lex.yy.o: lex.yy.c ../include/ircd.h ../include/struct.h \ ../include/ircd_defs.h y.tab.h @@ -527,7 +521,7 @@ ../include/match.h ../include/numeric.h ../include/res.h \ ../include/s_auth.h ../include/s_bsd.h ../include/s_conf.h \ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \ - ../include/send.h ../include/support.h ../include/whowas.h + ../include/send.h ../include/whowas.h listener.o: listener.c ../config.h ../include/listener.h \ ../include/ircd_defs.h ../include/ircd_events.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \ @@ -567,7 +561,7 @@ ../include/ircd_chattr.h ../include/ircd_snprintf.h ../include/list.h \ ../include/match.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/s_conf.h ../include/s_misc.h \ - ../include/send.h ../include/support.h + ../include/send.h m_clearmode.o: m_clearmode.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \ @@ -576,7 +570,7 @@ ../include/ircd_log.h ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/list.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/send.h ../include/support.h + ../include/send.h m_close.o: m_close.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/ircd.h \ @@ -661,7 +655,7 @@ ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ ../include/msg.h ../include/numeric.h ../include/numnicks.h \ ../include/s_conf.h ../include/s_misc.h ../include/send.h \ - ../include/support.h + m_help.o: m_help.c ../config.h ../include/client.h ../include/ircd_defs.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_events.h \ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \ @@ -703,7 +697,7 @@ ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/s_misc.h ../include/send.h ../include/support.h + ../include/s_misc.h ../include/send.h m_kick.o: m_kick.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ @@ -795,10 +789,10 @@ ../include/ircd_handler.h ../include/hash.h ../include/ircd.h \ ../include/struct.h ../include/ircd_features.h ../include/ircd_log.h \ ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/ircd_xopen.h ../include/msg.h \ + ../include/ircd_chattr.h ../include/msg.h \ ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ ../include/s_conf.h ../include/s_debug.h ../include/s_user.h \ - ../include/s_misc.h ../include/send.h ../include/support.h + ../include/s_misc.h ../include/send.h m_opmode.o: m_opmode.c ../config.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ ../include/ircd_events.h ../include/ircd_handler.h ../include/channel.h \ @@ -1051,7 +1045,7 @@ ../include/ircd_features.h ../include/ircd_log.h \ ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \ ../include/numeric.h ../include/numnicks.h ../include/send.h \ - ../include/support.h ../include/whocmds.h + ../include/whocmds.h m_whois.o: m_whois.c ../config.h ../include/channel.h \ ../include/ircd_defs.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_events.h ../include/ircd_handler.h \ @@ -1145,7 +1139,7 @@ ../include/packet.h ../include/parse.h ../include/querycmds.h \ ../include/res.h ../include/s_auth.h ../include/s_conf.h \ ../include/s_debug.h ../include/s_misc.h ../include/s_user.h \ - ../include/send.h ../include/support.h ../include/sys.h \ + ../include/send.h ../include/sys.h \ ../include/uping.h ../include/version.h s_conf.o: s_conf.c ../config.h ../include/s_conf.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ @@ -1159,7 +1153,7 @@ ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \ ../include/parse.h ../include/res.h ../include/s_bsd.h \ ../include/s_debug.h ../include/s_misc.h ../include/send.h \ - ../include/support.h ../include/sys.h + ../include/sys.h s_debug.o: s_debug.c ../config.h ../include/s_debug.h \ ../include/ircd_defs.h ../include/channel.h ../include/class.h \ ../include/client.h ../include/dbuf.h ../include/msgq.h \ @@ -1185,7 +1179,7 @@ ../include/parse.h ../include/querycmds.h ../include/res.h \ ../include/s_bsd.h ../include/s_conf.h ../include/s_debug.h \ ../include/s_stats.h ../include/s_user.h ../include/send.h \ - ../include/support.h ../include/sys.h ../include/uping.h \ + ../include/sys.h ../include/uping.h \ ../include/userload.h ../include/watch.h s_numeric.o: s_numeric.c ../config.h ../include/s_numeric.h \ ../include/channel.h ../include/ircd_defs.h ../include/client.h \ @@ -1200,7 +1194,7 @@ ../include/ircd.h ../include/struct.h ../include/ircd_alloc.h \ ../include/ircd_reply.h ../include/ircd_string.h \ ../include/ircd_chattr.h ../include/ircd_snprintf.h \ - ../include/ircd_xopen.h ../include/jupe.h ../include/list.h \ + ../include/jupe.h ../include/list.h \ ../include/match.h ../include/msg.h ../include/numeric.h \ ../include/numnicks.h ../include/parse.h ../include/querycmds.h \ ../include/ircd_features.h ../include/s_bsd.h ../include/s_conf.h \ @@ -1230,7 +1224,7 @@ ../include/numeric.h ../include/numnicks.h ../include/parse.h \ ../include/querycmds.h ../include/random.h ../include/s_bsd.h \ ../include/s_conf.h ../include/s_debug.h ../include/s_misc.h \ - ../include/s_serv.h ../include/send.h ../include/support.h \ + ../include/s_serv.h ../include/send.h \ ../include/supported.h ../include/sys.h ../include/userload.h \ ../include/version.h ../include/watch.h ../include/whowas.h \ ../include/handlers.h @@ -1243,7 +1237,7 @@ ../include/match.h ../include/msg.h ../include/numnicks.h \ ../include/parse.h ../include/s_bsd.h ../include/s_debug.h \ ../include/s_misc.h ../include/s_user.h ../include/sys.h -support.o: support.c ../config.h ../include/support.h ../include/fileio.h \ +support.o: support.c ../config.h ../include/fileio.h \ ../include/ircd.h ../include/struct.h ../include/ircd_defs.h \ ../include/ircd_chattr.h ../include/ircd_snprintf.h ../include/s_bsd.h \ ../include/s_debug.h ../include/send.h ../include/sys.h @@ -1280,7 +1274,7 @@ ../include/numeric.h ../include/numnicks.h ../include/querycmds.h \ ../include/random.h ../include/s_bsd.h ../include/s_conf.h \ ../include/s_misc.h ../include/s_user.h ../include/send.h \ - ../include/support.h ../include/sys.h ../include/userload.h \ + ../include/sys.h ../include/userload.h \ ../include/version.h ../include/whowas.h ../include/msg.h whowas.o: whowas.c ../config.h ../include/whowas.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ @@ -1288,7 +1282,7 @@ ../include/struct.h ../include/ircd_alloc.h ../include/ircd_chattr.h \ ../include/ircd_features.h ../include/ircd_string.h ../include/list.h \ ../include/numeric.h ../include/s_debug.h ../include/s_misc.h \ - ../include/s_user.h ../include/send.h ../include/support.h \ + ../include/s_user.h ../include/send.h \ ../include/sys.h ../include/msg.h y.tab.o: y.tab.c ../config.h ../include/s_conf.h ../include/client.h \ ../include/ircd_defs.h ../include/dbuf.h ../include/msgq.h \ @@ -1302,7 +1296,7 @@ ../include/numeric.h ../include/numnicks.h ../include/opercmds.h \ ../include/parse.h ../include/res.h ../include/s_bsd.h \ ../include/s_debug.h ../include/s_misc.h ../include/send.h \ - ../include/support.h ../include/sys.h + ../include/sys.h os_bsd.o: os_bsd.c ../config.h ../include/ircd_osdep.h ../include/msgq.h \ ../include/ircd_defs.h os_linux.o: os_linux.c ../config.h ../include/ircd_osdep.h \ Index: ircd-ircdev/ircd/channel.c diff -u ircd-ircdev/ircd/channel.c:1.8 ircd-ircdev/ircd/channel.c:1.9 --- ircd-ircdev/ircd/channel.c:1.8 Wed Nov 17 03:45:50 2004 +++ ircd-ircdev/ircd/channel.c Wed Nov 24 08:06:14 2004 @@ -18,8 +18,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: channel.c,v 1.8 2004/11/17 11:45:50 zolty Exp $ - * + */ +/** @file + * @brief Channel management and maintanance + * @version $Id: channel.c,v 1.9 2004/11/24 16:06:14 zolty Exp $ */ #include "config.h" @@ -50,7 +52,6 @@ #include "s_user.h" #include "send.h" #include "struct.h" -#include "support.h" #include "sys.h" #include "whowas.h" @@ -59,32 +60,20 @@ #include <stdlib.h> #include <string.h> +/** Linked list containing the full list of all channels */ struct Channel* GlobalChannelList = 0; +/** Number of struct Membership*'s allocated */ static unsigned int membershipAllocCount; +/** Freelist for struct Membership*'s */ static struct Membership* membershipFreeList; - -void del_invite(struct Client *, struct Channel *); - -const char* const PartFmt1 = ":%s " MSG_PART " %s"; -const char* const PartFmt2 = ":%s " MSG_PART " %s :%s"; -const char* const PartFmt1serv = "%s%s " TOK_PART " %s"; -const char* const PartFmt2serv = "%s%s " TOK_PART " %s :%s"; - - -static struct SLink* next_ban; -static struct SLink* prev_ban; -static struct SLink* removed_bans_list; - -/* - * Use a global variable to remember if an oper set a mode on a local channel. Ugly, - * but the only way to do it without changing set_mode intensively. - */ -int LocalChanOperMode = 0; +/** Freelist for struct Ban*'s */ +static struct Ban* free_bans; #if !defined(NDEBUG) -/* - * return the length (>=0) of a chain of links. +/** return the length (>=0) of a chain of links. + * @param lp pointer to the start of the linked list + * @return the number of items in the list */ static int list_length(struct SLink *lp) { @@ -96,6 +85,71 @@ } #endif +/** Set the mask for a ban, checking for IP masks. + * @param[in,out] ban Ban structure to modify. + * @param[in] banstr Mask to ban. + */ +static void +set_ban_mask(struct Ban *ban, const char *banstr) +{ + char *sep; + MyFree(ban->banstr); + if (!banstr) + return; + DupString(ban->banstr, banstr); + sep = strrchr(banstr, '@'); + if (sep) { + ban->nu_len = sep - banstr; + if (ipmask_parse(sep + 1, &ban->address, &ban->addrbits)) + ban->flags |= BAN_IPMASK; + } +} + +/** Allocate a new Ban structure. + * @param[in] banstr Ban mask to use. + * @return Newly allocated ban. + */ +struct Ban * +make_ban(const char *banstr) +{ + struct Ban *ban; + if (free_bans) { + ban = free_bans; + free_bans = free_bans->next; + } + else if (!(ban = MyMalloc(sizeof(*ban)))) + return NULL; + memset(ban, 0, sizeof(*ban)); + set_ban_mask(ban, banstr); + return ban; +} + +/** Deallocate a ban structure. + * @param[in] ban Ban to deallocate. + */ +void +free_ban(struct Ban *ban) +{ + MyFree(ban->who); + MyFree(ban->banstr); + ban->next = free_bans; + free_bans = ban; +} + +/** return the struct Membership* that represents a client on a channel + * This function finds a struct Membership* which holds the state about + * a client on a specific channel. The code is smart enough to iterate + * over the channels a user is in, or the users in a channel to find the + * user depending on which is likely to be more efficient. + * + * @param chptr pointer to the channel struct + * @param cptr pointer to the client struct + * + * @returns pointer to the struct Membership representing this client on + * this channel. Returns NULL if the client is not on the channel. + * Returns NULL if the client is actually a server. + * @see find_channel_member() + */ struct Membership* find_member_link(struct Channel* chptr, const struct Client* cptr) { struct Membership *m; @@ -136,11 +190,20 @@ return 0; } -/* - * find_chasing - Find the client structure for a nick name (user) +/** Find the client structure for a nick name (user) + * Find the client structure for a nick name (user) * using history mechanism if necessary. If the client is not found, an error * message (NO SUCH NICK) is generated. If the client was found * through the history, chasing will be 1 and otherwise 0. + * + * This function was used extensively in the P09 days, and since we now have + * numeric nicks is no longer quite as important. + * + * @param sptr Pointer to the client that has requested the search + * @param user a string represeting the client to be found + * @param chasing a variable set to 0 if the user was found directly, + * 1 otherwise + * @returns a pointer the client, or NULL if the client wasn't found. */ struct Client* find_chasing(struct Client* sptr, const char* user, int* chasing) { @@ -160,42 +223,18 @@ return who; } -/* - * Create a string of form "foo!bar@fubar" given foo, bar and fubar - * as the parameters. If NULL, they become "*". - */ -#define NUH_BUFSIZE (NICKLEN + USERLEN + HOSTLEN + 3) -static char *make_nick_user_host(char *namebuf, const char *nick, - const char *name, const char *host) -{ - ircd_snprintf(0, namebuf, NUH_BUFSIZE, "%s!%s@%s", nick, name, host); - return namebuf; -} - -/* - * Create a string of form "foo!bar@123.456.789.123" given foo, bar and the - * IP-number as the parameters. If NULL, they become "*". - */ -#define NUI_BUFSIZE (NICKLEN + USERLEN + 16 + 3) -static char *make_nick_user_ip(char *ipbuf, char *nick, char *name, - struct in_addr ip) -{ - ircd_snprintf(0, ipbuf, NUI_BUFSIZE, "%s!%s@%s", nick, name, - ircd_ntoa((const char*) &ip)); - return ipbuf; -} - -/* - * Subtract one user from channel i (and free channel - * block, if channel became empty). +/** Decrement the count of users, and free if empty. + * Subtract one user from channel i (and free channel * block, if channel + * became empty). + * + * @param chptr The channel to subtract one from. * * defined(UNDERNET) - * Returns: true (1) if channel still has members. + * @returns true (1) if channel still has members. * false (0) if the channel is now empty. * !defined(UNDERNET) * Returns: true (1) if channel still exists * false (0) if the channel was destroyed - * !defined(UNDERNET) */ int sub1_from_channel(struct Channel* chptr) { @@ -241,13 +280,24 @@ return 0; } +/** Destroy an empty channel + * This function destroys an empty channel, removing it from hashtables, + * and removing any resources it may have consumed. + * + * @param chptr The channel to destroy + * + * @returns 0 (success) + * + * FIXME: Change to return void, this function never fails. + */ int destruct_channel(struct Channel* chptr) { - struct SLink *tmp; - struct SLink *obtmp; + struct Ban *ban, *next; assert(0 == chptr->members); +#if 0 +/* FIXME-ZOLTAN BORRAR!! ¿? */ /* Channel became (or was) empty: Remove channel */ if (is_listed(chptr)) { @@ -263,20 +313,19 @@ } } } +*/ +#endif + /* * Now, find all invite links from channel structure */ - while ((tmp = chptr->invites)) - del_invite(tmp->value.cptr, chptr); + while (chptr->invites) + del_invite(chptr->invites->value.cptr, chptr); - tmp = chptr->banlist; - while (tmp) + for (ban = chptr->banlist; ban; ban = next) { - obtmp = tmp; - tmp = tmp->next; - MyFree(obtmp->value.ban.banstr); - MyFree(obtmp->value.ban.who); - free_link(obtmp); + next = ban->next; + free_ban(ban); } if (chptr->prev) chptr->prev->next = chptr->next; @@ -294,149 +343,13 @@ return 0; } -/* - * add_banid - * - * `cptr' must be the client adding the ban. - * - * If `change' is true then add `banid' to channel `chptr'. - * Returns 0 if the ban was added. - * Returns -2 if the ban already existed and was marked CHFL_BURST_BAN_WIPEOUT. - * Return -1 otherwise. - * - * Those bans that overlapped with `banid' are flagged with CHFL_BAN_OVERLAPPED - * when `change' is false, otherwise they will be removed from the banlist. - * Subsequently calls to next_overlapped_ban() or next_removed_overlapped_ban() - * respectively will return these bans until NULL is returned. - * - * If `firsttime' is true, the ban list as returned by next_overlapped_ban() - * is reset (unless a non-zero value is returned, in which case the - * CHFL_BAN_OVERLAPPED flag might not have been reset!). +/** returns Membership * if a person is joined and not a zombie + * @param cptr Client + * @param chptr Channel + * @returns pointer to the client's struct Membership * on the channel if that + * user is a full member of the channel, or NULL otherwise. * - * --Run - */ -int add_banid(struct Client *cptr, struct Channel *chptr, char *banid, - int change, int firsttime) -{ - struct SLink* ban; - struct SLink** banp; - int cnt = 0; - int removed_bans = 0; - int len = strlen(banid); - - if (firsttime) - { - next_ban = NULL; - assert(0 == prev_ban); - assert(0 == removed_bans_list); - } - if (MyUser(cptr)) - collapse(banid); - for (banp = &chptr->banlist; *banp;) - { - len += strlen((*banp)->value.ban.banstr); - ++cnt; - if (((*banp)->flags & CHFL_BURST_BAN_WIPEOUT)) - { - if (!strcmp((*banp)->value.ban.banstr, banid)) - { - (*banp)->flags &= ~CHFL_BURST_BAN_WIPEOUT; - return -2; - } - } - else if (!mmatch((*banp)->value.ban.banstr, banid)) - return -1; - if (!mmatch(banid, (*banp)->value.ban.banstr)) - { - struct SLink *tmp = *banp; - if (change) - { - if (MyUser(cptr)) - { - cnt--; - len -= strlen(tmp->value.ban.banstr); - } - *banp = tmp->next; - /* These will be sent to the user later as -b */ - tmp->next = removed_bans_list; - removed_bans_list = tmp; - removed_bans = 1; - } - else if (!(tmp->flags & CHFL_BURST_BAN_WIPEOUT)) - { - tmp->flags |= CHFL_BAN_OVERLAPPED; - if (!next_ban) - next_ban = tmp; - banp = &tmp->next; - } - else - banp = &tmp->next; - } - else - { - if (firsttime) - (*banp)->flags &= ~CHFL_BAN_OVERLAPPED; - banp = &(*banp)->next; - } - } - if (MyUser(cptr) && !removed_bans && - (len > (feature_int(FEAT_AVBANLEN) * feature_int(FEAT_MAXBANS)) || - (cnt >= feature_int(FEAT_MAXBANS)))) - { - send_reply(cptr, ERR_BANLISTFULL, chptr->chname, banid); - return -1; - } - if (change) - { - char* ip_start; - struct Membership* member; - ban = make_link(); - ban->next = chptr->banlist; - - ban->value.ban.banstr = (char*) MyMalloc(strlen(banid) + 1); - assert(0 != ban->value.ban.banstr); - strcpy(ban->value.ban.banstr, banid); - - if (feature_bool(FEAT_HIS_BANWHO) && IsServer(cptr)) - DupString(ban->value.ban.who, cli_name(&me)); - else - DupString(ban->value.ban.who, cli_name(cptr)); - assert(0 != ban->value.ban.who); - - ban->value.ban.when = TStime(); - ban->flags = CHFL_BAN; /* This bit is never used I think... */ - if ((ip_start = strrchr(banid, '@')) && check_if_ipmask(ip_start + 1)) - ban->flags |= CHFL_BAN_IPMASK; - chptr->banlist = ban; - - /* - * Erase ban-valid-bit - */ - for (member = chptr->members; member; member = member->next_member) - ClearBanValid(member); /* `ban' == channel member ! */ - } - return 0; -} - -struct SLink *next_removed_overlapped_ban(void) -{ - struct SLink *tmp = removed_bans_list; - if (prev_ban) - { - if (prev_ban->value.ban.banstr) /* Can be set to NULL in set_mode() */ - MyFree(prev_ban->value.ban.banstr); - MyFree(prev_ban->value.ban.who); - free_link(prev_ban); - prev_ban = 0; - } - if (tmp) - removed_bans_list = removed_bans_list->next; - prev_ban = tmp; - return tmp; -} - -/* - * find_channel_member - returns Membership * if a person is joined and not a zombie + * @see find_member_link() */ struct Membership* find_channel_member(struct Client* cptr, struct Channel* chptr) { @@ -447,84 +360,97 @@ return (member && !IsZombie(member)) ? member : 0; } -/* - * is_banned - a non-zero value if banned else 0. +/** Searches for a ban from a banlist that matches a user. + * @param[in] cptr The client to test. + * @param[in] banlist The list of bans to test. + * @return Pointer to a matching ban, or NULL if none exit. */ -static int is_banned(struct Client *cptr, struct Channel *chptr, - struct Membership* member) +struct Ban *find_ban(struct Client *cptr, struct Ban *banlist) { - struct SLink* tmp; + char nu[NICKLEN + USERLEN + 2]; #if defined(UNDERNET) - char tmphost[HOSTLEN + 1]; - char nu_realhost[NUH_BUFSIZE]; + char tmphost[HOSTLEN + 1]; #endif - char nu_host[NUH_BUFSIZE]; - char nu_ip[NUI_BUFSIZE]; - char* s; - char* sr = NULL; - char* ip_s = NULL; + char *sr; + struct Ban *found; - if (!IsUser(cptr)) - return 0; - - if (member && IsBanValid(member)) - return IsBanned(member); - - s = make_nick_user_host(nu_host, cli_name(cptr), (cli_user(cptr))->username, - (cli_user(cptr))->host); + /* Build nick!user and alternate host names. */ + ircd_snprintf(0, nu, sizeof(nu), "%s!%s", + cli_name(cptr), cli_user(cptr)->username); #if defined(UNDERNET) - if (IsAccount(cptr)) + if (!IsAccount(cptr)) + sr = NULL; + else if (HasHiddenHost(cptr)) + sr = cli_user(cptr)->realhost; + else { - if (HasHiddenHost(cptr)) - { - sr = make_nick_user_host(nu_realhost, cli_name(cptr), - cli_user(cptr)->username, - cli_user(cptr)->realhost); - } - else - { - ircd_snprintf(0, tmphost, HOSTLEN, "%s.%s", - cli_user(cptr)->account, feature_str(FEAT_HIDDEN_HOST)); - sr = make_nick_user_host(nu_realhost, cli_name(cptr), - cli_user(cptr)->username, - tmphost); - } - } -#endif /* defined(UNDERNET) */ - - for (tmp = chptr->banlist; tmp; tmp = tmp->next) { - if ((tmp->flags & CHFL_BAN_IPMASK)) { - if (!ip_s) - ip_s = make_nick_user_ip(nu_ip, cli_name(cptr), - (cli_user(cptr))->username, cli_ip(cptr)); - if (match(tmp->value.ban.banstr, ip_s) == 0) - break; - } - if (match(tmp->value.ban.banstr, s) == 0) - break; - else if (sr && match(tmp->value.ban.banstr, sr) == 0) - break; + ircd_snprintf(0, tmphost, HOSTLEN, "%s.%s", + cli_user(cptr)->account, feature_str(FEAT_HIDDEN_HOST)); + sr = tmphost; } +#else + sr = cli_user(cptr)->realhost; +#endif - if (member) { - SetBanValid(member); - if (tmp) { - SetBanned(member); - return 1; - } - else { - ClearBanned(member); - return 0; - } - } + /* Walk through ban list. */ + for (found = NULL; banlist; banlist = banlist->next) { + int res; + /* If we have found a positive ban already, only consider exceptions. */ + if (found && !(banlist->flags & BAN_EXCEPTION)) + continue; + /* Compare nick!user portion of ban. */ + banlist->banstr[banlist->nu_len] = '\0'; + res = match(banlist->banstr, nu); + banlist->banstr[banlist->nu_len] = '@'; + if (res) + continue; + /* Compare host portion of ban. */ + if (!((banlist->flags & BAN_IPMASK) + && ipmask_check(&cli_ip(cptr), &banlist->address, banlist->addrbits)) + && match(banlist->banstr + banlist->nu_len + 1, cli_user(cptr)->host) + && !(sr && match(banlist->banstr + banlist->nu_len + 1, sr) == 0)) + continue; + /* If an exception matches, no ban can match. */ + if (banlist->flags & BAN_EXCEPTION) + return NULL; + /* Otherwise, remember this ban but keep searching for an exception. */ + found = banlist; + } + return found; +} + +/** + * This function returns true if the user is banned on the said channel. + * This function will check the ban cache if applicable, otherwise will + * do the comparisons and cache the result. + * + * @param[in] member The Membership to test for banned-ness. + * @return Non-zero if the member is banned, zero if not. + */ +static int is_banned(struct Membership* member) +{ + if (IsBanValid(member)) + return IsBanned(member); - return (tmp != NULL); + SetBanValid(member); + if (find_ban(member->user, member->channel->banlist)) { + SetBanned(member); + return 1; + } else { + ClearBanned(member); + return 0; + } } -/* +/** add a user to a channel. * adds a user to a channel by adding another link to the channels member * chain. + * + * @param chptr The channel to add to. + * @param who The user to add. + * @param flags The flags the user gets initially. + * @param oplevel The oplevel the user starts with. */ void add_user_to_channel(struct Channel* chptr, struct Client* who, unsigned int flags, int oplevel) @@ -569,6 +495,12 @@ } } +/** Remove a person from a channel, given their Membership* + * + * @param member A member of a channel. + * + * @returns true if there are more people in the channel. + */ static int remove_member_from_channel(struct Membership* member) { struct Channel* chptr; @@ -589,7 +521,7 @@ */ if (IsDelayedJoin(member)) CheckDelayedJoins(chptr); - + /* * unlink client channel list */ @@ -608,6 +540,11 @@ return sub1_from_channel(chptr); } +/** Check if all the remaining members on the channel are zombies + * + * @returns False if the channel has any non zombie members, True otherwise. + * @see \ref zombie + */ static int channel_all_zombies(struct Channel* chptr) { struct Membership* member; @@ -618,8 +555,16 @@ } return 1; } - + +/** Remove a user from a channel + * This is the generic entry point for removing a user from a channel, this + * function will remove the client from the channel, and destory the channel + * if there are no more normal users left. + * + * @param cptr The client + * @param chptr The channel + */ void remove_user_from_channel(struct Client* cptr, struct Channel* chptr) { @@ -640,6 +585,12 @@ } } +/** Remove a user from all channels they are on. + * + * This function removes a user from all channels they are on. + * + * @param cptr The client to remove. + */ void remove_user_from_all_channels(struct Client* cptr) { struct Membership* chan; @@ -650,6 +601,14 @@ remove_user_from_channel(cptr, chan->channel); } +/** Check if this user is a legitimate chanop + * + * @param cptr Client to check + * @param chptr Channel to check + * + * @returns True if the user is a chanop (And not a zombie), False otherwise. + * @see \ref zombie + */ int is_chan_op(struct Client *cptr, struct Channel *chptr) { struct Membership* member; @@ -660,6 +619,16 @@ return 0; } +/** Check if a user is a Zombie on a specific channel. + * + * @param cptr The client to check. + * @param chptr The channel to check. + * + * @returns True if the client (cptr) is a zombie on the channel (chptr), + * False otherwise. + * + * @see \ref zombie + */ int is_zombie(struct Client *cptr, struct Channel *chptr) { struct Membership* member; @@ -671,6 +640,14 @@ return 0; } +/** Returns if a user has voice on a channel. + * + * @param cptr The client + * @param chptr The channel + * + * @returns True if the client (cptr) is voiced on (chptr) and is not a zombie. + * @see \ref zombie + */ int has_voice(struct Client* cptr, struct Channel* chptr) { struct Membership* member; @@ -682,6 +659,26 @@ return 0; } +/** Can this member send to a channel + * + * A user can speak on a channel iff: + * <ol> + * <li> They didn't use the Apass to gain ops. + * <li> They are op'd or voice'd. + * <li> You aren't banned. + * <li> The channel isn't +m + * <li> The channel isn't +n or you are on the channel. + * </ol> + * + * This function will optionally reveal a user on a delayed join channel if + * they are allowed to send to the channel. + * + * @param member The membership of the user + * @param reveal If true, the user will be "revealed" on a delayed + * joined channel. + * + * @returns True if the client can speak on the channel. + */ int member_can_send_to_channel(struct Membership* member, int reveal) { assert(0 != member); @@ -705,7 +702,7 @@ * but because of the amount of CPU time that is_banned chews * we only check it for our clients. */ - if (MyUser(member->user) && is_banned(member->user, member->channel, member)) + if (MyUser(member->user) && is_banned(member)) return 0; if (IsDelayedJoin(member) && reveal) @@ -714,6 +711,21 @@ return 1; } +/** Check if a client can send to a channel. + * + * Has the added check over member_can_send_to_channel() of servers can + * always speak. + * + * @param cptr The client to check + * @param chptr The channel to check + * @param reveal If the user should be revealed (see + * member_can_send_to_channel()) + * + * @returns true if the client is allowed to speak on the channel, false + * otherwise + * + * @see member_can_send_to_channel() + */ int client_can_send_to_channel(struct Client *cptr, struct Channel *chptr, int reveal) { struct Membership *member; @@ -738,15 +750,19 @@ ) return 0; else - return !is_banned(cptr, chptr, NULL); + return !find_ban(cptr, chptr->banlist); } return member_can_send_to_channel(member, reveal); } -/* - * find_no_nickchange_channel - * if a member and not (opped or voiced) and (banned or moderated) - * return the name of the first channel banned on +/** Returns the name of a channel that prevents the user from changing nick. + * if a member and not (opped or voiced) and (banned or moderated), return + * the name of the first channel banned on. + * + * @param cptr The client + * + * @returns the name of the first channel banned on, or NULL if the user + * can change nicks. */ const char* find_no_nickchange_channel(struct Client* cptr) { @@ -755,7 +771,7 @@ for (member = (cli_user(cptr))->channel; member; member = member->next_channel) { if (!IsVoicedOrOpped(member) && - (is_banned(cptr, member->channel, member) || + (is_banned(member) || (member->channel->mode.mode & MODE_MODERATED))) return member->channel->chname; } @@ -764,9 +780,20 @@ } -/* +/** Fill mbuf/pbuf with modes from chptr * write the "simple" list of channel modes for channel chptr onto buffer mbuf - * with the parameters in pbuf. + * with the parameters in pbuf as visible by cptr. + * + * This function will hide keys from non-op'd, non-server clients. + * + * @param cptr The client to generate the mode for. + * @param mbuf The buffer to write the modes into. + * @param pbuf The buffer to write the mode parameters into. + * @param buflen The length of the buffers. + * @param chptr The channel to get the modes from. + * @param member The membership of this client on this channel (or NULL + * if this client isn't on this channel) + * */ void channel_modes(struct Client *cptr, char *mbuf, char *pbuf, int buflen, struct Channel *chptr, struct Membership *member) @@ -824,7 +851,7 @@ previous_parameter = 1; } if (*chptr->mode.upass) { - *mbuf++ = 'u'; + *mbuf++ = 'U'; if (previous_parameter) strcat(pbuf, " "); if (IsServer(cptr) || (member && IsChanOp(member) ... [truncated message content] |