[IRC-Dev CVS] [CVS] Module ircd-ircdev: Change committed
Brought to you by:
zolty
From: Toni G. <zo...@us...> - 2005-10-17 14:02:50
|
CVSROOT : /cvsroot/irc-dev Module : ircd-ircdev Commit time: 2005-10-17 14:02:42 UTC Modified files: ChangeLog ChangeLog.es doc/ircd.sample-en.conf doc/ircd.sample-es.conf include/channel.h include/ircd_string.h include/match.h include/patchlevel.h ircd/Makefile.in ircd/channel.c ircd/ddb_db_native.c ircd/gline.c ircd/ircd.c ircd/ircd_string.c ircd/m_burst.c ircd/m_invite.c ircd/m_join.c ircd/m_mode.c ircd/m_names.c ircd/m_opmode.c ircd/m_ping.c ircd/match.c ircd/s_conf.c ircd/test/ircd_in_addr_t.c Added files: ircd/convert-conf.c Log message: Author: zoltan <zo...@ir...> Log message: 2005-10-17 Toni García <zo...@ir...> 1.0.alpha44 * Sincronización Undernet ---------------------- diff included ---------------------- Index: ircd-ircdev/ChangeLog diff -u ircd-ircdev/ChangeLog:1.45 ircd-ircdev/ChangeLog:1.46 --- ircd-ircdev/ChangeLog:1.45 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/ChangeLog Mon Oct 17 07:02:32 2005 @@ -1,10 +1,13 @@ # # ChangeLog for ircd-ircdev # -# $Id: ChangeLog,v 1.45 2005/09/01 11:25:42 zolty Exp $ +# $Id: ChangeLog,v 1.46 2005/10/17 14:02:32 zolty Exp $ # # Insert new changes at beginning of the change list. # +2005-10-17 Toni García <zo...@ir...> 1.0.alpha44 + * Undernet synchronization + 2005-09-01 Toni García <zo...@ir...> 1.0.alpha43 * Undernet synchronization Index: ircd-ircdev/ChangeLog.es diff -u ircd-ircdev/ChangeLog.es:1.45 ircd-ircdev/ChangeLog.es:1.46 --- ircd-ircdev/ChangeLog.es:1.45 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/ChangeLog.es Mon Oct 17 07:02:32 2005 @@ -1,10 +1,13 @@ # # Log de Cambios para ircd-ircdev # -# $Id: ChangeLog.es,v 1.45 2005/09/01 11:25:42 zolty Exp $ +# $Id: ChangeLog.es,v 1.46 2005/10/17 14:02:32 zolty Exp $ # # Insertar los nuevos cambios al principio de esta lista de cambios. # +2005-10-17 Toni García <zo...@ir...> 1.0.alpha44 + * Sincronización Undernet + 2005-09-01 Toni García <zo...@ir...> 1.0.alpha43 * Sincronización Undernet Index: ircd-ircdev/doc/ircd.sample-en.conf diff -u ircd-ircdev/doc/ircd.sample-en.conf:1.22 ircd-ircdev/doc/ircd.sample-en.conf:1.23 --- ircd-ircdev/doc/ircd.sample-en.conf:1.22 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/doc/ircd.sample-en.conf Mon Oct 17 07:02:32 2005 @@ -800,7 +800,7 @@ # "GLINEMAXUSERCOUNT" = "20"; # "SOCKSENDBUF" = "61440"; # "SOCKRECVBUF" = "61440"; -# "IPCHECK_CLONE_LIMIT = 24"; +# "IPCHECK_CLONE_LIMIT = "24"; # "IPCHECK_CLONE_PERIOD = "40"; # "IPCHECK_CLONE_DELAY = "600"; # "MPATH" = "ircd.motd"; @@ -859,7 +859,7 @@ # "HIS_BANWHO" = "TRUE"; # "HIS_KILLWHO" = "TRUE"; # "HIS_REWRITE" = "TRUE"; -# "HIS_REMOTE" = 1; +# "HIS_REMOTE" = "1"; # "HIS_NETSPLIT" = TRUE"; # "HIS_SERVERNAME" = "*.irc-dev.net"; # "HIS_SERVERINFO" = "IRC-Dev.Net, Desarrollo de IRC / IRC Development"; Index: ircd-ircdev/doc/ircd.sample-es.conf diff -u ircd-ircdev/doc/ircd.sample-es.conf:1.17 ircd-ircdev/doc/ircd.sample-es.conf:1.18 --- ircd-ircdev/doc/ircd.sample-es.conf:1.17 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/doc/ircd.sample-es.conf Mon Oct 17 07:02:32 2005 @@ -838,7 +838,7 @@ # "GLINEMAXUSERCOUNT" = "20"; # "SOCKSENDBUF" = "61440"; # "SOCKRECVBUF" = "61440"; -# "IPCHECK_CLONE_LIMIT = 24"; +# "IPCHECK_CLONE_LIMIT = "24"; # "IPCHECK_CLONE_PERIOD = "40"; # "IPCHECK_CLONE_DELAY = "600"; # "MPATH" = "ircd.motd"; @@ -897,7 +897,7 @@ # "HIS_BANWHO" = "TRUE"; # "HIS_KILLWHO" = "TRUE"; # "HIS_REWRITE" = "TRUE"; -# "HIS_REMOTE" = 1; +# "HIS_REMOTE" = "1"; # "HIS_NETSPLIT" = TRUE"; # "HIS_SERVERNAME" = "*.irc-dev.net"; # "HIS_SERVERINFO" = "IRC-Dev.Net, Desarrollo de IRC / IRC Development"; Index: ircd-ircdev/include/channel.h diff -u ircd-ircdev/include/channel.h:1.13 ircd-ircdev/include/channel.h:1.14 --- ircd-ircdev/include/channel.h:1.13 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/include/channel.h Mon Oct 17 07:02:32 2005 @@ -22,7 +22,7 @@ */ /** @file * @brief Channel management and maintenance. - * @version $Id: channel.h,v 1.13 2005/09/01 11:25:42 zolty Exp $ + * @version $Id: channel.h,v 1.14 2005/10/17 14:02:32 zolty Exp $ */ #ifndef INCLUDED_channel_h #define INCLUDED_channel_h @@ -213,10 +213,6 @@ */ #define MAGIC_REMOTE_JOIN_TS 1270080000 -/** - * used in can_join to determine if an oper forced a join on a channel - */ -#define MAGIC_OPER_OVERRIDE 1000 extern const char* const PartFmt1; @@ -430,7 +426,6 @@ /* * Proto types */ -extern void clean_channelname(char* name); extern void channel_modes(struct Client *cptr, char *mbuf, char *pbuf, int buflen, struct Channel *chptr, struct Membership *member); @@ -445,7 +440,6 @@ const struct Client* cptr); extern int sub1_from_channel(struct Channel* chptr); extern int destruct_channel(struct Channel* chptr); -extern int can_join(struct Client *sptr, struct Channel *chptr, char *key); extern void add_user_to_channel(struct Channel* chptr, struct Client* who, unsigned int flags, int oplevel); extern void make_zombie(struct Membership* member, struct Client* who, Index: ircd-ircdev/include/ircd_string.h diff -u ircd-ircdev/include/ircd_string.h:1.6 ircd-ircdev/include/ircd_string.h:1.7 --- ircd-ircdev/include/ircd_string.h:1.6 Wed Jun 22 00:54:29 2005 +++ ircd-ircdev/include/ircd_string.h Mon Oct 17 07:02:32 2005 @@ -21,7 +21,7 @@ */ /** @file ircd_string.h * @brief Public declarations and APIs for string operations. - * @version $Id: ircd_string.h,v 1.6 2005/06/22 07:54:29 zolty Exp $ + * @version $Id: ircd_string.h,v 1.7 2005/10/17 14:02:32 zolty Exp $ */ #ifndef INCLUDED_ircd_string_h #define INCLUDED_ircd_string_h @@ -51,7 +51,8 @@ char** vector, int size); extern const char* ircd_ntoa(const struct irc_in_addr* addr); extern const char* ircd_ntoa_r(char* buf, const struct irc_in_addr* addr); -extern int ircd_aton(struct irc_in_addr *addr, const char *str); +#define ircd_aton(ADDR, STR) ipmask_parse((STR), (ADDR), NULL) +extern int ipmask_parse(const char *in, struct irc_in_addr *mask, unsigned char *bits_ptr); extern char* host_from_uh(char* buf, const char* userhost, size_t len); extern char* ircd_strtok(char** save, char* str, char* fs); Index: ircd-ircdev/include/match.h diff -u ircd-ircdev/include/match.h:1.4 ircd-ircdev/include/match.h:1.5 --- ircd-ircdev/include/match.h:1.4 Mon Jan 10 04:22:00 2005 +++ ircd-ircdev/include/match.h Mon Oct 17 07:02:32 2005 @@ -21,7 +21,7 @@ */ /** @file match.h * @brief Interface for matching strings to IRC masks. - * @version $Id: match.h,v 1.4 2005/01/10 12:22:00 zolty Exp $ + * @version $Id: match.h,v 1.5 2005/10/17 14:02:32 zolty Exp $ */ #ifndef INCLUDED_match_h #define INCLUDED_match_h @@ -51,8 +51,6 @@ extern int matchdecomp(char *mask, const char *cmask); extern int mmexec(const char *wcm, int wminlen, const char *rcm, int rminlen); -extern int check_if_ipmask(const char *mask); -extern int ipmask_parse(const char *in, struct irc_in_addr *mask, unsigned char *bits_ptr); extern int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask, unsigned char bits); #endif /* INCLUDED_match_h */ Index: ircd-ircdev/include/patchlevel.h diff -u ircd-ircdev/include/patchlevel.h:1.44 ircd-ircdev/include/patchlevel.h:1.45 --- ircd-ircdev/include/patchlevel.h:1.44 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/include/patchlevel.h Mon Oct 17 07:02:32 2005 @@ -17,10 +17,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: patchlevel.h,v 1.44 2005/09/01 11:25:42 zolty Exp $ + * $Id: patchlevel.h,v 1.45 2005/10/17 14:02:32 zolty Exp $ * */ -#define PATCHLEVEL ".alpha43" +#define PATCHLEVEL ".alpha44" #define RELEASE "1.0" Index: ircd-ircdev/ircd/Makefile.in diff -u ircd-ircdev/ircd/Makefile.in:1.27 ircd-ircdev/ircd/Makefile.in:1.28 --- ircd-ircdev/ircd/Makefile.in:1.27 Wed May 25 09:56:23 2005 +++ ircd-ircdev/ircd/Makefile.in Mon Oct 17 07:02:32 2005 @@ -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.27 2005/05/25 16:56:23 zolty Exp $ +# $Id: Makefile.in,v 1.28 2005/10/17 14:02:32 zolty Exp $ #### Start of system configuration section. #### @@ -69,6 +69,9 @@ PURIFY = RINGLOG_O = +CONVERT_CONF_SRC = \ + convert-conf.c + ENGINE_SRC = \ engine_devpoll.c \ engine_epoll.c \ @@ -261,6 +264,8 @@ UMKPASSWD_OBJS = ${UMKPASSWD_SRC:%.c=%.o} +CONVERT_CONF_OBJS = ${CONVERT_CONF_SRC:%.c=%.o} + DEP_SRC = ${IRCD_SRC} ${UNDERNET_SRC} ${DDB_SRC} ${SERVICES_SRC} ${ENGINE_SRC} ${CRYPTO_SRC} all: @@ -271,13 +276,16 @@ .c.o: ${CC} ${CFLAGS} ${CPPFLAGS} -c $< -o $@ -build: ircd +build: ircd convert-conf ircd: ${OBJS} ../include/patchlevel.h version.o ${PURIFY} ${CC} ${OBJS} version.o ${RINGLOG_O} ${LDFLAGS} ${LIBS} \ -o ircd ${CHMOD} ${IRCDMODE} ircd +convert-conf: ${CONVERT_CONF_OBJS} + ${PURIFY} ${CC} ${CONVERT_CONF_OBJS} ${LDFLAGS} -o convert-conf + # # Make sure the anti hack checksums get included when things change # bleah @@ -356,7 +364,7 @@ @echo "Please remove the contents of ${DPATH} manually" clean: - ${RM} -f *.o *.bak ircd version.c umkpasswd ircd_osdep.c chattr.tab.c table_gen y.tab.* lex.yy.* + ${RM} -f *.o *.bak ircd version.c umkpasswd convert-conf chattr.tab.c table_gen y.tab.* lex.yy.* distclean: clean ${RM} -f Makefile stamp-m Index: ircd-ircdev/ircd/channel.c diff -u ircd-ircdev/ircd/channel.c:1.25 ircd-ircdev/ircd/channel.c:1.26 --- ircd-ircdev/ircd/channel.c:1.25 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/ircd/channel.c Mon Oct 17 07:02:32 2005 @@ -21,7 +21,7 @@ */ /** @file * @brief Channel management and maintanance - * @version $Id: channel.c,v 1.25 2005/09/01 11:25:42 zolty Exp $ + * @version $Id: channel.c,v 1.26 2005/10/17 14:02:32 zolty Exp $ */ #include "config.h" @@ -368,12 +368,15 @@ #if defined(UNDERNET) char tmphost[HOSTLEN + 1]; #endif + char iphost[SOCKIPLEN + 1]; + char *hostmask; char *sr; struct Ban *found; /* Build nick!user and alternate host names. */ ircd_snprintf(0, nu, sizeof(nu), "%s!%s", cli_name(cptr), cli_user(cptr)->username); + ircd_ntoa_r(iphost, &cli_ip(cptr)); #if defined(UNDERNET) if (!IsAccount(cptr)) @@ -403,11 +406,13 @@ if (res) continue; /* Compare host portion of ban. */ + hostmask = banlist->banstr + banlist->nu_len + 1; 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)) + && match(hostmask, cli_user(cptr)->host) + && !(sr && match(hostmask, sr))) continue; + /* If an exception matches, no ban can match. */ if (banlist->flags & BAN_EXCEPTION) return NULL; @@ -1320,106 +1325,6 @@ send_reply(cptr, RPL_ENDOFBANLIST, chptr->chname); } -/** Check a key against a keyring. - * We are now treating the key part of /join channellist key as a key - * ring; that is, we try one key against the actual channel key, and if that - * doesn't work, we try the next one, and so on. -Kev -Texaco - * Returns: 0 on match, 1 otherwise - * This version contributed by SeKs \<in...@in...\> - * - * @param key Key to check - * @param keyring Comma separated list of keys - * - * @returns True if the key was found and matches, false otherwise. - */ -static int compall(char *key, char *keyring) -{ - char *p1; - -top: - p1 = key; /* point to the key... */ - while (*p1 && *p1 == *keyring) - { /* step through the key and ring until they - don't match... */ - p1++; - keyring++; - } - - if (!*p1 && (!*keyring || *keyring == ',')) - /* ok, if we're at the end of the and also at the end of one of the keys - in the keyring, we have a match */ - return 0; - - if (!*keyring) /* if we're at the end of the key ring, there - weren't any matches, so we return 1 */ - return 1; - - /* Not at the end of the key ring, so step - through to the next key in the ring: */ - while (*keyring && *(keyring++) != ','); - - goto top; /* and check it against the key */ -} - -/** Returns if a user can join a channel with a specific key. - * - * @param sptr The client trying to join - * @param chptr The channel to join - * @param key The key to use - * - * @returns any error that occurred bitwised OR'd with MAGIC_OPER_OVERRIDE - * if the oper used the magic key, 0 if no error occured. - */ -int can_join(struct Client *sptr, struct Channel *chptr, char *key) -{ - int overrideJoin = 0; - - /* - * Now a banned user CAN join if invited -- Nemesi - * Now a user CAN escape channel limit if invited -- bfriendly - * Now a user CAN escape anything if invited -- Isomer - */ - - if (IsInvited(sptr, chptr)) - return 0; - - /* An oper can force a join on a local channel using "OVERRIDE" as the key. - a HACK(4) notice will be sent if he would not have been supposed - to join normally. */ - if (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_WALK_LCHAN) && - !BadPtr(key) && compall("OVERRIDE",chptr->mode.key) != 0 && - compall("OVERRIDE",key) == 0) - overrideJoin = MAGIC_OPER_OVERRIDE; - - if (chptr->mode.mode & MODE_INVITEONLY) - return overrideJoin + ERR_INVITEONLYCHAN; - - if (chptr->mode.limit && chptr->users >= chptr->mode.limit) - return overrideJoin + ERR_CHANNELISFULL; - - if ((chptr->mode.mode & MODE_REGONLY) && -#if defined(UNDERNET) - !IsAccount(sptr)) -#elif defined(DDB) || defined(SERVICES) - !IsNickRegistered(sptr)) -#endif - return overrideJoin + ERR_NEEDREGGEDNICK; - - if (find_ban(sptr, chptr->banlist)) - return overrideJoin + ERR_BANNEDFROMCHAN; - - /* - * now using compall (above) to test against a whole key ring -Kev - */ - if (*chptr->mode.key && (EmptyString(key) || compall(chptr->mode.key, key))) - return overrideJoin + ERR_BADCHANNELKEY; - - if (overrideJoin) - return ERR_DONTCHEAT; - - return 0; -} - /** Remove bells and commas from channel name * * @param cn Channel name to clean, modified in place. @@ -3639,9 +3544,7 @@ assert(0 != jbuf); if (!chan) { - if (jbuf->jb_type == JOINBUF_TYPE_JOIN) - sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect, "0"); - + sendcmdto_serv_butone(jbuf->jb_source, CMD_JOIN, jbuf->jb_connect, "0"); return; } Index: ircd-ircdev/ircd/convert-conf.c diff -u /dev/null ircd-ircdev/ircd/convert-conf.c:1.1 --- /dev/null Mon Oct 17 07:02:43 2005 +++ ircd-ircdev/ircd/convert-conf.c Mon Oct 17 07:02:32 2005 @@ -0,0 +1,650 @@ +/* + * IRC-Dev IRCD - An advanced and innovative IRC Daemon, ircd/convert-conf.c + * + * Copyright (C) 2002-2005 IRC-Dev Development Team <de...@ir...> + * Copyright (C) 2005 Michael Poole + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: convert-conf.c,v 1.1 2005/10/17 14:02:32 zolty Exp $ + * convert-conf.c - Convert ircu2.10.11 ircd.conf to ircu2.10.12 format. + * + */ + +#include <ctype.h> /* tolower(), toupper(), isdigit() */ +#include <stdio.h> /* *printf(), fgets() */ +#include <stdlib.h> /* free(), strtol() */ +#include <string.h> /* strlen(), memcpy(), strchr(), strspn() */ + +#define MAX_FIELDS 5 + +const char *admin_names[] = { "location", "contact", "contact", 0 }, + *connect_names[] = { "host", "password", "name", "#port", "class", 0 }, + *crule_names[] = { "server", "", "rule", 0 }, + *general_names[] = { "name", "vhost", "description", "", "#numeric", 0 }, + *motd_names[] = { "host", "file", 0 }, + *class_names[] = { "name", "#pingfreq", "#connectfreq", "#maxlinks", "#sendq", 0 }, + *removed_features[] = { "VIRTUAL_HOST", "OPERS_SEE_IN_SECRET_CHANNELS", "LOCOP_SEE_IN_SECRET_CHANNELS", 0 }; +char orig_line[512], line[512], dbuf[512]; +char *fields[MAX_FIELDS + 1]; +unsigned int nfields; +unsigned int lineno; + +/*** GENERIC SUPPORT CODE ***/ + +static int split_line(char *input, char **output) +{ + size_t quoted = 0, jj; + char *dest = dbuf, ch; + + nfields = 1; + output[0] = dest; + while (*input != '\0' && *input != '#') switch (ch = *input++) { + case ':': + if (quoted) + *dest++ = ch; + else { + *dest++ = '\0'; + if (nfields >= MAX_FIELDS) + return nfields; + output[nfields++] = dest; + } + break; + case '\\': + switch (ch = *input++) { + case 'b': *dest++ = '\b'; break; + case 'f': *dest++ = '\f'; break; + case 'n': *dest++ = '\n'; break; + case 'r': *dest++ = '\r'; break; + case 't': *dest++ = '\t'; break; + case 'v': *dest++ = '\v'; break; + default: *dest++ = ch; break; + } + break; + case '"': quoted = !quoted; break; + default: *dest++ = ch; break; + } + + *dest = '\0'; + for (jj = nfields; jj < MAX_FIELDS; ++jj) + output[jj] = dest; + return nfields; +} + +static void simple_line(const char *block, const char **names, const char *extra) +{ + size_t ii; + + /* Print the current line and start the new block. */ + fprintf(stdout, "# %s\n%s {\n", orig_line, block); + + /* Iterate over fields in input line, formatting each. */ + for (ii = 0; ii < nfields && names[ii]; ++ii) { + if (!fields[ii][0] || !names[ii][0]) + continue; + else if (names[ii][0] == '#') + fprintf(stdout, "\t%s = %s;\n", names[ii] + 1, fields[ii]); + else + fprintf(stdout, "\t%s = \"%s\";\n", names[ii], fields[ii]); + } + + /* Close the new block (including any fixed-form text). */ + if (extra) + fprintf(stdout, "\t%s\n", extra); + fputs("};\n", stdout); +} + +#define dupstring(TARGET, SOURCE) do { free(TARGET); if (SOURCE) { size_t len = strlen(SOURCE); (TARGET) = malloc(len+1); memcpy((TARGET), (SOURCE), len); } else (TARGET) = 0; } while(0) + +/*** MANAGING LISTS OF STRINGS ***/ + +struct string_list { + struct string_list *next; + char *origin; + char *extra; + char value[1]; +}; + +static struct string_list *string_get(struct string_list **list, const char *value) +{ + struct string_list *curr; + size_t len = strlen(value), ii; + + while ((curr = *list)) { + for (ii = 0; tolower(curr->value[ii]) == tolower(value[ii]) && ii < len; ++ii) ; + if (curr->value[ii] == '\0' && value[ii] == '\0') + return curr; + list = &curr->next; + } + + *list = calloc(1, sizeof(**list) + len); + memcpy((*list)->value, value, len); + return *list; +} + +/*** SERVER CONNECTION RELATED CODE ***/ + +struct connect { + char *host; + char *password; + char *port; + char *class; + char *hub; + char *maximum; + struct connect *next; + struct string_list *origins; + char name[1]; +} *connects; + +static struct connect *get_connect(const char *name) +{ + struct connect *conn; + size_t ii, nlen; + + /* Look for a pre-existing connection with the same name. */ + nlen = strlen(name); + for (conn = connects; conn; conn = conn->next) + { + for (ii = 0; tolower(name[ii]) == conn->name[ii] && ii < nlen; ++ii) ; + if (conn->name[ii] == '\0' && name[ii] == '\0') + break; + } + + /* If none was found, create a new one. */ + if (!conn) + { + conn = calloc(1, sizeof(*conn) + nlen); + for (ii = 0; ii < nlen; ++ii) + conn->name[ii] = tolower(name[ii]); + conn->next = connects; + connects = conn; + } + + /* Return the connection. */ + return conn; +} + +static void do_connect(void) +{ + struct connect *conn = get_connect(fields[2]); + dupstring(conn->host, fields[0]); + dupstring(conn->password, fields[1]); + dupstring(conn->port, fields[3]); + dupstring(conn->class, fields[4]); + string_get(&conn->origins, orig_line); +} + +static void do_hub(void) +{ + struct connect *conn = get_connect(fields[2]); + dupstring(conn->hub, fields[0]); + dupstring(conn->maximum, fields[3]); + string_get(&conn->origins, orig_line); +} + +static void do_leaf(void) +{ + struct connect *conn = get_connect(fields[2]); + free(conn->hub); + conn->hub = 0; + string_get(&conn->origins, orig_line); +} + +static void finish_connects(void) +{ + struct connect *conn; + struct string_list *sl; + + for (conn = connects; conn; conn = conn->next) + { + for (sl = conn->origins; sl; sl = sl->next) + fprintf(stdout, "# %s\n", sl->value); + fprintf(stdout, + "Connect {\n\tname =\"%s\";\n\thost = \"%s\";\n" + "\tpassword = \"%s\";\n\tclass = \"%s\";\n", + conn->name, conn->host, conn->password, conn->class); + if (conn->port && conn->port[0] != '\0') + fprintf(stdout, "\tport = %s;\n", conn->port); + else + fprintf(stdout, + "# Every Connect block should have a port number.\n" + "# To prevent autoconnects, set autoconnect = no.\n" + "#\tport = 4400;\n" + "\tautoconnect = no;\n"); + if (conn->maximum && conn->maximum[0] != '\0') + fprintf(stdout, "\tmaxhops = %s;\n", conn->maximum); + if (conn->hub && conn->hub[0] != '\0') + fprintf(stdout, "\thub = \"%s\";\n", conn->hub); + fprintf(stdout, "};\n\n"); + + } +} + +/*** FEATURE MANAGEMENT CODE ***/ + +struct feature { + struct string_list *values; + struct string_list *origins; + struct feature *next; + char name[1]; +} *features; + +struct remapped_feature { + const char *name; + const char *privilege; + int flags; /* 2 = global, 1 = local */ + struct feature *feature; +} remapped_features[] = { + /* Specially handled privileges: If you change the index of + * anything with NULL privilege, change the code in + * finish_operators() to match! + */ + { "CRYPT_OPER_PASSWORD", NULL, 0, 0 }, /* default: true */ + { "OPER_KILL", NULL, 2, 0 }, /* default: true */ + { "LOCAL_KILL_ONLY", NULL, 2, 0 }, /* default: false */ + /* remapped features that affect all opers */ + { "OPER_NO_CHAN_LIMIT", "chan_limit", 3, 0 }, + { "OPER_MODE_LCHAN", "mode_lchan", 3, 0 }, + { "OPER_WALK_THROUGH_LMODES", "walk_lchan", 3, 0 }, + { "NO_OPER_DEOP_LCHAN", "deop_lchan", 3, 0 }, + { "SHOW_INVISIBLE_USERS", "show_invis", 3, 0 }, + { "SHOW_ALL_INVISIBLE_USERS", "show_all_invis", 3, 0 }, + { "UNLIMIT_OPER_QUERY", "unlimit_query", 3, 0 }, + /* remapped features affecting only global opers */ + { "OPER_REHASH", "rehash", 2, 0 }, + { "OPER_RESTART", "restart", 2, 0 }, + { "OPER_DIE", "die", 2, 0 }, + { "OPER_GLINE", "gline", 2, 0 }, + { "OPER_LGLINE", "local_gline", 2, 0 }, + { "OPER_JUPE", "jupe", 2, 0 }, + { "OPER_LJUPE", "local_jupe", 2, 0 }, + { "OPER_OPMODE", "opmode", 2, 0 }, + { "OPER_LOPMODE", "local_opmode", 2, 0 }, + { "OPER_FORCE_OPMODE", "force_opmode", 2, 0 }, + { "OPER_FORCE_LOPMODE", "force_local_opmode", 2, 0 }, + { "OPER_BADCHAN", "badchan", 2, 0 }, + { "OPER_LBADCHAN", "local_badchan", 2, 0 }, + { "OPER_SET", "set", 2, 0 }, + { "OPER_WIDE_GLINE", "wide_gline", 2, 0 }, + /* remapped features affecting only local opers */ + { "LOCOP_KILL", "kill", 1, 0 }, + { "LOCOP_REHASH", "rehash", 1, 0 }, + { "LOCOP_RESTART", "restart", 1, 0 }, + { "LOCOP_DIE", "die", 1, 0 }, + { "LOCOP_LGLINE", "local_gline", 1, 0 }, + { "LOCOP_LJUPE", "local_jupe", 1, 0 }, + { "LOCOP_LOPMODE", "local_opmode", 1, 0 }, + { "LOCOP_FORCE_LOPMODE", "force_local_opmode", 1, 0 }, + { "LOCOP_LBADCHAN", "local_badchan", 1, 0 }, + { "LOCOP_WIDE_GLINE", "wide_gline", 1, 0 }, + { 0, 0, 0, 0 } +}; + +static void do_feature(void) +{ + struct feature *feat; + size_t ii; + + ii = strlen(fields[0]); + feat = calloc(1, sizeof(*feat) + ii); + while (ii-- > 0) + feat->name[ii] = toupper(fields[0][ii]); + feat->next = features; + features = feat; + string_get(&feat->origins, orig_line); + for (ii = 1; fields[ii] && fields[ii][0]; ++ii) + string_get(&feat->values, fields[ii]); +} + +static void finish_features(void) +{ + struct remapped_feature *rmf; + struct string_list *sl; + struct feature *feat; + size_t ii; + + fputs("Features {\n\t\"OPLEVELS\" = \"FALSE\";\n", stdout); + + for (feat = features; feat; feat = feat->next) { + /* See if the feature was remapped to an oper privilege. */ + for (rmf = remapped_features; rmf->name; rmf++) + if (0 == strcmp(feat->name, rmf->name)) + break; + if (rmf->name) { + rmf->feature = feat; + fprintf(stdout, "# Above feature mapped to an oper privilege.\n"); + continue; + } + + /* Was it removed? */ + for (ii = 0; removed_features[ii]; ++ii) + if (0 == strcmp(feat->name, removed_features[ii])) + break; + if (removed_features[ii]) { + fprintf(stdout, "# Above feature no longer exists.\n"); + continue; + } + + /* Wasn't remapped, wasn't removed: print it out. */ + fprintf(stdout, "\t\"%s\" =", feat->name); + for (sl = feat->values; sl; sl = sl->next) + fprintf(stdout, " \"%s\"", sl->value); + fprintf(stdout, ";\n"); + } + fputs("};\n\n", stdout); + +} + +/*** OPERATOR BLOCKS ***/ + +struct operator { + char *name; + char *host; + char *password; + char *class; + char *origin; + int is_local; + struct operator *next; +} *operators; + +static void do_operator(int is_local) +{ + struct operator *oper; + + oper = calloc(1, sizeof(*oper)); + dupstring(oper->host, fields[0]); + dupstring(oper->password, fields[1]); + dupstring(oper->name, fields[2]); + dupstring(oper->class, fields[4]); + dupstring(oper->origin, orig_line); + oper->is_local = is_local; + oper->next = operators; + operators = oper; +} + +static void finish_operators(void) +{ + struct remapped_feature *remap; + struct operator *oper; + struct feature *feat; + char *pw_salt = ""; + int global_kill = 0, mask = 0; + size_t ii; + + if ((feat = remapped_features[0].feature) && feat->values + && 0 == strcmp(feat->values->value, "FALSE")) + pw_salt = "$PLAIN$"; + + if ((feat = remapped_features[1].feature) && feat->values + && 0 == strcmp(feat->values->value, "FALSE")) + global_kill = 1; + else if ((feat = remapped_features[2].feature) && feat->values + && 0 == strcmp(feat->values->value, "FALSE")) + global_kill = 2; + + for (oper = operators; oper; oper = oper->next) { + fprintf(stdout, "# %s\nOperator {\n\tname = \"%s\";\n" + "\thost = \"%s\";\n\tpassword = \"%s%s\";\n" + "\tclass = \"%s\";\n", + oper->origin, oper->name, oper->host, pw_salt, + oper->password, oper->class); + if (oper->is_local) { + fputs("\tlocal = yes;\n", stdout); + mask = 1; + } else { + fputs("\tlocal = no;\n", stdout); + if (global_kill == 1) + fputs("\tkill = no;\n\tlocal_kill = no;\n", stdout); + else if (global_kill == 2) + fputs("\tkill = no;\n\tlocal_kill = yes;\n", stdout); + mask = 2; + } + for (ii = 0; (remap = &remapped_features[ii++])->name; ) { + if (!remap->feature || !remap->privilege + || !remap->feature->values || !remap->flags & mask) + continue; + fprintf(stdout, "\t%s = %s;\n", remap->privilege, + strcmp(remap->feature->values->value, "TRUE") ? "no" : "yes"); + } + fputs("};\n\n", stdout); + } +} + +/*** OTHER CONFIG TRANSFORMS ***/ + +static void do_kill(void) +{ + const char *host = fields[0], *reason = fields[1], *user = fields[2]; + + if (!memcmp(host, "$R", 3)) { + fprintf(stderr, "Empty realname K: line at line %u.\n", lineno); + return; + } + + /* Print the current line and start the new block. */ + fprintf(stdout, "# %s\nKill {\n", orig_line); + + /* Translate the user-matching portions. */ + if (host[0] == '$' && host[1] == 'R') { + /* Realname kill, possibly with a username */ + fprintf(stdout, "\trealname = \"%s\";\n", host + 2); + if (user[0] != '\0' && (user[0] != '*' || user[1] != '\0')) + fprintf(stdout, "\thost = \"%s@*\";\n", user); + } else { + /* Normal host or IP-based kill */ + if (user[0] != '\0' && (user[0] != '*' || user[1] != '\0')) + fprintf(stdout, "\thost = \"%s@%s\";\n", user, host); + else + fprintf(stdout, "\thost = \"%s\";\n", host); + } + + /* Translate the reason section. */ + if (reason[0] == '!') + fprintf(stdout, "\tfile = \"%s\";\n", reason + 1); + else + fprintf(stdout, "\treason = \"%s\";\n", reason); + + /* Close the block. */ + fprintf(stdout, "};\n"); +} + +static void do_port(void) +{ + const char *ipmask = fields[0], *iface = fields[1], *flags = fields[2], *port = fields[3]; + + /* Print the current line and start the new block. */ + fprintf(stdout, "# %s\nPort {\n", orig_line); + + /* Print the easy fields. */ + fprintf(stdout, "\tport = %s;\n", port); + if (iface && iface[0] != '\0') + fprintf(stdout, "\tvhost = \"%s\";\n", iface); + if (ipmask && ipmask[0] != '\0') + fprintf(stdout, "\tmask = \"%s\";\n", ipmask); + + /* Translate flag field. */ + while (*flags) switch (*flags++) { + case 'C': case 'c': /* client port is default state */; break; + case 'S': case 's': fprintf(stdout, "\tserver = yes;\n"); break; + case 'H': case 'h': fprintf(stdout, "\thidden = yes;\n"); break; + } + + /* Close the block. */ + fprintf(stdout, "};\n"); +} + +struct string_list *quarantines; + +static void do_quarantine(void) +{ + struct string_list *q; + q = string_get(&quarantines, fields[0]); + dupstring(q->origin, orig_line); + dupstring(q->extra, fields[1]); +} + +static void finish_quarantines(void) +{ + struct string_list *sl; + + if (quarantines) + { + fputs("Quarantine {\n", stdout); + for (sl = quarantines; sl; sl = sl->next) + fprintf(stdout, "# %s\n\t\"%s\" = \"%s\";\n", sl->origin, sl->value, sl->extra); + fputs("};\n\n", stdout); + } +} + +static void do_uworld(void) +{ + fprintf(stdout, "# %s\n", orig_line); + if (fields[0] && fields[0][0]) + fprintf(stdout, "Uworld { name = \"%s\"; };\n", fields[0]); + if (fields[1] && fields[1][0]) + fprintf(stdout, "Jupe { nick = \"%s\"; };\n", fields[1]); +} + +static void emit_client(const char *mask, const char *passwd, const char *class, long maxlinks, int is_ip) +{ + char *delim; + size_t len; + + delim = strchr(mask, '@'); + if (delim) { + *delim++ = '\0'; + if (is_ip) { + len = strspn(delim, "0123456789.*"); + if (delim[len]) { + fprintf(stderr, "Invalid IP mask on line %u.\n", lineno); + return; + } + fprintf(stdout, "Client {\n\tusername = \"%s\";\n\tip = \"%s\";\n", mask, delim); + } else { + fprintf(stdout, "Client {\n\tusername =\"%s\";\n\thost = \"%s\";\n", mask, delim); + } + } else if (is_ip) { + len = strspn(mask, "0123456789.*"); + if (mask[len]) + return; + fprintf(stdout, "Client {\n\tip = \"%s\";\n", mask); + } else { + if (!strchr(mask, '.') && !strchr(mask, '*')) + return; + fprintf(stdout, "Client {\n\thost = \"%s\";\n", mask); + } + + if (passwd) + fprintf(stdout, "\tpassword = \"%s\";\n", passwd); + + if (maxlinks >= 0) + fprintf(stdout, "\tmaxlinks = %ld;\n", maxlinks); + + fprintf(stdout, "\tclass = \"%s\";\n};\n", class); +} + +static void do_client(void) +{ + char *passwd = NULL, *delim; + long maxlinks; + + /* Print the current line. */ + fprintf(stdout, "# %s\n", orig_line); + + /* See if the password is really a maxlinks count. */ + maxlinks = strtol(fields[1], &delim, 10); + if (fields[1][0] == '\0') + maxlinks = -1; + else if (maxlinks < 0 || maxlinks > 99 || *delim != '\0') + passwd = fields[1]; + + /* Translate the IP and host mask fields into blocks. */ + emit_client(fields[0], passwd, fields[4], maxlinks, 1); + emit_client(fields[2], passwd, fields[4], maxlinks, 0); +} + +int main(int argc, char *argv[]) +{ + FILE *ifile; + + if (argc < 2) + ifile = stdin; + else if (!(ifile = fopen(argv[1], "rt"))) { + fprintf(stderr, "Unable to open file %s for input.\n", argv[1]); + return 1; + } + + for (lineno = 1; fgets(line, sizeof(line), ifile); ++lineno) { + /* Read line and pass comments through. */ + size_t len = strlen(line); + if (line[0] == '#') { + fputs(line, stdout); + continue; + } + /* Strip EOL character(s) and pass blank lines through. */ + while (len > 0 && (line[len-1] == '\n' || line[len-1] == '\r')) + line[--len] = '\0'; + if (len == 0) { + fputc('\n', stdout); + continue; + } + /* Skip but report invalid lines. */ + if (line[1] != ':') { + fprintf(stdout, "# %s\n", line); + fprintf(stderr, "Invalid input line %d.\n", lineno); + continue; + } + /* Copy the original line into a reusable variable. */ + strcpy(orig_line, line); + /* Split line into fields. */ + nfields = split_line(line + 2, fields); + + /* Process the input line. */ + switch (line[0]) { + case 'A': case 'a': simple_line("Admin", admin_names, NULL); break; + case 'C': case 'c': do_connect(); break; + case 'D': simple_line("CRule", crule_names, "all = yes;"); break; + case 'd': simple_line("CRule", crule_names, NULL); break; + case 'F': case 'f': do_feature(); break; + case 'H': case 'h': do_hub(); break; + case 'I': case 'i': do_client(); break; + case 'K': case 'k': do_kill(); break; + case 'L': case 'l': do_leaf(); break; + case 'M': case 'm': simple_line("General", general_names, NULL); break; + case 'O': do_operator(0); break; + case 'o': do_operator(1); break; + case 'P': case 'p': do_port(); break; + case 'Q': case 'q': do_quarantine(); break; + case 'T': case 't': simple_line("Motd", motd_names, NULL); break; + case 'U': case 'u': do_uworld(); break; + case 'Y': case 'y': simple_line("Class", class_names, NULL); break; + default: + fprintf(stderr, "Unknown line %u with leading character '%c'.\n", lineno, line[0]); + break; + } + } + + fclose(ifile); + + fputs("\n# The following lines were intentionally moved and rearranged." + "\n# Our apologies for any inconvenience this may cause." + "\n\n", stdout); + finish_connects(); + finish_quarantines(); + finish_features(); + finish_operators(); + + return 0; +} Index: ircd-ircdev/ircd/ddb_db_native.c diff -u ircd-ircdev/ircd/ddb_db_native.c:1.4 ircd-ircdev/ircd/ddb_db_native.c:1.5 --- ircd-ircdev/ircd/ddb_db_native.c:1.4 Mon May 16 03:17:27 2005 +++ ircd-ircdev/ircd/ddb_db_native.c Mon Oct 17 07:02:32 2005 @@ -22,7 +22,7 @@ */ /** @file * @brief Native DataBase implementation of Distributed DataBases. - * @version $Id: ddb_db_native.c,v 1.4 2005/05/16 10:17:27 zolty Exp $ + * @version $Id: ddb_db_native.c,v 1.5 2005/10/17 14:02:32 zolty Exp $ */ #include "config.h" @@ -67,20 +67,15 @@ ddb_db_init(void) { char path[1024]; + struct stat *sStat; unsigned char table; int fd; - int temp; -#if 0 - temp = chdir(feature_str(FEAT_DDBPATH)); - log_write(LS_SYSTEM, L_CRIT, 0, "chdir(), resultado: %d", temp); - if (0 != temp) - /* if (0 != chdir(feature_str(FEAT_DDBPATH))) */ + if ((stat(feature_str(FEAT_DDBPATH), sStat) == 0)) { if (0 != mkdir(feature_str(FEAT_DDBPATH), 0775)) ddb_die("Error when creating %s directory", feature_str(FEAT_DDBPATH)); } -#endif /* Verify if hashes file is exist. */ ircd_snprintf(0, path, sizeof(path), "%s/hashes", feature_str(FEAT_DDBPATH)); Index: ircd-ircdev/ircd/gline.c diff -u ircd-ircdev/ircd/gline.c:1.15 ircd-ircdev/ircd/gline.c:1.16 --- ircd-ircdev/ircd/gline.c:1.15 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/ircd/gline.c Mon Oct 17 07:02:32 2005 @@ -23,7 +23,7 @@ */ /** @file * @brief Implementation of Gline manipulation functions. - * @version $Id: gline.c,v 1.15 2005/09/01 11:25:42 zolty Exp $ + * @version $Id: gline.c,v 1.16 2005/10/17 14:02:32 zolty Exp $ */ #include "config.h" @@ -167,10 +167,8 @@ else gline->gl_host = NULL; - if (*user != '$' && ipmask_parse(host, &gline->gl_addr, &gline->gl_bits)) { - Debug((DEBUG_DEBUG,"IP gline: %s/%u", ircd_ntoa(&gline->gl_addr), gline->gl_bits)); + if (*user != '$' && ipmask_parse(host, &gline->gl_addr, &gline->gl_bits)) gline->gl_flags |= GLINE_IPMASK; - } if (after) { gline->gl_next = after->gl_next; @@ -229,10 +227,6 @@ continue; if (GlineIsIpMask(gline)) { -#ifdef DEBUGMODE - char tbuf1[SOCKIPLEN], tbuf2[SOCKIPLEN]; - Debug((DEBUG_DEBUG,"IP gline: %s %s/%u", ircd_ntoa_r(tbuf1, &cli_ip(acptr)), ircd_ntoa_r(tbuf2, &gline->gl_addr), gline->gl_bits)); -#endif if (!ipmask_check(&cli_ip(acptr), &gline->gl_addr, gline->gl_bits)) continue; } @@ -696,7 +690,7 @@ gline_free(gline); continue; } - + if ((flags & GLINE_GLOBAL && gline->gl_flags & GLINE_LOCAL) || (flags & GLINE_LASTMOD && !gline->gl_lastmod)) continue; @@ -705,19 +699,12 @@ Debug((DEBUG_DEBUG,"realname gline: '%s' '%s'",gline->gl_user,cli_info(cptr))); if (match(gline->gl_user+2, cli_info(cptr)) != 0) continue; - if (!GlineIsActive(gline)) - continue; - return gline; } else { if (match(gline->gl_user, (cli_user(cptr))->username) != 0) continue; if (GlineIsIpMask(gline)) { -#ifdef DEBUGMODE - char tbuf1[SOCKIPLEN], tbuf2[SOCKIPLEN]; - Debug((DEBUG_DEBUG,"IP gline: %s %s/%u", ircd_ntoa_r(tbuf1, &cli_ip(cptr)), ircd_ntoa_r(tbuf2, &gline->gl_addr), gline->gl_bits)); -#endif if (!ipmask_check(&cli_ip(cptr), &gline->gl_addr, gline->gl_bits)) continue; } Index: ircd-ircdev/ircd/ircd.c diff -u ircd-ircdev/ircd/ircd.c:1.21 ircd-ircdev/ircd/ircd.c:1.22 --- ircd-ircdev/ircd/ircd.c:1.21 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/ircd/ircd.c Mon Oct 17 07:02:32 2005 @@ -21,7 +21,7 @@ */ /** @file * @brief Entry point and other initialization functions for the daemon. - * @version $Id: ircd.c,v 1.21 2005/09/01 11:25:42 zolty Exp $ + * @version $Id: ircd.c,v 1.22 2005/10/17 14:02:32 zolty Exp $ */ #include "config.h" @@ -280,14 +280,14 @@ || ((ajupe = jupe_find(aconf->name)) && JupeIsActive(ajupe))) continue; + /* Do we need to postpone this connection further? */ + hold = aconf->hold > CurrentTime; + /* Update next possible connection check time. */ - if (next > aconf->hold || next == 0) + if (hold && (next > aconf->hold || next == 0)) next = aconf->hold; - /* Update the next time we can consider this entry. */ cltmp = aconf->conn_class; - hold = aconf->hold > CurrentTime; /* before we update aconf->hold */ - aconf->hold = ConFreq(cltmp) ? CurrentTime + ConFreq(cltmp) : 0; /* Do not try to connect if its use is still on hold until future, * too many links in its connection class, it is already linked, Index: ircd-ircdev/ircd/ircd_string.c diff -u ircd-ircdev/ircd/ircd_string.c:1.11 ircd-ircdev/ircd/ircd_string.c:1.12 --- ircd-ircdev/ircd/ircd_string.c:1.11 Wed Jun 22 00:54:29 2005 +++ ircd-ircdev/ircd/ircd_string.c Mon Oct 17 07:02:32 2005 @@ -21,7 +21,7 @@ */ /** @file * @brief Implementation of string operations. - * @version $Id: ircd_string.c,v 1.11 2005/06/22 07:54:29 zolty Exp $ + * @version $Id: ircd_string.c,v 1.12 2005/10/17 14:02:32 zolty Exp $ */ #include "config.h" @@ -456,12 +456,13 @@ /** Attempt to parse an IPv4 address into a network-endian form. * @param[in] input Input string. * @param[out] output Network-endian representation of the address. + * @param[out] pbits Number of bits found in pbits. * @return Number of characters used from \a input, or 0 if the parse failed. */ static unsigned int -ircd_aton_ip4(const char *input, unsigned int *output) +ircd_aton_ip4(const char *input, unsigned int *output, unsigned char *pbits) { - unsigned int dots = 0, pos = 0, part = 0, ip = 0; + unsigned int dots = 0, pos = 0, part = 0, ip = 0, bits; /* Intentionally no support for bizarre IPv4 formats (plain * integers, octal or hex components) -- only vanilla dotted @@ -469,33 +470,60 @@ */ if (input[0] == '.') return 0; - while (1) { - if (IsDigit(input[pos])) { - part = part * 10 + input[pos++] - '0'; - if (part > 255) - return 0; - if ((dots == 3) && !IsDigit(input[pos])) { - *output = htonl(ip | part); - return pos; - } - } else if (input[pos] == '.') { - if (input[++pos] == '.') + bits = 32; + while (1) switch (input[pos]) { + case '\0': + if (dots < 3) + return 0; + out: + ip |= part << (24 - 8 * dots); + *output = htonl(ip); + if (pbits) + *pbits = bits; + return pos; + case '.': + if (input[++pos] == '.') + return 0; + ip |= part << (24 - 8 * dots++); + part = 0; + if (input[pos] == '*') { + while (input[++pos] == '*') ; + if (input[pos] != '\0') return 0; - ip |= part << (24 - 8 * dots++); - part = 0; - } else + if (pbits) + *pbits = dots * 8; + *output = htonl(ip); + return pos; + } + break; + case '/': + if (!pbits || !IsDigit(input[pos + 1])) + return 0; + for (bits = 0; IsDigit(input[++pos]); ) + bits = bits * 10 + input[pos] - '0'; + if (bits > 32) + return 0; + goto out; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + part = part * 10 + input[pos++] - '0'; + if (part > 255) return 0; + break; + default: + return 0; } } /** Parse a numeric IPv4 or IPv6 address into an irc_in_addr. - * @param[out] ip Receives parsed IP address. * @param[in] input Input buffer. + * @param[out] ip Receives parsed IP address. + * @param[out] pbits If non-NULL, receives number of bits specified in address mask. * @return Number of characters used from \a input, or 0 if the * address was unparseable or malformed. */ int -ircd_aton(struct irc_in_addr *ip, const char *input) +ipmask_parse(const char *input, struct irc_in_addr *ip, unsigned char *pbits) { char *colon; char *dot; @@ -523,80 +551,104 @@ pos += 2; part_start = input + pos; } - while (ii < 8) { + while (ii < 8) switch (input[pos]) { unsigned char chval; - - switch (input[pos]) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - chval = input[pos] - '0'; - use_chval: - part = (part << 4) | chval; - if (part > 0xffff) + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + chval = input[pos] - '0'; + use_chval: + part = (part << 4) | chval; + if (part > 0xffff) + return 0; + pos++; + break; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + chval = input[pos] - 'A' + 10; + goto use_chval; + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + chval = input[pos] - 'a' + 10; + goto use_chval; + case ':': + part_start = input + ++pos; + if (input[pos] == '.') + return 0; + ip->in6_16[ii++] = htons(part); + part = 0; + if (input[pos] == ':') { + if (colon < 8) return 0; + colon = ii; pos++; - break; - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - chval = input[pos] - 'A' + 10; - goto use_chval; - case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - chval = input[pos] - 'a' + 10; - goto use_chval; - case ':': - part_start = input + ++pos; - if (input[pos] == '.') - return 0; - ip->in6_16[ii++] = htons(part); - part = 0; - if (input[pos] == ':') { - if (colon < 8) - return 0; - colon = ii; - pos++; - } - break; - case '.': { - uint32_t ip4; - unsigned int len; - len = ircd_aton_ip4(part_start, &ip4); - if (!len || (ii > 6)) - return 0; - ip->in6_16[ii++] = htons(ntohl(ip4) >> 16); - ip->in6_16[ii++] = htons(ntohl(ip4) & 65535); - if (colon < 8) { - unsigned int jj; - /* Shift stuff after "::" up and fill middle with zeros. */ - for (jj = 0; jj < ii - colon; jj++) - ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1]; - for (jj = 0; jj < 8 - ii; jj++) - ip->in6_16[colon + jj] = 0; - } - return part_start - input + len; - } - default: { - ip->in6_16[ii++] = htons(part); - if (colon < 8) { - unsigned int jj; - /* Shift stuff after "::" up and fill middle with zeros. */ - for (jj = 0; jj < ii - colon; jj++) - ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1]; - for (jj = 0; jj < 8 - ii; jj++) - ip->in6_16[colon + jj] = 0; - } - return pos; - } } + break; + case '.': { + uint32_t ip4; + unsigned int len; + len = ircd_aton_ip4(part_start, &ip4, pbits); + if (!len || (ii > 6)) + return 0; + ip->in6_16[ii++] = htons(ntohl(ip4) >> 16); + ip->in6_16[ii++] = htons(ntohl(ip4) & 65535); + if (pbits) + *pbits += 96; + pos = part_start + len - input; + goto finish; + } + case '/': + if (!pbits || !IsDigit(input[pos + 1])) + return 0; + ip->in6_16[ii++] = htons(part); + for (part = 0; IsDigit(input[++pos]); ) + part = part * 10 + input[pos] - '0'; + if (part > 128) + return 0; + *pbits = part; + goto finish; + case '*': + while (input[++pos] == '*') ; + if (input[pos] != '\0' || colon < 8) + return 0; + if (pbits) + *pbits = ii * 16; + return pos; + case '\0': + ip->in6_16[ii++] = htons(part); + if (colon == 8 && ii < 8) + return 0; + if (pbits) + *pbits = 128; + goto finish; + default: + return 0; + } + finish: + if (colon < 8) { + unsigned int jj; + /* Shift stuff after "::" up and fill middle with zeros. */ + for (jj = 0; jj < ii - colon; jj++) + ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1]; + for (jj = 0; jj < 8 - ii; jj++) + ip->in6_16[colon + jj] = 0; } return pos; - } else if (dot) { + } else if (dot || strchr(input, '/')) { unsigned int addr; - int len = ircd_aton_ip4(input, &addr); + int len = ircd_aton_ip4(input, &addr, pbits); if (len) { ip->in6_16[5] = htons(65535); ip->in6_16[6] = htons(ntohl(addr) >> 16); ip->in6_16[7] = htons(ntohl(addr) & 65535); - return len; + if (pbits) + *pbits += 96; } - } - return 0; /* parse failed */ + return len; + } else if (input[0] == '*') { + unsigned int pos = 0; + while (input[++pos] == '*') ; + if (input[pos] != '\0') + return 0; + if (pbits) + *pbits = 0; + return pos; + } else return 0; /* parse failed */ } Index: ircd-ircdev/ircd/m_burst.c diff -u ircd-ircdev/ircd/m_burst.c:1.13 ircd-ircdev/ircd/m_burst.c:1.14 --- ircd-ircdev/ircd/m_burst.c:1.13 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/ircd/m_burst.c Mon Oct 17 07:02:32 2005 @@ -19,7 +19,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: m_burst.c,v 1.13 2005/09/01 11:25:42 zolty Exp $ + * $Id: m_burst.c,v 1.14 2005/10/17 14:02:32 zolty Exp $ * */ @@ -403,11 +403,7 @@ strcpy(newban->who, "*"); */ newban->when = TStime(); - - newban->flags = BAN_BURSTED; /* set flags */ - if ((ptr = strrchr(ban, '@')) && check_if_ipmask(ptr + 1)) - newban->flags |= BAN_IPMASK; - + newban->flags = BAN_BURSTED; newban->next = 0; if (lp) lp->next = newban; /* link it in */ Index: ircd-ircdev/ircd/m_invite.c diff -u ircd-ircdev/ircd/m_invite.c:1.13 ircd-ircdev/ircd/m_invite.c:1.14 --- ircd-ircdev/ircd/m_invite.c:1.13 Sun Jul 3 13:21:42 2005 +++ ircd-ircdev/ircd/m_invite.c Mon Oct 17 07:02:32 2005 @@ -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: m_invite.c,v 1.13 2005/07/03 20:21:42 zolty Exp $ + * $Id: m_invite.c,v 1.14 2005/10/17 14:02:32 zolty Exp $ * */ @@ -141,12 +141,9 @@ if (is_silenced(sptr, acptr)) return 0; - clean_channelname(parv[2]); - - if (!IsChannelPrefix(*parv[2])) - return 0; - - if (!(chptr = FindChannel(parv[2]))) { + if (!IsChannelName(parv[2]) + || !strIsIrcCh(parv[2]) + || !(chptr = FindChannel(parv[2]))) { send_reply(sptr, ERR_NOSUCHCHANNEL, parv[2]); return 0; } Index: ircd-ircdev/ircd/m_join.c diff -u ircd-ircdev/ircd/m_join.c:1.13 ircd-ircdev/ircd/m_join.c:1.14 --- ircd-ircdev/ircd/m_join.c:1.13 Thu Sep 1 04:25:42 2005 +++ ircd-ircdev/ircd/m_join.c Mon Oct 17 07:02:32 2005 @@ -18,66 +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: m_join.c,v 1.13 2005/09/01 11:25:42 zolty Exp $ + * $Id: m_join.c,v 1.14 2005/10/17 14:02:32 zolty Exp $ * */ -/* - * m_functions execute protocol messages on this server: - * - * cptr is always NON-NULL, pointing to a *LOCAL* client - * structure (with an open socket connected!). This - * identifies the physical socket where the message - * originated (or which caused the m_function to be - * executed--some m_functions may call others...). - * - * sptr is the source of the message, defined by the - * prefix part of the message if present. If not - * or prefix not found, then sptr==cptr. - * - * (!IsServer(cptr)) => (cptr == sptr), because - * prefixes are taken *only* from servers... - * - * (IsServer(cptr)) - * (sptr == cptr) => the message didn't - * have the prefix. - * - * (sptr != cptr && IsServer(sptr) means - * the prefix specified servername. (?) - * - * (sptr != cptr && !IsServer(sptr) means - * that message originated from a remote - * user (not local). - * - * combining - * - * (!IsServer(sptr)) means that, sptr can safely - * taken as defining the target structure of the - * message in this server. - * - * *Always* true (if 'parse' and others are working correct): - * - * 1) sptr->from == cptr (note: cptr->from == cptr) - * - * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr - * *cannot* be a local connection, unless it's - * actually cptr!). [MyConnect(x) should probably - * be defined as (x == x->from) --msa ] - * - * parc number of variable parameter strings (if zero, - * parv is allowed to be NULL) - * - * parv a NULL terminated list of parameter pointers, - * - * parv[0], sender (prefix string), if not present - * this points to an empty string. - * parv[1]...parv[parc-1] - * pointers to additional parameters - * parv[parc] == NULL, *always* - * - * note: it is guaranteed that parv[0]..parv[parc-1] are all - * non-NULL pointers. - */ #include "config.h" #include "channel.h" @@ -102,23 +46,25 @@ #include <stdlib.h> #include <string.h> -/* - * Helper function to find last 0 in a comma-separated list of - * channel names. +/** Searches for and handles a 0 in a join list. + * @param[in] cptr Client that sent us the message. + * @param[in] sptr Original source of message. + * @param[in] chanlist List of channels to join. + * @return First token in \a chanlist after the final 0 entry, which + * may be its nul terminator (if the final entry is a 0 entry). */ static char * -last0(char *chanlist) +last0(struct Client *cptr, struct Client *sptr, char *chanlist) { char *p; + int join0 = 0; for (p = chanlist; p[0]; p++) /* find last "JOIN 0" */ if (p[0] == '0' && (p[1] == ',' || p[1] == '\0' || !IsChannelChar(p[1]))) { - chanlist = p; /* we'll start parsing here */ - - if (!p[1]) /* hit the end */ - break; - - p++; + if (*++p == ',') + p++; + chanlist = p; + join0 = 1; } else { while (p[0] != ',' && p[0] != '\0') /* skip past channel name */ p++; @@ -127,43 +73,34 @@ break; } - return chanlist; -} - -/* - * Helper function to perform a JOIN 0 if needed; returns 0 if channel - * name is not 0, else removes user from all channels and returns 1. - */ -static int -join0(struct JoinBuf *join, struct Client *cptr, struct Client *sptr, - char *chan) -{ - struct Membership *member; - struct JoinBuf part; + if (join0) { + struct JoinBuf part; + struct Membership *member; + + joinbuf_init(&part, sptr, cptr, JOINBUF_TYPE_PARTALL, + "Left all channels", 0); + + joinbuf_join(&part, 0, 0); + + while ((member = cli_user(sptr)->channel)) + joinbuf_join(&part, member->channel, + IsZombie(member) ? CHFL_ZOMBIE : + IsDelayedJoin(member) ? CHFL_DELAYED : + 0); - /* is it a JOIN 0? */ - if (chan[0] != '0' || chan[1] != '\0') - return 0; - - joinbuf_join(join, 0, 0); /* join special channel 0 */ - - /* leave all channels */ - joinbuf_init(&part, sptr, cptr, JOINBUF_TYPE_PARTALL, - "Left all channels", 0); - - while ((member = cli_user(sptr)->channel)) - joinbuf_join(&part, member->channel, - IsZombie(member) ? CHFL_ZOMBIE : - IsDelayedJoin(member) ? CHFL_DELAYED : - 0); + joinbuf_flush(&part); - joinbuf_flush(&part); + } - return 1; + return chanlist; } -/* - * m_join - generic message handler +/** Handle a JOIN message from a client connection. + * See @ref m_functions for discussion of the arguments. + * @param[in] cptr Client that sent us the message. + * @param[in] sptr Original source of message. + * @param[in] parc Number of arguments. + * @param[in] parv Argument vector. */ int m_join(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { @@ -171,8 +108,6 @@ struct JoinBuf join; struct JoinBuf create; struct Gline *gline; - unsigned int flags = 0; - int i, j, k = 0; char *p = 0; char *chanlist; char *name; @@ -184,34 +119,33 @@ joinbuf_init(&join, sptr, cptr, JOINBUF_TYPE_JOIN, 0, 0); joinbuf_init(&create, sptr, cptr, JOINBUF_TYPE_CREATE, 0, TStime()); - chanlist = last0(parv[1]); /* find last "JOIN 0" */ + chanlist = last0(cptr, sptr, parv[1]); /* find last "JOIN 0" */ keys = parv[2]; /* remember where keys are */ - for (name = ircd_strtok(&p, chanlist, ","); name; name = ircd_strtok(&p, 0, ",")) { - clean_channelname(name); + char *key = 0; - if (join0(&join, cptr, sptr, name)) /* did client do a JOIN 0? */ - continue; + /* If we have any more keys, take the first for this channel. */ + if (!BadPtr(keys) + && (keys = strchr(key = keys, ','))) + *keys++ = '\0'; + + /* Empty keys are the same as no keys. */ + if (key && !key[0]) + key = 0; - /* bad channel name */ - if (!IsChannelName(name)) + if (!IsChannelName(name) || !strIsIrcCh(name)) { + /* bad channel name */ send_reply(sptr, ERR_NOSUCHCHANNEL, name); continue; } - /* This checks if the channel contains control codes and rejects em - * until they are gone, then we will do it otherwise - *SOB Mode* - */ - for (k = 0, j = 0; name[j]; j++) - if (IsCntrl(name[j])) - k++; - if (k > 0) - { - send_reply(sptr, ERR_NOSUCHCHANNEL, name); - continue; + if (cli_user(sptr)->joined >= feature_int(FEAT_MAXCHANNELSPERUSER) + && !HasPriv(sptr, PRIV_CHAN_LIMIT)) { + send_reply(sptr, ERR_TOOMANYCHANNELS, name); + break; /* no point processing the other channels */ } /* BADCHANed channel */ @@ -221,123 +155,111 @@ continue; } - if ((chptr = FindChannel(name))) - { - if (find_member_link(chptr, sptr)) - continue; /* already on channel */ - - flags = CHFL_DEOPPED; - } - else - flags = CHFL_CHANOP; - - /* disallow creating local channels */ - if (IsLocalChannel(name) && !chptr && !feature_bool(FEAT_LOCAL_CHANNELS)) { + if (!(chptr = FindChannel(name))) { + if ((name[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS)) { send_reply(sptr, ERR_NOSUCHCHANNEL, name); continue; - } + } - if (cli_user(sptr)->joined >= feature_int(FEAT_MAXCHANNELSPERUSER) && - !HasPriv(sptr, PRIV_CHAN_LIMIT)) { - send_reply(sptr, ERR_TOOMANYCHANNELS, chptr ? chptr->chname : name); - break; /* no point processing the other channels */ - } + if (!(chptr = get_channel(sptr, name, CGT_CREATE))) + continue; - if (chptr) { + /* Try to add the new channel as a recent target for the user. */ + if (check_target_limit(sptr, chptr, chptr->chname, 1)) { #if defined(UNDERNET) - int is_level0_op = 0; - if (!BadPtr(keys) && *chptr->mode.apass) { - /* Don't use compall for the apass, only a single key is allowed. */ - if (strcmp(chptr->mode.apass, keys) == 0) { - is_level0_op = 1; - flags &= ~CHFL_DEOPPED; - flags |= CHFL_CHANOP | CHFL_CHANNEL_MANAGER; - } - else if (*chptr->mode.upass && strcmp(chptr->mode.upass, keys) == 0) { - is_level0_op = 1; - flags &= ~CHFL_DEOPPED; - flags |= CHFL_CHANOP; - } +/* FIXME zoltan */ + chptr->members = 0; + destruct_channel(chptr); + continue; } -#elif defined(DDB) - struct Ddb *ddb; - ... [truncated message content] |