X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/63aecfb960dbc12d2e459a8ba355a633a49ee71f..af81d5a0b09446188fd6f9c292b51519f2c1cedd:/src/channel.c diff --git a/src/channel.c b/src/channel.c index 1888d97..ece8bd9 100644 --- a/src/channel.c +++ b/src/channel.c @@ -21,7 +21,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: channel.c 3173 2007-01-31 23:57:18Z jilles $ + * $Id: channel.c 3580 2007-11-07 23:45:14Z jilles $ */ #include "stdinc.h" @@ -46,7 +46,7 @@ #include "balloc.h" #include "s_log.h" -extern dlink_list global_channel_list; +extern rb_dlink_list global_channel_list; extern struct config_channel_entry ConfigChannel; extern BlockHeap *channel_heap; @@ -93,7 +93,7 @@ allocate_channel(const char *chname) { struct Channel *chptr; chptr = BlockHeapAlloc(channel_heap); - DupNString(chptr->chname, chname, CHANNELLEN); + DupString(chptr->chname, chname); return (chptr); } @@ -109,8 +109,8 @@ allocate_ban(const char *banstr, const char *who) { struct Ban *bptr; bptr = BlockHeapAlloc(ban_heap); - DupNString(bptr->banstr, banstr, BANLEN); - DupNString(bptr->who, who, BANLEN); + DupString(bptr->banstr, banstr); + DupString(bptr->who, who); return (bptr); } @@ -134,7 +134,7 @@ struct membership * find_channel_membership(struct Channel *chptr, struct Client *client_p) { struct membership *msptr; - dlink_node *ptr; + rb_dlink_node *ptr; if(!IsClient(client_p)) return NULL; @@ -142,7 +142,7 @@ find_channel_membership(struct Channel *chptr, struct Client *client_p) /* Pick the most efficient list to use to be nice to things like * CHANSERV which could be in a large number of channels */ - if(dlink_list_length(&chptr->members) < dlink_list_length(&client_p->user->channel)) + if(rb_dlink_list_length(&chptr->members) < rb_dlink_list_length(&client_p->user->channel)) { DLINK_FOREACH(ptr, chptr->members.head) { @@ -215,11 +215,11 @@ add_user_to_channel(struct Channel *chptr, struct Client *client_p, int flags) msptr->client_p = client_p; msptr->flags = flags; - dlinkAdd(msptr, &msptr->usernode, &client_p->user->channel); - dlinkAdd(msptr, &msptr->channode, &chptr->members); + rb_dlinkAdd(msptr, &msptr->usernode, &client_p->user->channel); + rb_dlinkAdd(msptr, &msptr->channode, &chptr->members); if(MyClient(client_p)) - dlinkAdd(msptr, &msptr->locchannode, &chptr->locmembers); + rb_dlinkAdd(msptr, &msptr->locchannode, &chptr->locmembers); } /* remove_user_from_channel() @@ -240,15 +240,15 @@ remove_user_from_channel(struct membership *msptr) client_p = msptr->client_p; chptr = msptr->chptr; - dlinkDelete(&msptr->usernode, &client_p->user->channel); - dlinkDelete(&msptr->channode, &chptr->members); + rb_dlinkDelete(&msptr->usernode, &client_p->user->channel); + rb_dlinkDelete(&msptr->channode, &chptr->members); if(client_p->servptr == &me) - dlinkDelete(&msptr->locchannode, &chptr->locmembers); + rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers); chptr->users_last = CurrentTime; - if(!(chptr->mode.mode & MODE_PERMANENT) && dlink_list_length(&chptr->members) <= 0) + if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) destroy_channel(chptr); BlockHeapFree(member_heap, msptr); @@ -267,8 +267,8 @@ remove_user_from_channels(struct Client *client_p) { struct Channel *chptr; struct membership *msptr; - dlink_node *ptr; - dlink_node *next_ptr; + rb_dlink_node *ptr; + rb_dlink_node *next_ptr; if(client_p == NULL) return; @@ -278,14 +278,14 @@ remove_user_from_channels(struct Client *client_p) msptr = ptr->data; chptr = msptr->chptr; - dlinkDelete(&msptr->channode, &chptr->members); + rb_dlinkDelete(&msptr->channode, &chptr->members); if(client_p->servptr == &me) - dlinkDelete(&msptr->locchannode, &chptr->locmembers); + rb_dlinkDelete(&msptr->locchannode, &chptr->locmembers); chptr->users_last = CurrentTime; - if(!(chptr->mode.mode & MODE_PERMANENT) && dlink_list_length(&chptr->members) <= 0) + if(!(chptr->mode.mode & MODE_PERMANENT) && rb_dlink_list_length(&chptr->members) <= 0) destroy_channel(chptr); BlockHeapFree(member_heap, msptr); @@ -306,7 +306,7 @@ void invalidate_bancache_user(struct Client *client_p) { struct membership *msptr; - dlink_node *ptr; + rb_dlink_node *ptr; if(client_p == NULL) return; @@ -343,15 +343,15 @@ check_channel_name(const char *name) /* free_channel_list() * - * input - dlink list to free + * input - rb_dlink list to free * output - * side effects - list of b/e/I modes is cleared */ void -free_channel_list(dlink_list * list) +free_channel_list(rb_dlink_list * list) { - dlink_node *ptr; - dlink_node *next_ptr; + rb_dlink_node *ptr; + rb_dlink_node *next_ptr; struct Ban *actualBan; DLINK_FOREACH_SAFE(ptr, next_ptr, list->head) @@ -373,7 +373,7 @@ free_channel_list(dlink_list * list) void destroy_channel(struct Channel *chptr) { - dlink_node *ptr, *next_ptr; + rb_dlink_node *ptr, *next_ptr; DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head) { @@ -384,11 +384,12 @@ destroy_channel(struct Channel *chptr) free_channel_list(&chptr->banlist); free_channel_list(&chptr->exceptlist); free_channel_list(&chptr->invexlist); + free_channel_list(&chptr->quietlist); /* Free the topic */ free_topic(chptr); - dlinkDelete(&chptr->node, &global_channel_list); + rb_dlinkDelete(&chptr->node, &global_channel_list); del_from_channel_hash(chptr->chname, chptr); free_channel(chptr); } @@ -420,7 +421,7 @@ channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eo { struct membership *msptr; struct Client *target_p; - dlink_node *ptr; + rb_dlink_node *ptr; char lbuf[BUFSIZE]; char *t; int mlen; @@ -433,7 +434,7 @@ channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eo { is_member = IsMember(client_p, chptr); - cur_len = mlen = ircsprintf(lbuf, form_str(RPL_NAMREPLY), + cur_len = mlen = rb_sprintf(lbuf, form_str(RPL_NAMREPLY), me.name, client_p->name, channel_pub_or_secret(chptr), chptr->chname); @@ -456,7 +457,7 @@ channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eo t = lbuf + mlen; } - tlen = ircsprintf(t, "%s%s ", find_channel_status(msptr, stack), + tlen = rb_sprintf(t, "%s%s ", find_channel_status(msptr, stack), target_p->name); cur_len += tlen; @@ -491,8 +492,8 @@ channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eo void del_invite(struct Channel *chptr, struct Client *who) { - dlinkFindDestroy(who, &chptr->invites); - dlinkFindDestroy(chptr, &who->user->invited); + rb_dlinkFindDestroy(who, &chptr->invites); + rb_dlinkFindDestroy(chptr, &who->user->invited); } /* is_banned() @@ -510,7 +511,7 @@ is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr, char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; char src_althost[NICKLEN + USERLEN + HOSTLEN + 6]; char *s3 = NULL; - dlink_node *ptr; + rb_dlink_node *ptr; struct Ban *actualBan = NULL; struct Ban *actualExcept = NULL; @@ -520,8 +521,8 @@ is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr, /* if the buffers havent been built, do it here */ if(s == NULL) { - ircsprintf(src_host, "%s!%s@%s", who->name, who->username, who->host); - ircsprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost); + rb_sprintf(src_host, "%s!%s@%s", who->name, who->username, who->host); + rb_sprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost); s = src_host; s2 = src_iphost; @@ -531,14 +532,14 @@ is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr, /* if host mangling mode enabled, also check their real host */ if(!strcmp(who->host, who->localClient->mangledhost)) { - ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost); + rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost); s3 = src_althost; } /* if host mangling mode not enabled and no other spoof, * also check the mangled form of their host */ else if (!IsDynSpoof(who)) { - ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost); + rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost); s3 = src_althost; } } @@ -616,7 +617,7 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; char src_althost[NICKLEN + USERLEN + HOSTLEN + 6]; char *s3 = NULL; - dlink_node *ptr; + rb_dlink_node *ptr; struct Ban *actualBan = NULL; struct Ban *actualExcept = NULL; @@ -626,8 +627,8 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, /* if the buffers havent been built, do it here */ if(s == NULL) { - ircsprintf(src_host, "%s!%s@%s", who->name, who->username, who->host); - ircsprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost); + rb_sprintf(src_host, "%s!%s@%s", who->name, who->username, who->host); + rb_sprintf(src_iphost, "%s!%s@%s", who->name, who->username, who->sockhost); s = src_host; s2 = src_iphost; @@ -637,14 +638,14 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, /* if host mangling mode enabled, also check their real host */ if(!strcmp(who->host, who->localClient->mangledhost)) { - ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost); + rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->orighost); s3 = src_althost; } /* if host mangling mode not enabled and no other spoof, * also check the mangled form of their host */ else if (!IsDynSpoof(who)) { - ircsprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost); + rb_sprintf(src_althost, "%s!%s@%s", who->name, who->username, who->localClient->mangledhost); s3 = src_althost; } } @@ -716,32 +717,33 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr, int can_join(struct Client *source_p, struct Channel *chptr, char *key) { - dlink_node *lp; - dlink_node *ptr; + rb_dlink_node *invite = NULL; + rb_dlink_node *ptr; struct Ban *invex = NULL; char src_host[NICKLEN + USERLEN + HOSTLEN + 6]; char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; char src_althost[NICKLEN + USERLEN + HOSTLEN + 6]; int use_althost = 0; + int i = 0; hook_data_channel moduledata; s_assert(source_p->localClient != NULL); - ircsprintf(src_host, "%s!%s@%s", source_p->name, source_p->username, source_p->host); - ircsprintf(src_iphost, "%s!%s@%s", source_p->name, source_p->username, source_p->sockhost); + rb_sprintf(src_host, "%s!%s@%s", source_p->name, source_p->username, source_p->host); + rb_sprintf(src_iphost, "%s!%s@%s", source_p->name, source_p->username, source_p->sockhost); if(source_p->localClient->mangledhost != NULL) { /* if host mangling mode enabled, also check their real host */ if(!strcmp(source_p->host, source_p->localClient->mangledhost)) { - ircsprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->orighost); + rb_sprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->orighost); use_althost = 1; } /* if host mangling mode not enabled and no other spoof, * also check the mangled form of their host */ else if (!IsDynSpoof(source_p)) { - ircsprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->localClient->mangledhost); + rb_sprintf(src_althost, "%s!%s@%s", source_p->name, source_p->username, source_p->localClient->mangledhost); use_althost = 1; } } @@ -751,12 +753,12 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) if(chptr->mode.mode & MODE_INVITEONLY) { - DLINK_FOREACH(lp, source_p->user->invited.head) + DLINK_FOREACH(invite, source_p->user->invited.head) { - if(lp->data == chptr) + if(invite->data == chptr) break; } - if(lp == NULL) + if(invite == NULL) { if(!ConfigChannel.use_invex) return (ERR_INVITEONLYCHAN); @@ -779,19 +781,29 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key) return (ERR_BADCHANNELKEY); if(chptr->mode.limit && - dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit) - return (ERR_CHANNELISFULL); - + rb_dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit) + i = ERR_CHANNELISFULL; if(chptr->mode.mode & MODE_REGONLY && EmptyString(source_p->user->suser)) - return ERR_NEEDREGGEDNICK; - + i = ERR_NEEDREGGEDNICK; /* join throttling stuff --nenolod */ - if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0) + else if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0) { if ((CurrentTime - chptr->join_delta <= chptr->mode.join_time) && (chptr->join_count >= chptr->mode.join_num)) - return ERR_THROTTLE; + i = ERR_THROTTLE; + } + + /* allow /invite to override +l/+r/+j also -- jilles */ + if (i != 0 && invite == NULL) + { + DLINK_FOREACH(invite, source_p->user->invited.head) + { + if(invite->data == chptr) + break; + } + if (invite == NULL) + return i; } moduledata.client = source_p; @@ -867,15 +879,15 @@ find_bannickchange_channel(struct Client *client_p) { struct Channel *chptr; struct membership *msptr; - dlink_node *ptr; + rb_dlink_node *ptr; char src_host[NICKLEN + USERLEN + HOSTLEN + 6]; char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6]; if (!MyClient(client_p)) return NULL; - ircsprintf(src_host, "%s!%s@%s", client_p->name, client_p->username, client_p->host); - ircsprintf(src_iphost, "%s!%s@%s", client_p->name, client_p->username, client_p->sockhost); + rb_sprintf(src_host, "%s!%s@%s", client_p->name, client_p->username, client_p->host); + rb_sprintf(src_iphost, "%s!%s@%s", client_p->name, client_p->username, client_p->sockhost); DLINK_FOREACH(ptr, client_p->user->channel.head) { @@ -919,12 +931,12 @@ check_spambot_warning(struct Client *source_p, const char *name) { /* Its already known as a possible spambot */ if(name != NULL) - sendto_realops_snomask(SNO_BOTS, L_ALL, + sendto_realops_snomask(SNO_BOTS, L_NETWIDE, "User %s (%s@%s) trying to join %s is a possible spambot", source_p->name, source_p->username, source_p->orighost, name); else - sendto_realops_snomask(SNO_BOTS, L_ALL, + sendto_realops_snomask(SNO_BOTS, L_NETWIDE, "User %s (%s@%s) is a possible spambot", source_p->name, source_p->username, source_p->orighost); @@ -1072,11 +1084,7 @@ set_channel_topic(struct Channel *chptr, const char *topic, const char *topic_in } } -static const struct mode_letter -{ - const unsigned int mode; - const unsigned char letter; -} flags[] = +const struct mode_letter chmode_flags[] = { {MODE_INVITEONLY, 'i'}, {MODE_MODERATED, 'm'}, @@ -1099,9 +1107,8 @@ static const struct mode_letter * * inputs - pointer to channel * - pointer to client - * output - NONE - * side effects - write the "simple" list of channel modes for channel - * chptr onto buffer mbuf with the parameters in pbuf. + * output - string with simple modes + * side effects - result from previous calls overwritten * * Stolen from ShadowIRCd 4 --nenolod */ @@ -1118,46 +1125,47 @@ channel_modes(struct Channel *chptr, struct Client *client_p) *mbuf++ = '+'; *pbuf = '\0'; - for (i = 0; flags[i].mode; ++i) - if(chptr->mode.mode & flags[i].mode) - *mbuf++ = flags[i].letter; + for (i = 0; chmode_flags[i].mode; ++i) + if(chptr->mode.mode & chmode_flags[i].mode) + *mbuf++ = chmode_flags[i].letter; if(chptr->mode.limit) { *mbuf++ = 'l'; - if(IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p)) - pbuf += ircsprintf(pbuf, "%d ", chptr->mode.limit); + if(!IsClient(client_p) || IsMember(client_p, chptr)) + pbuf += rb_sprintf(pbuf, " %d", chptr->mode.limit); } if(*chptr->mode.key) { *mbuf++ = 'k'; - if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p)) - pbuf += ircsprintf(pbuf, "%s ", chptr->mode.key); + if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr)) + pbuf += rb_sprintf(pbuf, " %s", chptr->mode.key); } if(chptr->mode.join_num) { *mbuf++ = 'j'; - if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p)) - pbuf += ircsprintf(pbuf, "%d:%d ", chptr->mode.join_num, + if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr)) + pbuf += rb_sprintf(pbuf, " %d:%d", chptr->mode.join_num, chptr->mode.join_time); } - if(*chptr->mode.forward && (ConfigChannel.use_forward || IsServer(client_p) || IsMe(client_p))) + if(*chptr->mode.forward && (ConfigChannel.use_forward || !IsClient(client_p))) { *mbuf++ = 'f'; - if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p)) - pbuf += ircsprintf(pbuf, "%s ", chptr->mode.forward); + if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr)) + pbuf += rb_sprintf(pbuf, " %s", chptr->mode.forward); } *mbuf = '\0'; - ircsprintf(final, "%s %s", buf1, buf2); + strlcpy(final, buf1, sizeof final); + strlcat(final, buf2, sizeof final); return final; } @@ -1301,11 +1309,11 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, nocap = chcap_combos[j].cap_no; if(cap & CAP_TS6) - mbl = preflen = ircsprintf(modebuf, ":%s TMODE %ld %s ", + mbl = preflen = rb_sprintf(modebuf, ":%s TMODE %ld %s ", use_id(source_p), (long) chptr->channelts, chptr->chname); else - mbl = preflen = ircsprintf(modebuf, ":%s MODE %s ", + mbl = preflen = rb_sprintf(modebuf, ":%s MODE %s ", source_p->name, chptr->chname); /* loop the list of - modes we have */ @@ -1369,7 +1377,7 @@ send_cap_mode_changes(struct Client *client_p, struct Client *source_p, if(arg != NULL) { - len = ircsprintf(pbuf, "%s ", arg); + len = rb_sprintf(pbuf, "%s ", arg); pbuf += len; pbl += len; mc++;