X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/25365ce71652e0e6fee548c88f1ddecab50084fb..c33da0d24ed3cd737263e0469fa600681ec75d42:/ircd/channel.c?ds=sidebyside diff --git a/ircd/channel.c b/ircd/channel.c index 70eb5c2b..0a01f972 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -434,6 +434,47 @@ channel_pub_or_secret(struct Channel *chptr) return ("*"); } +int +iter_comm_channels_step(rb_dlink_node *pos1, rb_dlink_node *pos2, + struct membership **ms1, struct membership **ms2, + struct Channel **chptr) +{ + *ms1 = pos1 ? pos1->data : NULL; + *ms2 = pos2 ? pos2->data : NULL; + + /* we're at the end */ + if (*ms1 == NULL && *ms2 == NULL) + return 0; + + /* one side is at the end, keep stepping the other one */ + if (*ms1 == NULL || *ms2 == NULL) + { + *chptr = *ms1 != NULL ? (*ms1)->chptr : (*ms2)->chptr; + return 1; + } + + /* common channel */ + if ((*ms1)->chptr == (*ms2)->chptr) + { + *chptr = (*ms1)->chptr; + return 1; + } + + /* null out the channel that's further ahead; we'll get to it later */ + if (irccmp((*ms1)->chptr->chname, (*ms2)->chptr->chname) > 0) + { + *ms1 = NULL; + *chptr = (*ms2)->chptr; + return 1; + } + else + { + *ms2 = NULL; + *chptr = (*ms1)->chptr; + return 1; + } +} + /* channel_member_names() * * input - channel to list, client to list to, show endofnames @@ -446,11 +487,6 @@ channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eo struct membership *msptr; struct Client *target_p; rb_dlink_node *ptr; - char lbuf[BUFSIZE]; - char *t; - int mlen; - int tlen; - int cur_len; int is_member; int stack = IsCapable(client_p, CLICAP_MULTI_PREFIX); @@ -458,11 +494,11 @@ channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eo { is_member = IsMember(client_p, chptr); - cur_len = mlen = sprintf(lbuf, form_str(RPL_NAMREPLY), - me.name, client_p->name, - channel_pub_or_secret(chptr), chptr->chname); - - t = lbuf + cur_len; + send_multiline_init(client_p, " ", form_str(RPL_NAMREPLY), + me.name, + client_p->name, + channel_pub_or_secret(chptr), + chptr->chname); RB_DLINK_FOREACH(ptr, chptr->members.head) { @@ -474,49 +510,21 @@ channel_member_names(struct Channel *chptr, struct Client *client_p, int show_eo if (IsCapable(client_p, CLICAP_USERHOST_IN_NAMES)) { - /* space, possible "@+" prefix */ - if (cur_len + strlen(target_p->name) + strlen(target_p->username) + strlen(target_p->host) + 5 >= BUFSIZE - 5) - { - *(t - 1) = '\0'; - sendto_one(client_p, "%s", lbuf); - cur_len = mlen; - t = lbuf + mlen; - } - - tlen = sprintf(t, "%s%s!%s@%s ", find_channel_status(msptr, stack), - target_p->name, target_p->username, target_p->host); + send_multiline_item(client_p, "%s%s!%s@%s", + find_channel_status(msptr, stack), + target_p->name, + target_p->username, + target_p->host); } else { - /* space, possible "@+" prefix */ - if(cur_len + strlen(target_p->name) + 3 >= BUFSIZE - 3) - { - *(t - 1) = '\0'; - sendto_one(client_p, "%s", lbuf); - cur_len = mlen; - t = lbuf + mlen; - } - - tlen = sprintf(t, "%s%s ", find_channel_status(msptr, stack), - target_p->name); + send_multiline_item(client_p, "%s%s", + find_channel_status(msptr, stack), + target_p->name); } - - cur_len += tlen; - t += tlen; } - /* The old behaviour here was to always output our buffer, - * even if there are no clients we can show. This happens - * when a client does "NAMES" with no parameters, and all - * the clients on a -sp channel are +i. I dont see a good - * reason for keeping that behaviour, as it just wastes - * bandwidth. --anfl - */ - if(cur_len != mlen) - { - *(t - 1) = '\0'; - sendto_one(client_p, "%s", lbuf); - } + send_multiline_fini(client_p, NULL); } if(show_eon) @@ -853,7 +861,7 @@ can_send(struct Channel *chptr, struct Client *source_p, struct membership *mspt * side effects - check for flood attack on target chptr */ bool -flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, char *chname) +flood_attack_channel(enum message_type msgtype, struct Client *source_p, struct Channel *chptr, char *chname) { int delta; @@ -886,7 +894,7 @@ flood_attack_channel(int p_or_n, struct Client *source_p, struct Channel *chptr, /* Add a bit of penalty */ chptr->received_number_of_privmsgs += 2; } - if(MyClient(source_p) && (p_or_n != 1)) + if(MyClient(source_p) && (msgtype != MESSAGE_TYPE_NOTICE)) sendto_one(source_p, ":%s NOTICE %s :*** Message to %s throttled due to flooding", me.name, source_p->name, chptr->chname); @@ -1133,7 +1141,7 @@ channel_modes(struct Channel *chptr, struct Client *client_p) for (i = 0; i < 256; i++) { - if(chmode_table[i].set_func == chm_hidden && (!HasPrivilege(client_p, "auspex:cmodes") || !IsClient(client_p))) + if(chmode_table[i].set_func == chm_hidden && !HasPrivilege(client_p, "auspex:cmodes") && IsClient(client_p)) continue; if(chptr->mode.mode & chmode_flags[i]) *mbuf++ = i;