Changeset 786


Ignore:
Timestamp:
10/14/06 10:02:21 (6 years ago)
Author:
wd
Message:

Merge in many changes from modules. My bad for not staying on top of these!

Location:
branches/ithildin-scons/modules
Files:
55 edited

Legend:

Unmodified
Added
Removed
  • branches/ithildin-scons/modules/ircd/addons/acl.c

    r665 r786  
    2626 * CIDR mask, or something else) */ 
    2727#define ACL_DEFAULT_HASH 0 
    28 /* the default rule at which inserts happen */ 
    29 #define ACL_DEFAULT_RULE 1000 
    30 #define ACL_DEFAULT_CONF_RULE 2000 
    3128 
    3229/* function prototypes */ 
     
    3633XINFO_FUNC(xinfo_acl_handler); 
    3734 
    38 /* create an acl structure with the given definition (or find one if it exists 
    39  * already) and add it in to the system.  ACLs are equivalent for our purposes 
    40  * if they are in the same stage and have the same host-pattern.  It doesn't 
    41  * make sense to have an accept for a host and a deny for host (with the 
    42  * exception that hosts which have a password are considered different enough 
    43  * to be left alone. */ 
    44 acl_t *create_acl(int stage, int acc, char *host, const char *type) { 
     35/* Create an ACL with the given data.  We will override ACLs that are 
     36 * similar enough to ourself (same stage/host/access/rule#) unless they have 
     37 * special parameter data (such as passwords or 'info line' bans) */ 
     38acl_t *create_acl(int stage, int acc, char *host, const char *type, int rule) { 
    4539    acl_t *ap, *ap2; 
    4640    char *at, hostcopy[USERLEN + HOSTLEN + 2]; 
    47     struct acl_tq *list; 
     41    struct acl_list *list; 
    4842     
    49     if ((ap = find_acl(stage, host, type, NULL, NULL)) != NULL) { 
    50         if ((ap->pass != NULL && (ap->access != acc)) || ap->info != NULL) 
    51             ap = NULL; /* if it has a password, don't trample it unless we are 
    52                           adding another rule with a password and the same 
    53                           access.  if it has an info field, don't trample it at 
    54                           all. */ 
     43    /* look for an ACL in this stage from the same hostname and with the 
     44     * same access and rule number.  If we find one we will delete it unless 
     45     * it has an info-line, in which case we will leave it alone.  (This is 
     46     * sort of a broken concession to not having a create command which 
     47     * takes that information...) */ 
     48    if ((ap = find_acl(stage, acc, host, type, rule, NULL, NULL)) != NULL) { 
     49        if (ap->info != NULL) 
     50            ap = NULL; 
    5551    } 
    5652 
     
    7874     
    7975    /* add them into the big list... */ 
    80     ap->rule = acl.default_rule; 
     76    if (rule == ACL_DEFAULT_RULE) 
     77        ap->rule = acl.default_rule; 
     78    else 
     79        ap->rule = (short)rule; 
    8180    ap->hash = get_acl_hash(ap->host); 
    8281 
     
    9089        list = acl.stage3_list; 
    9190 
    92     if (TAILQ_EMPTY(list)) 
    93         TAILQ_INSERT_HEAD(list, ap, intlp); 
     91    if (LIST_EMPTY(list)) 
     92        LIST_INSERT_HEAD(list, ap, intlp); 
    9493    else { 
    95         TAILQ_FOREACH(ap2, list, intlp) { 
     94        LIST_FOREACH(ap2, list, intlp) { 
    9695            if (ap2->rule > ap->rule) { 
    97                 TAILQ_INSERT_BEFORE(ap2, ap, intlp); 
     96                LIST_INSERT_BEFORE(ap2, ap, intlp); 
    9897                break; 
    99             } 
    100         } 
    101         if (ap2 == NULL) 
    102             TAILQ_INSERT_TAIL(list, ap, intlp); 
     98            } else if (LIST_NEXT(ap2, intlp) == NULL) { 
     99                LIST_INSERT_AFTER(ap2, ap, intlp); 
     100                break; 
     101            } 
     102        } 
    103103    } 
    104104 
     
    153153/* this function finds an ACL based on stage/host/type, and possibly based on 
    154154 * the pass/info parameters. */ 
    155 acl_t *find_acl(int stage, char *hostmask, const char *type, char *pass, 
    156         char *info) { 
    157     struct acl_tq *list; 
     155acl_t *find_acl(int stage, int acc, char *hostmask, const char *type, 
     156        int rule, char *pass, char *info) { 
     157    struct acl_list *list; 
    158158    char *at, hostcopy[USERLEN + HOSTLEN + 2], user[USERLEN + 1]; 
    159159    char host[HOSTLEN + 1]; 
    160160    acl_t *ap; 
    161161 
     162     
    162163    /* extract user@host data */ 
    163164    strlcpy(hostcopy, hostmask, USERLEN + HOSTLEN + 2); 
     
    172173    } 
    173174 
     175    if (rule == ACL_DEFAULT_RULE) 
     176        rule = acl.default_rule; 
     177 
    174178    if (stage == ACL_STAGE_CONNECT) 
    175179        list = acl.stage1_list; 
     
    180184 
    181185    /* now try and find them in the bucket. */ 
    182     TAILQ_FOREACH(ap, list, intlp) { 
     186    LIST_FOREACH(ap, list, intlp) { 
     187        if (acc != ACL_ACCESS_ANY && ap->access != acc) 
     188            continue; 
     189        if (rule != ACL_ANY_RULE && ap->rule != rule) 
     190            continue; 
     191 
    183192        if (!strcasecmp(ap->user, user) && !strcasecmp(ap->host, host) && 
    184193                !strcasecmp(ap->type, type) && 
     
    202211    /* and remove it from whatever list it's in */ 
    203212    if (ap->stage == ACL_STAGE_CONNECT) 
    204         TAILQ_REMOVE(acl.stage1_list, ap, intlp); 
     213        LIST_REMOVE(ap, intlp); 
    205214    else if (ap->stage == ACL_STAGE_PREREG) 
    206         TAILQ_REMOVE(acl.stage2_list, ap, intlp); 
     215        LIST_REMOVE(ap, intlp); 
    207216    else 
    208         TAILQ_REMOVE(acl.stage3_list, ap, intlp); 
     217        LIST_REMOVE(ap, intlp); 
    209218 
    210219    /* now free the memory */ 
     
    217226    if (ap->info != NULL) 
    218227        free(ap->info); 
     228    if (ap->redirect != NULL) 
     229        free(ap->redirect); 
    219230    if (ap->timer != TIMER_INVALID) 
    220231        destroy_timer(ap->timer); 
     
    308319    /* now match.  skip over any entries that aren't the default hash or our 
    309320     * hash. */ 
    310     TAILQ_FOREACH(ap, acl.stage1_list, intlp) { 
     321    LIST_FOREACH(ap, acl.stage1_list, intlp) { 
    311322        if (ap->hash != hash && ap->hash != ACL_DEFAULT_HASH) 
    312323            continue; 
     
    347358     * and the ip (using hostmatch and ipmatch).  All together that is four 
    348359     * calls.  Also, our hash space is expanded. */ 
    349     TAILQ_FOREACH(ap, acl.stage2_list, intlp) { 
     360    LIST_FOREACH(ap, acl.stage2_list, intlp) { 
    350361        if (ap->hash != hash && ap->hash != iphash && 
    351362                ap->hash != ACL_DEFAULT_HASH) 
     
    393404     * aren't allowed because of a class being full we actually have to keep on 
    394405     * looking to see if they fit in somewhere else. blechhh. */ 
    395     TAILQ_FOREACH(ap, acl.stage3_list, intlp) { 
     406    LIST_FOREACH(ap, acl.stage3_list, intlp) { 
    396407        if (ap->hash != hash && ap->hash != iphash && 
    397408                ap->hash != ACL_DEFAULT_HASH) 
     
    400411        /* check password/info first, since they're cheaper than all the 
    401412         * match calls (I guess */ 
    402         if (ap->pass != NULL && strcmp(ap->pass, cp->pass)) 
     413        if (ap->pass != NULL && cp->pass != NULL && strcmp(ap->pass, cp->pass)) 
    403414            continue; /* password incorrect */ 
    404415        if (ap->info != NULL && !match(ap->info, cp->cli->info)) 
     
    409420                /* okay, it actually matches. */ 
    410421                if (ap->access == ACL_DENY) { 
     422                    /* Is this a redirect?  Maybe so, let's send them the 
     423                     * redirect message if it is. */ 
     424                    if (ap->redirect != NULL) 
     425                        sendto_one(cp->cli, RPL_FMT(cp->cli, RPL_REDIR), 
     426                                ap->redirect, ap->redirect_port); 
     427 
    411428                    /* if there's a reason for the ban and they weren't already 
    412                      * denied set ret, otherwise just leave it alone */ 
     429                     * denied set ret, otherwise just leave it alone.  Why? 
     430                     * this is possible if there is no more room in their 
     431                     * connection class.  We want them to know that they 
     432                     * would be authorized if the class wasn't full, instead 
     433                     * of telling them they are not at all authorized. */ 
    413434                    ret = (ret != NULL ? ret : ap->reason); 
    414435                    break; /* we'll return below. */ 
     
    430451    } 
    431452 
    432     if (ret == NULL && !TAILQ_EMPTY(acl.stage3_list)) 
     453    if (ret == NULL && !LIST_EMPTY(acl.stage3_list)) 
    433454        return "You are not authorised to use this server."; 
    434455    return ret; 
     
    444465} 
    445466 
     467/* These two are the defaults for runtime and configured rule numbers, 
     468 * respectively. */ 
     469#define ACLCONF_DEFAULT_RULE 1000 
     470#define ACLCONF_DEFAULT_CONF_RULE 2000 
    446471HOOK_FUNCTION(acl_conf_hook) { 
    447472    conf_entry_t *cep; 
    448473    conf_list_t *clp; 
    449474    acl_t *ap, *ap2; 
    450     int stg, acc; 
    451     char *s, *class, *pass, *info, *reason; 
     475    int stg, acc, redirect_port = 0; 
     476    char *s, *class, *pass, *info, *reason, *redir; 
     477    char redirect[SERVLEN + 1]; 
    452478    class_t *cls; 
    453     int odr, rn, dcr; /* Old Default Rule, Rule Number, Default Conf Rule */ 
     479    int rule; 
     480    int default_rule; /* default rule for config entries */ 
    454481 
    455482    /* remove anything that points to a conf.  usually this will only be 
     
    466493    /* see about setting the default rule number.. */ 
    467494    if ((s = conf_find_entry("default-acl-rule", *ircd.confhead, 1)) != NULL) 
    468         acl.default_rule = str_conv_int(s, ACL_DEFAULT_RULE); 
     495        acl.default_rule = str_conv_int(s, ACLCONF_DEFAULT_RULE); 
    469496    else 
    470         acl.default_rule = ACL_DEFAULT_RULE; 
     497        acl.default_rule = ACLCONF_DEFAULT_RULE; 
    471498    if ((s = conf_find_entry("default-acl-conf-rule", *ircd.confhead, 1)) != 
    472499            NULL) 
    473         dcr = str_conv_int(s, ACL_DEFAULT_CONF_RULE); 
     500        default_rule = str_conv_int(s, ACLCONF_DEFAULT_CONF_RULE); 
    474501    else 
    475         dcr = ACL_DEFAULT_CONF_RULE; 
     502        default_rule = ACLCONF_DEFAULT_CONF_RULE; 
    476503 
    477504    /* now read through the conf looking for ACLs, as we find them parse and 
     
    482509    while ((cep = conf_find_next("acl", NULL, CONF_TYPE_LIST, cep, 
    483510                    *ircd.confhead, 1)) != NULL) { 
    484         rn = dcr; 
     511        rule = default_rule; 
    485512        if (cep->string != NULL) 
    486             rn = str_conv_int(cep->string, -1); 
    487         if (rn < 0 || rn > USHRT_MAX) { 
    488             log_warn("got acl with bogus rule number (%d)", rn); 
    489             rn = dcr; 
     513            rule = str_conv_int(cep->string, -1); 
     514        if (rule < 0 || rule > USHRT_MAX) { 
     515            log_warn("got acl with bogus rule number (%d)", rule); 
     516            rule = default_rule; 
    490517        } 
    491518 
     
    522549        pass = conf_find_entry("pass", clp, 1); 
    523550        info = conf_find_entry("info", clp, 1); 
    524         if (access == ACL_DENY) { 
     551        if (acc == ACL_DENY) { 
    525552            if ((reason = conf_find_entry("reason", clp, 1)) == NULL) 
    526553                reason = "You are not authorised to use this server."; 
    527554        } 
     555 
     556        if ((redir = conf_find_entry("redirect", clp, 1)) != NULL) { 
     557            /* try finding the port .. */ 
     558            if ((s = strchr(redir, ':')) != NULL) { 
     559                strlcpy(redirect, redir, (s - redir <= SERVLEN ? 
     560                            (s - redir) + 1 : SERVLEN + 1)); 
     561                if ((redirect_port = str_conv_int(s + 1, 0)) == 0) 
     562                    log_warn("Could not parse server:port combo for redirect " 
     563                            "%s", redir); 
     564            } else { 
     565                strlcpy(redirect, redir, SERVLEN + 1); 
     566                redirect_port = 6667; 
     567            } 
     568 
     569            if (acc != ACL_DENY) { 
     570                log_warn("Redirection forces a DENY ACL type."); 
     571                acc = ACL_DENY; 
     572            } 
     573        } else 
     574            *redirect = '\0'; 
     575                 
     576 
    528577 
    529578        /* now iterate through all the host lists and all the regular hosts and 
    530579         * add the acl.  yikes!  Use this macro to make life a bit easier. */ 
    531580#define ACL_PARSE_ADD(_host) do {                                             \ 
    532         odr = acl.default_rule;                                               \ 
    533         acl.default_rule = rn;                                                \ 
    534         ap = create_acl(stg, acc, _host, "acl");                              \ 
    535         acl.default_rule = odr;                                               \ 
     581        ap = create_acl(stg, acc, _host, "acl", rule);                        \ 
    536582        ap->conf = clp;                                                       \ 
    537583        ap->cls = cls;                                                        \ 
     
    546592        if (str_conv_bool(conf_find_entry("skip-ident", clp, 1), 0))          \ 
    547593            ap->flags |= ACL_FL_SKIP_IDENT;                                   \ 
     594        if (*redirect != '\0' && redirect_port != 0) {                        \ 
     595            ap->redirect = strdup(redirect);                                  \ 
     596            ap->redirect_port = redirect_port;                                \ 
     597        }                                                                     \ 
    548598} while (0) 
    549599 
     
    572622     * for ACLs based on four parameters: mask, stage, access, and type. */ 
    573623    acl_t *ap; 
    574     struct acl_tq *list; 
     624    struct acl_list *list; 
    575625    char rpl[XINFO_LEN]; 
    576626    char *mask = NULL, *type = NULL; 
     
    645695    } 
    646696    while (list != NULL) { 
    647         TAILQ_FOREACH(ap, list, intlp) { 
     697        LIST_FOREACH(ap, list, intlp) { 
    648698            if (acc != -1 && ap->access != acc) 
    649699                continue; 
     
    694744 
    695745    LIST_ALLOC(acl.list); 
    696     TAILQ_ALLOC(acl.stage1_list); 
    697     TAILQ_ALLOC(acl.stage2_list); 
    698     TAILQ_ALLOC(acl.stage3_list); 
    699  
    700     add_xinfo_handler(xinfo_acl_handler, "ACL", XINFO_HANDLER_OPER, NULL, 
     746    LIST_ALLOC(acl.stage1_list); 
     747    LIST_ALLOC(acl.stage2_list); 
     748    LIST_ALLOC(acl.stage3_list); 
     749 
     750    add_xinfo_handler(xinfo_acl_handler, "ACL", XINFO_HANDLER_OPER,  
    701751            "Provides information about the server Access Control List"); 
    702752 
     
    716766        destroy_acl(LIST_FIRST(acl.list)); 
    717767    LIST_FREE(acl.list); 
    718     TAILQ_FREE(acl.stage1_list); 
    719     TAILQ_FREE(acl.stage2_list); 
    720     TAILQ_FREE(acl.stage3_list); 
     768    LIST_FREE(acl.stage1_list); 
     769    LIST_FREE(acl.stage2_list); 
     770    LIST_FREE(acl.stage3_list); 
    721771 
    722772    remove_xinfo_handler(xinfo_acl_handler); 
  • branches/ithildin-scons/modules/ircd/addons/acl.h

    r665 r786  
    1616#define ACL_STAGE_REGISTER 3 
    1717    int     stage;                  /* one of 1, 2, or 3 */ 
     18#define ACL_ACCESS_ANY -1 
    1819#define ACL_DENY 0 
    1920#define ACL_ALLOW 1 
     
    3132                                       only) */ 
    3233    char    *pass;                  /* password */ 
     34    char    *redirect;              /* redirect server (or NULL if none) */ 
     35    int     redirect_port;          /* redirect port */ 
     36 
    3337    time_t  added;                  /* when it was added */ 
    3438    time_t  expire;                 /* when this will expire */ 
     
    4448                                       NULL otherwise. */ 
    4549 
    46     TAILQ_ENTRY(acl) intlp;         /* list pointers.  intlp is for internal */ 
    47     LIST_ENTRY(acl) lp;             /* use.  lp is part of 'the big list'. */ 
     50    LIST_ENTRY(acl) intlp;          /* list pointers.  intlp is for internal 
     51                                       (stage-segregated) lists */ 
     52    LIST_ENTRY(acl) lp;             /* lp is for the 'big list'. */ 
    4853} acl_t; 
    4954 
    50 TAILQ_HEAD(acl_tq, acl); 
     55LIST_HEAD(acl_list, acl); 
    5156 
    5257extern struct acl_module_data { 
    53     struct acl_tq *stage1_list; 
    54     struct acl_tq *stage2_list; 
    55     struct acl_tq *stage3_list; 
    56     LIST_HEAD(, acl) *list; 
     58    struct acl_list *stage1_list; 
     59    struct acl_list *stage2_list; 
     60    struct acl_list *stage3_list; 
     61    struct acl_list *list; 
    5762 
    5863    unsigned short default_rule; 
    5964} acl; 
    6065 
    61 acl_t *create_acl(int, int, char *, const char *); 
    62 acl_t *find_acl(int, char *, const char *, char *, char *); 
     66#define ACL_ANY_RULE -1 
     67#define ACL_DEFAULT_RULE -2 
     68acl_t *create_acl(int, int, char *, const char *, int); 
     69acl_t *find_acl(int, int, char *, const char *, int, char *, char *); 
    6370void destroy_acl(acl_t *); 
    6471void acl_add_timer(acl_t *, time_t); 
  • branches/ithildin-scons/modules/ircd/addons/cmode_filter.c

    r613 r786  
    3535                "chanmode_flag", "chanmode_flag_query", 0, NULL); 
    3636 
    37     add_hook(ircd.events.can_send_channel, can_send_filter); 
     37    add_hook_before(ircd.events.can_send_channel, can_send_filter, NULL); 
    3838    add_hook(me.events.read_conf, filter_conf_hook); 
    3939 
  • branches/ithildin-scons/modules/ircd/addons/cmode_strip.c

    r613 r786  
    4242                "chanmode_flag", "chanmode_flag_query", 0, NULL); 
    4343 
    44     add_hook(ircd.events.can_send_channel, can_send_strip); 
     44    add_hook_before(ircd.events.can_send_channel, can_send_strip, NULL); 
    4545    add_hook(me.events.read_conf, strip_conf_hook); 
    4646 
     
    5858 
    5959    remove_hook(ircd.events.can_send_channel, can_send_strip); 
     60    remove_hook(me.events.read_conf, strip_conf_hook); 
    6061} 
    6162 
    62 #define ANSI_CHAR        '\033' 
    63 #define BLINK_CHAR        '\006' 
    64 #define BOLD_CHAR        '\002' 
    65 #define COLOR_CHAR        '\003' 
    66 #define INVERSE_CHAR        '\026' 
    67 #define UNDERLINE_CHAR        '\037' 
     63#define ANSI_CHAR       '\033' 
     64#define BLINK_CHAR      '\006' 
     65#define BOLD_CHAR       '\002' 
     66#define COLOR_CHAR      '\003' 
     67#define INVERSE_CHAR    '\026' 
     68#define UNDERLINE_CHAR  '\037' 
    6869 
    6970HOOK_FUNCTION(strip_conf_hook) { 
     
    117118 
    118119    if (chanmode_isset(ccap->chan, chanmode_strip)) { 
    119         char *from, *to; 
    120         from = to = ccap->extra; 
     120        unsigned char *from, *to; 
     121        from = to = (unsigned char *)ccap->extra; 
    121122 
    122123        while (*from != '\0') { 
    123             if (strip_chars[(unsigned char)*from]) { 
     124            if (strip_chars[*from]) { 
     125                /* We will always skip the character here, it just may not 
     126                 * match COLOR_CHAR in which case we simply continue on */ 
    124127                if (*from++ == COLOR_CHAR) { 
    125128                    if (isdigit(*from)) { 
    126                         if (isdigit(*++from)) { 
    127                             if (*++from == ',') { 
    128                                 if (isdigit(*++from)) { 
    129                                     if (isdigit(*from)) 
    130                                         from++; 
    131                                 } 
    132                             } 
     129                        if (isdigit(*++from)) 
     130                            from++; /* skip second digit which is optional */ 
     131 
     132                        if (*from == ',' && isdigit(*(from + 1))) { 
     133                            /* background color specified ... */ 
     134                            from += 2; 
     135                            if (isdigit(*from)) 
     136                                from++; 
    133137                        } 
    134138                    } 
    135139                } 
    136                 continue; 
    137             } 
    138             *to++ = *from++; 
     140            } else 
     141                *to++ = *from++; 
    139142        } 
     143        *to = '\0'; 
    140144    } 
    141145 
  • branches/ithildin-scons/modules/ircd/addons/core.c

    r689 r786  
    303303                        match(cbp->host, host)) 
    304304                    return CHANMODE_FAIL; /* already set. */ 
     305#else 
     306                if (!strcasecmp(cbp->nick, nick) && 
     307                        !strcasecmp(cbp->user, user) && 
     308                        !strcasecmp(cbp->host, host)) 
     309                    return CHANMODE_FAIL; 
    305310#endif 
    306311            } 
  • branches/ithildin-scons/modules/ircd/addons/hostcrypt.c

    r759 r786  
    243243    if (set) 
    244244        hostcrypt_encrypt(cli); 
    245     else 
    246         hostcrypt_decrypt(cli); 
     245    else { 
     246        /* Do not decrypt their hostname if they've been added to the 
     247         * history section.  This is indicative of an automated unsetting, 
     248         * not a manual one. */ 
     249        if (!(cli->flags & IRCD_CLIENT_HISTORY)) 
     250            hostcrypt_decrypt(cli); 
     251    } 
    247252 
    248253    return 1; 
  • branches/ithildin-scons/modules/ircd/addons/hostmask.c

    r579 r786  
    2020*/ 
    2121 
     22#define CGI_IRC_SPECIAL_MASK "cgi:irc" 
     23 
    2224static struct mdext_item *class_hostmask_mdi; 
    2325 
    2426HOOK_FUNCTION(hostmask_conf_hook); 
    2527HOOK_FUNCTION(hostmask_cc_hook); 
     28static int validate_cgiirc_host(const char *, char **, char **); 
    2629 
    2730MODULE_LOADER(hostmask) { 
     
    5356            /* verify the mask.  make sure it consists ONLY of valid 
    5457             * characters, and that it has multiple parts. */ 
    55             if (!istr_okay(ircd.maps.host, s) || strchr(s, '.') == NULL) 
    56                 log_error("hostmask %s is invalid.", s); 
    57             else 
     58            if (strcasecmp(s, CGI_IRC_SPECIAL_MASK) && 
     59                    (!istr_okay(ircd.maps.host, s) || 
     60                     strchr(s, '.') == NULL)) 
     61                log_error("hostmask for class %s is invalid", cls->name); 
     62            else { 
    5863                strlcpy(mdext(cls, class_hostmask_mdi), s, HOSTLEN + 1); 
     64                log_debug("setting hostmask for class %s to %s", cls->name, 
     65                        mdext(cls, class_hostmask_mdi)); 
     66            } 
    5967        } 
    6068    } 
     
    6573HOOK_FUNCTION(hostmask_cc_hook) { 
    6674    client_t *cli = (client_t *)data; 
    67     char *mask = NULL; 
     75    char *mask, *ip; 
    6876 
    69     if (cli->conn != NULL) 
    70         mask = mdext(cli->conn->cls, class_hostmask_mdi); 
     77    if (cli->conn == NULL) 
     78        return NULL; /* nothing to do */ 
    7179 
     80    mask = ip = NULL; 
     81 
     82    mask = mdext(cli->conn->cls, class_hostmask_mdi); 
    7283    if (mask != NULL && *mask != '\0') { 
     84        if (!strcasecmp(mask, CGI_IRC_SPECIAL_MASK)) { 
     85            /* Special CGI:IRC hack.  We take the password, if supplied, an 
     86             * use it as a hostname (as long as it's valid).  Good stuff. */ 
     87            if (cli->conn->pass != NULL && *cli->conn->pass != '\0' && 
     88                    validate_cgiirc_host(cli->conn->pass, &ip, &mask)) { 
     89                log_debug("cgi:irc connection masked as %s / %s", ip, mask); 
     90                strcpy(cli->ip, ip); /* set the IP as well */ 
     91            } else { 
     92                log_warn("cgi:irc hostmasked connection provided invalid " 
     93                        "host (%s) (%s!%s@%s)", 
     94                        (cli->conn->pass == NULL ? "" : cli->conn->pass), 
     95                        cli->nick, cli->user, cli->host); 
     96                return NULL; 
     97            } 
     98            /* fallthrough to normal mask case. */ 
     99        } 
    73100        sendto_flag(SFLAG("SPY"), "Changing hostname for %s!%s@%s to %s", 
    74101                cli->nick, cli->user, cli->host, mask); 
     
    79106} 
    80107 
     108/* CGIIRC(6)+__(2)+\0(1)+ip+host */ 
     109#define CGIIRC_HOST_SIZE 9 + IPADDR_MAXLEN + HOSTLEN 
     110 
     111/* validate the string from a CGI:IRC connection.  The string is of the form 
     112 * CGIIRC_<ip>_<host>.  We ensure that both the IP and hostname are valid.  */ 
     113static int validate_cgiirc_host(const char *in, char **ip, char **host) { 
     114    static char str[CGIIRC_HOST_SIZE]; 
     115    char *s_ip, *s_host; 
     116 
     117    *ip = *host = NULL; 
     118    strlcpy(str, in, CGIIRC_HOST_SIZE); 
     119     
     120    if (strncmp(str, "CGIIRC_", 7)) 
     121        return 0; 
     122 
     123    s_ip = str + 7; 
     124    if ((s_host = strchr(s_ip, '_')) == NULL) 
     125        return 0; /* no hostname */ 
     126    *s_host++ = '\0'; 
     127 
     128    /* now we have ip/host, let's validate */ 
     129    if (*s_ip == '\0' || *s_host == '\0') 
     130        return 0; 
     131 
     132    if (get_address_type(s_ip) == PF_UNSPEC) 
     133        return 0; /* bad IP */ 
     134 
     135    if (strchr(s_host, '.') == NULL || !istr_okay(ircd.maps.host, s_host)) 
     136        return 0; /* bogus host */ 
     137 
     138    *ip = s_ip; 
     139    *host = s_host; 
     140    return 1; 
     141} 
     142 
    81143/* vi:set ts=8 sts=4 sw=4 tw=76 et: */ 
  • branches/ithildin-scons/modules/ircd/addons/quarantine.c

    r579 r786  
    237237    } 
    238238 
    239     add_xinfo_handler(xinfo_quarantine_handler, "QUARANTINE", 0, NULL, 
     239    add_xinfo_handler(xinfo_quarantine_handler, "QUARANTINE", 0,  
    240240            "Provides a list of nickname and channel quarantines"); 
    241241 
  • branches/ithildin-scons/modules/ircd/addons/throttle.c

    r665 r786  
    164164 
    165165    if (tp->banned + len >= me.now)  { 
    166         if ((ap = find_acl(ACL_STAGE_CONNECT, cp->host, throttle_acl_type, 
    167                         NULL, NULL)) == NULL) { 
     166        if ((ap = find_acl(ACL_STAGE_CONNECT, ACL_DENY, cp->host, 
     167                        throttle_acl_type, ACL_DEFAULT_RULE, NULL, NULL)) == NULL) { 
    168168            ap = create_acl(ACL_STAGE_CONNECT, ACL_DENY, cp->host, 
    169                     throttle_acl_type); 
     169                    throttle_acl_type, ACL_DEFAULT_RULE); 
    170170            ap->reason = strdup(THROTTLE_ERRMSG); 
    171171        } 
  • branches/ithildin-scons/modules/ircd/client.c

    r744 r786  
    6868            sendto_serv_butone(cli->server, cli, NULL, NULL, "QUIT", ":%s", 
    6969                    msg); 
    70         /* uh, also, if they're leaving from a squit we need to send a QUIT to 
    71          * servers without NOQUIT support. */ 
    72         if (cli->flags & IRCD_CLIENT_SQUIT) 
    73             sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, cli->server, 
    74                     cli, NULL, NULL, "QUIT", ":%s", msg); 
    7570 
    7671        clp = LIST_FIRST(&cli->chans); 
     
    119114            ircd.stats.serv.unkclients--; 
    120115        cli->conn->cli = NULL; 
    121         destroy_connection(cli->conn, msg); 
     116 
     117        /* If sendq_flush does not close the connection for us (it will 
     118         * return 0 if it does) then close the connection.  This ensures 
     119         * that we do best-effort work on dumping the last dribbly bits of 
     120         * the sendq out to the client if we can.  We do not try hard to 
     121         * make this work, though! */ 
     122        if (sendq_flush(cli->conn)) 
     123            destroy_connection(cli->conn, msg); 
    122124    } 
    123125 
     
    137139 * however, as that is left up to the caller. */ 
    138140void client_change_nick(client_t *cli, char *to) { 
    139     int casechng; 
     141    int casechng = !istrcmp(ircd.maps.nick, cli->nick, to); 
    140142     
    141143    /* check to see if this is just a case change.  if it is, istrcmp will 
    142144     * return 0.  if it's a case change, we don't do anything except set the 
    143145     * new nickname in the client structure. */ 
    144     casechng = !istrcmp(ircd.maps.nick, cli->nick, to); 
    145     if (!casechng) { 
     146    if (*cli->nick != '\0' && !casechng) { 
    146147        hash_delete(ircd.hashes.client, cli); 
    147         client_add_history(cli); 
    148     } 
     148 
     149        /* History entries for unregistered clients are extremely useless, 
     150         * and detrimental sometimes. */ 
     151        if (CLIENT_REGISTERED(cli)) 
     152            client_add_history(cli); 
     153    } 
     154 
    149155    strncpy(cli->nick, to, NICKLEN); 
     156 
    150157    if (!casechng) { 
    151158        hash_insert(ircd.hashes.client, cli); 
    152         hook_event(ircd.events.client_nick, cli); 
     159 
     160        /* We only hook client_nick for registered clients, there is little 
     161         * value in hooking it for nonregistered folks. */ 
     162        if (CLIENT_REGISTERED(cli)) 
     163            hook_event(ircd.events.client_nick, cli); 
    153164    } 
    154165} 
     
    180191                if (returns[x] != NULL) {/* denied, with a reason */ 
    181192                    destroy_client(cli, (char *)returns[x]); 
    182                         return IRCD_CLOSEDCONN; /* not successful */ 
     193                        return IRCD_CONNECTION_CLOSED; /* not successful */ 
    183194                } 
    184195                x++; 
     
    189200            LIST_INSERT_HEAD(ircd.connections.clients, cp, lp); 
    190201            ircd.stats.serv.unkclients--; 
     202 
    191203        } 
    192204 
    193205        cli->signon = cli->ts = me.now; 
    194206        cli->hops = 0; /* our client, they're 0 hops from us <G> */ 
    195     } 
    196  
    197     /* do other work now.. */ 
    198     if (MYCLIENT(cli)) { 
     207 
    199208        /* only hook for local registration */ 
    200209        hook_event(ircd.events.client_connect, cli); 
     210 
     211        /* clear the password after client_connect, assume that nothing else 
     212         * will need to hook it and use it anymore. */ 
     213        if (cp != NULL) { 
     214            /* clean out their password */ 
     215            if (cp->pass != NULL) { 
     216                free(cp->pass); 
     217                cp->pass = NULL; 
     218            } 
     219        } 
    201220 
    202221        /* accounting stuff */ 
  • branches/ithildin-scons/modules/ircd/client.h

    r593 r786  
    1212 
    1313struct client { 
    14     char    nick[NICKLEN + 1];        /* nickname */ 
    15     char    user[USERLEN + 1];        /* username on IRC (different from username 
    16                                    in conn */ 
    17     char    host[HOSTLEN + 1];        /* hostname on IRC */ 
    18     char    *orighost;                /* concession for host-changing modules.  this 
    19                                    will normally point to the 'host' field of 
    20                                    the client, but may be pointed elsewhere if 
    21                                    need be. */ 
    22     char    ip[IPADDR_MAXLEN + 1]; /* IP address (NICKIP) */ 
    23     char    info[GCOSLEN + 1];        /* gecos/gcos info (ircname) */ 
     14    char    nick[NICKLEN + 1];      /* nickname */ 
     15    char    user[USERLEN + 1];      /* username on IRC (different from username 
     16                                       in conn */ 
     17    char    host[HOSTLEN + 1];      /* hostname on IRC */ 
     18    char    *orighost;              /* concession for host-changing modules.  this 
     19                                       will normally point to the 'host' field of 
     20                                       the client, but may be pointed elsewhere if 
     21                                       need be. */ 
     22    char    ip[IPADDR_MAXLEN + 1];  /* IP address (NICKIP) */ 
     23    char    info[GCOSLEN + 1];      /* gecos/gcos info (ircname) */ 
    2424 
    2525#define IRCD_CLIENT_REGISTERED        0x0001 
     
    2828#define IRCD_CLIENT_KILLED        0x0002 
    2929#define IRCD_CLIENT_HISTORY        0x0004 
    30 #define IRCD_CLIENT_SQUIT       0x0008 
    31     int            flags; 
     30    int     flags; 
    3231 
    3332    /* check to see if this is our client.  we know it's ours if their server 
     
    3635#define MYCLIENT(cli) (cli->server == ircd.me) 
    3736    struct connection *conn;        /* the connection for this client, NULL if 
    38                                    remote or pseudo-client. */ 
     37                                       remote or pseudo-client. */ 
    3938 
    40     time_t  signon;                /* signon time */ 
    41     time_t  ts;                        /* timestamp of the nickname */ 
    42     time_t  last;                /* used for idle time (different from 
    43                                    conn->last) */ 
    44     int            hops;                /* how many hops away are they? */ 
    45     uint64_t modes;                /* the user's modes, see below */ 
     39    time_t  signon;                 /* signon time */ 
     40    time_t  ts;                     /* timestamp of the nickname */ 
     41    time_t  last;                   /* used for idle time (different from 
     42                                       conn->last) */ 
     43    int     hops;                   /* how many hops away are they? */ 
     44    uint64_t modes;                 /* the user's modes, see below */ 
    4645 
    47     struct userchans chans;        /* our channels */ 
     46    struct userchans chans;         /* our channels */ 
    4847 
    49     struct privilege_set *pset;        /* privileges (usually derived from class) */ 
    50     struct server *server;        /* server which owns this client */ 
     48    struct privilege_set *pset;     /* privileges (usually derived from class) */ 
     49    struct server *server;          /* server which owns this client */ 
    5150 
    5251    struct client_history *hist; 
    5352 
    54     char    *mdext;                /* mdext data */ 
     53    char    *mdext;                 /* mdext data */ 
    5554     
    5655    LIST_ENTRY(client) lp; 
     
    139138 
    140139struct usermode { 
    141     unsigned char mode;                    /* the actual mode */ 
    142     char    avail;                    /* 1 if available, 0 otherwise */ 
    143 #define USERMODE_FL_GLOBAL  0x1            /* the usermode is spread across the 
     140    unsigned char mode;             /* the actual mode */ 
     141    char    avail;                  /* 1 if available, 0 otherwise */ 
     142#define USERMODE_FL_GLOBAL  0x1     /* the usermode is spread across the 
    144143                                       network */ 
    145 #define USERMODE_FL_OPER    0x2            /* the usermode is operator only */ 
     144#define USERMODE_FL_OPER    0x2     /* the usermode is operator only */ 
    146145#define USERMODE_FL_PRESERVE 0x4    /* preserve the mode once set unless 
    147146                                       explicitly unset by the user */ 
    148     int            flags;                    /* flags for the usermode */ 
    149     uint64_t mask;                    /* the bitmask for the mode */ 
    150     msymbol_t *changer;                    /* the changer function for the mode */ 
    151     int sflag;                            /* send flag (if any) for this mode. */ 
     147    int     flags;                  /* flags for the usermode */ 
     148    uint64_t mask;                  /* the bitmask for the mode */ 
     149    msymbol_t *changer;             /* the changer function for the mode */ 
     150    int     sflag;                  /* send flag (if any) for this mode. */ 
    152151}; 
    153152 
    154153TAILQ_HEAD(client_history_list, client_history); 
    155154struct client_history { 
    156     char    nick[NICKLEN + 1];            /* these are all the same as in the */ 
     155    char    nick[NICKLEN + 1];      /* these are all the same as in the */ 
    157156    char    serv[SERVLEN + 1]; 
    158157 
    159     client_t *cli;                    /* points to the client we created this 
     158    client_t *cli;                  /* points to the client we created this 
    160159                                       from.  for currently online clients the 
    161160                                       nick will be different. */ 
    162     time_t  signoff;                    /* when the client signed off */ 
     161    time_t  signoff;                /* when the client signed off */ 
    163162 
    164163    TAILQ_ENTRY(client_history) lp; 
     
    176175 * functions when checking for access */ 
    177176struct client_check_args { 
    178     client_t *from;        /* the client performing the action */ 
    179     client_t *to;        /* the client being acted on */ 
    180     char    *extra;        /* any extra data */ 
     177    client_t *from;                 /* the client performing the action */ 
     178    client_t *to;                   /* the client being acted on */ 
     179    char    *extra;                 /* any extra data */ 
    181180}; 
    182181 
    183 #define CLIENT_CHECK_OVERRIDE        HOOK_COND_SPASS 
    184 #define CLIENT_CHECK_OK                HOOK_COND_PASS 
    185 #define CLIENT_CHECK_NO                HOOK_COND_FAIL 
     182#define CLIENT_CHECK_OVERRIDE   HOOK_COND_SPASS 
     183#define CLIENT_CHECK_OK         HOOK_COND_PASS 
     184#define CLIENT_CHECK_NO         HOOK_COND_FAIL 
    186185int client_check_access(client_t *, client_t *, char *, event_t *); 
    187186#define can_can_send_client(from, to, arg) \ 
  • branches/ithildin-scons/modules/ircd/command.c

    r744 r786  
    401401            } 
    402402        } 
    403         /* check operator and command use privileges */ 
     403        /* check operator and command use privileges.  Why do this only for 
     404         * local clients?  Because we need to assume that even if we are not 
     405         * configured to accept commands from a client, every other server 
     406         * is.  Without a distributed privilege understanding we have to 
     407         * assume positive intent. */ 
    404408        if ((cmd->client.flags & COMMAND_FL_OPERATOR && !OPER(cli)) || 
    405409                !BPRIV(cli, cmd->priv)) { 
     
    426430     * touch it in this state. */ 
    427431    switch ((ret = cmd->client.cmd(cmd, argc, argv, cli))) { 
    428     case IRCD_CLOSEDCONN: 
    429     case IRCD_PARSESTOP: 
     432    case IRCD_CONNECTION_CLOSED: 
     433    case IRCD_PROTOCOL_CHANGED: 
    430434        return ret; 
    431435    } 
     
    433437    /* same as above, if it's not ours we need to get out of here now. 
    434438     * commands that destroy non-local clients are not under obligation to 
    435      * return IRCD_CLOSEDCONN for those clients, so we don't know that the 
    436      * client structure is dead.  Avoid the race here. */ 
     439     * return IRCD_CONNECTION_CLOSED  for those clients, so we don't know 
     440     * that the client structure is dead, and we're done handling it at any 
     441     * rate. */ 
    437442    if (ours == false || cli->conn == NULL || cli->conn->cls->flood <= 0) 
    438443        return ret; 
     
    476481        if (cli->conn->flood >= flimit) { 
    477482            destroy_client(cli, "Excess Flood"); 
    478             return IRCD_CLOSEDCONN; 
     483            return IRCD_CONNECTION_CLOSED; 
    479484        } 
    480485    } 
  • branches/ithildin-scons/modules/ircd/command.h

    r672 r786  
    2020/* error numbers which can be returned by the command executer and commands 
    2121 * themselves */ 
    22 #define IRCD_CLOSEDCONN -1  /* connection closed, stop any parsing */ 
    23 #define IRCD_PARSESTOP  -2  /* finish current work on buffer and then stop 
    24                                parsing (this differs from CLOSEDCONN in that 
    25                                the buf field of the connection can continue to 
    26                                be modified, this is basically an allowance for 
    27                                the rfc1459 hackery) */ 
     22 
     23/* Connection has been closed.  Stop any parsing or handling of the 
     24 * associated pointers *IMMEDIATELY* */ 
     25#define IRCD_CONNECTION_CLOSED      -1 
     26/* Notification that the protocol has been changed.  This should cause 
     27 * parsing to stop AFTER the finalized cleanup on the existing buffer. 
     28 * Input functions are only gauranteed that the connection structure is 
     29 * still valid for the buffer variables, parsing routines should never be 
     30 * called after this is returned.*/ 
     31#define IRCD_PROTOCOL_CHANGED       -2 
     32 
    2833 
    2934extern union cptr_u { 
  • branches/ithildin-scons/modules/ircd/commands/acl.c

    r586 r786  
    228228 
    229229    /* see if it exists */ 
    230     ap = find_acl(stage, mask, type, NULL, NULL); 
     230    ap = find_acl(stage, acc, mask, type, ACL_DEFAULT_RULE, NULL, NULL); 
    231231 
    232232    /* are we adding..? */ 
     
    238238        } 
    239239 
    240         ap = create_acl(stage, acc, mask, type); 
     240        ap = create_acl(stage, acc, mask, type, ACL_DEFAULT_RULE); 
    241241        ap->reason = strdup(reason); 
    242242        /* if the expire time is non-zero, set a conf to 0x1 so it will get 
  • branches/ithildin-scons/modules/ircd/commands/akill.c

    r586 r786  
    5555    char *info = NULL; 
    5656 
    57     if (!SERVER_MASTER(srv)) { 
     57    /* XXX: This is a hack to allow sglinebursts to be sent from non-master 
     58     * servers.  I guess we should detect the bursting condition and only 
     59     * accept these at that time, but that's not we do it. :) */ 
     60    if (!SERVER_MASTER(srv) && strcasecmp(argv[0], "SGLINE") && 
     61            strcasecmp(argv[0], "UNSGLINE")) { 
    5862        sendto_serv_butone(NULL, NULL, ircd.me, NULL, "GLOBOPS", 
    5963                ":Non-master server %s trying to %s", srv->name, argv[0]); 
     
    6468 
    6569    if (!strcasecmp(argv[0], "AKILL")) { 
     70        char *user, *host, *set_by; 
     71        time_t set_at; 
    6672        /* arguments: host user length set-by set-at reason */ 
    6773        if ((!SERVER_SUPPORTS(sptr, PROTOCOL_SFL_SHORTAKILL) && argc != 7) || 
     
    7278        } 
    7379 
    74         snprintf(mask, USERLEN + HOSTLEN + 2, "%s@%s", argv[2], argv[1]); 
    75         if (SERVER_SUPPORTS(sptr, PROTOCOL_SFL_SHORTAKILL)) 
    76             reason = (argc > 3 ? argv[3] : ""); 
    77         else { 
     80        host = argv[1]; 
     81        user = argv[2]; 
     82        if (SERVER_SUPPORTS(sptr, PROTOCOL_SFL_SHORTAKILL)) { 
     83            reason = (argc > 3 ? argv[3] : "<no reason>"); 
     84 
     85            /* others we don't get ... */ 
     86            set_by = "<unknown>"; 
     87            set_at = me.now; 
     88            expire = 0; 
     89        } else { 
    7890            expire = str_conv_time(argv[3], 0); 
     91            set_by = argv[4]; 
     92            set_at = str_conv_time(argv[5], me.now); 
    7993            reason = argv[6]; 
    8094        } 
     95        snprintf(mask, USERLEN + HOSTLEN + 2, "%s@%s", user, host); 
     96 
     97        /* propogate out.  If we're getting data from a 'SHORTAKILL' server 
     98         * we'll end up sending out some fallacious/made up stuff.  Oh well! */ 
    8199        sendto_serv_pflag_butone(PROTOCOL_SFL_SHORTAKILL, true, sptr, NULL, 
    82                 srv, NULL, "AKILL", "%s %s :%s", argv[1], argv[2], reason); 
     100                srv, NULL, "AKILL", "%s %s :%s", host, user, reason); 
    83101        sendto_serv_pflag_butone(PROTOCOL_SFL_SHORTAKILL, false, sptr, NULL, 
    84                 srv, NULL, "AKILL", "%s %s %s %s %s :%s", argv[1], argv[2], 
    85                 argv[3], argv[4], argv[5], argv[6]); 
     102                srv, NULL, "AKILL", "%s %s %d %s %d :%s", host, user, 
     103                expire, set_by, set_at, reason); 
    86104    } else if (!strcasecmp(argv[0], "RAKILL")) { 
    87105        /* arguments: host user */ 
     
    173191 
    174192    if (op == ACL_ADD) { 
    175         ap = create_acl(stage, ACL_DENY, mask, type); 
     193        ap = create_acl(stage, ACL_DENY, mask, type, ACL_DEFAULT_RULE); 
    176194        ap->conf = ACL_CONF_TEMP; 
    177195        if (expire) 
     
    184202        acl_force_check(ap->stage, ap, srv->name, false); 
    185203    } else if (op == ACL_DEL) { 
    186         if ((ap = find_acl(stage, mask, type, NULL, info))) 
     204        if ((ap = find_acl(stage, ACL_DENY, mask, type, ACL_DEFAULT_RULE, NULL, info))) 
    187205            destroy_acl(ap); 
    188206    } 
  • branches/ithildin-scons/modules/ircd/commands/die.c

    r598 r786  
    5656    } 
    5757    while ((cp = LIST_FIRST(ircd.connections.servers)) != NULL) 
    58         destroy_server(cp->srv, smsg, NULL); 
     58        destroy_server(cp->srv, smsg); 
    5959     
    6060    /* mark the process for shutdown.  this won't actually kill the process, 
     
    6262    exit_process(NULL, NULL); 
    6363 
    64     return IRCD_CLOSEDCONN; /* and nothing else matters! */ 
     64    return IRCD_CONNECTION_CLOSED; /* and nothing else matters! */ 
    6565} 
    6666 
  • branches/ithildin-scons/modules/ircd/commands/error.c

    r601 r786  
    2424    sendto_flag(ircd.sflag.ops, "ERROR :from %s -- %s", srv->name, argv[1]); 
    2525    /* ERROR means destroy the connection. :) */ 
    26     destroy_server(srv, argv[1], srv); 
    27     return IRCD_CLOSEDCONN; 
     26    destroy_server(srv, argv[1]); 
     27    return IRCD_CONNECTION_CLOSED; 
    2828} 
    2929/* vi:set ts=8 sts=4 sw=4 tw=76 et: */ 
  • branches/ithildin-scons/modules/ircd/commands/info.c

    r579 r786  
    3434    CMSG("371", ":%s"); 
    3535#define RPL_INFOSTART 373 
    36     CMSG("373", ":Server INFO"); 
     36    CMSG("373", ":%s Server INFO"); 
    3737#define RPL_ENDOFINFO 374 
    3838    CMSG("374", ":End of /INFO list."); 
     
    5959    int i, lines = 2; 
    6060 
    61     sendto_one(cli, RPL_FMT(cli, RPL_INFOSTART)); 
     61    sendto_one(cli, RPL_FMT(cli, RPL_INFOSTART), ircd.me->name); 
    6262    if (info_text_copying != NULL) { 
    6363        for (i = 0;info_text_copying[i] != NULL;i++) 
  • branches/ithildin-scons/modules/ircd/commands/join.c

    r679 r786  
    106106                fargv[1] = clp->chan->name; 
    107107                switch ((i = command_exec_client(2, fargv, cli))) { 
    108                 case IRCD_PARSESTOP: 
    109                 case IRCD_CLOSEDCONN: 
     108                case IRCD_PROTOCOL_CHANGED: 
     109                case IRCD_CONNECTION_CLOSED: 
    110110                    return i; 
    111111                } 
     
    144144        sendto_channel_local(chan, cli, NULL, "JOIN", NULL); 
    145145        if (new) 
    146             sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, cli, NULL, 
    147                     NULL, "SJOIN", "%d %s + :%s%s", chan->created, chan->name, 
    148                     chanmode_getprefixes(chan, cli), cli->nick); 
     146            sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, NULL, 
     147                    cli->server, NULL, "SJOIN", "%d %s + :%s%s", chan->created, 
     148                    chan->name, chanmode_getprefixes(chan, cli), cli->nick); 
    149149        else 
    150150            sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, cli, 
  • branches/ithildin-scons/modules/ircd/commands/kill.c

    r579 r786  
    135135        destroy_client(cp, msg); 
    136136        if (cp == cli) 
    137             return IRCD_CLOSEDCONN; /* suicide kills end here. */ 
     137            return IRCD_CONNECTION_CLOSED; /* suicide kills end here. */ 
    138138 
    139139        if (++count == KILL_MAX) { 
  • branches/ithildin-scons/modules/ircd/commands/mode.c

    r613 r786  
    8989                        &argv[2], 1); 
    9090        } else { 
    91             return channel_mode(cli, NULL, chan, 0, argc - 2, &argv[2], 1); 
     91            return channel_mode(cli, NULL, chan, chan->created, argc - 2, 
     92                    &argv[2], 1); 
    9293        } 
    9394    } else if ((cp = find_client(argv[1])) != NULL) { 
     
    244245                (cli != NULL ? cli_server_uplink(cli) : srv), "MODE",         \ 
    245246                "%s %s", result, rbuf);                                       \ 
     247        sendto_serv_pflag_butone(PROTOCOL_SFL_TSMODE, false, sptr, cli,       \ 
     248                    srv, chan->name, "MODE", "%s%s %d", result, rbuf,         \ 
     249                    chan->created);                                           \ 
    246250        r = result + 1;                                                       \ 
    247251        rblen = 0;                                                            \ 
     
    251255} 
    252256/* this is a lot like my mode changer from bahamut 1.x.  hopefully it'll be a 
    253  * bit cleaner/more readable, thoughl.  Oh, and we now do the logic of ts 
     257 * bit cleaner/more readable, though.  Oh, and we now do the logic of ts 
    254258 * changes completely in this function.  lovely.  argc is the count only of the 
    255259 * mode changes and any arguments, and argv[0] is the mode changes if argc is 
     
    271275    char rbuf[RBUF_SIZE], *rb = rbuf; 
    272276    int rblen = 0; 
    273     int changeok = 1; 
    274     int keepours = 1; 
     277    bool changeok = true, keepours = true; 
    275278 
    276279    if (cli != NULL && MYCLIENT(cli) && argc == 0) { 
     
    298301                                       this. */ 
    299302 
    300     /* check timestamp. we only accept modes if ts is <= to ours.  if ts is 
    301      * less than ours, blast away our modes (all of them!).  if ts is greater, 
    302      * dump any mode changes.  this should really only apply at synchronization 
    303      * time, so we don't bother sending back an 'unset' if we dump their 
    304      * changes, as we assume they'll get the new ts soon anyhow. */ 
    305     if ((cli && !MYCLIENT(cli)) || srv) { 
    306         if (ts > chan->created) 
    307             changeok = 0; /* no changes! */ 
    308         else if (ts < chan->created) 
    309             keepours = 0; 
     303    /* 
     304     * Check timestamp.  From servers which do not have the TS flag in their 
     305     * protocol we ACCEPT the changes and set the channel's TS to 0 (this is 
     306     * a bad hack to support older servers, not reasonable behavior). 
     307     * In the case where TS is properly supported from the sending server we 
     308     * only accept modes if ts is <= to our own. 
     309     * 
     310     * If the sender's TS for the channel is LESS than ours we remove every 
     311     * mode we have set on the channel, treating them all as invalid.  This 
     312     * case should only *ever* occur during synchronization.  We do not send 
     313     * the mode changes down in the opposite direction because we will send 
     314     * this command, with the correct TS, down the wire and all other TS 
     315     * servers will do the same thing. 
     316     * 
     317     * Similarly if we ignore their changes (ts > ours) we simply return, 
     318     * believing that a TS server will properly remove its modes. 
     319     * 
     320     * This is perhaps an overly trusting maneuever and, should this become 
     321     * an issue, the code #if 0'd out below should suffice to reverse any 
     322     * changes we got. :) 
     323     */ 
     324 
     325    if ((cli != NULL && !MYCLIENT(cli)) || (srv != NULL && srv != ircd.me)) { 
     326        /* We need the uplink for either the server or client in order to 
     327         * verify flags. */ 
     328        server_t *sp = (srv != NULL ? srv_server_uplink(srv) : cli_server_uplink(cli)); 
     329 
     330        if (!SERVER_SUPPORTS(sp, PROTOCOL_SFL_TS)) { 
     331            /* server does not have TS support, set ts to 0, but we do not 
     332             * remove our own modes (because we believe the server will 
     333             * accept our modes as stupidly as we accepted theirs... */ 
     334            if (srv != NULL && !SERVER_MASTER(srv)) { 
     335                log_debug("server %s has no TS support, setting TS for %s to 0!", 
     336                        sp->name, chan->name); 
     337                ts = 0; 
     338                chan->created = 0; /* normally set when we reject our modes, but 
     339                                      we don't reject our modes in this case..  */ 
     340            } else 
     341                /* For master servers without TS protocol support just 
     342                 * default to giving them what we think is the right TS. 
     343                 * Why do this?  Because it fits in with the whole 'master' 
     344                 * concept.  We're going to take these modes no matter what. 
     345                 * Why break TS over it? */ 
     346                ts = chan->created; 
     347        } else { 
     348            if (ts > chan->created) 
     349                changeok = false; /* no changes! */ 
     350            else if (ts < chan->created) 
     351                keepours = false; 
     352        } 
    310353    } 
    311354 
    312355    if (!changeok) { 
     356        log_debug("rejecting changes to channel %s (ours=%d, theirs=%d", 
     357                chan->name, chan->created, ts); 
    313358#if 0 
    314359        /* invert their modes and send them right back. */ 
     
    344389        /* this is a rather complex case, we basically have to wade through 
    345390         * our modes and remove them as we go.  First we remove channel 
    346          * modes, then user prefixes.  blech, */ 
     391         * modes, then user prefixes.  
     392         * 
     393         * NB: We send reverted modes to local clients and non-ts servers 
     394         * only.  Servers which are TS will get the updated TS and revert 
     395         * their modes accordingly on their own.  This helps to reduce spam 
     396         * from changes of this nature. */ 
    347397        unsigned char *s; 
    348398        int cnt = 0; 
     
    351401        r = result + 1; 
    352402        rblen = 0; 
     403 
     404        log_debug("reverting our modes for channel %s (ours=%d, theirs=%d", 
     405                chan->name, chan->created, ts); 
     406        chan->created = ts; 
    353407 
    354408        s = ircd.cmodes.avail; 
  • branches/ithildin-scons/modules/ircd/commands/motd.c

    r579 r786  
    3737    /* numerics .. */ 
    3838#define RPL_MOTD 372 
    39     CMSG("372", ":%s"); 
     39    CMSG("372", ":- %s"); 
    4040#define RPL_MOTDSTART 375 
    4141    CMSG("375", ":- %s Message of the Day - "); 
  • branches/ithildin-scons/modules/ircd/commands/nick.c

    r593 r786  
    106106            sendto_one(cli, RPL_FMT(cli, changeok), argv[1]); 
    107107        else if (changeok < 0) { 
    108             strcpy(cli->nick, argv[1]); 
    109             /* add the client to the hash immediately to prevent collisions. */ 
    110             hash_insert(ircd.hashes.client, cli); 
     108            client_change_nick(cli, argv[1]); 
    111109            /* if the username has been filled in then assume the USER command 
    112110             * was called as well. */ 
     
    158156     * a channel, sendto_common_channels ensures they'll get the message */ 
    159157    sendto_common_channels(cli, NULL, "NICK", ":%s", argv[1]); 
    160     sendto_serv_butone(sptr, cli, NULL, NULL, "NICK", "%s :%d", argv[1], 
    161             cli->ts); 
     158    sendto_serv_butone(sptr, cli, NULL, NULL, "NICK", "%s :%d", 
     159            argv[1], cli->ts); 
    162160    client_change_nick(cli, argv[1]); 
    163161 
     
    289287check_collision(client_t *known, client_t *unknown, bool new) { 
    290288 
     289    /* This condition is extremely incorrect for what should be obvious 
     290     * reasons. */ 
     291    assert(known != unknown); 
     292 
    291293    /* known is the only one which might be a local connection.  if it is on 
    292294     * our server and is unregistered then drop it no matter what. */ 
  • branches/ithildin-scons/modules/ircd/commands/oper.c

    r579 r786  
    2323MODULE_LOADER(oper) { 
    2424 
    25     add_xinfo_handler(xinfo_oper_func, "OPERATORS", 0, NULL, 
     25    add_xinfo_handler(xinfo_oper_func, "OPERATORS", 0, 
    2626            "Provides information about server operators"); 
    2727 
  • branches/ithildin-scons/modules/ircd/commands/pass.c

    r577 r786  
    1717*/ 
    1818 
     19static void copy_in_pass(connection_t *, char *); 
     20 
    1921CLIENT_COMMAND(pass, 1, 1, COMMAND_FL_UNREGISTERED) { 
     22 
    2023    /* just copy the pass in */ 
    21     strncpy(cli->conn->pass, argv[1], PASSWDLEN); 
    22  
     24    copy_in_pass(cli->conn, argv[1]); 
    2325    return COMMAND_WEIGHT_NONE; 
    2426} 
    2527 
    2628SERVER_COMMAND(pass, 1, 1, COMMAND_FL_UNREGISTERED) { 
     29 
    2730    /* just copy the pass in */ 
    28     strncpy(srv->conn->pass, argv[1], PASSWDLEN); 
    29  
     31    copy_in_pass(srv->conn, argv[1]); 
    3032    return 0; 
    3133} 
     34 
     35static void copy_in_pass(connection_t *conn, char *pass) { 
     36 
     37    /* Hack to support CGI IRC, which sends the 'real hostname' as the client 
     38     * password.  What?  Let's use HOSTLEN I guess! */ 
     39    if (conn->pass != NULL) 
     40        free(conn->pass); /* dump whatever was there before.. */ 
     41    conn->pass = strdup(pass); 
     42} 
     43 
    3244/* vi:set ts=8 sts=4 sw=4 tw=76 et: */ 
  • branches/ithildin-scons/modules/ircd/commands/quit.c

    r579 r786  
    3737 
    3838    if (MYCLIENT(cli)) { 
     39        snprintf(fmsg, TOPICLEN, MSG_FMT(cli, quit_format), msg); 
     40        fmsg[TOPICLEN] = '\0'; 
     41 
    3942        /* We check to see if their message would be moderated in any channels 
    4043         * they are in.  If this is the case they are parted from the channels 
    4144         * before the quit is sent. */ 
    42         if (!CLIENT_MASTER(cli) && msg != NULL) { 
     45        if (!CLIENT_MASTER(cli) && *fmsg != '\0') { 
    4346            clp = LIST_FIRST(&cli->chans); 
    4447            while (clp != NULL) { 
    4548                clp2 = LIST_NEXT(clp, lpcli); 
    4649 
    47                 if (can_can_send_channel(cli, clp->chan, msg) >= 0) { 
     50                if (can_can_send_channel(cli, clp->chan, fmsg) >= 0) { 
    4851                    sendto_channel_local(clp->chan, cli, NULL, "PART", NULL); 
    4952                    sendto_serv_butone(sptr, cli, NULL, clp->chan->name, 
     
    5558        } 
    5659 
    57         /* if it's our client, the connection will be closed.  we check here 
    58          * because we can't after a destroy_client() */ 
    59         snprintf(fmsg, TOPICLEN, MSG_FMT(cli, quit_format), msg); 
    60         fmsg[TOPICLEN] = '\0'; 
     60        /* Be sure to return appropriately for our local clients */ 
    6161        destroy_client(cli, fmsg); 
    62         return IRCD_CLOSEDCONN; 
     62        return IRCD_CONNECTION_CLOSED; 
     63    } else { 
     64        destroy_client(cli, msg); 
     65        return COMMAND_WEIGHT_NONE; 
    6366    } 
    64     destroy_client(cli, msg); 
    65     return COMMAND_WEIGHT_NONE; 
    6667} 
    6768 
  • branches/ithildin-scons/modules/ircd/commands/rehash.c

    r579 r786  
    6060    /* it's for us. */ 
    6161    sendto_one(cli, RPL_FMT(cli, RPL_REHASHING), me.conf_file); 
    62     sendto_flag(ircd.sflag.ops, "%s is rehashing the server.", cli->nick); 
     62    sendto_flag(ircd.sflag.ops, "%s is rehashing the server configuration.", cli->nick); 
    6363    log_notice("%s!%s@%s rehashed the server", cli->nick, cli->user, 
    6464            cli->host); 
  • branches/ithildin-scons/modules/ircd/commands/server.c

    r624 r786  
    5353        if (clp == NULL) { 
    5454            /* no access for this server */ 
    55             destroy_server(srv, "no access", NULL); 
    56             return IRCD_CLOSEDCONN; 
     55            destroy_server(srv, "no access"); 
     56            return IRCD_CONNECTION_CLOSED; 
    5757        } 
    5858 
     
    6666                    ":Link %s cancelled, server %s already exists", 
    6767                    srv->conn->host, argv[1]); 
    68             destroy_server(srv, "Server Exists", NULL); 
    69             return IRCD_CLOSEDCONN; 
     68            destroy_server(srv, "Server Exists"); 
     69            return IRCD_CONNECTION_CLOSED; 
    7070        } 
    7171 
     
    7777        } 
    7878        if (servers > 1 && !SERVER_HUB((ircd.me))) { 
    79             destroy_server(srv, "I'm a leaf, not a hub!", NULL); 
    80             return IRCD_CLOSEDCONN; 
     79            destroy_server(srv, "I'm a leaf, not a hub!"); 
     80            return IRCD_CONNECTION_CLOSED; 
    8181        }    
    8282         
     
    9696        if (SOCKET_SSL(srv->conn->sock)) { 
    9797            if (!server_ssl_verify(srv)) { 
    98                 destroy_server(srv, "no access", NULL); 
    99                 return IRCD_CLOSEDCONN; 
     98                destroy_server(srv, "no access"); 
     99                return IRCD_CONNECTION_CLOSED; 
    100100            } 
    101101        } else 
     
    107107            s = conf_find_entry("address", clp, 1); 
    108108            if (s == NULL || strcmp(s, ip)) { 
    109                 destroy_server(srv, "no access", NULL); 
    110                 return IRCD_CLOSEDCONN; 
     109                destroy_server(srv, "no access"); 
     110                return IRCD_CONNECTION_CLOSED; 
    111111            } 
    112112 
    113113            /* now check passwords. */ 
    114114            if ((pass = conf_find_entry("theirpass", clp, 1)) == NULL) { 
    115                 destroy_server(srv, "no access", NULL); 
    116                 return IRCD_CLOSEDCONN; /* passwordless servers are a bad 
     115                destroy_server(srv, "no access"); 
     116                return IRCD_CONNECTION_CLOSED; /* passwordless servers are a bad 
    117117                                           idea! */ 
    118118            } 
    119119 
    120             if (strcmp(pass, srv->conn->pass)) { 
     120            if (srv->conn->pass == NULL || strcmp(pass, srv->conn->pass)) { 
    121121                destroy_connection(srv->conn, "password mismatch"); 
    122                 return IRCD_CLOSEDCONN; /* password mismatch */ 
     122                return IRCD_CONNECTION_CLOSED; /* password mismatch */ 
    123123            } 
    124124        } 
     
    152152                sendto_serv_butone(srv, NULL, ircd.me, NULL, "GNOTICE", 
    153153                        ":Non-Hub link %s introduced %s.", srv->name, argv[1]); 
    154                 destroy_server(srv, "Too many servers.", NULL); 
    155                 return IRCD_CLOSEDCONN; 
     154                destroy_server(srv, "Too many servers."); 
     155                return IRCD_CONNECTION_CLOSED; 
    156156            } 
    157157        } 
     
    193193    else { 
    194194        destroy_client(cli, "no access"); 
    195         return IRCD_CLOSEDCONN; 
     195        return IRCD_CONNECTION_CLOSED; 
    196196    } 
    197197 
     
    200200            (pp = find_protocol(s)) == NULL) { 
    201201        destroy_client(cli, "no access"); 
    202         return IRCD_CLOSEDCONN; 
     202        return IRCD_CONNECTION_CLOSED; 
    203203    } 
    204204 
     
    216216    cp->proto->setup(cp); 
    217217    if ((ret = s_server_cmd(NULL, argc, argv, cp->srv)) != 0) 
    218         return ret; /* Give them whatever s_server_cmd gave, it 
    219                                    will always return 0 on success, anything 
    220                                    else is an error. */ 
    221  
    222     return IRCD_PARSESTOP; /* make sure they halt immediately. */ 
     218        return ret; /* Give them whatever s_server_cmd gave, it will always 
     219                       return 0 on success, anything else is an error. */ 
     220 
     221    /* Inform them that the protocol has been changed. */ 
     222    return IRCD_PROTOCOL_CHANGED; 
    223223} 
    224224 
  • branches/ithildin-scons/modules/ircd/commands/sjoin.c

    r586 r786  
    3939    add_to_channel(cli, chan, true); 
    4040    sendto_channel_local(chan, cli, NULL, "JOIN", NULL); 
    41     sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, sptr, cli, NULL, NULL, 
    42             "SJOIN", "%d %s", chan->created, chan->name); 
    43     sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, sptr, cli, NULL, NULL, 
    44             "JOIN", "%s", chan->name); 
     41    sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, cli->server, cli, NULL, 
     42            NULL, "SJOIN", "%d %s", chan->created, chan->name); 
     43    sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, cli->server, cli, NULL, 
     44            NULL, "JOIN", "%s", chan->name); 
    4545 
    4646    return COMMAND_WEIGHT_NONE; 
     
    5555SERVER_COMMAND(sjoin, 4, 5, 0) { 
    5656    channel_t *chan; 
    57     char *joiners = argv[argc - 1], *prefix; 
    58     char *s; 
     57    char *client, *prefix; 
     58    char *buf = argv[argc - 1]; 
    5959    char realjoiners[512]; 
    6060    client_t *cp; 
    6161    time_t ts = str_conv_int(argv[1], 0); 
    62     int changeok = 1; 
     62    bool changeok = true; 
    6363    int i; 
    6464    int mset = 0; 
     
    6868 
    6969    mlen = 0; 
     70    /* make sure to set this incase we never actually touch the modes below, 
     71     * this prevents us from sending out goofy SJOIn data */ 
     72    *modes = *modebuf = '\0'; 
    7073    chan = find_channel(argv[2]); 
    7174 
     
    7578        chan->created = ts; 
    7679    }  
     80 
     81    /* Check TS before running channel_mode (which will reset TS in a 
     82     * variety of conditions).  All we need to know is whether or not to 
     83     * accept ops down below, channel_mode does the rest of the logic... */ 
     84    if (ts > chan->created) 
     85        changeok = false; 
     86 
    7787    /* handle mode changes.  we basically dump off the stuff to the mode 
    7888     * command handler.  We subtract four from argc (argv[0] is cmd, 
     
    8191    channel_mode(NULL, srv, chan, ts, (argc - 4), argv + 3, 0); 
    8292 
    83     /* check for ts changes. */ 
    84     /* we actually accept the older ts here.  if their ts is newer than 
    85      * ours we will quite likely have to undo changes and stuff. 
    86      * basically, we shouldn't trust any changes made to a channel whose ts 
    87      * isn't the same or lower than ours. */ 
    88     if (ts > chan->created) 
    89         changeok = 0; 
    90     else if (ts < chan->created) 
    91         chan->created = ts; 
    92     /* otherwise everything is the same and copacetic */ 
    93  
    9493    /* now parse the list of joiners, and propogate our SJOIN out to others */ 
    9594    *realjoiners = '\0'; 
    96     while (*joiners) { 
    97         s = strchr(joiners, ' '); 
    98         if (s != NULL) 
    99             *s = '\0'; 
     95    while ((client = strsep(&buf, " ")) != NULL) { 
     96        if (*client == '\0') 
     97            continue; 
    10098 
    10199        /* handle prefix stuff.  first find out where the prefixes end and the 
    102100         * nick begins,  prefixes can't be normal nick characters for obvious 
    103101         * reasons, so use this fact.. */ 
    104         prefix = joiners; 
    105         while (*joiners && !istr_okay(ircd.maps.nick, joiners)) 
    106             joiners++; 
     102        prefix = client; 
     103        while (*client && !istr_okay(ircd.maps.nick, client)) 
     104            client++; 
    107105        /* now we know what our prefixes are.. */ 
    108106 
    109         cp = find_client(joiners); 
     107        cp = find_client(client); 
    110108        if (cp != NULL) { 
    111109            add_to_channel(cp, chan, true); 
     
    114112                strcat(realjoiners, prefix); 
    115113            else /* otherwise, just the nick! */ 
    116                 strcat(realjoiners, joiners); 
     114                strcat(realjoiners, client); 
    117115            strcat(realjoiners, " "); 
    118116 
     
    120118             * channel. */ 
    121119            sendto_channel_local(chan, cp, NULL, "JOIN", NULL); 
    122             sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, sptr, cp, 
     120            sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, srv, cp, 
    123121                    NULL, chan->name, "JOIN", NULL); 
    124122            if (changeok) { 
    125                 while (prefix != joiners) { 
    126                     chanmode_setprefix(*prefix, chan, joiners, &i); 
     123                while (prefix != client) { 
     124                    chanmode_setprefix(*prefix, chan, client, &i); 
     125                    /* XXX: hardcoded prefixes :( */ 
    127126                    if (*prefix == '@') 
    128127                        modes[mset++] = 'o'; 
     
    132131                        continue; 
    133132                    modes[mset] = '\0'; 
    134                     mlen += sprintf(&modebuf[mlen], " %s", joiners); 
     133                    mlen += sprintf(&modebuf[mlen], " %s", client); 
    135134                    prefix++; 
    136135                } 
    137                 if (mset == 6) { /* if we've got six modes to set */ 
     136                if (mset >= 6) { /* if we've got six (or more) modes to set */ 
    138137                    /* okay... assume that non SJOIN servers also don't use 
    139138                     * TSMODE.. */ 
    140                     sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, sptr, 
    141                            NULL, srv, chan->name, "MODE", "%s%s %d", modes, 
     139                    sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, srv, 
     140                           NULL, srv, chan->name, "MODE", "+%s%s %d", modes, 
    142141                           modebuf, chan->created);  
    143142                    sendto_channel_local(chan, NULL, srv, "MODE", "+%s%s", 
     
    148147            } 
    149148        } else 
    150             log_warn("got SJOIN for unknown nick %s", joiners); 
    151  
    152         if (s != NULL) 
    153             joiners = s + 1; 
    154         else /* if there's nothing left, break */ 
    155             break; 
     149            log_warn("got SJOIN for unknown nick %s on %s", client, 
     150                    chan->name); 
    156151    } 
    157152 
    158153    /* if we have leftover modes, send them first */ 
    159154    if (changeok && mset) { 
    160         sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, sptr, 
    161                NULL, srv, chan->name, "MODE", "%s%s %d", modes, 
     155        sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, false, srv, 
     156               NULL, srv, chan->name, "MODE", "+%s%s %d", modes, 
    162157               modebuf, chan->created);  
    163158        sendto_channel_local(chan, NULL, srv, "MODE", "+%s%s", 
     
    173168        mlen += sprintf(&modebuf[mlen], " %s", argv[i++]); 
    174169 
    175     sendto_serv_butone(srv, NULL, srv, NULL, "SJOIN", "%d %s %s%s :%s", 
    176             chan->created, chan->name, argv[3], modebuf, realjoiners); 
     170    sendto_serv_pflag_butone(PROTOCOL_SFL_SJOIN, true, srv, NULL, srv, NULL, 
     171            "SJOIN", "%d %s %s%s :%s", chan->created, chan->name, argv[3], 
     172            modebuf, realjoiners); 
    177173 
    178174    return 1; 
  • branches/ithildin-scons/modules/ircd/commands/squit.c

    r744 r786  
    5555                /* preserve this old behavior. ;) I find it amusing. */ 
    5656                destroy_client(cli, argv[2]); 
    57                 return IRCD_CLOSEDCONN; 
     57                return IRCD_CONNECTION_CLOSED; 
    5858            } 
    5959 
     
    6767        if (MYSERVER(sp)) { 
    6868            if (!MYCLIENT(cli)) { 
    69                 sendto_flag(SFLAG("GNOTICE"), "Remote SQUIT %s from %s (%s)", 
    70                         sp->name, cli->nick, msg); 
    7169                sendto_serv_butone(NULL, NULL, ircd.me, NULL, "GNOTICE", 
    7270                        ":Remote SQUIT %s from %s (%s)", sp->name, cli->nick, 
    7371                        msg); 
     72                sendto_flag(SFLAG("GNOTICE"), "Remote SQUIT %s from %s (%s)", 
     73                        sp->name, cli->nick, msg); 
    7474            } 
    75             destroy_server(sp, msg, NULL); 
    76         } else { 
    77             /* Otherwise this is not a verification of a server quit, just a 
    78              * request to do so.  In this case we pass the request towards the 
    79              * server and wait for confirmation. */ 
    80             sendto_serv_from(sp, cli, NULL, sp->name, "SQUIT", msg); 
    81         } 
     75        } else 
     76            /* We are an interrim along the road, ensure the final 
     77             * destination gets the message. */ 
     78            sendto_serv_from(sp, cli, NULL, sp->name, "SQUIT", ":%s", msg); 
     79 
     80        destroy_server(sp, msg); 
    8281    } else 
    8382        sendto_one(cli, RPL_FMT(cli, ERR_NOSUCHSERVER), argv[1]); 
     
    9392     * parameters we lovingly drop the sender on his head. */ 
    9493    if (argc < 2) { 
    95         destroy_server(srv, msg, NULL); 
    96         return IRCD_CLOSEDCONN; 
     94        destroy_server(srv, msg); 
     95        return IRCD_CONNECTION_CLOSED; 
    9796    } 
    9897 
    9998    if ((sp = find_server(argv[1])) == NULL) { 
    100         log_warn("received SQUIT for unknown server %s from %s", argv[1], 
     99        log_debug("received SQUIT for unknown server %s from %s", argv[1], 
    101100                srv->name); 
    102101        return 0; 
     
    115114        sendto_serv_butone(NULL, NULL, ircd.me, NULL, "GNOTICE", 
    116115                ":Remote SQUIT %s from %s (%s)", sp->name, srv->name, msg); 
    117         destroy_server(sp, msg, NULL); 
    118         if (sp == srv) 
    119             /* be sure to let them know that the connection will be closed */ 
    120             return IRCD_CLOSEDCONN; 
    121     } else { 
    122         /* Otherwise we need to see if this is coming from the direction of the 
    123          * server, or from somewhere else.  If it's coming from somewhere else, 
    124          * it's a request to SQUIT the server, if it's coming from the 
    125          * direction of the server it means the server *did* quit */ 
    126         if (srv_server_uplink(srv) != srv_server_uplink(sp)) 
    127             /* a request to SQUIT ... */ 
    128             sendto_serv_from(sp, NULL, srv, sp->name, "SQUIT", msg); 
    129         else 
    130             destroy_server(sp, msg, srv); 
    131     } 
     116    } else 
     117        /* Otherwise we must continue to pass the SQUIT towards its final 
     118         * destination, as well as destroying the server.  See the 
     119         * commentary in destroy_server for an explanation of what messages 
     120         * this sends. */ 
     121        sendto_serv_from(sp, NULL, srv, sp->name, "SQUIT", ":%s", msg); 
    132122 
    133     return 0; 
     123    destroy_server(sp, msg); 
     124 
     125    if (sp == srv) 
     126        /* If the command came from the server we're killing, be sure to 
     127         * send back a 'CLOSEDCONN' so we stop parsing the buffer. */ 
     128        return IRCD_CONNECTION_CLOSED; 
     129    else 
     130        return 0; 
    134131} 
    135132 
  • branches/ithildin-scons/modules/ircd/commands/svinfo.c

    r598 r786  
    4141                "Link %s dropped, wrong TS protocol version (%s,%s)", 
    4242                sptr->conn->host, argv[1], argv[2]); 
    43         destroy_server(sptr, "Incompatible TS version", NULL); 
    44         return IRCD_CLOSEDCONN; 
     43        destroy_server(sptr, "Incompatible TS version"); 
     44        return IRCD_CONNECTION_CLOSED; 
    4545    } 
    4646 
     
    5757                ":Link %s dropped, excessive TS delta (delta=%d)", 
    5858                sptr->conn->host, delta); 
    59         destroy_server(sptr, "Excessive TS delta", NULL); 
    60         return IRCD_CLOSEDCONN; 
     59        destroy_server(sptr, "Excessive TS delta"); 
     60        return IRCD_CONNECTION_CLOSED; 
    6161    } 
    6262 
  • branches/ithildin-scons/modules/ircd/commands/svsmode.c

    r586 r786  
    4949    channel_t *chan; 
    5050    client_t *cp; 
    51     time_t ts; 
    52     char *s; 
    53     int oarg = 2; 
    54     int plus = 1; 
    55     uint64_t oldmode; 
    56     char result[64]; 
     51    char **myargv; 
     52    int myargc; 
    5753 
    5854    if (check_channame(argv[1]) && (chan = find_channel(argv[1])) != NULL) { 
     
    6056        channel_mode(cli, srv, chan, chan->created, argc - 2, argv + 2, 1); 
    6157    } else if ((cp = find_client(argv[1])) != NULL) { 
    62         /* this is less simple.  svsmode sends +d <x> to set 'services id' on 
    63          * people, and we'll handle that here.  XXX: this is a hack, and we 
    64          * should call user_mode() but we don't. :( */ 
    65         if (isdigit(*argv[oarg])) 
    66             ts = str_conv_int(argv[oarg++], 0); 
    67         else 
    68             ts = 0; 
     58        /* Services setting "client modes."  There's also this sort of like, 
     59         * stupid hack where they send "+d <ts>" which is a 'servicesid' 
     60         * used to track clients on the network.  We one-off support this 
     61         * and treat everything else as a real client mode. */ 
    6962 
    70         if (ts && cp->ts != ts) 
    71             return; /* not the same client */ 
    72  
    73         oldmode = cp->modes; 
    74         s = argv[oarg++]; 
    75         while (*s) { 
    76             switch (*s) { 
    77                 case '+': 
    78                     plus = 1; 
    79                     break; 
    80                 case '-': 
    81                     plus = 0; 
    82                     break; 
    83                 case 'd': 
    84                     /* special case to set 'services id' */ 
    85                     if (oarg < argc) 
    86                         SVSID(cp) = str_conv_int(argv[oarg++], 0); 
    87                     break; 
    88                 default: 
    89                     if (plus) 
    90                         usermode_set(*s, NULL, cp, NULL, NULL); 
    91                     else 
    92                         usermode_unset(*s, NULL, cp, NULL, NULL); 
    93                     break; 
    94             } 
    95             s++; 
     63        /* They may send a ts along first.  We must skip this. */ 
     64        if (isdigit(*argv[2])) { 
     65            myargv = argv + 3; /* skip to argv[3] */ 
     66            myargc = argc - 3; 
     67        } else { 
     68            myargv = argv + 2; 
     69            myargc = argc - 2; 
    9670        } 
    9771 
    98         if (MYCLIENT(cp))  { 
    99             usermode_diff(oldmode, cp->modes, result, 0); 
    100             if (*result != '\0') { 
    101                 if (cli != NULL) 
    102                     sendto_one_from(cp, cli, NULL, "MODE", ":%s", result); 
    103                 else 
    104                     sendto_one_from(cp, cp, NULL, "MODE", ":%s", result); 
    105             } 
     72        if (myargc == 2 && (!strcmp(myargv[0], "+d") || 
     73                    !strcmp(myargv[0], "+T"))) { 
     74            if (!strcmp(argv[0], "+d")) 
     75                /* this is so dumb */ 
     76                SVSID(cp) = str_conv_int(myargv[1], 0); 
     77 
     78            sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", 
     79                    "%s %s", myargv[0], myargv[1]); 
     80            return; 
    10681        } 
    107         if (argc > 3) 
    108             sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", 
    109                     "%d %s %s", ts, argv[2], argv[3]); 
    110         else 
    111             sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", 
    112                     "%d %s", ts, argv[2]); 
     82        if (MYCLIENT(cp)) 
     83            /* Is this our client?  If so do the usermode thing.  Otherwise 
     84             * just pass along the command, we expect a MODE back when it is 
     85             * processed by the user's server. */ 
     86            user_mode(NULL, cp, myargc, myargv, true); 
     87 
     88        sendto_serv_butone(sptr, cli, srv, cp->nick, "SVSMODE", "%s", 
     89                myargv[0]); 
    11390    } 
    11491} 
  • branches/ithildin-scons/modules/ircd/commands/topic.c

    r613 r786  
    3737    add_isupport("TOPICLEN", ISUPPORT_FL_INT, (char *)&i64); 
    3838 
    39     add_hook(ircd.events.channel_add, topic_channel_add_hook); 
     39    /* stuff this hook in nice and early so we are always in front of NAMES. 
     40     * THis should be harmless, at least for now.  Some clients seem to 
     41     * depend on speculative wording in RFC1459 that says RPL_TOPIC and 
     42     * RPL_NAMREPLY are sent.  They believe this implies that RPL_TOPIC must 
     43     * be first.  Most clients do not break when this isn't the case, but a 
     44     * few poorly written ones do. */ 
     45    add_hook_before(ircd.events.channel_add, topic_channel_add_hook, NULL); 
     46 
    4047    add_hook(ircd.events.server_establish, topic_server_establish_hook); 
    4148 
  • branches/ithildin-scons/modules/ircd/commands/version.c

    r579 r786  
    4040            ircd.vercomment); 
    4141    send_isupport(cli); 
     42    if (me.debug) 
     43        sendto_one(cli, "NOTICE", ":This server is running in debug mode. " 
     44                "Some traffic may be logged."); 
    4245 
    4346    return COMMAND_WEIGHT_MEDIUM; 
  • branches/ithildin-scons/modules/ircd/commands/watch.c

    r579 r786  
    200200            int sblen = 0; 
    201201 
     202            /* XXX: static sized buffer-fuck.  this must be cleaned up */ 
    202203            wp = find_watch(cli->nick); 
    203204            sendto_one(cli, RPL_FMT(cli, RPL_WATCHSTAT), cwp->count, 
    204205                    (wp != NULL ? wp->count : 0)); 
    205206            LIST_FOREACH(wlp, &cwp->list, lpwtch) { 
    206                 if (320 - sblen <= strlen(wlp->watch->nick)) { 
     207                if (310 - sblen <= strlen(wlp->watch->nick)) { 
    207208                    /* send the list if it's getting full */ 
    208209                    sendto_one(cli, RPL_FMT(cli, RPL_WATCHLIST), sbuf); 
    209210                    sblen = 0; 
    210211                } 
    211                 sblen += snprintf(sbuf + sblen, 320 - sblen, "%s ", 
     212                sblen += snprintf(sbuf + sblen, 310 - sblen, "%s ", 
    212213                        wlp->watch->nick); 
    213214            } 
  • branches/ithildin-scons/modules/ircd/commands/whois.c

    r579 r786  
    5757CLIENT_COMMAND(whois, 1, 2, 0) { 
    5858    client_t *target; 
     59    char *nick = (argc > 2 ? argv[2] : argv[1]); 
    5960    struct chanlink *clp; 
    6061#define WHOISBUFLEN 320 
     
    6768        return COMMAND_WEIGHT_HIGH; 
    6869 
    69     if (argc > 2) 
    70         target = find_client(argv[2]); 
    71     else 
    72         target = find_client(argv[1]); 
    73  
     70    target = find_client(nick); 
    7471    if (target == NULL) { 
    75         sendto_one(cli, RPL_FMT(cli, ERR_NOSUCHNICK), 
    76                 (argc > 2 ? argv[2] : argv[1])); 
    77         return COMMAND_WEIGHT_NONE; 
     72        sendto_one(cli, RPL_FMT(cli, ERR_NOSUCHNICK), nick); 
     73        sendto_one(cli, RPL_FMT(cli, RPL_ENDOFWHOIS), nick); 
     74        return COMMAND_WEIGHT_LOW; 
    7875    } 
    7976 
     
    8380    /* show them the real host if they can see it and this is either a local 
    8481     * real client (conn != NULL) or orighost points somewhere different */ 
    85     if (CAN_SEE_REAL_HOST(cli, target)) { 
    86         if (target->conn != NULL) { 
    87             /* in this case show them the values we got from identd/dns */ 
    88             if (*target->conn->user == '\0' || *target->conn->user == '~') 
    89             sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 
    90                         target->user, target->conn->host, target->ip); 
    91             else 
    92                 sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 
    93                         target->conn->user, target->conn->host, target->ip); 
    94         } else if (target->orighost != target->host) 
    95             sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 
    96                     target->user, target->orighost, target->ip); 
    97     } 
     82    if (CAN_SEE_REAL_HOST(cli, target) && target->orighost != target->host) 
     83        sendto_one(cli, RPL_FMT(cli, RPL_WHOISACTUALLY), target->nick, 
     84                target->user, target->orighost, target->ip); 
    9885    if (!CLIENT_MASTER(target) || MYCLIENT(target)) { 
    9986        /* don't show channels that master clients are in unless this is a 
  • branches/ithildin-scons/modules/ircd/commands/whowas.c

    r579 r786  
    5454    if (target == NULL) { 
    5555        sendto_one(cli, RPL_FMT(cli, ERR_WASNOSUCHNICK), argv[1]); 
    56         return COMMAND_WEIGHT_NONE; 
     56        sendto_one(cli, RPL_FMT(cli, RPL_ENDOFWHOWAS), argv[1]); 
     57        return COMMAND_WEIGHT_LOW; 
    5758    } 
    5859 
  • branches/ithildin-scons/modules/ircd/commands/xinfo.c

    r744 r786  
    3030MODULE_LOADER(xinfo) { 
    3131 
    32     add_xinfo_handler(xinfo_class_handler, "CLASS", 0, NULL, 
     32    add_xinfo_handler(xinfo_class_handler, "CLASS", 0, 
    3333            "Provides information about server connection classes"); 
    34     add_xinfo_handler(xinfo_client_handler, "CLIENT", XINFO_HANDLER_OPER, NULL, 
     34    add_xinfo_handler(xinfo_client_handler, "CLIENT", XINFO_HANDLER_OPER, 
    3535            "Provices information about clients on this server"); 
    3636    add_xinfo_handler(xinfo_connects_handler, "CONNECTS", XINFO_HANDLER_OPER, 
    37             NULL, "Shows information about server uplinks"); 
    38     add_xinfo_handler(xinfo_hash_handler, "HASH", XINFO_HANDLER_OPER, NULL, 
     37            "Shows information about server uplinks"); 
     38    add_xinfo_handler(xinfo_hash_handler, "HASH", XINFO_HANDLER_OPER, 
    3939            "Shows hash table statistics."); 
    40     add_xinfo_handler(xinfo_me_handler, "ME", XINFO_HANDLER_LOCAL, NULL, 
     40    add_xinfo_handler(xinfo_me_handler, "ME", XINFO_HANDLER_LOCAL, 
    4141            "Provides information about your connection statistics"); 
    4242    add_xinfo_handler(xinfo_privilege_handler, "PRIVILEGE", 
    43             XINFO_HANDLER_LOCAL | XINFO_HANDLER_OPER, NULL, 
     43            XINFO_HANDLER_LOCAL | XINFO_HANDLER_OPER, 
    4444            "Provides information about available privileges"); 
    45     add_xinfo_handler(xinfo_server_handler, "SERVER", 0, NULL, 
     45    add_xinfo_handler(xinfo_server_handler, "SERVER", 0, 
    4646            "Provides information about this (or other) servers"); 
    47     add_xinfo_handler(xinfo_xinfo_handler, "XINFO", 0, NULL, 
     47    add_xinfo_handler(xinfo_xinfo_handler, "XINFO", 0, 
    4848            "Provides a list of available XINFO query-handlers"); 
    4949 
     
    136136        return COMMAND_WEIGHT_LOW; /* silently ignore these */ 
    137137    if ((xhp->flags & XINFO_HANDLER_OPER && !OPER(cli)) || 
    138             (xhp->flags & XINFO_HANDLER_PRIV && !BPRIV(cli, xhp->priv))) { 
     138            !BPRIV(cli, xhp->priv)) { 
    139139        sendto_one(cli, RPL_FMT(cli, ERR_NOPRIVILEGES)); 
    140140        return COMMAND_WEIGHT_LOW; 
     
    182182    client_t *cp; 
    183183    char rpl[XINFO_LEN]; 
     184    char *user; 
     185    char ip[IPADDR_MAXLEN + 1]; 
    184186 
    185187    if (argc < 2) { 
     
    197199    } 
    198200                 
    199     snprintf(rpl, XINFO_LEN, "%s!%s@%s[%s]", cp->nick, cp->user, cp->host, 
    200             cp->ip); 
     201    if (cp->conn != NULL) { 
     202        /* give them the connection info if we can... */ 
     203        if (*cp->conn->user == '\0' || *cp->conn->user == '~') 
     204            user = cp->user; /* this information is not valuable here */ 
     205        else 
     206            user = cp->conn->user; 
     207        if (cp->conn->sock != NULL) /* should never be NULL but.. */ 
     208            get_socket_address(isock_raddr(cp->conn->sock), ip, 
     209                    IPADDR_MAXLEN + 1, NULL); 
     210        else 
     211            strcpy(ip, cp->ip); 
     212        snprintf(rpl, XINFO_LEN, "%s!%s@%s[%s]", cp->nick, user, 
     213                cp->conn->host, ip); 
     214    } else 
     215        snprintf(rpl, XINFO_LEN, "%s!%s@%s[%s]", cp->nick, cp->user, 
     216                cp->host, cp->ip); 
    201217    sendto_one(cli, RPL_FMT(cli, RPL_XINFO), "ADDRESS", rpl); 
    202218    snprintf(rpl, XINFO_LEN, "TS %d SIGNON %d IDLE %d", cp->ts, 
     
    425441            continue; /* non-local */ 
    426442        if ((xhp->flags & XINFO_HANDLER_OPER && !OPER(cli)) || 
    427                 (xhp->flags & XINFO_HANDLER_PRIV && !BPRIV(cli, xhp->priv))) 
     443                !BPRIV(cli, xhp->priv)) 
    428444            continue; /* not privileged */ 
    429445 
  • branches/ithildin-scons/modules/ircd/conf.c

    r744 r786  
    335335                    log_warn("could not enable SSL on %s/%d", addr, port); 
    336336                    destroy_socket(isp); 
     337                    return; 
    337338                } 
    338339#endif 
     
    505506            /* update their flags, too. */ 
    506507            server_set_flags(srv); 
    507         } 
    508     } 
    509  
    510     /* now check for autoconnects */ 
     508        } else 
     509            srv->conf = NULL; /* important to re-set this if we need to */ 
     510    } 
     511 
     512    /* Wipe out any existing auto-connect info.. */ 
     513    while (!LIST_EMPTY(ircd.lists.server_connects)) 
     514        destroy_server_connect(LIST_FIRST(ircd.lists.server_connects)); 
     515 
     516    /* And add new ones */ 
    511517    cep = NULL; 
    512518    while ((cep = conf_find_next("server", NULL, CONF_TYPE_LIST, cep, conf, 1)) 
  • branches/ithildin-scons/modules/ircd/connection.c

    r744 r786  
    4141        return; 
    4242    } else if (c->srv != NULL) { 
    43         destroy_server(c->srv, reason, NULL); 
     43        destroy_server(c->srv, reason); 
    4444        return; 
    4545    } 
    4646 
    47     /* empty their sendq */ 
    48     while (STAILQ_FIRST(&c->sendq) != NULL) 
    49         sendq_pop(c); 
    50     /* if there is a reason, send them a message */ 
    51     if (reason != NULL && *reason != '\0') { 
     47    /* Try to send them an error message if we can.  We assume someone has 
     48     * tried to flush their sendq or doesn't think we should, so if it's 
     49     * empty we send an error, otherwise we clean it off and don't bother 
     50     * trying to send since other sends have already failed (and we infer 
     51     * that this means the socket is not writeable) */ 
     52    if (STAILQ_EMPTY(&c->sendq) && reason != NULL && *reason != '\0') { 
    5253        snprintf(msg, 512, "\r\nERROR :Closing Link: %s (%s)\r\n",  
    5354                c->host, reason); 
    5455        socket_write(c->sock, msg, strlen(msg)); 
    55     } 
     56    } else { 
     57        while (STAILQ_FIRST(&c->sendq) != NULL) 
     58            sendq_pop(c); 
     59    } 
     60 
     61    if (c->pass != NULL) 
     62        free(c->pass); 
     63 
    5664    if (c->buf != NULL) 
    5765        free(c->buf); 
     
    182190 
    183191/* this is used to initialize the stage2 lookups.  it is kept separate so that 
    184  * SSL accpets can be done prior to the data sending. */ 
     192 * SSL accepts can be done prior to the data sending. */ 
    185193static void connection_init_lookups(connection_t *c) { 
    186194    char msg[256]; 
     
    363371    connection_t *c = (connection_t *)s->udata; 
    364372    char msg[512]; 
     373    int ret; 
    365374 
    366375#ifdef HAVE_OPENSSL 
     
    379388#endif 
    380389             
    381     /* We have to assume that once c->proto->input() is called, 'c' is 
    382      * potentially no longer valid.  We're the high end of the chain: 
    383      * socket read ready -> read data -> parse data -> execute command, the 
    384      * command execution could invalidate the client (and thus connection) so 
    385      * we take the easy road and read last because that way we don't touch 'c' 
    386      * anymore and so if it is invalidated by destruction, it's still safe. */ 
     390    /* 
     391     * Read first, then write, then check errors.  If the read succeeds 
     392     * (does not return IRCD_CONNECTION_CLOSED) we should be ensured that 
     393     * the connection is still valid. 
     394     */ 
     395 
     396    if (SOCKET_READ(s)) { 
     397        ret = (int)c->proto->input(ep, data); 
     398        /* We do this in a while loop because we may end up doing more than 
     399         * one proto change (unlikely but the support for this is nearly 
     400         * free so...) */ 
     401        while (ret == IRCD_PROTOCOL_CHANGED) { 
     402            /* A protocol change implies two things to us: 
     403             * 1) We may need to resize the buffer for this protocol.  We 
     404             * can only resize up, not down!  In the down case we do the 
     405             * wrong thing and close the connection instead of looping a 
     406             * parser to clear the buffer. (XXX: worth fixing?) 
     407             * 2) If there is any data in the buffer we should call the new 
     408             * protocol's input function, protocol changes may leave 
     409             * lingering data which would otherwise generate socket events 
     410             * if we acted on it, so.. act on it here. */ 
     411 
     412            if (c->bufsize < c->proto->bufsize) { 
     413                /* We must resize the buffer... we can happily just use 
     414                 * realloc here, since nothing should depend on the address 
     415                 * of c->buf between input calls */ 
     416                c->buf = realloc(c->buf, c->proto->bufsize); 
     417                c->bufsize = c->proto->bufsize; 
     418            } 
     419            if (c->buflen > 0) 
     420                /* We pass NULL as the event parameter for the input 
     421                 * function as a way of saying "this was forcefully called 
     422                 * outisde the normal event mechanism".  This is to tell the 
     423                 * protocol handler that it should try to flush its current 
     424                 * buffer even if there is no data from the socket. 
     425                 * XXX: this is kind of a hack... */ 
     426                ret = (int)c->proto->input(NULL, data); 
     427            else 
     428                ret = 0; /* kill the loop :) */ 
     429        } 
     430 
     431        if (ret == IRCD_CONNECTION_CLOSED) 
     432            return NULL; /* nothing to do... */ 
     433    } 
     434 
     435    if (SOCKET_WRITE(s)) 
     436        /* Only flag that we are writeable.  The writer hook takes care of 
     437         * doing buffered writes for us outside the construct of this loop. 
     438         * I thiml, potentially falsely, that it may be beneficial to batch 
     439         * writes and reads in this manner. */ 
     440        c->flags |= IRCD_CONNFL_WRITEABLE; 
     441 
    387442    if (SOCKET_ERROR(s)) { 
    388443        if (c->srv != NULL) { 
     
    400455        return NULL; 
    401456    } 
    402     if (SOCKET_WRITE(s)) 
    403         c->flags |= IRCD_CONNFL_WRITEABLE; 
    404     if (SOCKET_READ(s)) 
    405         c->proto->input(ep, data); 
    406457 
    407458    return NULL; 
  • branches/ithildin-scons/modules/ircd/connection.h

    r579 r786  
    22 * connection.h: support structures/prototypes for connection.c 
    33 *  
    4  * Copyright 2002 the Ithildin Project. 
     4 * Copyright 2002-2006 the Ithildin Project. 
    55 * See the COPYING file for more information on licensing and use. 
    66 *  
     
    88 */ 
    99 
    10 #ifndef IRCD_SOCKET_H 
    11 #define IRCD_SOCKET_H 
     10#ifndef IRCD_CONNECTION_H 
     11#define IRCD_CONNECTION_H 
    1212 
    1313struct connection { 
    14     isocket_t *sock;                    /* our socket */ 
    15     client_t *cli;                    /* either a client or a server, should */ 
    16     server_t *srv;                    /* never be both! */ 
    17     char    host[HOSTLEN + 1];            /* user and host data (as given by 
     14    isocket_t *sock;                /* our socket */ 
     15    client_t *cli;                  /* either a client or a server, should */ 
     16    server_t *srv;                  /* never be both! */ 
     17    char    host[HOSTLEN + 1];      /* user and host data (as given by 
    1818                                       identd/dns) */ 
    1919    char    user[USERLEN + 1]; 
    20     char    pass[PASSWDLEN + 1];    /* password, after registration feel 
    21                                        free to use this as empty bufferspace */ 
     20    char    *pass;                  /* password, if not NULL it must be 
     21                                       malloc'd memory.  It will be 
     22                                       destroyed after client registration.  */ 
    2223 
    23     char    *buf;                    /* temporary buffer pointer, possibly 
     24    char    *buf;                   /* temporary buffer pointer, possibly 
    2425                                       used in many places */ 
    2526    size_t  buflen;                 /* length of data in the buffer */ 
    26     size_t  bufsize;                    /* size of the temporary buffer. */ 
     27    size_t  bufsize;                /* size of the temporary buffer. */ 
     28    size_t  bufresize;              /* When non-0 a resize request for the 
     29                                       buffer.  We do this in the socket 
     30                                       event hook, after reading has 
     31                                       completed. */ 
    2732 
    28     class_t   *cls;                    /* our connection class */ 
    29     protocol_t *proto;                    /* our current protocol */ 
     33    class_t   *cls;                 /* our connection class */ 
     34    protocol_t *proto;              /* our current protocol */ 
    3035    message_set_t *mset;            /* our message set, NULL for servers */ 
    3136 
    32     time_t  signon;                    /* time of connection (not registration) */ 
    33     time_t  last;                    /* last update to this item */ 
    34     int            flood;                    /* flood level (clients only) */ 
     37    time_t  signon;                 /* time of connection (not registration) */ 
     38    time_t  last;                   /* last update to this item */ 
     39    int     flood;                  /* flood level (clients only) */ 
    3540 
    3641    struct { 
    37         int64_t sent;                    /* bytes sent */ 
    38         int64_t psent;                    /* "packets" sent */ 
    39         int64_t recv;                    /* bytes received */ 
    40         int64_t precv;                    /* "packets" received */ 
     42        int64_t sent;               /* bytes sent */ 
     43        int64_t psent;              /* "packets" sent */ 
     44        int64_t recv;               /* bytes received */ 
     45        int64_t precv;              /* "packets" received */ 
    4146    } stats; 
    4247 
    43 #define IRCD_CONNFL_DNS_PTR                0x1 
    44 #define IRCD_CONNFL_DNS_ADDR                0x2 
     48#define IRCD_CONNFL_DNS_PTR     0x1 
     49#define IRCD_CONNFL_DNS_ADDR    0x2 
    4550#define IRCD_CONNFL_DNS        (IRCD_CONNFL_DNS_PTR | IRCD_CONNFL_DNS_ADDR) 
    46 #define IRCD_CONNFL_IDENT                0x4 
    47 #define IRCD_CONNFL_STAGE2                0x8 
    48 #define IRCD_CONN_DONE(x)                                                \ 
    49     (((x)->flags & (IRCD_CONNFL_DNS | IRCD_CONNFL_IDENT)) ==                \ 
     51#define IRCD_CONNFL_IDENT       0x4 
     52#define IRCD_CONNFL_STAGE2      0x8 
     53#define IRCD_CONN_DONE(x)                                                     \ 
     54    (((x)->flags & (IRCD_CONNFL_DNS | IRCD_CONNFL_IDENT)) ==                  \ 
    5055     (IRCD_CONNFL_DNS | IRCD_CONNFL_IDENT)) 
    51 #define IRCD_CONN_NEED_STAGE2(x)        (!((x)->flags & IRCD_CONNFL_STAGE2)) 
     56#define IRCD_CONN_NEED_STAGE2(x) (!((x)->flags & IRCD_CONNFL_STAGE2)) 
    5257 
    5358#define IRCD_CONNFL_WRITEABLE 0x100 /* set if the socket is writeable */ 
     
    6873#endif 
    6974 
    70     int            flags;                    /* connection flags (DO NOT PUT 
     75    int     flags;                  /* connection flags (DO NOT PUT 
    7176                                       CLIENT/SERVER FLAGS HERE) */ 
    7277 
    73     int            sendq_items;            /* items on the send queue */ 
    74     STAILQ_HEAD(, sendq_item) sendq; /* and te queue itself */ 
     78    int     sendq_items;            /* items on the send queue */ 
     79    STAILQ_HEAD(, sendq_item) sendq;/* and te queue itself */ 
    7580    LIST_ENTRY(connection) lp; 
    7681}; 
  • branches/ithildin-scons/modules/ircd/doc/conf.txt

    r579 r786  
    6666    reason "You are not authorized to use this server."; 
    6767 
     68    // redirect: (optional) 
     69    // This specifies that a connection should be redirected to the 
     70    // specified server/port (server:port form).  If the port is left off 
     71    // it is assumed to be the default port (typically 6667).  This applies 
     72    // only to entries in stage 3. 
     73    // NB: redirect ACLs are always deny type.  That is, the redirect message 
     74    // is provided and then the connection is closed. 
     75    redirect <some-irc-server:some-port>; 
     76 
    6877    // skip-dns: (optional) 
    6978    // This option can be used to skip doing a dns lookup on a connection. 
     
    111120    // hostmask: addons/hostmask (optional) 
    112121    // This masks all users in this connection class to the given hostname. 
     122    // The special mask "cgi:irc" enables support for the CGI:IRC web gateway 
     123    // to pass in the user's real hostname via the PASS command.  If you set 
     124    // the hostmask to "cgi:irc" and a connection in the class either does not 
     125    // give a password or gives an invalid host the connection will be 
     126    // unmasked. 
    113127    hostmask <some.host.name>; 
    114128 
  • branches/ithildin-scons/modules/ircd/ircd.c

    r744 r786  
    1818IDSTRING(rcsid, "$Id$"); 
    1919 
    20 MODULE_REGISTER(PACKAGE_VERSION); 
     20MODULE_REGISTER("1.0rc1"); 
    2121/* 
    2222@DEPENDENCIES@: dns ident 
     
    443443        CMSG("004", "%s %s %s %s");                         /* rpl_myinfo */ 
    444444        CMSG("005", "%s :are available on this server.");   /* rpl_isupport */ 
     445        CMSG("010", "%s %d :Please redirect your client to this server and " 
     446                "port."); /* rpl_redir */ 
    445447        CMSG("263", ":Server load is temporarily too heavy, please wait a " 
    446448                "while and try again."); /* rpl_loadtoohigh */ 
  • branches/ithildin-scons/modules/ircd/protocol.c

    r744 r786  
    2121static int protocol_packet_parse(connection_t *cp, char *end); 
    2222 
     23/* Return codes from protocol_packet_parse */ 
     24#define PROTOCOL_PARSE_PROTOSET 1 
     25#define PROTOCOL_PARSE_1459STOP 2 
     26 
    2327#define DEFAULT_BUFFER_SIZE 512 
    2428HOOK_FUNCTION(protocol_default_input) { 
     
    4044                cp->bufsize - cp->buflen); 
    4145    if (ret < 0) 
    42         return NULL; /* the error should be picked up by the handler. */ 
     46        return (void *)0; /* the error should be picked up by the handler. */ 
    4347    else if (ret == 0) 
    44         return NULL; /* nothing to do */ 
     48        return (void *)0; /* nothing to do */ 
    4549 
    4650    cp->buflen += ret; 
     
    6367            s = strchr(cp->buf, '\n'); 
    6468            if (s == NULL) 
    65                 return NULL; /* no command terminator found and we're out of 
    66                                 data */ 
     69                return (void *)0; /* no command terminator found and we're out 
     70                                     of data */ 
    6771        } 
    6872        /* make a local copy of the packet, then pass it off to the parser. 
     
    7478        else 
    7579            *s = '\0'; 
    76         if ((ret = protocol_packet_parse(cp, s)) == IRCD_PARSESTOP) 
    77             return NULL; /* stop parsing.. */ 
    78         else if (ret == IRCD_CLOSEDCONN) 
    79             return NULL; 
     80 
     81        /* Parse the packet, we must stop parsing immediately if the 
     82         * connection is closed.  Additionally, we stop parsing immediately 
     83         * if we get the 1459 return because the code that returns it 
     84         * modifies our buffer for us.  In that case we return proto changed 
     85         * and let input be call for us above. */ 
     86        if ((ret = protocol_packet_parse(cp, s)) == IRCD_CONNECTION_CLOSED) 
     87            return (void *)ret; /* stop parsing.. */ 
     88        else if (ret == PROTOCOL_PARSE_1459STOP) 
     89            return (void *)IRCD_PROTOCOL_CHANGED; 
    8090        s++; /* increment s, now we see if our packet contains more data */ 
    8191        if ((size_t)(s - cp->buf) < cp->buflen) { 
     
    8696            *cp->buf = '\0'; /* no leftovers! */ 
    8797        } 
    88         if (ret) { 
    89             /* if the parser was otherwise successful, see if we have left over 
    90              * data and call the input function for the protocol if we do, then 
    91              * return. */ 
    92             if (cp->buflen != 0) 
    93                 cp->proto->input(NULL, (void *)cp->sock); 
    94             return NULL; /* now stop. */ 
    95         } 
    96     } 
    97  
    98     return NULL; 
     98        if (ret == PROTOCOL_PARSE_PROTOSET) 
     99            return (void *)IRCD_PROTOCOL_CHANGED; 
     100    } 
     101 
     102    return (void *)0; 
    99103} 
    100104 
     
    110114    if (!strncasecmp(cp->buf, "QUIT", 4)) { 
    111115        destroy_connection(cp, ""); 
    112         return IRCD_CLOSEDCONN; 
     116        return IRCD_CONNECTION_CLOSED; 
    113117    } else if (!strncasecmp(cp->buf, "PROTOCOL", 8)) { 
    114118        /* we received a 'protocol' command.  cool.  this makes our life easy, 
     
    119123        if (*s == '\0') { 
    120124            destroy_connection(cp, "bogus protocol command"); 
    121             return IRCD_CLOSEDCONN; 
     125            return IRCD_CONNECTION_CLOSED; 
    122126        } 
    123127 
     
    139143        sprintf(emsg, "protocol %s is not supported", s); 
    140144        destroy_connection(cp, emsg); 
    141         return IRCD_CLOSEDCONN; 
     145        return IRCD_CONNECTION_CLOSED; 
    142146    } 
    143147         
     
    147151         
    148152    if (rfc1459) { 
    149         /* an ugly hack.  re-add the [\r]\n, then call the input function. */ 
     153        /* Re-adjust the buffer and return the special token to immediately 
     154         * and successfully halt parsing (see above).  We do this because 
     155         * the protocol itself needs to receive the message we hooked onto 
     156         * for 1459 verification. */ 
    150157        if (*(end - 1) == '\0') 
    151158            *(end - 1) = '\r'; 
    152159        *end = '\n'; 
    153         /* we had re-set cp->buflen here, but I don't see why we're doing that? 
    154          * PARSESTOP prevents the buffer adjustments above, so let's not jack 
    155          * with cp->buflen.  Yikes. */ 
    156 #if 0 
    157         cp->buflen = strlen(cp->buf); /* ... */ 
    158 #endif 
    159         cp->proto->input(NULL, (void *)cp->sock); 
    160         return IRCD_PARSESTOP; 
    161     } 
    162     return 1; /* success */ 
     160 
     161        return PROTOCOL_PARSE_1459STOP; 
     162    } 
     163 
     164    return PROTOCOL_PARSE_PROTOSET; 
    163165} 
    164166 
     
    231233    if ((i64p = (uint64_t *)module_symbol(pp->dll, "protocol_flags")) != NULL) 
    232234        pp->flags = *i64p; 
     235 
     236    if ((i64p = (uint64_t *)module_symbol(pp->dll, "protocol_buffer_size")) != NULL) 
     237        pp->bufsize = *i64p; 
     238    else 
     239        pp->bufsize = DEFAULT_BUFFER_SIZE; 
    233240} 
    234241 
     
    271278        cp2 = LIST_NEXT(cp, lp); 
    272279        if (cp->proto == pp) 
    273             destroy_server(cp->srv, "protocol removed", NULL); 
     280            destroy_server(cp->srv, "protocol removed"); 
    274281        cp = cp2; 
    275282    } 
  • branches/ithildin-scons/modules/ircd/protocol.h

    r579 r786  
    2020struct protocol { 
    2121    char    *name;            /* name of protocol */ 
    22     hook_function_t input;  /* function hooked when data is available */ 
     22 
     23    /* The input function is hooked when data is available.  The return code 
     24     * (if not 0) from the command parser should be honored and also 
     25     * returned up the chain (it is used by the socket hook function) */ 
     26    hook_function_t input;  
    2327 
    2428    /* function called to create a new message.  the arguments are: sender 
     
    4347     * these are somewhat hackish.  client and server protocols may have 
    4448     * different flags with the same value, so beware! */ 
    45 #define PROTOCOL_SFL_SJOIN        0x0001 
    46 #define PROTOCOL_SFL_NOQUIT        0x0002 
    47 #define PROTOCOL_SFL_TSMODE        0x0004 
    48 #define PROTOCOL_SFL_ATTR        0x0008 
    49 #define PROTOCOL_SFL_TS                0x0010 
    50 #define PROTOCOL_SFL_SHORTAKILL        0x0020 
     49#define PROTOCOL_SFL_SJOIN      0x0001 
     50#define PROTOCOL_SFL_NOQUIT     0x0002 
     51#define PROTOCOL_SFL_TSMODE     0x0004 
     52#define PROTOCOL_SFL_ATTR       0x0008 
     53#define PROTOCOL_SFL_TS         0x0010 
     54#define PROTOCOL_SFL_SHORTAKILL 0x0020 
    5155 
    52 #define PROTOCOL_MFL_NOCACHE        (0x01ULL << 56) 
     56    /* Top eight bits (currently) reserved for "module" flags.  Right now 
     57     * just one, nocache, exists.  This instructs the send* functions to not 
     58     * cache messages when they otherwise would.  This is a hack to allow 
     59     * sending slightly different messages to different individual members 
     60     * in a protocol (see the hostcrypt addon for a real-world example of 
     61     * the usefulness/uselessness of this. :) */ 
     62#define PROTOCOL_MFL_NOCACHE    (0x01ULL << 56) 
    5363    uint64_t flags; 
     64 
     65    /* the buffer size we should allocate for clients in this protocol */ 
     66    uint64_t bufsize; 
    5467 
    5568    /* the module this protocol is represented by */ 
  • branches/ithildin-scons/modules/ircd/protocols/dreamforge.c

    r616 r786  
    22 * dreamforge.c: the dreamforge server<->server protocol 
    33 *  
    4  * Copyright 2003, 2004 the Ithildin Project. 
     4 * Copyright 2003-2006 the Ithildin Project. 
    55 * See the COPYING file for more information on licensing and use. 
    66 */ 
  • branches/ithildin-scons/modules/ircd/protocols/ithildin1.c

    r579 r786  
    2828void sync_channel(connection_t *, channel_t *); 
    2929 
    30 /* With \n included.  We allow longer server messages as a convenience here. */ 
    31 #define MAX_PACKET_LEN 1024 
     30/* With \n included.  We allow longer server messages as a convenience here 
     31 * (reduces net traffic on very big commands like SJOINs) */ 
     32#define MAX_PACKET_LEN 512 
    3233/* Use the rfc1459-type input routine, since we do effectively the same thing 
    3334 * here.  Note also that MAX_COMMAND_ARGS remains unchanged. */ 
     
    123124            "%s %d %d %s %s %s :%s", cli->nick, cli->hops + 1, cli->ts, 
    124125            cli->user, cli->orighost, cli->server->name, cli->info); 
     126    sendto_serv_from(conn->srv, cli, NULL, cli->nick, "MODE", "%s", 
     127            usermode_getstr(cli->modes, 1)); 
    125128} 
    126129 
    127 #define BUF_SIZE 768 
     130#define BUF_SIZE 320 
    128131#include "shared/sjoin_sync_channel.c" 
    129132 
  • branches/ithildin-scons/modules/ircd/protocols/shared/rfc1459_io.c

    r765 r786  
    1010#endif 
    1111 
     12const uint64_t protocol_buffer_size = MAX_PACKET_LEN; 
     13 
    1214HOOK_FUNCTION(input); 
    1315struct send_msg *output(struct protocol_sender *, char *, char *, char *, 
    1416        va_list); 
     17 
    1518/* input as much data as we can from the user. */ 
    1619HOOK_FUNCTION(input) { 
     
    6366                    (cp->cli != NULL ? cp->cli->nick : 
    6467                     (cp->srv != NULL ? cp->srv->name : "")), cp->buf); 
    65             if ((ret = packet_parse(cp)) == IRCD_CLOSEDCONN) 
    66                 return NULL; /* connection closed, stop immediately */ 
     68            if ((ret = packet_parse(cp)) == IRCD_CONNECTION_CLOSED) 
     69                return (void *)ret; /* connection closed, stop immediately */ 
    6770            s++; /* increment s, now we see if our packet contains more data */ 
    6871            if (s - cp->buf < cp->buflen) { 
     
    7578            } 
    7679 
    77             if (ret == IRCD_PARSESTOP) 
    78                 return NULL; 
     80            if (ret == IRCD_PROTOCOL_CHANGED) 
     81                return (void *)ret; 
    7982        } 
    8083    } 
    8184 
    8285    /* if there are any errors they will be picked up elsewhere */ 
    83     return NULL; 
     86    return (void *)0; 
    8487} 
    8588 
  • branches/ithildin-scons/modules/ircd/send.c

    r744 r786  
    608608    } 
    609609    free(ircd.sflag.flags[flg].name); 
     610 
     611    memset(&ircd.sflag.flags[flg], 0, sizeof(struct send_flag)); 
    610612    ircd.sflag.flags[flg].num = -1; 
    611613} 
     
    631633 
    632634    /* otherwise, put them in. */ 
    633     clp = malloc(sizeof(struct chanlink)); 
     635    clp = calloc(1, sizeof(struct chanlink)); 
    634636    clp->cli = cli; 
    635637    clp->chan = NULL; 
     
    672674    char lmsg[512]; 
    673675    va_list vl; 
    674          
     676 
    675677    if (flg < 0 || flg >= ircd.sflag.size || ircd.sflag.flags[flg].num < 0) 
    676678        return; /* nothing to do here. */ 
  • branches/ithildin-scons/modules/ircd/send.h

    r593 r786  
    166166      ircd.messages.msgs[index].default_fmt)) 
    167167 
    168 /* below here are defines for the numerics added by default */ 
    169 #define RPL_WELCOME 001 
    170 #define RPL_YOURHOST 002 
    171 #define RPL_CREATED 003 
    172 #define RPL_MYINFO 004 
    173 #define RPL_ISUPPORT 005 
     168/* below here are defines for the numerics added by default. Worth noting 
     169 * that it is unwise to prefix numerics with leading 0s because then they 
     170 * will be interpreted as octal numbers (not that uh.. I did that...) */ 
     171#define RPL_WELCOME 1 
     172#define RPL_YOURHOST 2 
     173#define RPL_CREATED 3 
     174#define RPL_MYINFO 4 
     175#define RPL_ISUPPORT 5 
     176#define RPL_REDIR 10 
    174177#define RPL_LOADTOOHIGH 263 
    175178 
  • branches/ithildin-scons/modules/ircd/server.c

    r744 r786  
    4242 * quits for its clients out to users, and sending the split message.  it calls 
    4343 * itself recursively to remove other servers connected to the server it is 
    44  * called for, as well.   The source argument is used as the 'but one' 
    45  * argument when sending SQUITs via sendto_serv_butone. */ 
     44 * called for, as well.  We do not take care of sending a SQUIT message to 
     45 * srv!  This is important, because some callers (specifically the SQUIT 
     46 * command code) may very well need to pass on a SQUIT if this isn't a 
     47 * locally connected server.  In this case they are expected to do so, we 
     48 * don't do it here because we don't have the information required. */ 
    4649static int destroy_server_count = 0; 
    4750static char destroy_server_splitmsg[512]; 
    48 void destroy_server(server_t *srv, char *msg, server_t *source) { 
     51void destroy_server(server_t *srv, char *msg) { 
    4952    client_t *cp, *cp2; 
    5053    server_t *sp, *sp2; 
     
    5659        sprintf(destroy_server_splitmsg, "%s %s", srv->parent->name, srv->name); 
    5760 
    58     /* now remove each client on the server, and remove all servers on the 
    59      * server.  this is recursive.  neat */ 
    60     cp = LIST_FIRST(ircd.lists.clients); 
    61     while (cp != NULL) { 
    62         cp2 = LIST_NEXT(cp, lp); 
    63         if (cp->server == srv) { 
    64             cp->flags |= IRCD_CLIENT_KILLED | IRCD_CLIENT_SQUIT; 
    65             destroy_client(cp, destroy_server_splitmsg); 
     61    if (SERVER_REGISTERED(srv)) { 
     62        /* First remove all its attached servers, this runs recursively and 
     63         * will send out SQUITs and QUITs and all that gack for servers that 
     64         * are NOQUIT-dumb */ 
     65        sp = LIST_FIRST(ircd.lists.servers); 
     66        while (sp != NULL) { 
     67            sp2 = LIST_NEXT(sp, lp); 
     68            if (sp->parent == srv) 
     69                destroy_server(sp, msg); 
     70            sp = sp2; 
    6671        } 
    67         cp = cp2; 
    68     } 
    69     sp = LIST_FIRST(ircd.lists.servers); 
    70     while (sp != NULL) { 
    71         sp2 = LIST_NEXT(sp, lp); 
    72         if (sp->parent == srv) 
    73             destroy_server(sp, msg, source); 
    74         sp = sp2; 
    75     } 
    76  
    77     if (SERVER_REGISTERED(srv)) { 
     72 
     73        /* Now remove all the clients from this server */ 
     74        cp = LIST_FIRST(ircd.lists.clients); 
     75        while (cp != NULL) { 
     76            cp2 = LIST_NEXT(cp, lp); 
     77            if (cp->server == srv) { 
     78                cp->flags |= IRCD_CLIENT_KILLED; 
     79                /* Send out QUITs for servers that are not 'NOQUIT' enabled. 
     80                 * In doing so we send QUITs to *everything* that doesn't do 
     81                 * NOQUIT, including the source of the SQUIT! The only place 
     82                 * we don't send towards is srv, since we believe this will 
     83                 * be handled properly downstream.  That is, NOQUIT makes 
     84                 * the strange assumption that every server in the path of a 
     85                 * SQUIT knows all about the server being squit, but other 
     86                 * servers not in the path might not.  Why/how this makes 
     87                 * sense is a mystery to me, and this is *really* spammy. */ 
     88                sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, srv, 
     89                        cp, NULL, NULL, "QUIT", ":%s", 
     90                        destroy_server_splitmsg); 
     91                destroy_client(cp, destroy_server_splitmsg); 
     92            } 
     93            cp = cp2; 
     94        } 
     95 
    7896        ircd.stats.servers--; 
    7997        if (srv->conn != NULL) 
    8098            ircd.stats.serv.servers--; 
    81         LIST_REMOVE(srv, lp); 
    82     } 
    83  
    84     /* Send the SQUIT for this server, last but not least. */ 
    85     if (SERVER_REGISTERED(srv)) { 
     99 
     100        /* Send the SQUIT for this server, last but not least. */ 
    86101        /* Some servers are really dumb.  For servers which properly support 
    87102         * NOQUIT we can simply send a single SQUIT for the first-tier 
    88103         * server.  For other servers (dreamforge is stupid like this) we 
    89          * have to send a SQUIT for *every single server* that goes away. */ 
     104         * have to send a SQUIT for *every single server* that goes away, 
     105         * and we do it in the same fashion as when sending out QUITs, that 
     106         * is, everything but srv will get a SQUIT, even if it might not 
     107         * need it (see above commentary) */ 
    90108        if (destroy_server_count == 1) 
    91             sendto_serv_butone(source, NULL, NULL, srv->name, "SQUIT", msg); 
     109            sendto_serv_butone(srv, NULL, NULL, srv->name, "SQUIT", 
     110                    ":%s", ircd.me->name); 
    92111        else 
    93             sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, source, 
    94                     NULL, NULL, srv->name, "SQUIT", msg); 
    95     } 
    96  
    97     /* if this server is ours, we have to close the connection.  also, we 
    98      * should try as best we can to flush the buffer.  this probably won't work 
    99      * very well, but we take a stab at it. */ 
     112            sendto_serv_pflag_butone(PROTOCOL_SFL_NOQUIT, false, srv, 
     113                    NULL, NULL, srv->name, "SQUIT", ":%s", ircd.me->name); 
     114 
     115        /* Lastly, remove 'srv' from the list of servers */ 
     116        LIST_REMOVE(srv, lp); 
     117    } 
     118 
     119    /* If this server is ours we have to close the connection.  We try first 
     120     * to flush the sendq.  If sendq_flush returns 0 it has closed the 
     121     * connection for us (socket error), otherwise we close it ourself. */ 
    100122    if (MYSERVER(srv)) { 
    101         if (sendq_flush(srv->conn)) { 
    102             srv->conn->srv = NULL; 
     123        srv->conn->srv = NULL; 
     124        if (sendq_flush(srv->conn)) 
    103125            destroy_connection(srv->conn, msg); 
    104         } 
    105126    } 
    106127 
     
    172193    /* XXX: we should perform more stringement protocol checks. */ 
    173194    sendto_serv_from(srv, NULL, NULL, NULL, "PROTOCOL", "%s", 
    174             s == NULL ?  "bahamut14" : s); 
     195            s == NULL ?  "ithildin1" : s); 
    175196 
    176197    /* send them our password unless we're using SSL for the server, in which 
     
    272293        LIST_REMOVE(sp->conn, lp); 
    273294        LIST_INSERT_HEAD(ircd.connections.servers, sp->conn, lp); 
     295         
     296        /* clean out the password area */ 
     297        if (sp->conn->pass != NULL) { 
     298            free(sp->conn->pass); 
     299            sp->conn->pass = NULL; 
     300        } 
    274301    } 
    275302 
     
    494521                "connection to server %s failed (%s)", sp->name, 
    495522                socket_strerror(sock)); 
    496         destroy_server(sp, "", NULL); 
     523        destroy_server(sp, ""); 
    497524        scp->srv = NULL; /* don't forget to unset this */ 
    498525 
  • branches/ithildin-scons/modules/ircd/server.h

    r598 r786  
    8888 
    8989server_t *create_server(connection_t *); 
    90 void destroy_server(server_t *, char *, server_t *); 
     90void destroy_server(server_t *, char *); 
    9191server_t *find_server(char *); 
    9292 
  • branches/ithildin-scons/modules/ircd/support.c

    r744 r786  
    3535    ip = malloc(sizeof(struct isupport)); 
    3636    memset(ip, 0, sizeof(struct isupport)); 
    37     ip->name = strdup(name); 
     37    strlcpy(ip->name, name, ISUPPORTNAME_MAXLEN + 1); 
    3838    /* now insert into a list.  we alphabetically sort our list, just 
    3939     * because I like to. :) */ 
     
    8484    if (ip != NULL) { 
    8585        LIST_REMOVE(ip, lp); 
    86         free(ip->name); 
    8786        if (!(ip->flags & ISUPPORT_FL_PRIV) && ip->value.str != NULL) 
    8887            free(ip->value.str); 
     
    127126            slen = tc = 0; 
    128127        } 
    129         slen += sprintf(str + slen, " %s", token); 
     128         
     129        /* tricky code here to prevent sending an additional space at the 
     130         * beginning of the line when one is not needed. */ 
     131        slen += sprintf(str + slen, (slen ? " %s" : "%s"), token); 
    130132    } 
    131133    /* send remnants */ 
     
    144146 * fifth is a description of the handler (usually short).  The function returns 
    145147 * non-zero upon successful installation. */ 
    146 int add_xinfo_handler(xinfo_func func, char *name, int flags, 
    147         void *udata, char *desc) { 
     148int add_xinfo_handler(xinfo_func func, char *name, int flags, char *desc) { 
    148149    struct xinfo_handler *xhp = find_xinfo_handler(name); 
     150    uint64_t i64 = 1; 
     151    char privname[XINFONAME_MAXLEN + 1 + 6]; /* add 6 for "xinfo-" tag */ 
    149152 
    150153    if (xhp != NULL) 
     
    153156    xhp = malloc(sizeof(struct xinfo_handler)); 
    154157    xhp->func = func; 
    155     xhp->name = strdup(name); 
     158    strlcpy(xhp->name, name, XINFONAME_MAXLEN + 1); 
    156159    xhp->flags = flags; 
    157     if (xhp->flags & XINFO_HANDLER_PRIV) 
    158         xhp->priv = *(int *)udata; 
    159     else 
    160         xhp->priv = -1; 
     160 
     161    /* Create a privilege for them.  Always bool, this is simply a "yes/no" 
     162     * flag to whether or not this information is available.  Always default 
     163     * to 1 */ 
     164    sprintf(privname, "xinfo-%s", xhp->name); 
     165    xhp->priv = create_privilege(privname, PRIVILEGE_FL_BOOL, &i64, NULL); 
     166 
    161167    xhp->desc = strdup((desc != NULL ? desc : "no description")); 
    162168 
     
    206212        if (xhp->func == func) { 
    207213            LIST_REMOVE(xhp, lp); 
    208             free(xhp->name); 
    209214            free(xhp->desc); 
    210215            free(xhp); 
  • branches/ithildin-scons/modules/ircd/support.h

    r593 r786  
    1111#define IRCD_SUPPORT_H 
    1212 
     13#define ISUPPORTNAME_MAXLEN 31 /* XXX: what does the spec say, if anything, 
     14                                  about this...? */ 
     15 
    1316/* a feature may have a straightforward string value, or it may have a value 
    1417 * which is connect-time dependent.  features which are connect-time dependent 
    1518 * are assumed to be privileges, but see below. */ 
    1619struct isupport { 
    17     char    *name;        /* name of the feature supported. */ 
     20    char name[ISUPPORTNAME_MAXLEN + 1]; 
    1821    union { 
    1922        char *str;        /* string value */ 
     
    4750        char **argv __UNUSED) 
    4851 
     52#define XINFONAME_MAXLEN ISUPPORTNAME_MAXLEN 
     53 
    4954/* The xinfo_handler structure contains a each xinfo handler's necessary 
    5055 * details. */ 
    5156struct xinfo_handler { 
    52     char *name; 
     57    char name[XINFONAME_MAXLEN + 1]; 
    5358    char *desc; 
    5459#define XINFO_HANDLER_LOCAL 0x1 
    5560#define XINFO_HANDLER_OPER  0x2 
    56 #define XINFO_HANDLER_PRIV  0x4 
    5761    int flags; 
    58     int priv; /* privilege, if any */ 
     62    int priv; /* privilege */ 
    5963    xinfo_func func; 
    6064 
     
    6468#define XINFO_LEN 512 
    6569 
    66 int add_xinfo_handler(xinfo_func, char *, int, void *, char *); 
     70int add_xinfo_handler(xinfo_func, char *, int, char *); 
    6771struct xinfo_handler *find_xinfo_handler(char *); 
    6872void remove_xinfo_handler(xinfo_func); 
  • branches/ithildin-scons/modules/log/log.c

    r677 r786  
    126126 
    127127                    if ((lhp->file = fopen(fname, "a")) == NULL) { 
     128                        /* Be sure to set DEFUNCT *first* to avoid nasty log 
     129                         * recursion!  This way when we come back around to 
     130                         * this rule we will not hit it again. */ 
     131                        lhp->flags |= LOG_FL_DEFUNCT; 
    128132                        log_error("cannot open logfile %s: %s", 
    129133                                lhp->filename, strerror(errno)); 
    130                         lhp->flags |= LOG_FL_DEFUNCT; 
    131134                    } 
    132135                } 
Note: See TracChangeset for help on using the changeset viewer.