X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fm_names.c;h=6c84d5079b8bae2e4655e90c55a67e8fce5f5e91;hb=a36ad5e29241b0c89379947b13887cb6930ef3e0;hp=160bbef086b124e045b2d5a18f42534b397213c1;hpb=ae91ef6320f611af74e70a0db2620c338fbaa7d5;p=ircu2.10.12-pk.git diff --git a/ircd/m_names.c b/ircd/m_names.c index 160bbef..6c84d50 100644 --- a/ircd/m_names.c +++ b/ircd/m_names.c @@ -79,18 +79,13 @@ * note: it is guaranteed that parv[0]..parv[parc-1] are all * non-NULL pointers. */ -#if 0 -/* - * No need to include handlers.h here the signatures must match - * and we don't need to force a rebuild of all the handlers everytime - * we add a new one to the list. --Bleep - */ -#include "handlers.h" -#endif /* 0 */ +#include "config.h" + #include "channel.h" #include "client.h" #include "hash.h" #include "ircd.h" +#include "ircd_log.h" #include "ircd_reply.h" #include "ircd_string.h" #include "msg.h" @@ -98,609 +93,231 @@ #include "numnicks.h" #include "s_user.h" #include "send.h" - -#include + +/* #include -- Now using assert in ircd_log.h */ #include /* - * m_names - generic message handler + * Sends a suitably formatted 'names' reply to 'sptr' consisting of nicks within + * 'chptr', depending on 'filter'. + * + * NAMES_ALL - Lists all users on channel. + * NAMES_VIS - Only list visible (-i) users. --Gte (04/06/2000). + * NAMES_DEL - Show join-delayed names list. + * NAMES_EON - When OR'd with the other two, adds an 'End of Names' numeric + * used by m_join * - * parv[0] = sender prefix - * parv[1] = channel */ -int m_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) -{ - struct Channel *chptr; + +void do_names(struct Client* sptr, struct Channel* chptr, int filter) +{ + int mlen; + int idx; + int flag; + int needs_space; + int len; + char buf[BUFSIZE]; struct Client *c2ptr; struct Membership* member; - struct Channel *ch2ptr = 0; - int idx, flag, len, mlen; - char *s, *para = parc > 1 ? parv[1] : 0; - char buf[BUFSIZE]; - - if (parc > 2 && hunt_server(1, cptr, sptr, "%s%s " TOK_NAMES " %s %s", 2, parc, parv)) - return 0; - - mlen = strlen(me.name) + 10 + strlen(sptr->name); - - if (!EmptyString(para)) + + assert(chptr); + assert(sptr); + assert((filter&NAMES_ALL) != (filter&NAMES_VIS)); + + /* Tag Pub/Secret channels accordingly. */ + + strcpy(buf, "* "); + if (PubChannel(chptr)) + *buf = '='; + else if (SecretChannel(chptr)) + *buf = '@'; + + len = strlen(chptr->chname); + strcpy(buf + 2, chptr->chname); + strcpy(buf + 2 + len, " :"); + + idx = len + 4; + flag = 1; + needs_space = 0; + + if (!ShowChannel(sptr, chptr)) /* Don't list private channels unless we are on them. */ + return; + + /* Iterate over all channel members, and build up the list. */ + + mlen = strlen(cli_name(&me)) + 10 + strlen(cli_name(sptr)); + + for (member = chptr->members; member; member = member->next_member) { - s = strchr(para, ','); - if (s) - { - parv[1] = ++s; - m_names(cptr, sptr, parc, parv); - } - clean_channelname(para); - ch2ptr = FindChannel(para); - } + c2ptr = member->user; - /* - * First, do all visible channels (public and the one user self is) - */ + if (((filter&NAMES_VIS)!=0) && IsInvisible(c2ptr)) + continue; - for (chptr = GlobalChannelList; chptr; chptr = chptr->next) - { - if ((chptr != ch2ptr) && !EmptyString(para)) - continue; /* -- wanted a specific channel */ - if (!MyConnect(sptr) && EmptyString(para)) + if (IsZombie(member) && member->user != sptr) continue; -#ifndef GODMODE - if (!ShowChannel(sptr, chptr)) - continue; /* -- users on this are not listed */ -#endif - - /* Find users on same channel (defined by chptr) */ - - strcpy(buf, "* "); - len = strlen(chptr->chname); - strcpy(buf + 2, chptr->chname); - strcpy(buf + 2 + len, " :"); - - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - idx = len + 4; - flag = 1; - for (member = chptr->members; member; member = member->next_member) - { - c2ptr = member->user; -#ifndef GODMODE - if (sptr != c2ptr && IsInvisible(c2ptr) && !find_channel_member(sptr, chptr)) + + if (IsDelayedJoin(member) && (member->user != sptr) && !(filter & NAMES_DEL)) continue; -#endif - if (IsZombie(member)) - { - if (member->user != sptr) - continue; - else - { - strcat(buf, "!"); - idx++; - } - } - else if (IsChanOp(member)) - { - strcat(buf, "@"); - idx++; - } - else if (HasVoice(member)) - { - strcat(buf, "+"); - idx++; - } - strcat(buf, c2ptr->name); - strcat(buf, " "); - idx += strlen(c2ptr->name) + 1; - flag = 1; -#ifdef GODMODE - { - char yxx[6]; - sprintf_irc(yxx, "%s%s", NumNick(c2ptr)); - assert(c2ptr == findNUser(yxx)); - sprintf_irc(buf + strlen(buf), "(%s) ", yxx); - idx += 6; - } - if (mlen + idx + NICKLEN + 11 > BUFSIZE) -#else - if (mlen + idx + NICKLEN + 5 > BUFSIZE) -#endif - /* space, modifier, nick, \r \n \0 */ - { - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - strcpy(buf, "* "); - ircd_strncpy(buf + 2, chptr->chname, len + 1); - buf[len + 2] = 0; - strcat(buf, " :"); - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - idx = len + 4; - flag = 0; - } - } - if (flag) - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - } - if (!EmptyString(para)) - { - sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0], - ch2ptr ? ch2ptr->chname : para); - return (1); - } - /* Second, do all non-public, non-secret channels in one big sweep */ + if ((!IsDelayedJoin(member) || (member->user == sptr)) && (filter & NAMES_DEL)) + continue; - strcpy(buf, "* * :"); - idx = 5; - flag = 0; - for (c2ptr = GlobalClientList; c2ptr; c2ptr = c2ptr->next) - { - struct Channel *ch3ptr; - int showflag = 0, secret = 0; - -#ifndef GODMODE - if (!IsUser(c2ptr) || (sptr != c2ptr && IsInvisible(c2ptr))) -#else - if (!IsUser(c2ptr)) -#endif - continue; - member = c2ptr->user->channel; - /* - * Don't show a client if they are on a secret channel or when - * they are on a channel sptr is on since they have already - * been show earlier. -avalon - */ - while (member) - { - ch3ptr = member->channel; -#ifndef GODMODE - if (PubChannel(ch3ptr) || find_channel_member(sptr, ch3ptr)) -#endif - showflag = 1; - if (SecretChannel(ch3ptr)) - secret = 1; - member = member->next_channel; - } - if (showflag) /* Have we already shown them ? */ - continue; -#ifndef GODMODE - if (secret) /* On any secret channels ? */ - continue; -#endif - strcat(buf, c2ptr->name); - strcat(buf, " "); - idx += strlen(c2ptr->name) + 1; + if (needs_space) + buf[idx++] = ' '; + needs_space=1; + if (IsZombie(member)) + buf[idx++] = '!'; + else if (IsChanOp(member)) + buf[idx++] = '@'; + else if (HasVoice(member)) + buf[idx++] = '+'; + strcpy(buf + idx, cli_name(c2ptr)); + idx += strlen(cli_name(c2ptr)); flag = 1; -#ifdef GODMODE - { - char yxx[6]; - sprintf_irc(yxx, "%s%s", NumNick(c2ptr)); - assert(c2ptr == findNUser(yxx)); - sprintf_irc(buf + strlen(buf), "(%s) ", yxx); - idx += 6; - } -#endif -#ifdef GODMODE - if (mlen + idx + NICKLEN + 9 > BUFSIZE) -#else - if (mlen + idx + NICKLEN + 3 > BUFSIZE) /* space, \r\n\0 */ -#endif + if (mlen + idx + NICKLEN + 5 > BUFSIZE) + /* space, modifier, nick, \r \n \0 */ { - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - strcpy(buf, "* * :"); - idx = 5; + send_reply(sptr, (filter & NAMES_DEL) ? RPL_DELNAMREPLY : RPL_NAMREPLY, buf); + idx = len + 4; flag = 0; + needs_space=0; } } if (flag) - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0], "*"); - return 1; - return 0; + send_reply(sptr, (filter & NAMES_DEL) ? RPL_DELNAMREPLY : RPL_NAMREPLY, buf); + if (filter&NAMES_EON) + send_reply(sptr, RPL_ENDOFNAMES, chptr->chname); } /* - * ms_names - server message handler + * m_names - generic message handler * * parv[0] = sender prefix * parv[1] = channel */ -int ms_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) + +int m_names(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { - struct Channel *chptr; + struct Channel *chptr; + struct Channel *ch2ptr; struct Client *c2ptr; - struct Membership* member; - struct Channel *ch2ptr = 0; - int idx, flag, len, mlen; - char *s, *para = parc > 1 ? parv[1] : 0; - char buf[BUFSIZE]; - - if (parc > 2 && hunt_server(1, cptr, sptr, "%s%s " TOK_NAMES " %s %s", 2, parc, parv)) + struct Membership* member; + char* s; + char* para = parc > 1 ? parv[1] : 0; + int showingdelayed = 0; + + if (parc > 1 && !ircd_strcmp(parv[1], "-D")) { + para = (parc > 2) ? parv[2] : 0; + showingdelayed = NAMES_DEL; + if (parc > 3 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %s %C", 3, parc, parv)) + return 0; + } else if (parc > 2 && hunt_server_cmd(sptr, CMD_NAMES, cptr, 1, "%s %C", 2, parc, parv)) return 0; - mlen = strlen(me.name) + 10 + strlen(sptr->name); + if (EmptyString(para)) { + send_reply(sptr, RPL_ENDOFNAMES, "*"); + return 0; + } - if (!EmptyString(para)) - { + do { s = strchr(para, ','); if (s) + *s++ = '\0'; + /* + * Special Case 1: "/names 0". + * Full list as per RFC. + */ + if ((*para == '0') || (*para == '\0')) { - parv[1] = ++s; - m_names(cptr, sptr, parc, parv); - } - clean_channelname(para); - ch2ptr = FindChannel(para); - } - - /* - * First, do all visible channels (public and the one user self is) - */ - - for (chptr = GlobalChannelList; chptr; chptr = chptr->next) - { - if ((chptr != ch2ptr) && !EmptyString(para)) - continue; /* -- wanted a specific channel */ - if (!MyConnect(sptr) && EmptyString(para)) - continue; -#ifndef GODMODE - if (!ShowChannel(sptr, chptr)) - continue; /* -- users on this are not listed */ -#endif - - /* Find users on same channel (defined by chptr) */ - - strcpy(buf, "* "); - len = strlen(chptr->chname); - strcpy(buf + 2, chptr->chname); - strcpy(buf + 2 + len, " :"); - - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - idx = len + 4; - flag = 1; - for (member = chptr->members; member; member = member->next_member) - { - c2ptr = member->user; -#ifndef GODMODE - if (sptr != c2ptr && IsInvisible(c2ptr) && !find_channel_member(sptr, chptr)) - continue; -#endif - if (IsZombie(member)) - { - if (member->user != sptr) - continue; + int idx; + int mlen; + int flag; + struct Channel *ch3ptr; + char buf[BUFSIZE]; + + mlen = strlen(cli_name(&me)) + 10 + strlen(cli_name(sptr)); + + /* List all visible channels/visible members */ + + for (ch2ptr = GlobalChannelList; ch2ptr; ch2ptr = ch2ptr->next) + { + if (!ShowChannel(sptr, ch2ptr)) + continue; /* Don't show secret chans. */ + else if (find_channel_member(sptr, ch2ptr)) + do_names(sptr, ch2ptr, showingdelayed|NAMES_ALL); /* Full list if we're in this chan. */ else - { - strcat(buf, "!"); - idx++; - } - } - else if (IsChanOp(member)) - { - strcat(buf, "@"); - idx++; - } - else if (HasVoice(member)) - { - strcat(buf, "+"); - idx++; - } - strcat(buf, c2ptr->name); - strcat(buf, " "); - idx += strlen(c2ptr->name) + 1; - flag = 1; -#ifdef GODMODE - { - char yxx[6]; - sprintf_irc(yxx, "%s%s", NumNick(c2ptr)); - assert(c2ptr == findNUser(yxx)); - sprintf_irc(buf + strlen(buf), "(%s) ", yxx); - idx += 6; - } - if (mlen + idx + NICKLEN + 11 > BUFSIZE) -#else - if (mlen + idx + NICKLEN + 5 > BUFSIZE) -#endif - /* space, modifier, nick, \r \n \0 */ - { - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - strcpy(buf, "* "); - ircd_strncpy(buf + 2, chptr->chname, len + 1); - buf[len + 2] = 0; - strcat(buf, " :"); - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - idx = len + 4; - flag = 0; - } - } - if (flag) - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - } - if (!EmptyString(para)) - { - sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0], - ch2ptr ? ch2ptr->chname : para); - return (1); - } + do_names(sptr, ch2ptr, showingdelayed|NAMES_VIS); + } - /* Second, do all non-public, non-secret channels in one big sweep */ + /* List all remaining users on channel '*' */ - strcpy(buf, "* * :"); - idx = 5; - flag = 0; - for (c2ptr = GlobalClientList; c2ptr; c2ptr = c2ptr->next) - { - struct Channel *ch3ptr; - int showflag = 0, secret = 0; - -#ifndef GODMODE - if (!IsUser(c2ptr) || (sptr != c2ptr && IsInvisible(c2ptr))) -#else - if (!IsUser(c2ptr)) -#endif - continue; - member = c2ptr->user->channel; - /* - * Don't show a client if they are on a secret channel or when - * they are on a channel sptr is on since they have already - * been show earlier. -avalon - */ - while (member) - { - ch3ptr = member->channel; -#ifndef GODMODE - if (PubChannel(ch3ptr) || find_channel_member(sptr, ch3ptr)) -#endif - showflag = 1; - if (SecretChannel(ch3ptr)) - secret = 1; - member = member->next_channel; - } - if (showflag) /* Have we already shown them ? */ - continue; -#ifndef GODMODE - if (secret) /* On any secret channels ? */ - continue; -#endif - strcat(buf, c2ptr->name); - strcat(buf, " "); - idx += strlen(c2ptr->name) + 1; - flag = 1; -#ifdef GODMODE - { - char yxx[6]; - sprintf_irc(yxx, "%s%s", NumNick(c2ptr)); - assert(c2ptr == findNUser(yxx)); - sprintf_irc(buf + strlen(buf), "(%s) ", yxx); - idx += 6; - } -#endif -#ifdef GODMODE - if (mlen + idx + NICKLEN + 9 > BUFSIZE) -#else - if (mlen + idx + NICKLEN + 3 > BUFSIZE) /* space, \r\n\0 */ -#endif - { - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); strcpy(buf, "* * :"); idx = 5; flag = 0; - } - } - if (flag) - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0], "*"); - return 1; - return 0; -} - -#if 0 -/* - * m_names - Added by Jto 27 Apr 1989 - * - * parv[0] = sender prefix - * parv[1] = channel - */ -int m_names(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) -{ - struct Channel *chptr; - struct Client *c2ptr; - struct Membership* member; - struct Channel *ch2ptr = 0; - int idx, flag, len, mlen; - char *s, *para = parc > 1 ? parv[1] : 0; - char buf[BUFSIZE]; - - if (parc > 2 && hunt_server(1, cptr, sptr, "%s%s " TOK_NAMES " %s %s", 2, parc, parv)) - return 0; + for (c2ptr = GlobalClientList; c2ptr; c2ptr = cli_next(c2ptr)) + { + int showflag = 0; - mlen = strlen(me.name) + 10 + strlen(sptr->name); + if (!IsUser(c2ptr) || (sptr != c2ptr && IsInvisible(c2ptr))) + continue; - if (!EmptyString(para)) - { - s = strchr(para, ','); - if (s) - { - parv[1] = ++s; - m_names(cptr, sptr, parc, parv); - } - clean_channelname(para); - ch2ptr = FindChannel(para); - } + member = cli_user(c2ptr)->channel; - /* - * First, do all visible channels (public and the one user self is) - */ + while (member) + { + ch3ptr = member->channel; + + if (PubChannel(ch3ptr) || find_channel_member(sptr, ch3ptr)) + showflag = 1; + + member = member->next_channel; + } - for (chptr = GlobalChannelList; chptr; chptr = chptr->next) - { - if ((chptr != ch2ptr) && !EmptyString(para)) - continue; /* -- wanted a specific channel */ - if (!MyConnect(sptr) && EmptyString(para)) - continue; -#ifndef GODMODE - if (!ShowChannel(sptr, chptr)) - continue; /* -- users on this are not listed */ -#endif - - /* Find users on same channel (defined by chptr) */ - - strcpy(buf, "* "); - len = strlen(chptr->chname); - strcpy(buf + 2, chptr->chname); - strcpy(buf + 2 + len, " :"); - - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - idx = len + 4; - flag = 1; - for (member = chptr->members; member; member = member->next_member) - { - c2ptr = member->user; -#ifndef GODMODE - if (sptr != c2ptr && IsInvisible(c2ptr) && !find_channel_member(sptr, chptr)) - continue; -#endif - if (IsZombie(member)) - { - if (member->user != sptr) + if (showflag) /* Have we already shown them? */ continue; - else + + strcpy(buf + idx, cli_name(c2ptr)); + idx += strlen(cli_name(c2ptr)); + buf[idx++] = ' '; + flag = 1; + + if (mlen + idx + NICKLEN + 3 > BUFSIZE) /* space, \r\n\0 */ { - strcat(buf, "!"); - idx++; + send_reply(sptr, RPL_NAMREPLY, buf); + strcpy(buf, "* * :"); + idx = 5; + flag = 0; } } - else if (IsChanOp(member)) - { - strcat(buf, "@"); - idx++; - } - else if (HasVoice(member)) - { - strcat(buf, "+"); - idx++; - } - strcat(buf, c2ptr->name); - strcat(buf, " "); - idx += strlen(c2ptr->name) + 1; - flag = 1; -#ifdef GODMODE + if (flag) + send_reply(sptr, RPL_NAMREPLY, buf); + send_reply(sptr, RPL_ENDOFNAMES, "*"); + } + else if ((chptr = FindChannel(para)) != NULL) + { + member = find_member_link(chptr, sptr); + if (member) { - char yxx[6]; - sprintf_irc(yxx, "%s%s", NumNick(c2ptr)); - assert(c2ptr == findNUser(yxx)); - sprintf_irc(buf + strlen(buf), "(%s) ", yxx); - idx += 6; + /* + * Special Case 2: User is on this channel, requesting full names list. + * (As performed with each /join) - ** High frequency usage ** + */ + do_names(sptr, chptr, showingdelayed|NAMES_ALL|NAMES_EON); } - if (mlen + idx + NICKLEN + 11 > BUFSIZE) -#else - if (mlen + idx + NICKLEN + 5 > BUFSIZE) -#endif - /* space, modifier, nick, \r \n \0 */ + else { - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - strcpy(buf, "* "); - ircd_strncpy(buf + 2, chptr->chname, len + 1); - buf[len + 2] = 0; - strcat(buf, " :"); - if (PubChannel(chptr)) - *buf = '='; - else if (SecretChannel(chptr)) - *buf = '@'; - idx = len + 4; - flag = 0; - } + /* + * Special Case 3: User isn't on this channel, show all visible users, in + * non secret channels. + */ + do_names(sptr, chptr, showingdelayed|NAMES_VIS|NAMES_EON); + } } - if (flag) - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - } - if (!EmptyString(para)) - { - sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0], - ch2ptr ? ch2ptr->chname : para); - return (1); - } - - /* Second, do all non-public, non-secret channels in one big sweep */ + else + send_reply(sptr, RPL_ENDOFNAMES, para); + } while ((para = s) != NULL); - strcpy(buf, "* * :"); - idx = 5; - flag = 0; - for (c2ptr = GlobalClientList; c2ptr; c2ptr = c2ptr->next) - { - struct Channel *ch3ptr; - int showflag = 0, secret = 0; - -#ifndef GODMODE - if (!IsUser(c2ptr) || (sptr != c2ptr && IsInvisible(c2ptr))) -#else - if (!IsUser(c2ptr)) -#endif - continue; - member = c2ptr->user->channel; - /* - * Don't show a client if they are on a secret channel or when - * they are on a channel sptr is on since they have already - * been show earlier. -avalon - */ - while (member) - { - ch3ptr = member->channel; -#ifndef GODMODE - if (PubChannel(ch3ptr) || find_channel_member(sptr, ch3ptr)) -#endif - showflag = 1; - if (SecretChannel(ch3ptr)) - secret = 1; - member = member->next_channel; - } - if (showflag) /* Have we already shown them ? */ - continue; -#ifndef GODMODE - if (secret) /* On any secret channels ? */ - continue; -#endif - strcat(buf, c2ptr->name); - strcat(buf, " "); - idx += strlen(c2ptr->name) + 1; - flag = 1; -#ifdef GODMODE - { - char yxx[6]; - sprintf_irc(yxx, "%s%s", NumNick(c2ptr)); - assert(c2ptr == findNUser(yxx)); - sprintf_irc(buf + strlen(buf), "(%s) ", yxx); - idx += 6; - } -#endif -#ifdef GODMODE - if (mlen + idx + NICKLEN + 9 > BUFSIZE) -#else - if (mlen + idx + NICKLEN + 3 > BUFSIZE) /* space, \r\n\0 */ -#endif - { - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - strcpy(buf, "* * :"); - idx = 5; - flag = 0; - } - } - if (flag) - sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf); - sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0], "*"); return 1; } -#endif /* 0 */ -