X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/92fb5c3175786a5ca7ed04cd207cf23a263576a8..b5482c91035029ff8b7c970d8f5b23dcbb885da3:/src/s_user.c diff --git a/src/s_user.c b/src/s_user.c index 9007818..f8d5e0c 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -21,11 +21,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: s_user.c 3159 2007-01-25 07:08:21Z nenolod $ + * $Id: s_user.c 3586 2007-11-20 11:16:43Z nenolod $ */ #include "stdinc.h" -#include "tools.h" #include "s_user.h" #include "channel.h" #include "class.h" @@ -38,17 +37,15 @@ #include "listener.h" #include "msg.h" #include "numeric.h" -#include "commio.h" #include "s_conf.h" #include "s_newconf.h" -#include "s_log.h" +#include "logger.h" #include "s_serv.h" #include "s_stats.h" #include "scache.h" #include "send.h" #include "supported.h" #include "whowas.h" -#include "memory.h" #include "packet.h" #include "reject.h" #include "cache.h" @@ -65,6 +62,7 @@ extern char *crypt(); char umodebuf[128]; +static int orphaned_umodes = 0; int user_modes[256] = { /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x0F */ /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x1F */ @@ -96,7 +94,7 @@ int user_modes[256] = { 0, /* W */ 0, /* X */ 0, /* Y */ - 0, /* Z */ + UMODE_SSLCLIENT, /* Z */ /* 0x5B */ 0, 0, 0, 0, 0, 0, /* 0x60 */ UMODE_ADMIN, /* a */ 0, /* b */ @@ -146,33 +144,41 @@ int user_modes[256] = { int show_lusers(struct Client *source_p) { + if(rb_dlink_list_length(&lclient_list) > (unsigned long)MaxClientCount) + MaxClientCount = rb_dlink_list_length(&lclient_list); + + if((rb_dlink_list_length(&lclient_list) + rb_dlink_list_length(&serv_list)) > + (unsigned long)MaxConnectionCount) + MaxConnectionCount = rb_dlink_list_length(&lclient_list) + + rb_dlink_list_length(&serv_list); + sendto_one_numeric(source_p, RPL_LUSERCLIENT, form_str(RPL_LUSERCLIENT), (Count.total - Count.invisi), - Count.invisi, dlink_list_length(&global_serv_list)); + Count.invisi, rb_dlink_list_length(&global_serv_list)); - if(dlink_list_length(&oper_list) > 0) + if(rb_dlink_list_length(&oper_list) > 0) sendto_one_numeric(source_p, RPL_LUSEROP, - form_str(RPL_LUSEROP), dlink_list_length(&oper_list)); + form_str(RPL_LUSEROP), rb_dlink_list_length(&oper_list)); - if(dlink_list_length(&unknown_list) > 0) + if(rb_dlink_list_length(&unknown_list) > 0) sendto_one_numeric(source_p, RPL_LUSERUNKNOWN, form_str(RPL_LUSERUNKNOWN), - dlink_list_length(&unknown_list)); + rb_dlink_list_length(&unknown_list)); - if(dlink_list_length(&global_channel_list) > 0) + if(rb_dlink_list_length(&global_channel_list) > 0) sendto_one_numeric(source_p, RPL_LUSERCHANNELS, form_str(RPL_LUSERCHANNELS), - dlink_list_length(&global_channel_list)); + rb_dlink_list_length(&global_channel_list)); sendto_one_numeric(source_p, RPL_LUSERME, form_str(RPL_LUSERME), - dlink_list_length(&lclient_list), - dlink_list_length(&serv_list)); + rb_dlink_list_length(&lclient_list), + rb_dlink_list_length(&serv_list)); sendto_one_numeric(source_p, RPL_LOCALUSERS, form_str(RPL_LOCALUSERS), - dlink_list_length(&lclient_list), + rb_dlink_list_length(&lclient_list), Count.max_loc, - dlink_list_length(&lclient_list), + rb_dlink_list_length(&lclient_list), Count.max_loc); sendto_one_numeric(source_p, RPL_GLOBALUSERS, form_str(RPL_GLOBALUSERS), @@ -184,14 +190,6 @@ show_lusers(struct Client *source_p) MaxConnectionCount, MaxClientCount, Count.totalrestartcount); - if(dlink_list_length(&lclient_list) > (unsigned long)MaxClientCount) - MaxClientCount = dlink_list_length(&lclient_list); - - if((dlink_list_length(&lclient_list) + dlink_list_length(&serv_list)) > - (unsigned long)MaxConnectionCount) - MaxConnectionCount = dlink_list_length(&lclient_list) + - dlink_list_length(&serv_list); - return 0; } @@ -222,7 +220,7 @@ show_lusers(struct Client *source_p) int register_local_user(struct Client *client_p, struct Client *source_p, const char *username) { - struct ConfItem *aconf; + struct ConfItem *aconf, *xconf; struct User *user = source_p->user; char tmpstr2[IRCD_BUFSIZE]; char ipaddr[HOSTIPLEN]; @@ -249,21 +247,21 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char source_p->flags |= FLAGS_PINGSENT; return -1; } - if(!(source_p->flags2 & FLAGS2_PING_COOKIE)) + if(!(source_p->flags & FLAGS_PING_COOKIE)) { return -1; } } /* hasnt finished client cap negotiation */ - if(source_p->flags2 & FLAGS2_CLICAP) + if(source_p->flags & FLAGS_CLICAP) return -1; /* still has DNSbls to validate against */ - if(dlink_list_length(&source_p->preClient->dnsbl_queries) > 0) + if(rb_dlink_list_length(&source_p->preClient->dnsbl_queries) > 0) return -1; - client_p->localClient->last = CurrentTime; + client_p->localClient->last = rb_current_time(); /* Straight up the maximum rate of flooding... */ source_p->localClient->allow_read = MAX_FLOOD_BURST; @@ -292,24 +290,21 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char /* Apply nick override */ if(*source_p->preClient->spoofnick) { + char note[NICKLEN + 10]; + del_from_client_hash(source_p->name, source_p); strlcpy(source_p->name, source_p->preClient->spoofnick, NICKLEN + 1); add_to_client_hash(source_p->name, source_p); - comm_note(source_p->localClient->fd, "Nick: %s", source_p->name); + + rb_snprintf(note, NICKLEN + 10, "Nick: %s", source_p->name); + rb_note(source_p->localClient->F, note); } if(!valid_hostname(source_p->host)) { - sendto_one(source_p, - ":%s NOTICE %s :*** Notice -- You have an illegal character in your hostname", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** Notice -- You have an illegal character in your hostname"); strlcpy(source_p->host, source_p->sockhost, sizeof(source_p->host)); - -#ifdef IPV6 - if(ConfigFileEntry.dot_in_ip6_addr == 1) - strlcat(source_p->host, ".", sizeof(source_p->host)); -#endif } @@ -328,10 +323,8 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char if(IsNeedIdentd(aconf)) { - ServerStats->is_ref++; - sendto_one(source_p, - ":%s NOTICE %s :*** Notice -- You need to install identd to use this server", - me.name, client_p->name); + ServerStats.is_ref++; + sendto_one_notice(source_p, ":*** Notice -- You need to install identd to use this server"); exit_client(client_p, source_p, &me, "Install identd"); return (CLIENT_EXITED); } @@ -357,10 +350,8 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char if(IsNeedSasl(aconf) && !*user->suser) { - ServerStats->is_ref++; - sendto_one(source_p, - ":%s NOTICE %s :*** Notice -- You need to identify via SASL to use this server", - me.name, client_p->name); + ServerStats.is_ref++; + sendto_one_notice(source_p, ":*** Notice -- You need to identify via SASL to use this server"); exit_client(client_p, source_p, &me, "SASL access only"); return (CLIENT_EXITED); } @@ -379,7 +370,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char if(strcmp(encr, aconf->passwd)) { - ServerStats->is_ref++; + ServerStats.is_ref++; sendto_one(source_p, form_str(ERR_PASSWDMISMATCH), me.name, source_p->name); exit_client(client_p, source_p, &me, "Bad Password"); return (CLIENT_EXITED); @@ -390,7 +381,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char if(source_p->localClient->passwd) { memset(source_p->localClient->passwd, 0, strlen(source_p->localClient->passwd)); - MyFree(source_p->localClient->passwd); + rb_free(source_p->localClient->passwd); source_p->localClient->passwd = NULL; } } @@ -407,40 +398,23 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char * -Taner */ /* Except "F:" clients */ - if(((dlink_list_length(&lclient_list) + 1) >= - ((unsigned long)GlobalSetOptions.maxclients + MAX_BUFFER) || - (dlink_list_length(&lclient_list) + 1) >= - ((unsigned long)GlobalSetOptions.maxclients - 5)) && !(IsExemptLimits(source_p))) + if(rb_dlink_list_length(&lclient_list) >= + (unsigned long)GlobalSetOptions.maxclients && !IsConfExemptLimits(aconf)) { sendto_realops_snomask(SNO_FULL, L_ALL, "Too many clients, rejecting %s[%s].", source_p->name, source_p->host); - ServerStats->is_ref++; + ServerStats.is_ref++; exit_client(client_p, source_p, &me, "Sorry, server is full - try later"); return (CLIENT_EXITED); } - /* valid user name check */ - - if(!valid_username(source_p->username)) - { - sendto_realops_snomask(SNO_REJ, L_ALL, - "Invalid username: %s (%s@%s)", - source_p->name, source_p->username, source_p->host); - ServerStats->is_ref++; - ircsprintf(tmpstr2, "Invalid username [%s]", source_p->username); - exit_client(client_p, source_p, &me, tmpstr2); - return (CLIENT_EXITED); - } - - /* end of valid user name check */ - /* kline exemption extends to xline too */ if(!IsExemptKline(source_p) && - find_xline(source_p->info, 1) != NULL) + (xconf = find_xline(source_p->info, 1)) != NULL) { - ServerStats->is_ref++; - add_reject(source_p); + ServerStats.is_ref++; + add_reject(source_p, xconf->name, NULL); exit_client(client_p, source_p, &me, "Bad user info"); return CLIENT_EXITED; } @@ -453,7 +427,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char source_p->sockhost, source_p->preClient->dnsbl_listed->host); else { - dlink_list varlist; + rb_dlink_list varlist = { NULL, NULL, 0 }; substitution_append_var(&varlist, "nick", source_p->name); substitution_append_var(&varlist, "ip", source_p->sockhost); @@ -461,7 +435,7 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char substitution_append_var(&varlist, "dnsbl-host", source_p->preClient->dnsbl_listed->host); substitution_append_var(&varlist, "network-name", ServerInfo.network_name); - ServerStats->is_ref++; + ServerStats.is_ref++; sendto_one(source_p, form_str(ERR_YOUREBANNEDCREEP), me.name, source_p->name, @@ -472,12 +446,29 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char sendto_one_notice(source_p, ":*** Your IP address %s is listed in %s", source_p->sockhost, source_p->preClient->dnsbl_listed->host); source_p->preClient->dnsbl_listed->hits++; - add_reject(source_p); + add_reject(source_p, NULL, NULL); exit_client(client_p, source_p, &me, "*** Banned (DNS blacklist)"); return CLIENT_EXITED; } } + /* valid user name check */ + + if(!valid_username(source_p->username)) + { + sendto_realops_snomask(SNO_REJ, L_ALL, + "Invalid username: %s (%s@%s)", + source_p->name, source_p->username, source_p->host); + ServerStats.is_ref++; + sendto_one_notice(source_p, ":*** Your username is invalid. Please make sure that your username contains " + "only alphanumeric characters."); + rb_sprintf(tmpstr2, "Invalid username [%s]", source_p->username); + exit_client(client_p, source_p, &me, tmpstr2); + return (CLIENT_EXITED); + } + + /* end of valid user name check */ + /* Store original hostname -- jilles */ strlcpy(source_p->orighost, source_p->host, HOSTLEN + 1); @@ -491,9 +482,18 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char SetDynSpoof(source_p); } - if(IsAnyDead(client_p)) + source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes & ~orphaned_umodes; + + call_hook(h_new_local_user, source_p); + + /* If they have died in send_* or were thrown out by the + * new_local_user hook don't do anything. */ + if(IsAnyDead(source_p)) return CLIENT_EXITED; + /* To avoid inconsistencies, do not abort the registration + * starting from this point -- jilles + */ inetntop_sock((struct sockaddr *)&source_p->localClient->ip, ipaddr, sizeof(ipaddr)); sendto_realops_snomask(SNO_CCONN, L_ALL, @@ -511,10 +511,6 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char show_ip(NULL, source_p) ? source_p->localClient->fullcaps : " ", source_p->info); - /* If they have died in send_* don't do anything. */ - if(IsAnyDead(source_p)) - return CLIENT_EXITED; - add_to_hostname_hash(source_p->orighost, source_p); /* Allocate a UID if it was not previously allocated. @@ -526,30 +522,33 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char add_to_id_hash(source_p->id, source_p); } - source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes; + if (IsSSL(source_p)) + source_p->umodes |= UMODE_SSLCLIENT; if (source_p->umodes & UMODE_INVISIBLE) Count.invisi++; s_assert(!IsClient(source_p)); - dlinkMoveNode(&source_p->localClient->tnode, &unknown_list, &lclient_list); + del_unknown_ip(source_p); + rb_dlinkMoveNode(&source_p->localClient->tnode, &unknown_list, &lclient_list); SetClient(source_p); - /* XXX source_p->servptr is &me, since local client */ - source_p->servptr = find_server(NULL, user->server); - dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->users); + source_p->servptr = &me; + rb_dlinkAdd(source_p, &source_p->lnode, &source_p->servptr->serv->users); + /* Increment our total user count here */ if(++Count.total > Count.max_tot) Count.max_tot = Count.total; + source_p->localClient->allow_read = MAX_FLOOD_BURST; Count.totalrestartcount++; s_assert(source_p->localClient != NULL); - if(dlink_list_length(&lclient_list) > (unsigned long)Count.max_loc) + if(rb_dlink_list_length(&lclient_list) > (unsigned long)Count.max_loc) { - Count.max_loc = dlink_list_length(&lclient_list); + Count.max_loc = rb_dlink_list_length(&lclient_list); if(!(Count.max_loc % 10)) sendto_realops_snomask(SNO_GENERAL, L_ALL, "New Max Local Clients: %d", Count.max_loc); @@ -559,8 +558,6 @@ register_local_user(struct Client *client_p, struct Client *source_p, const char if(find_tgchange(source_p->sockhost)) USED_TARGETS(source_p) = 6; - call_hook(h_new_local_user, source_p); - monitor_signon(source_p); user_welcome(source_p); @@ -639,7 +636,7 @@ introduce_client(struct Client *client_p, struct Client *source_p, struct User * nick, source_p->hopcount + 1, (long) source_p->tsinfo, ubuf, source_p->username, source_p->host, - user->server, source_p->info); + source_p->servptr->name, source_p->info); } else sendto_server(client_p, NULL, NOCAPS, NOCAPS, @@ -647,7 +644,7 @@ introduce_client(struct Client *client_p, struct Client *source_p, struct User * nick, source_p->hopcount + 1, (long) source_p->tsinfo, ubuf, source_p->username, source_p->host, - user->server, source_p->info); + source_p->servptr->name, source_p->info); if (IsDynSpoof(source_p)) { @@ -683,7 +680,7 @@ introduce_client(struct Client *client_p, struct Client *source_p, struct User * source_p->localClient->passwd); } memset(source_p->localClient->passwd, 0, strlen(source_p->localClient->passwd)); - MyFree(source_p->localClient->passwd); + rb_free(source_p->localClient->passwd); source_p->localClient->passwd = NULL; } @@ -811,18 +808,14 @@ report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf) /* If this user is being spoofed, tell them so */ if(IsConfDoSpoofIp(aconf)) { - sendto_one(source_p, - ":%s NOTICE %s :*** Spoofing your IP. congrats.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** Spoofing your IP. congrats."); } /* If this user is in the exception class, Set it "E lined" */ if(IsConfExemptKline(aconf)) { SetExemptKline(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from K/D/G/X lines. congrats.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from K/G/X lines. congrats."); } if(IsConfExemptGline(aconf)) @@ -831,74 +824,48 @@ report_and_set_user_flags(struct Client *source_p, struct ConfItem *aconf) /* dont send both a kline and gline exempt notice */ if(!IsConfExemptKline(aconf)) - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from G lines.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from G lines."); } if(IsConfExemptDNSBL(aconf)) /* kline exempt implies this, don't send both */ if(!IsConfExemptKline(aconf)) - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from DNS blacklists.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from DNS blacklists."); /* If this user is exempt from user limits set it F lined" */ if(IsConfExemptLimits(aconf)) { - SetExemptLimits(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from user limits. congrats.", - me.name, source_p->name); - } - - /* If this user is exempt from idle time outs */ - if(IsConfIdlelined(aconf)) - { - SetIdlelined(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from idle limits. congrats.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from user limits. congrats."); } if(IsConfExemptFlood(aconf)) { SetExemptFlood(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from flood limits.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from flood limits."); } if(IsConfExemptSpambot(aconf)) { SetExemptSpambot(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from spambot checks.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from spambot checks."); } if(IsConfExemptJupe(aconf)) { SetExemptJupe(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from juped channel warnings.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from juped channel warnings."); } if(IsConfExemptResv(aconf)) { SetExemptResv(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from resvs.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from resvs."); } if(IsConfExemptShide(aconf)) { SetExemptShide(source_p); - sendto_one(source_p, - ":%s NOTICE %s :*** You are exempt from serverhiding.", - me.name, source_p->name); + sendto_one_notice(source_p, ":*** You are exempt from serverhiding."); } } @@ -968,10 +935,12 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char *m++ = (char) i; *m = '\0'; - sendto_one(source_p, form_str(RPL_UMODEIS), me.name, source_p->name, buf); + sendto_one_numeric(source_p, RPL_UMODEIS, form_str(RPL_UMODEIS), buf); + if (source_p->snomask != 0) - sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name, + sendto_one_numeric(source_p, RPL_SNOMASK, form_str(RPL_SNOMASK), construct_snobuf(source_p->snomask)); + return 0; } @@ -999,7 +968,7 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char { ++Count.oper; SetOper(source_p); - dlinkAddAlloc(source_p, &oper_list); + rb_dlinkAddAlloc(source_p, &oper_list); } } else @@ -1025,13 +994,13 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char } source_p->flags2 &= ~OPER_FLAGS; - MyFree(source_p->localClient->opername); + rb_free(source_p->localClient->opername); source_p->localClient->opername = NULL; - dlinkFindDestroy(source_p, &local_oper_list); + rb_dlinkFindDestroy(source_p, &local_oper_list); } - dlinkFindDestroy(source_p, &oper_list); + rb_dlinkFindDestroy(source_p, &oper_list); } break; @@ -1041,6 +1010,7 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char /* can only be set on burst */ case 'S': + case 'Z': case ' ': case '\n': case '\r': @@ -1083,8 +1053,9 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char if((flag = user_modes[(unsigned char) *pm])) { if(MyConnect(source_p) - && !IsOper(source_p) - && (ConfigFileEntry.oper_only_umodes & flag)) + && ((!IsOper(source_p) + && (ConfigFileEntry.oper_only_umodes & flag)) + || (orphaned_umodes & flag))) { if (what == MODE_ADD || source_p->umodes & flag) badflag = YES; @@ -1110,23 +1081,20 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char if(MyClient(source_p) && (source_p->snomask & SNO_NCHANGE) && !IsOperN(source_p)) { - sendto_one(source_p, - ":%s NOTICE %s :*** You need oper and N flag for +s +n", me.name, parv[0]); + sendto_one_notice(source_p, ":*** You need oper and nick_changes flag for +s +n"); source_p->snomask &= ~SNO_NCHANGE; /* only tcm's really need this */ } if(MyClient(source_p) && (source_p->umodes & UMODE_OPERWALL) && !IsOperOperwall(source_p)) { - sendto_one(source_p, - ":%s NOTICE %s :*** You need oper and operwall flag for +z", me.name, parv[0]); + sendto_one_notice(source_p, ":*** You need oper and operwall flag for +z"); source_p->umodes &= ~UMODE_OPERWALL; } if(MyConnect(source_p) && (source_p->umodes & UMODE_ADMIN) && (!IsOperAdmin(source_p) || IsOperHiddenAdmin(source_p))) { - sendto_one(source_p, - ":%s NOTICE %s :*** You need oper and A flag for +a", me.name, parv[0]); + sendto_one_notice(source_p, ":*** You need oper and admin flag for +a"); source_p->umodes &= ~UMODE_ADMIN; } @@ -1146,7 +1114,7 @@ user_mode(struct Client *client_p, struct Client *source_p, int parc, const char */ send_umode_out(client_p, source_p, setflags); if (showsnomask && MyConnect(source_p)) - sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name, + sendto_one_numeric(source_p, RPL_SNOMASK, form_str(RPL_SNOMASK), construct_snobuf(source_p->snomask)); return (0); @@ -1216,11 +1184,11 @@ send_umode_out(struct Client *client_p, struct Client *source_p, int old) { struct Client *target_p; char buf[BUFSIZE]; - dlink_node *ptr; + rb_dlink_node *ptr; send_umode(NULL, source_p, old, 0, buf); - DLINK_FOREACH(ptr, serv_list.head) + RB_DLINK_FOREACH(ptr, serv_list.head) { target_p = ptr->data; @@ -1246,14 +1214,11 @@ send_umode_out(struct Client *client_p, struct Client *source_p, int old) void user_welcome(struct Client *source_p) { - sendto_one(source_p, form_str(RPL_WELCOME), me.name, source_p->name, - ServerInfo.network_name, source_p->name); - sendto_one(source_p, form_str(RPL_YOURHOST), me.name, - source_p->name, + sendto_one_numeric(source_p, RPL_WELCOME, form_str(RPL_WELCOME), ServerInfo.network_name, source_p->name); + sendto_one_numeric(source_p, RPL_YOURHOST, form_str(RPL_YOURHOST), get_listener_name(source_p->localClient->listener), ircd_version); - - sendto_one(source_p, form_str(RPL_CREATED), me.name, source_p->name, creation); - sendto_one(source_p, form_str(RPL_MYINFO), me.name, source_p->name, me.name, ircd_version, umodebuf); + sendto_one_numeric(source_p, RPL_CREATED, form_str(RPL_CREATED), creation); + sendto_one_numeric(source_p, RPL_MYINFO, form_str(RPL_MYINFO), me.name, ircd_version, umodebuf); show_isupport(source_p); @@ -1261,13 +1226,8 @@ user_welcome(struct Client *source_p) if(ConfigFileEntry.short_motd) { - sendto_one(source_p, - "NOTICE %s :*** Notice -- motd was last changed at %s", - source_p->name, user_motd_changed); - - sendto_one(source_p, - "NOTICE %s :*** Notice -- Please read the motd if you haven't read it", - source_p->name); + sendto_one_notice(source_p, ":*** Notice -- motd was last changed at %s", user_motd_changed); + sendto_one_notice(source_p, ":*** Notice -- Please read the motd if you haven't read it"); sendto_one(source_p, form_str(RPL_MOTDSTART), me.name, source_p->name, me.name); @@ -1322,10 +1282,10 @@ oper_up(struct Client *source_p, struct oper_conf *oper_p) SetExemptKline(source_p); source_p->flags2 |= oper_p->flags; - DupString(source_p->localClient->opername, oper_p->name); + source_p->localClient->opername = rb_strdup(oper_p->name); - dlinkAddAlloc(source_p, &local_oper_list); - dlinkAddAlloc(source_p, &oper_list); + rb_dlinkAddAlloc(source_p, &local_oper_list); + rb_dlinkAddAlloc(source_p, &oper_list); if(IsOperAdmin(source_p) && !IsOperHiddenAdmin(source_p)) source_p->umodes |= UMODE_ADMIN; @@ -1341,37 +1301,81 @@ oper_up(struct Client *source_p, struct oper_conf *oper_p) sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s (%s@%s) is now an operator", source_p->name, source_p->username, source_p->host); + if(!(old & UMODE_INVISIBLE) && IsInvisible(source_p)) + ++Count.invisi; + if((old & UMODE_INVISIBLE) && !IsInvisible(source_p)) + --Count.invisi; send_umode_out(source_p, source_p, old); - sendto_one(source_p, form_str(RPL_SNOMASK), me.name, source_p->name, + sendto_one_numeric(source_p, RPL_SNOMASK, form_str(RPL_SNOMASK), construct_snobuf(source_p->snomask)); sendto_one(source_p, form_str(RPL_YOUREOPER), me.name, source_p->name); - sendto_one(source_p, ":%s NOTICE %s :*** Oper privs are %s", me.name, - source_p->name, get_oper_privs(oper_p->flags)); + sendto_one_notice(source_p, ":*** Oper privs are %s", get_oper_privs(oper_p->flags)); send_oper_motd(source_p); return (1); } +/* + * find_umode_slot + * + * inputs - NONE + * outputs - an available umode bitmask or + * 0 if no umodes are available + * side effects - NONE + */ +unsigned int +find_umode_slot(void) +{ + unsigned int all_umodes = 0, my_umode = 0, i; + + for (i = 0; i < 128; i++) + all_umodes |= user_modes[i]; + + for (my_umode = 1; my_umode && (all_umodes & my_umode); + my_umode <<= 1); + + return my_umode; +} + void construct_umodebuf(void) { int i; char *ptr = umodebuf; + static int prev_user_modes[128]; *ptr = '\0'; for (i = 0; i < 128; i++) + { + if (prev_user_modes[i] != 0 && prev_user_modes[i] != user_modes[i]) + { + if (user_modes[i] == 0) + { + orphaned_umodes |= prev_user_modes[i]; + sendto_realops_snomask(SNO_DEBUG, L_ALL, "Umode +%c is now orphaned", i); + } + else + { + orphaned_umodes &= ~prev_user_modes[i]; + sendto_realops_snomask(SNO_DEBUG, L_ALL, "Orphaned umode +%c is picked up by module", i); + } + user_modes[i] = prev_user_modes[i]; + } + else + prev_user_modes[i] = user_modes[i]; if (user_modes[i]) *ptr++ = (char) i; + } *ptr++ = '\0'; } void change_nick_user_host(struct Client *target_p, const char *nick, const char *user, - const char *host, int newts, char *format, ...) + const char *host, int newts, const char *format, ...) { - dlink_node *ptr; + rb_dlink_node *ptr; struct Channel *chptr; struct membership *mscptr; int changed = irccmp(target_p->name, nick); @@ -1399,7 +1403,7 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use target_p->name, target_p->username, target_p->host, reason); - DLINK_FOREACH(ptr, target_p->user->channel.head) + RB_DLINK_FOREACH(ptr, target_p->user->channel.head) { mscptr = ptr->data; chptr = mscptr->chptr; @@ -1442,8 +1446,8 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use target_p->host, nick); } - strlcpy(target_p->username, user, USERLEN); - strlcpy(target_p->host, host, HOSTLEN); + strlcpy(target_p->username, user, sizeof target_p->username); + strlcpy(target_p->host, host, sizeof target_p->host); if (changed) add_history(target_p, 1);