[srvx-commits] CVS: services/src amorph.txt,NONE,1.1 hash.c,1.149,1.150 hash.h,1.74,1.75 main.c,1.11
Brought to you by:
entrope
Update of /cvsroot/srvx/services/src In directory usw-pr-cvs1:/tmp/cvs-serv604/src Modified Files: hash.c hash.h main.c proto.c proto.def proto.h proto_bahamut.c proto_ircu_p10.c tools.h Added Files: amorph.txt Log Message: add nick-change callback list fix some more bugs in protocol-related stuff (init_proto() wouldn't find the "proto" module since it is called from proto's mod_init) --- NEW FILE --- Amorphous Service Modules ------------------------- Common - help, readhelp, timecmd, write, etc. StaffList - ircops, helpers, staff, etc. AuthServ - basic non-staff handle functions (plus god) AuthServAdmin - staff handle-related functions NickServ - nick registration NickServAdmin - staff nick-related function ChanServReg - basic channel registration/unreg code ChanServSwitch - transitions from X2 ChanServUsers - manipulation of channel user lists/structs ChanServChannel - channel operations ChanServAdmin - events, peek, info, last, command, search, expire, etc. ChanServToys - say, emote, unf, ping, wut, 8ball, d, etc. OpServAccess - opserv access levels for users and commands OpServAlert - alert-related things OpServChannel - addbad, addsecret, etc. OpServHost - addtrust, etc. OpServHax - channel manipulation, dump, raw OpServNetban - gline related functions OpServProxy - proxy checking control OpServClone - clone control (clone, reserve, unreserve, etc.) OpServModules - module control OpServConfig - query, set, log, loginfo OpServControl - die, reconnect, reopen, writeall, sanity, etc. OpServAlias - alias, unalias, etc. ProxyCheck - proxy checking backend (maybe) How it works ------------ The server core consists of common functionality like the configury support, G-line database, channel and user tracking, logging, module management, protocol placeholders, policer, rules/service management, time queue, uplink management and miscellaneous tools. The core then loads a special-purpose protocol module (binding several functions into pointers in the core) and any other modules the config file indicates. Each of these modules (including the protocol module) may register service commands. Each service bot is defined by an entry in a "bots" section of the config file. This defines the configuration for each bot -- especially the commands they provide. The bot entry can also contain an "extends" entry, naming another bot entry that is the template for the current bot. (If the bot entry's name starts with the character "*", the bot will not be instantiated, but can be used as a template for other bots.) The module loading works like this: In the config file, there is a section called "modules". This record is keyed by module name. Each datum in "modules" is another record, containing information on where to find the library (in the "path" key) and global configuration for that module. The search path order for loading modules is this: File named by "modules/${modname}/path" File in module directory (default value: ${libdir}/srvx) with module's name System library load path (i.e. no prefix to library argument) When a module is loaded, a function in the module called "mod_init" is called. This function may officially register the module -- this lets other modules depend on it by version, and indicates which modules it depends on. (If it depends on a module that isn't loaded, srvx tries to recursively load that module.) The module can then register service functions, callbacks, rules, etc. Index: hash.c =================================================================== RCS file: /cvsroot/srvx/services/src/hash.c,v retrieving revision 1.149 retrieving revision 1.150 diff -C2 -r1.149 -r1.150 *** hash.c 2001/10/12 02:03:34 1.149 --- hash.c 2001/10/12 04:03:51 1.150 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 249,252 **** --- 247,268 ---- } + static nick_change_func_t *ncf2_list; + static unsigned int ncf2_size = 0, ncf2_used = 0; + + void + reg_nick_change_func(nick_change_func_t handler) + { + if (ncf2_used == ncf2_size) { + if (ncf2_size) { + ncf2_size <<= 1; + ncf2_list = realloc(ncf2_list, ncf2_size*sizeof(nick_change_func_t)); + } else { + ncf2_size = 8; + ncf2_list = malloc(ncf2_size*sizeof(nick_change_func_t)); + } + } + ncf2_list[ncf2_used++] = handler; + } + static del_user_func_t *duf_list; static size_t duf_size = 0, duf_used = 0; *************** *** 380,383 **** --- 396,401 ---- void NickChange(struct user *user, const char *new_nick) { + unsigned int nn; + /* don't do anything if there's no change */ if (!strncmp(new_nick, user->nick, NICKLEN)) return; *************** *** 385,388 **** --- 403,416 ---- /* remove old entry from clients dictionary */ dict_remove2(clients, user->nick, 1); + + /* Make callbacks for nick changes. + * This needs to be done with the old nick still in place, else + * dict lookups based on user->nick will miss the user. + * It is safe to re-insert using new_nick (which may be a + * temporary pointer) since the later value of user->nick will be + * correct. */ + for (nn=0; nn<ncf2_used; nn++) { + ncf2_list[nn](user, new_nick); + } /* copy new nick */ Index: hash.h =================================================================== RCS file: /cvsroot/srvx/services/src/hash.h,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -r1.74 -r1.75 *** hash.h 2001/10/12 02:03:34 1.74 --- hash.h 2001/10/12 04:03:51 1.75 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 180,183 **** --- 178,183 ---- void DelUser(struct user *user, struct user *killer, int announce, const char *why); void ReintroduceUser(struct user *user); + typedef void (*nick_change_func_t)(struct user *user, const char *new_nick); + void reg_nick_change_func(nick_change_func_t handler); void NickChange(struct user *user, const char *new_nick); Index: main.c =================================================================== RCS file: /cvsroot/srvx/services/src/main.c,v retrieving revision 1.114 retrieving revision 1.115 diff -C2 -r1.114 -r1.115 *** main.c 2001/10/02 16:04:36 1.114 --- main.c 2001/10/12 04:03:51 1.115 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 461,470 **** if ((tmp = conf_server_ping_timeout()) != -1) ping_timeout = tmp; modules_init(); - tools_init(); timeq_init(); gline_init(); sockcheck_init(); /* could be modularized */ hash_init(); - proto_init(); service_init(); conf_rlimits(); --- 459,466 ---- Index: proto.c =================================================================== RCS file: /cvsroot/srvx/services/src/proto.c,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -r1.77 -r1.78 *** proto.c 2001/10/10 04:51:23 1.77 --- proto.c 2001/10/12 04:03:51 1.78 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 28,47 **** #include "log.h" #include "modules.h" #define PROTO_FUNC(retval, name, arglist) retval (*name) arglist; #define PROTO_VARIABLE(type, name) type name; #include "proto.h" void ! proto_init(void) { ! struct module *pmod; int failed = 0; void *addr; - pmod = module_find_loaded("proto"); - if (!pmod) { - log(MAIN_LOG, LOG_ERROR, "Unable to find protocol module\n"); - return; - } #define PROTO_FUNC(rettype, name, arglist) if (!(name = get_module_symbol(pmod, #name))) { log(MAIN_LOG, LOG_ERROR, "Protocol module does not export symbol %s\n", #name); failed++; } #define PROTO_VARIABLE(type, name) if ((addr = get_module_symbol(pmod, #name))) { name = *(type*)addr; } else { log(MAIN_LOG, LOG_ERROR, "Protocol module does not export symbol %s\n", #name); failed++; } --- 26,341 ---- #include "log.h" #include "modules.h" + #include "tools.h" #define PROTO_FUNC(retval, name, arglist) retval (*name) arglist; #define PROTO_VARIABLE(type, name) type name; #include "proto.h" + unsigned char user_inverse_modes[256]; + unsigned char channel_inverse_modes[256]; + + static void + proto_build_inverse_modes(void) { + unsigned int nn; + /* Go through and record which bit each character corresponds to. + * Since some modes don't exist in some protocols, the + * corresponding position in the *_modes string is a space; but we + * don't want to give spaces a value, so erase them afterwards. + */ + for (nn=0; proto_user_modes[nn]; nn++) { + user_inverse_modes[proto_user_modes[nn]] = nn + 1; + } + user_inverse_modes[' '] = 0; + for (nn=0; proto_channel_modes[nn]; nn++) { + channel_inverse_modes[proto_channel_modes[nn]] = nn + 1; + } + channel_inverse_modes[' '] = 0; + } + void ! mod_usermode(struct user *user, const char *mode_change) { ! unsigned long orig_modes; ! int add = 1; ! unsigned char modechar; ! ! if (!user || !mode_change || !*mode_change) return; ! orig_modes = user->modes; ! while (1) { ! switch (modechar = *mode_change++) { ! case 0: case ' ': return; ! case '+': add = 1; break; ! case '-': add = 0; break; ! default: ! if (user_inverse_modes[modechar]) { ! if (add) { ! user->modes |= (1 << (user_inverse_modes[modechar]-1)); ! } else { ! user->modes &= ~(1 << (user_inverse_modes[modechar]-1)); ! } ! } ! } ! #undef do_user_mode ! } ! /* TODO: add callback to notify things of mode changes */ ! } ! ! int ! make_usermode(struct user *user, char *out, unsigned int len) ! { ! unsigned int nn, jj=0; ! len--; /* to allow for \0 at end */ ! out[jj++] = '+'; ! for (nn=0; proto_user_modes[nn] && (jj<len); nn++) { ! if ((proto_user_modes[nn] != ' ') && (user->modes & (1 << nn))) { ! out[jj++] = proto_user_modes[nn]; ! } ! } ! out[jj++] = 0; ! return 1; ! } ! ! void ! mod_chanmode(struct channel *channel, const char *mode_change, const char *key, int limit) ! { ! int add = 1, n; ! const char *word = mode_change; ! unsigned char modechar; ! ! if (!mode_change || !*mode_change) return; ! while (*word != ' ' && *word) word++; ! while (*word == ' ') word++; ! while (1) { ! switch (modechar = *mode_change++) { ! case 0: case ' ': return; ! case '+': add = 1; break; ! case '-': add = 0; break; ! case 'k': ! if (add) { ! if (key) { ! safestrncpy(channel->key, key, sizeof(channel->key)); ! } else { ! for (n=0; *word != ' ' && *word; n++) { ! channel->key[n] = *word++; ! } ! channel->key[n] = 0; ! } ! } else { ! channel->key[0] = 0; ! } ! break; ! case 'l': ! if (add) { ! if (limit) { ! channel->limit = limit; ! } else { ! channel->limit = strtoul(word, NULL, 0); ! } ! while (*word != ' ' && *word) word++; ! while (*word == ' ') word++; ! } else { ! channel->limit = 0; ! } ! break; ! default: ! if ((n = channel_inverse_modes[modechar])) { ! if (add) { ! channel->modes |= 1 << (n-1); ! } else { ! channel->modes &= ~(1 << (n-1)); ! } ! } ! break; ! } ! } ! } ! ! int ! make_chanmode(struct channel *channel, char *out, unsigned int len) ! { ! unsigned int nn, jj=0; ! len--; /* to allow for \0 at end */ ! out[jj++] = '+'; ! for (nn=0; proto_channel_modes[nn] && (jj<len); nn++) { ! if ((proto_channel_modes[nn] != ' ') && (channel->modes & (1 << nn))) { ! out[jj++] = proto_channel_modes[nn]; ! } ! } ! if (channel->limit || channel->key[0]) { ! if (jj < len-2) { ! if (channel->limit) out[jj++] = 'l'; ! if (channel->key[0]) out[jj++] = 'k'; ! if (channel->limit) { ! if (jj < len) out[jj++] = ' '; ! jj += snprintf(out+jj, len-jj, "%d", channel->limit); ! if (jj >= len) jj = len-1; ! } ! if (channel->key[0]) { ! if (jj < len) out[jj++] = ' '; ! jj += snprintf(out+jj, len-jj, "%s", channel->key); ! if (jj >= len) jj = len-1; ! } ! } ! } ! out[jj++] = 0; ! return 1; ! } ! ! int ! verify_chanmode(const char *modes) { ! const char *word; ! int add = 1; ! unsigned char modechar; ! ! if (!modes) return 0; ! if (!*modes) return 1; ! if ((*modes != '+') && (*modes != '-')) return 0; ! word = modes; ! while (*word != ' ' && *word) word++; ! while (*word == ' ') word++; ! while (1) { ! switch (modechar = *modes++) { ! case 0: ! case ' ': ! return 1; ! case '+': add = 1; break; ! case '-': add = 0; break; ! case 'k': ! if (add && !*word) return 0; ! break; ! case 'l': ! if (add && (!*word || (strtoul(word, NULL, 0) <= 0))) return 0; ! break; ! default: ! if (!channel_inverse_modes[modechar]) return 0; ! break; ! } ! } ! } ! ! char * ! generate_hostmask(struct user *user, int options) ! { ! char *nickname, *username, *hostname; ! char *mask; ! int len, ii; ! ! /* figure out string parts */ ! if (options & GENMASK_OMITNICK) { ! nickname = NULL; ! } else if (options & GENMASK_USENICK) { ! nickname = user->nick; ! } else { ! nickname = "*"; ! } ! if (options & GENMASK_STRICT) { ! username = user->username; ! } else { ! username = alloca(strlen(user->username)+2); ! username[0] = '*'; ! strcpy(username+1, user->username + ((*user->username == '~')?1:0)); ! } ! hostname = user->hostname; ! if (options & GENMASK_STRICT) { ! /* leave hostname as is */ ! } else if ((options & GENMASK_BYIP) || !hostname[strspn(hostname, "0123456789.")]) { ! /* Should generate an IP-based hostmask. By popular acclaim, a /16 ! * hostmask is used by default. */ ! unsigned masked_ip, mask, masklen; ! masklen = 16; ! mask = ~0 << masklen; ! masked_ip = user->ip & mask; ! hostname = alloca(32); ! if (options & GENMASK_SRVXMASK) { ! sprintf(hostname, "%d.%d.%d.%d/%d", (masked_ip>>24)&0xFF, (masked_ip>>16)&0xFF, (masked_ip>>8)&0xFF, masked_ip&0xFF, masklen); ! } else { ! int ofs = 0; ! for (ii=0; ii<4; ii++) { ! if (masklen) { ! ofs += sprintf(hostname+ofs, "%d.", (masked_ip>>24)&0xFF); ! masklen -= 8; ! masked_ip <<= 8; ! } else { ! ofs += sprintf(hostname+ofs, "*."); ! } ! } ! /* Truncate the last . */ ! hostname[ofs-1] = 0; ! } ! } else { ! int cnt; ! /* This heuristic could be made smarter. Is it worth the effort? */ ! for (ii=cnt=0; hostname[ii]; ii++) { ! if (hostname[ii] == '.') cnt++; ! } ! if (cnt == 1) { ! /* only a two-level domain name; leave hostname */ ! } else if (cnt == 2) { ! for (ii=0; user->hostname[ii] != '.'; ii++) ; ! hostname = alloca(strlen(user->hostname+ii)+2); ! sprintf(hostname, "*%s", user->hostname+ii+1); ! } else { ! for (cnt=3, ii--; cnt; ii--) { ! if (user->hostname[ii] == '.') cnt--; ! } ! hostname = alloca(strlen(user->hostname+ii)+2); ! sprintf(hostname, "*%s", user->hostname+ii+1); ! } ! } ! /* Emit hostmask */ ! len = strlen(username) + strlen(hostname) + 2; ! if (nickname) { ! len += strlen(nickname) + 1; ! mask = malloc(len); ! sprintf(mask, "%s!%s@%s", nickname, username, hostname); ! } else { ! mask = malloc(len); ! sprintf(mask, "%s@%s", username, hostname); ! } ! return mask; ! } ! ! int ! user_matches_glob(struct user *user, const char *orig_glob, int include_nick) ! { ! char *glob, *marker; ! /* Make a writable copy of the glob */ ! glob = alloca(strlen(orig_glob)+1); ! strcpy(glob, orig_glob); ! /* Check the nick, if it's present */ ! if (include_nick) { ! if (!(marker = strchr(glob, '!'))) { ! log(MAIN_LOG, LOG_ERROR, "match_glob_user(\"%s\", \"%s\", %d) called, and glob doesn't include a '!'\n", user->nick, orig_glob, include_nick); ! return 0; ! } ! *marker = 0; ! if (!match_ircglob(user->nick, glob)) return 0; ! glob = marker + 1; ! } ! /* Check the ident */ ! if (!(marker = strchr(glob, '@'))) { ! log(MAIN_LOG, LOG_ERROR, "match_glob_user(\"%s\", \"%s\", %d) called, and glob doesn't include an '@'\n", user->nick, orig_glob, include_nick); ! return 0; ! } ! *marker = 0; ! if (!match_ircglob(user->username, glob)) return 0; ! glob = marker + 1; ! /* Now check the host part */ ! if (!glob[strspn(glob, "0123456789./*?")]) { ! /* Looks like an IP-based mask */ ! unsigned char userip[20]; ! sprintf(userip, "%ld.%ld.%ld.%ld", (user->ip >> 24) & 255, (user->ip >> 16) & 255, (user->ip >> 8) & 255, user->ip & 255); ! return match_ircglob(userip, glob); ! } else { ! /* The host part of the mask isn't IP-based */ ! return match_ircglob(user->hostname, glob); ! } ! } ! ! void ! proto_init(struct module *pmod) ! { int failed = 0; void *addr; #define PROTO_FUNC(rettype, name, arglist) if (!(name = get_module_symbol(pmod, #name))) { log(MAIN_LOG, LOG_ERROR, "Protocol module does not export symbol %s\n", #name); failed++; } #define PROTO_VARIABLE(type, name) if ((addr = get_module_symbol(pmod, #name))) { name = *(type*)addr; } else { log(MAIN_LOG, LOG_ERROR, "Protocol module does not export symbol %s\n", #name); failed++; } *************** *** 49,52 **** --- 343,347 ---- #undef PROTO_FUNC #undef PROTO_VARIABLE + proto_build_inverse_modes(); if (failed) { log(MAIN_LOG, LOG_ERROR, "%d unresolved protocol functions\n", failed); Index: proto.def =================================================================== RCS file: /cvsroot/srvx/services/src/proto.def,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** proto.def 2001/10/10 04:00:41 1.2 --- proto.def 2001/10/12 04:03:51 1.3 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 79,84 **** /****************************/ ! PROTO_VARIABLE(const char *, proto_user_modes) ! PROTO_VARIABLE(const char *, proto_channel_modes) PROTO_VARIABLE(int, proto_chanserv_joins_channels) PROTO_VARIABLE(unsigned int, proto_max_mode_args) --- 77,82 ---- /****************************/ ! PROTO_VARIABLE(const unsigned char *, proto_user_modes) ! PROTO_VARIABLE(const unsigned char *, proto_channel_modes) PROTO_VARIABLE(int, proto_chanserv_joins_channels) PROTO_VARIABLE(unsigned int, proto_max_mode_args) Index: proto.h =================================================================== RCS file: /cvsroot/srvx/services/src/proto.h,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -r1.47 -r1.48 *** proto.h 2001/10/12 02:03:34 1.47 --- proto.h 2001/10/12 04:03:51 1.48 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 28,31 **** --- 26,30 ---- struct server; struct user; + struct module; typedef void (*chanmsg_func_t) (struct user *bot, struct user *source, struct channel *chan, char *text); *************** *** 62,66 **** int user_matches_glob(struct user *user, const char *glob, int include_nick); ! void proto_init(void); /********************/ --- 61,65 ---- int user_matches_glob(struct user *user, const char *glob, int include_nick); ! void proto_init(struct module *proto_mod); /********************/ Index: proto_bahamut.c =================================================================== RCS file: /cvsroot/srvx/services/src/proto_bahamut.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** proto_bahamut.c 2001/10/12 02:03:34 1.17 --- proto_bahamut.c 2001/10/12 04:03:51 1.18 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 1381,1386 **** /* Set protocol-specific variables */ ! proto_user_modes = "h"; ! proto_channel_modes = "rRcO"; proto_chanserv_joins_channels = 0; proto_max_mode_args = MAXNUMPARAMS; --- 1379,1384 ---- /* Set protocol-specific variables */ ! proto_user_modes = "oiws h"; ! proto_channel_modes = "psmtinrRcO"; proto_chanserv_joins_channels = 0; proto_max_mode_args = MAXNUMPARAMS; *************** *** 1448,1452 **** /* let rest of protocol stuff initialize */ ! proto_init(); return 0; }; --- 1446,1450 ---- /* let rest of protocol stuff initialize */ ! proto_init(proto_module); return 0; }; Index: proto_ircu_p10.c =================================================================== RCS file: /cvsroot/srvx/services/src/proto_ircu_p10.c,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** proto_ircu_p10.c 2001/10/12 02:03:34 1.27 --- proto_ircu_p10.c 2001/10/12 04:03:51 1.28 *************** *** 15,20 **** * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ */ --- 15,18 ---- *************** *** 1666,1671 **** /* Set protocol-specific variables */ ! proto_user_modes = "dkgh"; ! proto_channel_modes = ""; proto_chanserv_joins_channels = 1; proto_max_mode_args = 6; --- 1664,1669 ---- /* Set protocol-specific variables */ ! proto_user_modes = "oiwsdkgh"; ! proto_channel_modes = "psmtin"; proto_chanserv_joins_channels = 1; proto_max_mode_args = 6; *************** *** 1776,1780 **** /* let rest of protocol stuff initialize */ ! proto_init(); return 0; } --- 1774,1778 ---- /* let rest of protocol stuff initialize */ ! proto_init(proto_module); return 0; } Index: tools.h =================================================================== RCS file: /cvsroot/srvx/services/src/tools.h,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** tools.h 2001/10/10 04:00:41 1.15 --- tools.h 2001/10/12 04:03:51 1.16 *************** *** 29,42 **** #define disabled_string(string) (!strcasecmp((string), "off") || !strcmp((string), "0") || !strcasecmp((string), "disabled")) - struct user; - struct channel; - extern unsigned char channel_inverse_modes[256]; - - void tools_init(void); - - int getusermodes(char *sender); - void mod_usermode(struct user *user, const char *modes); - void mod_chanmode(struct channel *channel, const char *mode_change, const char *key, int limit); - int verify_chanmode(const char *modes); int split_line(unsigned char *line, int irc_colon, int argv_size, unsigned char *argv[]); --- 29,32 ---- *************** *** 44,60 **** int mmatch(const char *glob, const char *newglob); int match_ircglob(const char *text, const char *glob); - int user_matches_glob(struct user *user, const char *glob, int include_nick); int is_ircmask(const unsigned char *text); int is_gline(const unsigned char *text); - /* The "default" for generate_hostmask is to have all of these options off. */ - #define GENMASK_STRICT 1 - #define GENMASK_USENICK 2 - #define GENMASK_OMITNICK 4 /* Hurray for Kevin! */ - #define GENMASK_BYIP 8 - #define GENMASK_SRVXMASK 16 - char *generate_hostmask(struct user *user, int options); - unsigned long ParseInterval(const unsigned char *interval); unsigned long ParseVolume(const unsigned char *volume); --- 34,41 ---- *************** *** 73,85 **** const char *preposition(char *word); - int ban_match_user(struct user *user, char *ban); - int ban_match_user_host(struct user *user, char *hostmask, char *ban); DECLARE_LIST(string_buffer, char); void string_buffer_append_string(struct string_buffer *buf, const char *tail); void string_buffer_replace(struct string_buffer *buf, unsigned int from, unsigned int len, const char *repl); - - int make_chanmode(struct channel *chan, char *out, unsigned int len); - int make_usermode(struct user *user, char *out, unsigned int len); #endif /* ifdef _TOOLS_H_ */ --- 54,61 ---- |