home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / in4wjcxu / other / irc / ircd / channel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-14  |  43.1 KB  |  1,969 lines

  1. /************************************************************************
  2.  *   IRC - Internet Relay Chat, ircd/channel.c
  3.  *   Copyright (C) 1990 Jarkko Oikarinen and
  4.  *                      University of Oulu, Co Center
  5.  *
  6.  *   This program is free software; you can redistribute it and/or modify
  7.  *   it under the terms of the GNU General Public License as published by
  8.  *   the Free Software Foundation; either version 1, or (at your option)
  9.  *   any later version.
  10.  *
  11.  *   This program is distributed in the hope that it will be useful,
  12.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *   GNU General Public License for more details.
  15.  *
  16.  *   You should have received a copy of the GNU General Public License
  17.  *   along with this program; if not, write to the Free Software
  18.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /* -- Jto -- 09 Jul 1990
  22.  * Bug fix
  23.  */
  24.  
  25. /* -- Jto -- 03 Jun 1990
  26.  * Moved m_channel() and related functions from s_msg.c to here
  27.  * Many changes to start changing into string channels...
  28.  */
  29.  
  30. /* -- Jto -- 24 May 1990
  31.  * Moved is_full() from list.c
  32.  */
  33.  
  34. #ifndef    lint
  35. static    char sccsid[] = "@(#)channel.c    2.58 2/18/94 (C) 1990 University of Oulu, Computing\
  36.  Center and Jarkko Oikarinen";
  37. #endif
  38.  
  39. #include "struct.h"
  40. #include "common.h"
  41. #include "sys.h"
  42. #include "numeric.h"
  43. #include "channel.h"
  44. #include "h.h"
  45.  
  46. aChannel *channel = NullChn;
  47.  
  48. static    void    add_invite PROTO((aClient *, aChannel *));
  49. static    int    add_banid PROTO((aClient *, aChannel *, char *));
  50. static    int    can_join PROTO((aClient *, aChannel *, char *));
  51. static    void    channel_modes PROTO((aClient *, char *, char *, aChannel *));
  52. static    int    check_channelmask PROTO((aClient *, aClient *, char *));
  53. static    int    del_banid PROTO((aChannel *, char *));
  54. static    Link    *is_banned PROTO((aClient *, aChannel *));
  55. static    int    set_mode PROTO((aClient *, aClient *, aChannel *, int,\
  56.                     char **, char *,char *));
  57. static    void    sub1_from_channel PROTO((aChannel *));
  58.  
  59. void    clean_channelname PROTO((char *));
  60. void    del_invite PROTO((aClient *, aChannel *));
  61.  
  62. static    char    *PartFmt = ":%s PART %s";
  63. /*
  64.  * some buffers for rebuilding channel/nick lists with ,'s
  65.  */
  66. static    char    nickbuf[BUFSIZE], buf[BUFSIZE];
  67. static    char    modebuf[MODEBUFLEN], parabuf[MODEBUFLEN];
  68.  
  69. /*
  70.  * return the length (>=0) of a chain of links.
  71.  */
  72. static    int    list_length(lp)
  73. Reg1    Link    *lp;
  74. {
  75.     Reg2    int    count = 0;
  76.  
  77.     for (; lp; lp = lp->next)
  78.         count++;
  79.     return count;
  80. }
  81.  
  82. /*
  83. ** find_chasing
  84. **    Find the client structure for a nick name (user) using history
  85. **    mechanism if necessary. If the client is not found, an error
  86. **    message (NO SUCH NICK) is generated. If the client was found
  87. **    through the history, chasing will be 1 and otherwise 0.
  88. */
  89. static    aClient *find_chasing(sptr, user, chasing)
  90. aClient *sptr;
  91. char    *user;
  92. Reg1    int    *chasing;
  93. {
  94.     Reg2    aClient *who = find_client(user, (aClient *)NULL);
  95.  
  96.     if (chasing)
  97.         *chasing = 0;
  98.     if (who)
  99.         return who;
  100.     if (!(who = get_history(user, (long)KILLCHASETIMELIMIT)))
  101.         {
  102.         sendto_one(sptr, err_str(ERR_NOSUCHNICK),
  103.                me.name, sptr->name, user);
  104.         return NULL;
  105.         }
  106.     if (chasing)
  107.         *chasing = 1;
  108.     return who;
  109. }
  110.  
  111. /*
  112.  *  Fixes a string so that the first white space found becomes an end of
  113.  * string marker (`\-`).  returns the 'fixed' string or "*" if the string
  114.  * was NULL length or a NULL pointer.
  115.  */
  116. static    char    *check_string(s)
  117. Reg1    char *s;
  118. {
  119.     static    char    star[2] = "*";
  120.     char    *str = s;
  121.  
  122.     if (BadPtr(s))
  123.         return star;
  124.  
  125.     for ( ;*s; s++)
  126.         if (isspace(*s))
  127.             {
  128.             *s = '\0';
  129.             break;
  130.             }
  131.  
  132.     return (BadPtr(str)) ? star : str;
  133. }
  134.  
  135. /*
  136.  * create a string of form "foo!bar@fubar" given foo, bar and fubar
  137.  * as the parameters.  If NULL, they become "*".
  138.  */
  139. static    char *make_nick_user_host(nick, name, host)
  140. Reg1    char    *nick, *name, *host;
  141. {
  142.     static    char    namebuf[NICKLEN+USERLEN+HOSTLEN+6];
  143.     Reg2    char    *s = namebuf;
  144.  
  145.     bzero(namebuf, sizeof(namebuf));
  146.     nick = check_string(nick);
  147.     strncpyzt(namebuf, nick, NICKLEN + 1);
  148.     s += strlen(s);
  149.     *s++ = '!';
  150.     name = check_string(name);
  151.     strncpyzt(s, name, USERLEN + 1);
  152.     s += strlen(s);
  153.     *s++ = '@';
  154.     host = check_string(host);
  155.     strncpyzt(s, host, HOSTLEN + 1);
  156.     s += strlen(s);
  157.     *s = '\0';
  158.     return (namebuf);
  159. }
  160.  
  161. /*
  162.  * Ban functions to work with mode +b
  163.  */
  164. /* add_banid - add an id to be banned to the channel  (belongs to cptr) */
  165.  
  166. static    int    add_banid(cptr, chptr, banid)
  167. aClient    *cptr;
  168. aChannel *chptr;
  169. char    *banid;
  170. {
  171.     Reg1    Link    *ban;
  172.     Reg2    int    cnt = 0, len = 0;
  173.  
  174.     if (MyClient(cptr))
  175.         (void)collapse(banid);
  176.     for (ban = chptr->banlist; ban; ban = ban->next)
  177.         {
  178.         len += strlen(ban->value.cp);
  179.         if (MyClient(cptr) &&
  180.             ((len > MAXBANLENGTH) || (++cnt >= MAXBANS) ||
  181.              !match(ban->value.cp, banid) ||
  182.              !match(banid, ban->value.cp)))
  183.             return -1;
  184.         else if (!mycmp(ban->value.cp, banid))
  185.             return -1;
  186.         
  187.         }
  188.     ban = make_link();
  189.     bzero((char *)ban, sizeof(Link));
  190.     ban->flags = CHFL_BAN;
  191.     ban->next = chptr->banlist;
  192.     ban->value.cp = (char *)MyMalloc(strlen(banid)+1);
  193.     (void)strcpy(ban->value.cp, banid);
  194.     chptr->banlist = ban;
  195.     return 0;
  196. }
  197.  
  198. /*
  199.  * del_banid - delete an id belonging to cptr
  200.  * if banid is null, deleteall banids belonging to cptr.
  201.  */
  202. static    int    del_banid(chptr, banid)
  203. aChannel *chptr;
  204. char    *banid;
  205. {
  206.     Reg1 Link **ban;
  207.     Reg2 Link *tmp;
  208.  
  209.     if (!banid)
  210.         return -1;
  211.     for (ban = &(chptr->banlist); *ban; ban = &((*ban)->next))
  212.         if (mycmp(banid, (*ban)->value.cp)==0)
  213.             {
  214.             tmp = *ban;
  215.             *ban = tmp->next;
  216.             MyFree(tmp->value.cp);
  217.             free_link(tmp);
  218.             break;
  219.             }
  220.     return 0;
  221. }
  222.  
  223. /*
  224.  * is_banned - returns a pointer to the ban structure if banned else NULL
  225.  */
  226. static    Link    *is_banned(cptr, chptr)
  227. aClient *cptr;
  228. aChannel *chptr;
  229. {
  230.     Reg1    Link    *tmp;
  231.     char    *s;
  232.  
  233.     if (!IsPerson(cptr))
  234.         return NULL;
  235.  
  236.     s = make_nick_user_host(cptr->name, cptr->user->username,
  237.                   cptr->user->host);
  238.  
  239.     for (tmp = chptr->banlist; tmp; tmp = tmp->next)
  240.         if (match(tmp->value.cp, s) == 0)
  241.             break;
  242.     return (tmp);
  243. }
  244.  
  245. /*
  246.  * adds a user to a channel by adding another link to the channels member
  247.  * chain.
  248.  */
  249. static    void    add_user_to_channel(chptr, who, flags)
  250. aChannel *chptr;
  251. aClient *who;
  252. int    flags;
  253. {
  254.     Reg1    Link *ptr;
  255.  
  256.     if (who->user)
  257.         {
  258.         ptr = make_link();
  259.         ptr->value.cptr = who;
  260.         ptr->flags = flags;
  261.         ptr->next = chptr->members;
  262.         chptr->members = ptr;
  263.         chptr->users++;
  264.  
  265.         ptr = make_link();
  266.         ptr->value.chptr = chptr;
  267.         ptr->next = who->user->channel;
  268.         who->user->channel = ptr;
  269.         who->user->joined++;
  270.         }
  271. }
  272.  
  273. void    remove_user_from_channel(sptr, chptr)
  274. aClient *sptr;
  275. aChannel *chptr;
  276. {
  277.     Reg1    Link    **curr;
  278.     Reg2    Link    *tmp;
  279.  
  280.     for (curr = &chptr->members; (tmp = *curr); curr = &tmp->next)
  281.         if (tmp->value.cptr == sptr)
  282.             {
  283.             *curr = tmp->next;
  284.             free_link(tmp);
  285.             break;
  286.             }
  287.     for (curr = &sptr->user->channel; (tmp = *curr); curr = &tmp->next)
  288.         if (tmp->value.chptr == chptr)
  289.             {
  290.             *curr = tmp->next;
  291.             free_link(tmp);
  292.             break;
  293.             }
  294.     sptr->user->joined--;
  295.     sub1_from_channel(chptr);
  296. }
  297.  
  298. static    void    change_chan_flag(lp, chptr)
  299. Link    *lp;
  300. aChannel *chptr;
  301. {
  302.     Reg1    Link *tmp;
  303.  
  304.     if ((tmp = find_user_link(chptr->members, lp->value.cptr)))
  305.         if (lp->flags & MODE_ADD)
  306.             tmp->flags |= lp->flags & MODE_FLAGS;
  307.         else
  308.             tmp->flags &= ~lp->flags & MODE_FLAGS;
  309. }
  310.  
  311. int    is_chan_op(cptr, chptr)
  312. aClient *cptr;
  313. aChannel *chptr;
  314. {
  315.     Reg1    Link    *lp;
  316.  
  317.     if (chptr)
  318.         if ((lp = find_user_link(chptr->members, cptr)))
  319.             return (lp->flags & CHFL_CHANOP);
  320.  
  321.     return 0;
  322. }
  323.  
  324. int    has_voice(cptr, chptr)
  325. aClient *cptr;
  326. aChannel *chptr;
  327. {
  328.     Reg1    Link    *lp;
  329.  
  330.     if (chptr)
  331.         if ((lp = find_user_link(chptr->members, cptr)))
  332.             return (lp->flags & CHFL_VOICE);
  333.  
  334.     return 0;
  335. }
  336.  
  337. int    can_send(cptr, chptr)
  338. aClient *cptr;
  339. aChannel *chptr;
  340. {
  341.     Reg1    Link    *lp;
  342.     Reg2    int    member;
  343.  
  344.     member = IsMember(cptr, chptr);
  345.     lp = find_user_link(chptr->members, cptr);
  346.  
  347.     if (chptr->mode.mode & MODE_MODERATED &&
  348.         (!lp || !(lp->flags & (CHFL_CHANOP|CHFL_VOICE))))
  349.             return (MODE_MODERATED);
  350.  
  351.     if (chptr->mode.mode & MODE_NOPRIVMSGS && !member)
  352.         return (MODE_NOPRIVMSGS);
  353.  
  354.     return 0;
  355. }
  356.  
  357. aChannel *find_channel(chname, chptr)
  358. Reg1    char    *chname;
  359. Reg2    aChannel *chptr;
  360. {
  361.     return hash_find_channel(chname, chptr);
  362. }
  363.  
  364. /*
  365.  * write the "simple" list of channel modes for channel chptr onto buffer mbuf
  366.  * with the parameters in pbuf.
  367.  */
  368. static    void    channel_modes(cptr, mbuf, pbuf, chptr)
  369. aClient    *cptr;
  370. Reg1    char    *mbuf, *pbuf;
  371. aChannel *chptr;
  372. {
  373.     *mbuf++ = '+';
  374.     if (chptr->mode.mode & MODE_SECRET)
  375.         *mbuf++ = 's';
  376.     else if (chptr->mode.mode & MODE_PRIVATE)
  377.         *mbuf++ = 'p';
  378.     if (chptr->mode.mode & MODE_MODERATED)
  379.         *mbuf++ = 'm';
  380.     if (chptr->mode.mode & MODE_TOPICLIMIT)
  381.         *mbuf++ = 't';
  382.     if (chptr->mode.mode & MODE_INVITEONLY)
  383.         *mbuf++ = 'i';
  384.     if (chptr->mode.mode & MODE_NOPRIVMSGS)
  385.         *mbuf++ = 'n';
  386.     if (chptr->mode.limit)
  387.         {
  388.         *mbuf++ = 'l';
  389.         if (IsMember(cptr, chptr) || IsServer(cptr))
  390.             (void)sprintf(pbuf, "%d ", chptr->mode.limit);
  391.         }
  392.     if (*chptr->mode.key)
  393.         {
  394.         *mbuf++ = 'k';
  395.         if (IsMember(cptr, chptr) || IsServer(cptr))
  396.             (void)strcat(pbuf, chptr->mode.key);
  397.         }
  398.     *mbuf++ = '\0';
  399.     return;
  400. }
  401. static    void    send_mode_list(cptr, chname, top, mask, flag)
  402. aClient    *cptr;
  403. Link    *top;
  404. int    mask;
  405. char    flag, *chname;
  406. {
  407.     Reg1    Link    *lp;
  408.     Reg2    char    *cp, *name;
  409.     int    count = 0, send = 0;
  410.  
  411.     cp = modebuf + strlen(modebuf);
  412.     if (*parabuf)    /* mode +l or +k xx */
  413.         count = 1;
  414.     for (lp = top; lp; lp = lp->next)
  415.         {
  416.         if (!(lp->flags & mask))
  417.             continue;
  418.         if (mask == CHFL_BAN)
  419.             name = lp->value.cp;
  420.         else
  421.             name = lp->value.cptr->name;
  422.         if (strlen(parabuf) + strlen(name) + 10 < (size_t) MODEBUFLEN)
  423.             {
  424.             (void)strcat(parabuf, " ");
  425.             (void)strcat(parabuf, name);
  426.             count++;
  427.             *cp++ = flag;
  428.             *cp = '\0';
  429.             }
  430.         else if (*parabuf)
  431.             send = 1;
  432.         if (count == 3)
  433.             send = 1;
  434.         if (send)
  435.             {
  436.             sendto_one(cptr, ":%s MODE %s %s %s",
  437.                    me.name, chname, modebuf, parabuf);
  438.             send = 0;
  439.             *parabuf = '\0';
  440.             cp = modebuf;
  441.             *cp++ = '+';
  442.             if (count != 3)
  443.                 {
  444.                 (void)strcpy(parabuf, name);
  445.                 *cp++ = flag;
  446.                 }
  447.             count = 0;
  448.             *cp = '\0';
  449.             }
  450.         }
  451. }
  452. /*
  453.  * send "cptr" a full list of the modes for channel chptr.
  454.  */
  455. void    send_channel_modes(cptr, chptr)
  456. aClient *cptr;
  457. aChannel *chptr;
  458. {
  459.     if (*chptr->chname != '#')
  460.         return;
  461.  
  462.     *modebuf = *parabuf = '\0';
  463.     channel_modes(cptr, modebuf, parabuf, chptr);
  464.  
  465.     send_mode_list(cptr, chptr->chname, chptr->members, CHFL_CHANOP, 'o');
  466.     if (modebuf[1] || *parabuf)
  467.         sendto_one(cptr, ":%s MODE %s %s %s",
  468.                me.name, chptr->chname, modebuf, parabuf);
  469.  
  470.     *parabuf = '\0';
  471.     *modebuf = '+';
  472.     modebuf[1] = '\0';
  473.     send_mode_list(cptr, chptr->chname, chptr->banlist, CHFL_BAN, 'b');
  474.     if (modebuf[1] || *parabuf)
  475.         sendto_one(cptr, ":%s MODE %s %s %s",
  476.                me.name, chptr->chname, modebuf, parabuf);
  477.  
  478.     *parabuf = '\0';
  479.     *modebuf = '+';
  480.     modebuf[1] = '\0';
  481.     send_mode_list(cptr, chptr->chname, chptr->members, CHFL_VOICE, 'v');
  482.     if (modebuf[1] || *parabuf)
  483.         sendto_one(cptr, ":%s MODE %s %s %s",
  484.                me.name, chptr->chname, modebuf, parabuf);
  485. }
  486.  
  487. /*
  488.  * m_mode
  489.  * parv[0] - sender
  490.  * parv[1] - channel
  491.  */
  492.  
  493. int    m_mode(cptr, sptr, parc, parv)
  494. aClient *cptr;
  495. aClient *sptr;
  496. int    parc;
  497. char    *parv[];
  498. {
  499.     int    mcount = 0, chanop;
  500.     aChannel *chptr;
  501.  
  502.     if (check_registered(sptr))
  503.         return 0;
  504.  
  505.     /* Now, try to find the channel in question */
  506.     if (parc > 1)
  507.         {
  508.         chptr = find_channel(parv[1], NullChn);
  509.         if (chptr == NullChn)
  510.             return m_umode(cptr, sptr, parc, parv);
  511.         }
  512.     else
  513.         {
  514.         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
  515.                me.name, parv[0], "MODE");
  516.           return 0;
  517.         }
  518.  
  519.     clean_channelname(parv[1]);
  520.     if (check_channelmask(sptr, cptr, parv[1]))
  521.         return 0;
  522.     chanop = is_chan_op(sptr, chptr) || IsServer(sptr);
  523.  
  524.     if (parc < 3)
  525.         {
  526.         *modebuf = *parabuf = '\0';
  527.         modebuf[1] = '\0';
  528.         channel_modes(sptr, modebuf, parabuf, chptr);
  529.         sendto_one(sptr, rpl_str(RPL_CHANNELMODEIS), me.name, parv[0],
  530.                chptr->chname, modebuf, parabuf);
  531.         return 0;
  532.         }
  533.     mcount = set_mode(cptr, sptr, chptr, parc - 2, parv + 2,
  534.               modebuf, parabuf);
  535.  
  536.     if ((mcount < 0) && MyConnect(sptr) && !IsServer(sptr))
  537.         {
  538.         sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
  539.                me.name, parv[0], chptr->chname);
  540.         return 0;
  541.         }
  542.     if (strlen(modebuf) > (size_t)1)
  543.         {
  544.         if ((IsServer(cptr) && !IsServer(sptr) && !chanop) ||
  545.             (mcount < 0))
  546.             {
  547.             sendto_ops("Fake: %s MODE %s %s %s",
  548.                    parv[0], parv[1], modebuf, parabuf);
  549.             ircstp->is_fake++;
  550.             }
  551.         else
  552.             sendto_channel_butserv(chptr, sptr,
  553.                         ":%s MODE %s %s %s", parv[0],
  554.                         chptr->chname, modebuf,
  555.                         parabuf);
  556.         sendto_match_servs(chptr, cptr, ":%s MODE %s %s %s",
  557.                    parv[0], chptr->chname, modebuf, parabuf);
  558.         }
  559.     return 0;
  560. }
  561.  
  562. /*
  563.  * Check and try to apply the channel modes passed in the parv array for
  564.  * the client ccptr to channel chptr.  The resultant changes are printed
  565.  * into mbuf and pbuf (if any) and applied to the channel.
  566.  */
  567. static    int    set_mode(cptr, sptr, chptr, parc, parv, mbuf, pbuf)
  568. Reg2    aClient *cptr, *sptr;
  569. aChannel *chptr;
  570. int    parc;
  571. char    *parv[], *mbuf, *pbuf;
  572. {
  573.     static    Link    chops[MAXMODEPARAMS];
  574.     static    int    flags[] = {
  575.                 MODE_PRIVATE,    'p', MODE_SECRET,     's',
  576.                 MODE_MODERATED,  'm', MODE_NOPRIVMSGS, 'n',
  577.                 MODE_TOPICLIMIT, 't', MODE_INVITEONLY, 'i',
  578.                 MODE_VOICE,      'v', MODE_KEY,        'k',
  579.                 0x0, 0x0 };
  580.  
  581.     Reg1    Link    *lp;
  582.     Reg2    char    *curr = parv[0], *cp;
  583.     Reg3    int    *ip;
  584.     u_int    whatt = MODE_ADD;
  585.     int    limitset = 0, count = 0, chasing = 0;
  586.     int    nusers, ischop, new, len, keychange = 0, opcnt = 0;
  587.     char    fm = '\0';
  588.     aClient *who;
  589.     Mode    *mode, oldm;
  590.  
  591.     *mbuf = *pbuf = '\0';
  592.     if (parc < 1)
  593.         return 0;
  594.  
  595.     mode = &(chptr->mode);
  596.     bcopy((char *)mode, (char *)&oldm, sizeof(Mode));
  597.     ischop = IsServer(sptr) || is_chan_op(sptr, chptr);
  598.     new = mode->mode;
  599.  
  600.     while (curr && *curr && count >= 0)
  601.         {
  602.         switch (*curr)
  603.         {
  604.         case '+':
  605.             whatt = MODE_ADD;
  606.             break;
  607.         case '-':
  608.             whatt = MODE_DEL;
  609.             break;
  610.         case 'o' :
  611.         case 'v' :
  612.             if (--parc <= 0)
  613.                 break;
  614.             parv++;
  615.             *parv = check_string(*parv);
  616.             if (MyClient(sptr) && opcnt >= MAXMODEPARAMS)
  617.                 break;
  618.             /*
  619.              * Check for nickname changes and try to follow these
  620.              * to make sure the right client is affected by the
  621.              * mode change.
  622.              */
  623.             if (!(who = find_chasing(sptr, parv[0], &chasing)))
  624.                 break;
  625.               if (!IsMember(who, chptr))
  626.                 {
  627.                     sendto_one(cptr, err_str(ERR_USERNOTINCHANNEL),
  628.                        me.name, cptr->name,
  629.                        parv[0], chptr->chname);
  630.                 break;
  631.                 }
  632.             /*
  633.             ** If this server noticed the nick change, the
  634.             ** information must be propagated back upstream.
  635.             ** This is a bit early, but at most this will generate
  636.             ** just some extra messages if nick appeared more than
  637.             ** once in the MODE message... --msa
  638.             */
  639.             if (chasing && ischop)
  640.                 sendto_one(cptr, ":%s MODE %s %c%c %s",
  641.                        me.name, chptr->chname,
  642.                        whatt == MODE_ADD ? '+' : '-',
  643.                        *curr, who->name);
  644.  
  645.             if (who == cptr && whatt == MODE_ADD && *curr == 'o')
  646.                 break;
  647.             /*
  648.              * to stop problems, don't allow +v and +o to mix
  649.              * into the one message if from a client.
  650.              */
  651.             if (!fm)
  652.                 fm = *curr;
  653.             else if (MyClient(sptr) && (*curr != fm))
  654.                 break;
  655.             if (whatt == MODE_ADD)
  656.                 {
  657.                 lp = &chops[opcnt++];
  658.                 lp->value.cptr = who;
  659.                 lp->flags = (*curr == 'o') ? MODE_CHANOP:
  660.                                   MODE_VOICE;
  661.                 lp->flags |= MODE_ADD;
  662.                 }
  663.             else if (whatt == MODE_DEL)
  664.                 {
  665.                 lp = &chops[opcnt++];
  666.                 lp->value.cptr = who;
  667.                 lp->flags = (*curr == 'o') ? MODE_CHANOP:
  668.                                   MODE_VOICE;
  669.                 lp->flags |= MODE_DEL;
  670.                 }
  671.             count++;
  672.             break;
  673.         case 'k':
  674.             if (--parc <= 0)
  675.                 break;
  676.             parv++;
  677.             /* check now so we eat the parameter if present */
  678.             if (keychange)
  679.                 break;
  680.             *parv = check_string(*parv);
  681.             {
  682.                 u_char    *s;
  683.  
  684.                 for (s = (u_char *)*parv; *s; s++)
  685.                     *s &= 0x7f;
  686.             }
  687.             if (MyClient(sptr) && opcnt >= MAXMODEPARAMS)
  688.                 break;
  689.             if (!fm)
  690.                 fm = *curr;
  691.             else if (MyClient(sptr) && (*curr != fm))
  692.                 break;
  693.             if (whatt == MODE_ADD)
  694.                 {
  695.                 if (*mode->key && !IsServer(cptr))
  696.                     sendto_one(cptr, err_str(ERR_KEYSET),
  697.                            me.name, cptr->name,
  698.                            chptr->chname);
  699.                 else if (ischop &&
  700.                     (!*mode->key || IsServer(cptr)))
  701.                     {
  702.                     lp = &chops[opcnt++];
  703.                     lp->value.cp = *parv;
  704.                     if (strlen(lp->value.cp) >
  705.                         (size_t) KEYLEN)
  706.                         lp->value.cp[KEYLEN] = '\0';
  707.                     lp->flags = MODE_KEY|MODE_ADD;
  708.                     keychange = 1;
  709.                     }
  710.                 }
  711.             else if (whatt == MODE_DEL)
  712.                 {
  713.                 if (ischop && (mycmp(mode->key, *parv) == 0 ||
  714.                      IsServer(cptr)))
  715.                     {
  716.                     lp = &chops[opcnt++];
  717.                     lp->value.cp = mode->key;
  718.                     lp->flags = MODE_KEY|MODE_DEL;
  719.                     keychange = 1;
  720.                     }
  721.                 }
  722.             count++;
  723.             break;
  724.         case 'b':
  725.             if (--parc <= 0)
  726.                 {
  727.                 for (lp = chptr->banlist; lp; lp = lp->next)
  728.                     sendto_one(cptr, rpl_str(RPL_BANLIST),
  729.                          me.name, cptr->name,
  730.                          chptr->chname, lp->value.cp);
  731.                 sendto_one(cptr, rpl_str(RPL_ENDOFBANLIST),
  732.                        me.name, cptr->name, chptr->chname);
  733.                 break;
  734.                 }
  735.             parv++;
  736.             if (BadPtr(*parv))
  737.                 break;
  738.             if (MyClient(sptr) && opcnt >= MAXMODEPARAMS)
  739.                 break;
  740.             if (whatt == MODE_ADD)
  741.                 {
  742.                 lp = &chops[opcnt++];
  743.                 lp->value.cp = *parv;
  744.                 lp->flags = MODE_ADD|MODE_BAN;
  745.                 }
  746.             else if (whatt == MODE_DEL)
  747.                 {
  748.                 lp = &chops[opcnt++];
  749.                 lp->value.cp = *parv;
  750.                 lp->flags = MODE_DEL|MODE_BAN;
  751.                 }
  752.             count++;
  753.             break;
  754.         case 'l':
  755.             /*
  756.              * limit 'l' to only *1* change per mode command but
  757.              * eat up others.
  758.              */
  759.             if (limitset || !ischop)
  760.                 {
  761.                 if (whatt == MODE_ADD && --parc > 0)
  762.                     parv++;
  763.                 break;
  764.                 }
  765.             if (whatt == MODE_DEL)
  766.                 {
  767.                 limitset = 1;
  768.                 nusers = 0;
  769.                 break;
  770.                 }
  771.             if (--parc > 0)
  772.                 {
  773.                 if (BadPtr(*parv))
  774.                     break;
  775.                 if (MyClient(sptr) && opcnt >= MAXMODEPARAMS)
  776.                     break;
  777.                 if (!(nusers = atoi(*++parv)))
  778.                     continue;
  779.                 lp = &chops[opcnt++];
  780.                 lp->flags = MODE_ADD|MODE_LIMIT;
  781.                 limitset = 1;
  782.                 count++;
  783.                 break;
  784.                 }
  785.             sendto_one(cptr, err_str(ERR_NEEDMOREPARAMS),
  786.                        me.name, cptr->name, "MODE +l");
  787.             break;
  788.         case 'i' : /* falls through for default case */
  789.             if (whatt == MODE_DEL)
  790.                 while (lp = chptr->invites)
  791.                     del_invite(lp->value.cptr, chptr);
  792.         default:
  793.             for (ip = flags; *ip; ip += 2)
  794.                 if (*(ip+1) == *curr)
  795.                     break;
  796.  
  797.             if (*ip)
  798.                 {
  799.                 if (whatt == MODE_ADD)
  800.                     {
  801.                     if (*ip == MODE_PRIVATE)
  802.                         new &= ~MODE_SECRET;
  803.                     else if (*ip == MODE_SECRET)
  804.                         new &= ~MODE_PRIVATE;
  805.                     new |= *ip;
  806.                     }
  807.                 else
  808.                     new &= ~*ip;
  809.                 count++;
  810.                 }
  811.             else
  812.                 sendto_one(cptr, err_str(ERR_UNKNOWNMODE),
  813.                         me.name, cptr->name, *curr);
  814.             break;
  815.         }
  816.         curr++;
  817.         /*
  818.          * Make sure modes strings such as "+m +t +p +i" are parsed
  819.          * fully.
  820.          */
  821.         if (!*curr && parc > 0)
  822.             {
  823.             curr = *++parv;
  824.             parc--;
  825.             }
  826.         } /* end of while loop for MODE processing */
  827.  
  828.     whatt = 0;
  829.  
  830.     for (ip = flags; *ip; ip += 2)
  831.         if ((*ip & new) && !(*ip & oldm.mode))
  832.             {
  833.             if (whatt == 0)
  834.                 {
  835.                 *mbuf++ = '+';
  836.                 whatt = 1;
  837.                 }
  838.             if (ischop)
  839.                 mode->mode |= *ip;
  840.             *mbuf++ = *(ip+1);
  841.             }
  842.  
  843.     for (ip = flags; *ip; ip += 2)
  844.         if ((*ip & oldm.mode) && !(*ip & new))
  845.             {
  846.             if (whatt != -1)
  847.                 {
  848.                 *mbuf++ = '-';
  849.                 whatt = -1;
  850.                 }
  851.             if (ischop)
  852.                 mode->mode &= ~*ip;
  853.             *mbuf++ = *(ip+1);
  854.             }
  855.  
  856.     if (limitset && !nusers && mode->limit)
  857.         {
  858.         if (whatt != -1)
  859.             {
  860.             *mbuf++ = '-';
  861.             whatt = -1;
  862.             }
  863.         mode->mode &= ~MODE_LIMIT;
  864.         mode->limit = 0;
  865.         *mbuf++ = 'l';
  866.         }
  867.  
  868.     /*
  869.      * Reconstruct "+bkov" chain.
  870.      */
  871.     if (opcnt)
  872.         {
  873.         Reg1    int    i = 0;
  874.         Reg2    char    c;
  875.         char    *user, *host, numeric[16];
  876.  
  877.         /* restriction for 2.7 servers */
  878.         if (!IsServer(cptr) && opcnt > (MAXMODEPARAMS-2))
  879.             opcnt = (MAXMODEPARAMS-2);
  880.  
  881.         for (; i < opcnt; i++)
  882.             {
  883.             lp = &chops[i];
  884.             /*
  885.              * make sure we have correct mode change sign
  886.              */
  887.             if (whatt != (lp->flags & (MODE_ADD|MODE_DEL)))
  888.                 if (lp->flags & MODE_ADD)
  889.                     {
  890.                     *mbuf++ = '+';
  891.                     whatt = MODE_ADD;
  892.                     }
  893.                 else
  894.                     {
  895.                     *mbuf++ = '-';
  896.                     whatt = MODE_DEL;
  897.                     }
  898.             len = strlen(pbuf);
  899.             /*
  900.              * get c as the mode char and tmp as a pointer to
  901.              * the paramter for this mode change.
  902.              */
  903.             switch(lp->flags & MODE_WPARAS)
  904.             {
  905.             case MODE_CHANOP :
  906.                 c = 'o';
  907.                 cp = lp->value.cptr->name;
  908.                 break;
  909.             case MODE_VOICE :
  910.                 c = 'v';
  911.                 cp = lp->value.cptr->name;
  912.                 break;
  913.             case MODE_BAN :
  914.                 c = 'b';
  915.                 cp = lp->value.cp;
  916.                 if ((user = index(cp, '!')))
  917.                     *user++ = '\0';
  918.                 if ((host = rindex(user ? user : cp, '@')))
  919.                     *host++ = '\0';
  920.                 cp = make_nick_user_host(cp, user, host);
  921.                 break;
  922.             case MODE_KEY :
  923.                 c = 'k';
  924.                 cp = lp->value.cp;
  925.                 break;
  926.             case MODE_LIMIT :
  927.                 c = 'l';
  928.                 (void)sprintf(numeric, "%-15d", nusers);
  929.                 if ((cp = index(numeric, ' ')))
  930.                     *cp = '\0';
  931.                 cp = numeric;
  932.                 break;
  933.             }
  934.  
  935.             if (len + strlen(cp) + 2 > (size_t) MODEBUFLEN)
  936.                 break;
  937.             /*
  938.              * pass on +/-o/v regardless of whether they are
  939.              * redundant or effective but check +b's to see if
  940.              * it existed before we created it.
  941.              */
  942.             switch(lp->flags & MODE_WPARAS)
  943.             {
  944.             case MODE_KEY :
  945.                 *mbuf++ = c;
  946.                 (void)strcat(pbuf, cp);
  947.                 len += strlen(cp);
  948.                 (void)strcat(pbuf, " ");
  949.                 len++;
  950.                 if (!ischop)
  951.                     break;
  952.                 if (strlen(cp) > (size_t) KEYLEN)
  953.                     *(cp+KEYLEN) = '\0';
  954.                 if (whatt == MODE_ADD)
  955.                     strncpyzt(mode->key, cp,
  956.                           sizeof(mode->key));
  957.                 else
  958.                     *mode->key = '\0';
  959.                 break;
  960.             case MODE_LIMIT :
  961.                 *mbuf++ = c;
  962.                 (void)strcat(pbuf, cp);
  963.                 len += strlen(cp);
  964.                 (void)strcat(pbuf, " ");
  965.                 len++;
  966.                 if (!ischop)
  967.                     break;
  968.                 mode->limit = nusers;
  969.                 break;
  970.             case MODE_CHANOP :
  971.             case MODE_VOICE :
  972.                 *mbuf++ = c;
  973.                 (void)strcat(pbuf, cp);
  974.                 len += strlen(cp);
  975.                 (void)strcat(pbuf, " ");
  976.                 len++;
  977.                 if (ischop)
  978.                     change_chan_flag(lp, chptr);
  979.                 break;
  980.             case MODE_BAN :
  981.                 if (ischop && ((whatt & MODE_ADD) &&
  982.                      !add_banid(sptr, chptr, cp) ||
  983.                      (whatt & MODE_DEL) &&
  984.                      !del_banid(chptr, cp)))
  985.                     {
  986.                     *mbuf++ = c;
  987.                     (void)strcat(pbuf, cp);
  988.                     len += strlen(cp);
  989.                     (void)strcat(pbuf, " ");
  990.                     len++;
  991.                     }
  992.                 break;
  993.             }
  994.             } /* for (; i < opcnt; i++) */
  995.         } /* if (opcnt) */
  996.  
  997.     *mbuf++ = '\0';
  998.  
  999.     return ischop ? count : -count;
  1000. }
  1001.  
  1002. static    int    can_join(sptr, chptr, key)
  1003. aClient    *sptr;
  1004. Reg2    aChannel *chptr;
  1005. char    *key;
  1006. {
  1007.     Reg1    Link    *lp;
  1008.  
  1009.     if (is_banned(sptr, chptr))
  1010.         return (ERR_BANNEDFROMCHAN);
  1011.     if (chptr->mode.mode & MODE_INVITEONLY)
  1012.         {
  1013.         for (lp = sptr->user->invited; lp; lp = lp->next)
  1014.             if (lp->value.chptr == chptr)
  1015.                 break;
  1016.         if (!lp)
  1017.             return (ERR_INVITEONLYCHAN);
  1018.         }
  1019.  
  1020.     if (*chptr->mode.key && (BadPtr(key) || mycmp(chptr->mode.key, key)))
  1021.         return (ERR_BADCHANNELKEY);
  1022.  
  1023.     if (chptr->mode.limit && chptr->users >= chptr->mode.limit)
  1024.         return (ERR_CHANNELISFULL);
  1025.  
  1026.     return 0;
  1027. }
  1028.  
  1029. /*
  1030. ** Remove bells and commas from channel name
  1031. */
  1032.  
  1033. void    clean_channelname(cn)
  1034. Reg1    char *cn;
  1035. {
  1036.     for (; *cn; cn++)
  1037.         if (*cn == '\007' || *cn == ' ' || *cn == ',')
  1038.             {
  1039.             *cn = '\0';
  1040.             return;
  1041.             }
  1042. }
  1043.  
  1044. /*
  1045. ** Return -1 if mask is present and doesnt match our server name.
  1046. */
  1047. static    int    check_channelmask(sptr, cptr, chname)
  1048. aClient    *sptr, *cptr;
  1049. char    *chname;
  1050. {
  1051.     Reg1    char    *s;
  1052.  
  1053.     if (*chname == '&' && IsServer(cptr))
  1054.         return -1;
  1055.     s = rindex(chname, ':');
  1056.     if (!s)
  1057.         return 0;
  1058.  
  1059.     s++;
  1060.     if (matches(s, me.name) || (IsServer(cptr) && matches(s, cptr->name)))
  1061.         {
  1062.         if (MyClient(sptr))
  1063.             sendto_one(sptr, err_str(ERR_BADCHANMASK),
  1064.                    me.name, sptr->name, chname);
  1065.         return -1;
  1066.         }
  1067.     return 0;
  1068. }
  1069.  
  1070. /*
  1071. **  Get Channel block for i (and allocate a new channel
  1072. **  block, if it didn't exists before).
  1073. */
  1074. static    aChannel *get_channel(cptr, chname, flag)
  1075. aClient *cptr;
  1076. char    *chname;
  1077. int    flag;
  1078.     {
  1079.     Reg1    aChannel *chptr;
  1080.     int    len;
  1081.  
  1082.     if (BadPtr(chname))
  1083.         return NULL;
  1084.  
  1085.     len = strlen(chname);
  1086.     if (MyClient(cptr) && len > CHANNELLEN)
  1087.         {
  1088.         len = CHANNELLEN;
  1089.         *(chname+CHANNELLEN) = '\0';
  1090.         }
  1091.     if ((chptr = find_channel(chname, (aChannel *)NULL)))
  1092.         return (chptr);
  1093.     if (flag == CREATE)
  1094.         {
  1095.         chptr = (aChannel *)MyMalloc(sizeof(aChannel) + len);
  1096.         bzero((char *)chptr, sizeof(aChannel));
  1097.         strncpyzt(chptr->chname, chname, len+1);
  1098.         if (channel)
  1099.             channel->prevch = chptr;
  1100.         chptr->prevch = NULL;
  1101.         chptr->nextch = channel;
  1102.         channel = chptr;
  1103.         (void)add_to_channel_hash_table(chname, chptr);
  1104.         }
  1105.     return chptr;
  1106.     }
  1107.  
  1108. static    void    add_invite(cptr, chptr)
  1109. aClient *cptr;
  1110. aChannel *chptr;
  1111. {
  1112.     Reg1    Link    *inv, **tmp;
  1113.  
  1114.     del_invite(cptr, chptr);
  1115.     /*
  1116.      * delete last link in chain if the list is max length
  1117.      */
  1118.     if (list_length(cptr->user->invited) >= MAXCHANNELSPERUSER)
  1119.         {
  1120. /*        This forgets the channel side of invitation     -Vesa
  1121.         inv = cptr->user->invited;
  1122.         cptr->user->invited = inv->next;
  1123.         free_link(inv);
  1124. */
  1125.         del_invite(cptr, cptr->user->invited->value.chptr);
  1126.  
  1127.         }
  1128.     /*
  1129.      * add client to channel invite list
  1130.      */
  1131.     inv = make_link();
  1132.     inv->value.cptr = cptr;
  1133.     inv->next = chptr->invites;
  1134.     chptr->invites = inv;
  1135.     /*
  1136.      * add channel to the end of the client invite list
  1137.      */
  1138.     for (tmp = &(cptr->user->invited); *tmp; tmp = &((*tmp)->next))
  1139.         ;
  1140.     inv = make_link();
  1141.     inv->value.chptr = chptr;
  1142.     inv->next = NULL;
  1143.     (*tmp) = inv;
  1144. }
  1145.  
  1146. /*
  1147.  * Delete Invite block from channel invite list and client invite list
  1148.  */
  1149. void    del_invite(cptr, chptr)
  1150. aClient *cptr;
  1151. aChannel *chptr;
  1152. {
  1153.     Reg1    Link    **inv, *tmp;
  1154.  
  1155.     for (inv = &(chptr->invites); (tmp = *inv); inv = &tmp->next)
  1156.         if (tmp->value.cptr == cptr)
  1157.             {
  1158.             *inv = tmp->next;
  1159.             free_link(tmp);
  1160.             break;
  1161.             }
  1162.  
  1163.     for (inv = &(cptr->user->invited); (tmp = *inv); inv = &tmp->next)
  1164.         if (tmp->value.chptr == chptr)
  1165.             {
  1166.             *inv = tmp->next;
  1167.             free_link(tmp);
  1168.             break;
  1169.             }
  1170. }
  1171.  
  1172. /*
  1173. **  Subtract one user from channel i (and free channel
  1174. **  block, if channel became empty).
  1175. */
  1176. static    void    sub1_from_channel(chptr)
  1177. Reg1    aChannel *chptr;
  1178. {
  1179.     Reg2    Link *tmp;
  1180.     Link    *obtmp;
  1181.  
  1182.     if (--chptr->users <= 0)
  1183.         {
  1184.         /*
  1185.          * Now, find all invite links from channel structure
  1186.          */
  1187.         while ((tmp = chptr->invites))
  1188.             del_invite(tmp->value.cptr, chptr);
  1189.  
  1190.         tmp = chptr->banlist;
  1191.         while (tmp)
  1192.             {
  1193.             obtmp = tmp;
  1194.             tmp = tmp->next;
  1195.             MyFree(obtmp->value.cp);
  1196.             free_link(obtmp);
  1197.             }
  1198.         if (chptr->prevch)
  1199.             chptr->prevch->nextch = chptr->nextch;
  1200.         else
  1201.             channel = chptr->nextch;
  1202.         if (chptr->nextch)
  1203.             chptr->nextch->prevch = chptr->prevch;
  1204.         (void)del_from_channel_hash_table(chptr->chname, chptr);
  1205.         MyFree((char *)chptr);
  1206.         }
  1207. }
  1208.  
  1209. /*
  1210. ** m_join
  1211. **    parv[0] = sender prefix
  1212. **    parv[1] = channel
  1213. **    parv[2] = channel password (key)
  1214. */
  1215. int    m_join(cptr, sptr, parc, parv)
  1216. Reg2    aClient *cptr, *sptr;
  1217. int    parc;
  1218. char    *parv[];
  1219. {
  1220.     static    char    jbuf[BUFSIZE];
  1221.     Reg1    Link    *lp;
  1222.     Reg3    aChannel *chptr;
  1223.     Reg4    char    *name, *key = NULL;
  1224.     int    i, flags = 0;
  1225.     char    *p = NULL, *p2 = NULL;
  1226.  
  1227.     if (check_registered_user(sptr))
  1228.         return 0;
  1229.  
  1230.     if (parc < 2 || *parv[1] == '\0')
  1231.         {
  1232.         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
  1233.                me.name, parv[0], "JOIN");
  1234.         return 0;
  1235.         }
  1236.  
  1237.     *jbuf = '\0';
  1238.     /*
  1239.     ** Rebuild list of channels joined to be the actual result of the
  1240.     ** JOIN.  Note that "JOIN 0" is the destructive problem.
  1241.     */
  1242.     for (i = 0, name = strtoken(&p, parv[1], ","); name;
  1243.          name = strtoken(&p, NULL, ","))
  1244.         {
  1245.         clean_channelname(name);
  1246.         if (check_channelmask(sptr, cptr, name)==-1)
  1247.             continue;
  1248.         if (*name == '&' && !MyConnect(sptr))
  1249.             continue;
  1250.         if (*name == '0' && !atoi(name))
  1251.             (void)strcpy(jbuf, "0");
  1252.         else if (!IsChannelName(name))
  1253.             {
  1254.             if (MyClient(sptr))
  1255.                 sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL),
  1256.                        me.name, parv[0], name);
  1257.             continue;
  1258.             }
  1259.         if (*jbuf)
  1260.             (void)strcat(jbuf, ",");
  1261.         (void)strncat(jbuf, name, sizeof(jbuf) - i - 1);
  1262.         i += strlen(name)+1;
  1263.         }
  1264.     (void)strcpy(parv[1], jbuf);
  1265.  
  1266.     p = NULL;
  1267.     if (parv[2])
  1268.         key = strtoken(&p2, parv[2], ",");
  1269.     parv[2] = NULL;    /* for m_names call later, parv[parc] must == NULL */
  1270.     for (name = strtoken(&p, jbuf, ","); name;
  1271.          key = (key) ? strtoken(&p2, NULL, ",") : NULL,
  1272.          name = strtoken(&p, NULL, ","))
  1273.         {
  1274.         /*
  1275.         ** JOIN 0 sends out a part for all channels a user
  1276.         ** has joined.
  1277.         */
  1278.         if (*name == '0' && !atoi(name))
  1279.             {
  1280.             while ((lp = sptr->user->channel))
  1281.                 {
  1282.                 chptr = lp->value.chptr;
  1283.                 sendto_channel_butserv(chptr, sptr, PartFmt,
  1284.                         parv[0], chptr->chname);
  1285.                 remove_user_from_channel(sptr, chptr);
  1286.                 }
  1287.             sendto_match_servs(NULL, cptr, ":%s JOIN 0", parv[0]);
  1288.             continue;
  1289.             }
  1290.  
  1291.         if (MyConnect(sptr))
  1292.             {
  1293.             /*
  1294.             ** local client is first to enter prviously nonexistant
  1295.             ** channel so make them (rightfully) the Channel
  1296.             ** Operator.
  1297.             */
  1298.             flags = (ChannelExists(name)) ? 0 : CHFL_CHANOP;
  1299.  
  1300.             if (sptr->user->joined >= MAXCHANNELSPERUSER)
  1301.                 {
  1302.                 sendto_one(sptr, err_str(ERR_TOOMANYCHANNELS),
  1303.                        me.name, parv[0], name);
  1304.                 return 0;
  1305.                 }
  1306.             }
  1307.  
  1308.         chptr = get_channel(sptr, name, CREATE);
  1309.  
  1310.         if (!chptr ||
  1311.             (MyConnect(sptr) && (i = can_join(sptr, chptr, key))))
  1312.             {
  1313.             sendto_one(sptr,
  1314.                    ":%s %d %s %s :Sorry, cannot join channel.",
  1315.                    me.name, i, parv[0], name);
  1316.             continue;
  1317.             }
  1318.         if (IsMember(sptr, chptr))
  1319.             continue;
  1320.  
  1321.         /*
  1322.         **  Complete user entry to the new channel (if any)
  1323.         */
  1324.         add_user_to_channel(chptr, sptr, flags);
  1325.         /*
  1326.         ** notify all other users on the new channel
  1327.         */
  1328.         sendto_channel_butserv(chptr, sptr, ":%s JOIN :%s",
  1329.                     parv[0], name);
  1330.         sendto_match_servs(chptr, cptr, ":%s JOIN :%s", parv[0], name);
  1331.  
  1332.         if (MyClient(sptr))
  1333.             {
  1334.             del_invite(sptr, chptr);
  1335.             if (flags == CHFL_CHANOP)
  1336.                 sendto_match_servs(chptr, cptr,
  1337.                            ":%s MODE %s +o %s",
  1338.                            me.name, name, parv[0]);
  1339.             if (chptr->topic[0] != '\0')
  1340.                 sendto_one(sptr, rpl_str(RPL_TOPIC), me.name,
  1341.                        parv[0], name, chptr->topic);
  1342.             parv[1] = name;
  1343.             (void)m_names(cptr, sptr, 2, parv);
  1344.             }
  1345.         }
  1346.     return 0;
  1347. }
  1348.  
  1349. /*
  1350. ** m_part
  1351. **    parv[0] = sender prefix
  1352. **    parv[1] = channel
  1353. */
  1354. int    m_part(cptr, sptr, parc, parv)
  1355. aClient *cptr, *sptr;
  1356. int    parc;
  1357. char    *parv[];
  1358.     {
  1359.     Reg1    aChannel *chptr;
  1360.     char    *p = NULL, *name;
  1361.  
  1362.     if (check_registered_user(sptr))
  1363.         return 0;
  1364.  
  1365.     if (parc < 2 || parv[1][0] == '\0')
  1366.         {
  1367.         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
  1368.                me.name, parv[0], "PART");
  1369.         return 0;
  1370.         }
  1371.  
  1372. #ifdef    V28PlusOnly
  1373.     *buf = '\0';
  1374. #endif
  1375.  
  1376.     for (; (name = strtoken(&p, parv[1], ",")); parv[1] = NULL)
  1377.         {
  1378.         chptr = get_channel(sptr, name, 0);
  1379.         if (!chptr)
  1380.             {
  1381.             sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL),
  1382.                    me.name, parv[0], name);
  1383.             continue;
  1384.             }
  1385.         if (check_channelmask(sptr, cptr, name))
  1386.             continue;
  1387.         if (!IsMember(sptr, chptr))
  1388.             {
  1389.             sendto_one(sptr, err_str(ERR_NOTONCHANNEL),
  1390.                        me.name, parv[0], name);
  1391.             continue;
  1392.             }
  1393.         /*
  1394.         **  Remove user from the old channel (if any)
  1395.         */
  1396. #ifdef    V28PlusOnly
  1397.         if (*buf)
  1398.             (void)strcat(buf, ",");
  1399.         (void)strcat(buf, name);
  1400. #else
  1401.         sendto_match_servs(chptr, cptr, PartFmt, parv[0], name);
  1402. #endif
  1403.         sendto_channel_butserv(chptr, sptr, PartFmt, parv[0], name);
  1404.         remove_user_from_channel(sptr, chptr);
  1405.         }
  1406. #ifdef    V28PlusOnly
  1407.     if (*buf)
  1408.         sendto_serv_butone(cptr, PartFmt, parv[0], buf);
  1409. #endif
  1410.     return 0;
  1411.     }
  1412.  
  1413. /*
  1414. ** m_kick
  1415. **    parv[0] = sender prefix
  1416. **    parv[1] = channel
  1417. **    parv[2] = client to kick
  1418. **    parv[3] = kick comment
  1419. */
  1420. int    m_kick(cptr, sptr, parc, parv)
  1421. aClient *cptr, *sptr;
  1422. int    parc;
  1423. char    *parv[];
  1424. {
  1425.     aClient *who;
  1426.     aChannel *chptr;
  1427.     int    chasing = 0;
  1428.     char    *comment, *name, *p = NULL, *user, *p2 = NULL;
  1429. #ifdef    V28PlusOnly
  1430.     int    mlen, len = 0, nlen;
  1431. #endif
  1432.  
  1433.     if (check_registered(sptr))
  1434.         return 0;
  1435.  
  1436.     if (parc < 3 || *parv[1] == '\0')
  1437.         {
  1438.         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
  1439.                me.name, parv[0], "KICK");
  1440.         return 0;
  1441.         }
  1442.     if (IsServer(sptr))
  1443.         sendto_ops("KICK from %s for %s %s",
  1444.                parv[0], parv[1], parv[2]);
  1445.     comment = (BadPtr(parv[3])) ? parv[0] : parv[3];
  1446.     if (strlen(comment) > (size_t) TOPICLEN)
  1447.         comment[TOPICLEN] = '\0';
  1448.  
  1449.     *nickbuf = *buf = '\0';
  1450. #ifdef    V28PlusOnly
  1451.     mlen = 7 + strlen(parv[0]);
  1452. #endif
  1453.  
  1454.     for (; (name = strtoken(&p, parv[1], ",")); parv[1] = NULL)
  1455.         {
  1456.         chptr = get_channel(sptr, name, !CREATE);
  1457.         if (!chptr)
  1458.             {
  1459.             sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL),
  1460.                    me.name, parv[0], name);
  1461.             continue;
  1462.             }
  1463.         if (check_channelmask(sptr, cptr, name))
  1464.             continue;
  1465.         if (!IsServer(sptr) && !is_chan_op(sptr, chptr))
  1466.             {
  1467.             sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
  1468.                    me.name, parv[0], chptr->chname);
  1469.             continue;
  1470.             }
  1471. #ifdef    V28PlusOnly
  1472.         if (len + mlen + strlen(name) < (size_t) BUFSIZE / 2)
  1473.             {
  1474.             if (*buf)
  1475.                 (void)strcat(buf, ",");
  1476.             (void)strcat(buf, name);
  1477.             len += strlen(name) + 1;
  1478.             }
  1479.         else
  1480.             continue;
  1481.         nlen = 0;
  1482. #endif
  1483.  
  1484.         for (; (user = strtoken(&p2, parv[2], ",")); parv[2] = NULL)
  1485.             {
  1486.             if (!(who = find_chasing(sptr, user, &chasing)))
  1487.                 continue; /* No such user left! */
  1488. #ifdef    V28PlusOnly
  1489.             if (nlen + mlen + strlen(who->name) >
  1490.                 (size_t) BUFSIZE - NICKLEN)
  1491.                 continue;
  1492. #endif
  1493.             if (IsMember(who, chptr))
  1494.                 {
  1495.                 sendto_channel_butserv(chptr, sptr,
  1496.                         ":%s KICK %s %s :%s", parv[0],
  1497.                         name, who->name, comment);
  1498. #ifdef    V28PlusOnly
  1499.                 if (*nickbuf)
  1500.                     (void)strcat(nickbuf, ",");
  1501.                 (void)strcat(nickbuf, who->name);
  1502.                 nlen += strlen(who->name);
  1503. #else
  1504.                 sendto_match_servs(chptr, cptr,
  1505.                            ":%s KICK %s %s :%s",
  1506.                            parv[0], name,
  1507.                            who->name, comment);
  1508. #endif
  1509.                 remove_user_from_channel(who, chptr);
  1510.                 }
  1511.             else
  1512.                 sendto_one(sptr, err_str(ERR_USERNOTINCHANNEL),
  1513.                        me.name, parv[0], user, name);
  1514. #ifndef    V28PlusOnly
  1515.             if (!IsServer(cptr))
  1516.                 break;
  1517. #endif
  1518.             } /* loop on parv[2] */
  1519. #ifndef    V28PlusOnly
  1520.         if (!IsServer(cptr))
  1521.             break;
  1522. #endif
  1523.         } /* loop on parv[1] */
  1524.  
  1525. #ifdef    V28PlusOnly
  1526.     if (*buf && *nickbuf)
  1527.         sendto_serv_butone(cptr, ":%s KICK %s %s :%s",
  1528.                    parv[0], buf, nickbuf, comment);
  1529. #endif
  1530.     return (0);
  1531. }
  1532.  
  1533. int    count_channels(sptr)
  1534. aClient    *sptr;
  1535. {
  1536. Reg1    aChannel    *chptr;
  1537.     Reg2    int    count = 0;
  1538.  
  1539.     for (chptr = channel; chptr; chptr = chptr->nextch)
  1540. #ifdef    SHOW_INVISIBLE_LUSERS
  1541.         if (SecretChannel(chptr))
  1542.             {
  1543.             if (IsAnOper(sptr))
  1544.                 count++;
  1545.             }
  1546.         else
  1547. #endif
  1548.             count++;
  1549.     return (count);
  1550. }
  1551.  
  1552. /*
  1553. ** m_topic
  1554. **    parv[0] = sender prefix
  1555. **    parv[1] = topic text
  1556. */
  1557. int    m_topic(cptr, sptr, parc, parv)
  1558. aClient *cptr, *sptr;
  1559. int    parc;
  1560. char    *parv[];
  1561.     {
  1562.     aChannel *chptr = NullChn;
  1563.     char    *topic = NULL, *name, *p = NULL;
  1564.     
  1565.     if (check_registered(sptr))
  1566.         return 0;
  1567.  
  1568.     if (parc < 2)
  1569.         {
  1570.         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
  1571.                me.name, parv[0], "TOPIC");
  1572.         return 0;
  1573.         }
  1574.  
  1575.     for (; (name = strtoken(&p, parv[1], ",")); parv[1] = NULL)
  1576.         {
  1577.         if (parc > 1 && IsChannelName(name))
  1578.             {
  1579.             chptr = find_channel(name, NullChn);
  1580.             if (!chptr || !IsMember(sptr, chptr))
  1581.                 {
  1582.                 sendto_one(sptr, err_str(ERR_NOTONCHANNEL),
  1583.                        me.name, parv[0], name);
  1584.                 continue;
  1585.                 }
  1586.             if (parc > 2)
  1587.                 topic = parv[2];
  1588.             }
  1589.  
  1590.         if (!chptr)
  1591.             {
  1592.             sendto_one(sptr, rpl_str(RPL_NOTOPIC),
  1593.                    me.name, parv[0], name);
  1594.             return 0;
  1595.             }
  1596.  
  1597.         if (check_channelmask(sptr, cptr, name))
  1598.             continue;
  1599.     
  1600.         if (!topic)  /* only asking  for topic  */
  1601.             {
  1602.             if (chptr->topic[0] == '\0')
  1603.             sendto_one(sptr, rpl_str(RPL_NOTOPIC),
  1604.                    me.name, parv[0], chptr->chname);
  1605.             else
  1606.                 sendto_one(sptr, rpl_str(RPL_TOPIC),
  1607.                        me.name, parv[0],
  1608.                        chptr->chname, chptr->topic);
  1609.             } 
  1610.         else if (((chptr->mode.mode & MODE_TOPICLIMIT) == 0 ||
  1611.               is_chan_op(sptr, chptr)) && topic)
  1612.             {
  1613.             /* setting a topic */
  1614.             strncpyzt(chptr->topic, topic, sizeof(chptr->topic));
  1615.             sendto_match_servs(chptr, cptr,":%s TOPIC %s :%s",
  1616.                        parv[0], chptr->chname,
  1617.                        chptr->topic);
  1618.             sendto_channel_butserv(chptr, sptr, ":%s TOPIC %s :%s",
  1619.                            parv[0],
  1620.                            chptr->chname, chptr->topic);
  1621.             }
  1622.         else
  1623.               sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
  1624.                  me.name, parv[0], chptr->chname);
  1625.         }
  1626.     return 0;
  1627.     }
  1628.  
  1629. /*
  1630. ** m_invite
  1631. **    parv[0] - sender prefix
  1632. **    parv[1] - user to invite
  1633. **    parv[2] - channel number
  1634. */
  1635. int    m_invite(cptr, sptr, parc, parv)
  1636. aClient *cptr, *sptr;
  1637. int    parc;
  1638. char    *parv[];
  1639.     {
  1640.     aClient *acptr;
  1641.     aChannel *chptr;
  1642.  
  1643.     if (check_registered_user(sptr))
  1644.         return 0;
  1645.  
  1646.     if (parc < 3 || *parv[1] == '\0')
  1647.         {
  1648.         sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
  1649.                me.name, parv[0], "INVITE");
  1650.         return -1;
  1651.         }
  1652.  
  1653.     if (!(acptr = find_person(parv[1], (aClient *)NULL)))
  1654.         {
  1655.         sendto_one(sptr, err_str(ERR_NOSUCHNICK),
  1656.                me.name, parv[0], parv[1]);
  1657.         return 0;
  1658.         }
  1659.     clean_channelname(parv[2]);
  1660.     if (check_channelmask(sptr, cptr, parv[2]))
  1661.         return 0;
  1662.     if (!(chptr = find_channel(parv[2], NullChn)))
  1663.         {
  1664.  
  1665.         sendto_prefix_one(acptr, sptr, ":%s INVITE %s :%s",
  1666.                   parv[0], parv[1], parv[2]);
  1667.         return 0;
  1668.         }
  1669.  
  1670.     if (chptr && !IsMember(sptr, chptr))
  1671.         {
  1672.         sendto_one(sptr, err_str(ERR_NOTONCHANNEL),
  1673.                me.name, parv[0], parv[2]);
  1674.         return -1;
  1675.         }
  1676.  
  1677.     if (IsMember(acptr, chptr))
  1678.         {
  1679.         sendto_one(sptr, err_str(ERR_USERONCHANNEL),
  1680.                me.name, parv[0], parv[1], parv[2]);
  1681.         return 0;
  1682.         }
  1683.     if (chptr && (chptr->mode.mode & MODE_INVITEONLY))
  1684.         {
  1685.         if (!is_chan_op(sptr, chptr))
  1686.             {
  1687.             sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
  1688.                    me.name, parv[0], chptr->chname);
  1689.             return -1;
  1690.             }
  1691.         else if (!IsMember(sptr, chptr))
  1692.             {
  1693.             sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
  1694.                    me.name, parv[0],
  1695.                    ((chptr) ? (chptr->chname) : parv[2]));
  1696.             return -1;
  1697.             }
  1698.         }
  1699.  
  1700.     if (MyConnect(sptr))
  1701.         {
  1702.         sendto_one(sptr, rpl_str(RPL_INVITING), me.name, parv[0],
  1703.                acptr->name, ((chptr) ? (chptr->chname) : parv[2]));
  1704.         if (acptr->user->away)
  1705.             sendto_one(sptr, rpl_str(RPL_AWAY), me.name, parv[0],
  1706.                    acptr->name, acptr->user->away);
  1707.         }
  1708.     if (MyConnect(acptr))
  1709.         if (chptr && (chptr->mode.mode & MODE_INVITEONLY) &&
  1710.             sptr->user && is_chan_op(sptr, chptr))
  1711.             add_invite(acptr, chptr);
  1712.     sendto_prefix_one(acptr, sptr, ":%s INVITE %s :%s",parv[0],
  1713.               acptr->name, ((chptr) ? (chptr->chname) : parv[2]));
  1714.     return 0;
  1715.     }
  1716.  
  1717.  
  1718. /*
  1719. ** m_list
  1720. **      parv[0] = sender prefix
  1721. **      parv[1] = channel
  1722. */
  1723. int    m_list(cptr, sptr, parc, parv)
  1724. aClient *cptr, *sptr;
  1725. int    parc;
  1726. char    *parv[];
  1727.     {
  1728.     aChannel *chptr;
  1729.     char    *name, *p = NULL;
  1730.  
  1731.     sendto_one(sptr, rpl_str(RPL_LISTSTART), me.name, parv[0]);
  1732.  
  1733.     if (parc < 2 || BadPtr(parv[1]))
  1734.         {
  1735.         for (chptr = channel; chptr; chptr = chptr->nextch)
  1736.             {
  1737.             if (!sptr->user ||
  1738.                 (SecretChannel(chptr) && !IsMember(sptr, chptr)))
  1739.                 continue;
  1740.             sendto_one(sptr, rpl_str(RPL_LIST), me.name, parv[0],
  1741.                    ShowChannel(sptr, chptr)?chptr->chname:"*",
  1742.                    chptr->users,
  1743.                    ShowChannel(sptr, chptr)?chptr->topic:"");
  1744.             }
  1745.         sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, parv[0]);
  1746.         return 0;
  1747.         }
  1748.  
  1749.     if (hunt_server(cptr, sptr, ":%s LIST %s %s", 2, parc, parv))
  1750.         return 0;
  1751.  
  1752.     for (; (name = strtoken(&p, parv[1], ",")); parv[1] = NULL)
  1753.         {
  1754.         chptr = find_channel(name, NullChn);
  1755.         if (chptr && ShowChannel(sptr, chptr) && sptr->user)
  1756.             sendto_one(sptr, rpl_str(RPL_LIST), me.name, parv[0],
  1757.                    ShowChannel(sptr,chptr) ? name : "*",
  1758.                    chptr->users, chptr->topic);
  1759.          }
  1760.     sendto_one(sptr, rpl_str(RPL_LISTEND), me.name, parv[0]);
  1761.     return 0;
  1762.     }
  1763.  
  1764.  
  1765. /************************************************************************
  1766.  * m_names() - Added by Jto 27 Apr 1989
  1767.  ************************************************************************/
  1768.  
  1769. /*
  1770. ** m_names
  1771. **    parv[0] = sender prefix
  1772. **    parv[1] = channel
  1773. */
  1774. int    m_names(cptr, sptr, parc, parv)
  1775. aClient *cptr, *sptr;
  1776. int    parc;
  1777. char    *parv[];
  1778.     Reg1    aChannel *chptr;
  1779.     Reg2    aClient *c2ptr;
  1780.     Reg3    Link    *lp;
  1781.     aChannel *ch2ptr = NULL;
  1782.     int    idx, flag, len, mlen;
  1783.     char    *s, *para = parc > 1 ? parv[1] : NULL;
  1784.  
  1785.     if (parc > 1 &&
  1786.         hunt_server(cptr, sptr, ":%s NAMES %s %s", 2, parc, parv))
  1787.         return 0;
  1788.  
  1789.     mlen = strlen(me.name) + 10;
  1790.  
  1791.     if (!BadPtr(para))
  1792.         {
  1793.         s = index(para, ',');
  1794.         if (s)
  1795.             {
  1796.             parv[1] = ++s;
  1797.             (void)m_names(cptr, sptr, parc, parv);
  1798.             }
  1799.         clean_channelname(para);
  1800.         ch2ptr = find_channel(para, (aChannel *)NULL);
  1801.         }
  1802.  
  1803.     *buf = '\0';
  1804.  
  1805.     /* Allow NAMES without registering
  1806.      *
  1807.      * First, do all visible channels (public and the one user self is)
  1808.      */
  1809.  
  1810.     for (chptr = channel; chptr; chptr = chptr->nextch)
  1811.         {
  1812.         if ((chptr != ch2ptr) && !BadPtr(para))
  1813.             continue; /* -- wanted a specific channel */
  1814.         if (!MyConnect(sptr) && BadPtr(para))
  1815.             continue;
  1816.         if (!ShowChannel(sptr, chptr))
  1817.             continue; /* -- users on this are not listed */
  1818.  
  1819.         /* Find users on same channel (defined by chptr) */
  1820.  
  1821.         (void)strcpy(buf, "* ");
  1822.         len = strlen(chptr->chname);
  1823.         (void)strcpy(buf + 2, chptr->chname);
  1824.         (void)strcpy(buf + 2 + len, " :");
  1825.  
  1826.         if (PubChannel(chptr))
  1827.             *buf = '=';
  1828.         else if (SecretChannel(chptr))
  1829.             *buf = '@';
  1830.         idx = len + 4;
  1831.         flag = 1;
  1832.         for (lp = chptr->members; lp; lp = lp->next)
  1833.             {
  1834.             c2ptr = lp->value.cptr;
  1835.             if (IsInvisible(c2ptr) && !IsMember(sptr,chptr))
  1836.                 continue;
  1837.                 if (lp->flags & CHFL_CHANOP)
  1838.                 (void)strcat(buf, "@");
  1839.             else if (lp->flags & CHFL_VOICE)
  1840.                 (void)strcat(buf, "+");
  1841.             (void)strncat(buf, c2ptr->name, NICKLEN);
  1842.             idx += strlen(c2ptr->name) + 1;
  1843.             flag = 1;
  1844.             (void)strcat(buf," ");
  1845.             if (mlen + idx + NICKLEN > BUFSIZE - 2)
  1846.                 {
  1847.                 sendto_one(sptr, rpl_str(RPL_NAMREPLY),
  1848.                        me.name, parv[0], buf);
  1849.                 (void)strncpy(buf, "* ", 3);
  1850.                 (void)strncpy(buf+2, chptr->chname, len + 1);
  1851.                 (void)strcat(buf, " :");
  1852.                 if (PubChannel(chptr))
  1853.                     *buf = '=';
  1854.                 else if (SecretChannel(chptr))
  1855.                     *buf = '@';
  1856.                 idx = len + 4;
  1857.                 flag = 0;
  1858.                 }
  1859.             }
  1860.         if (flag)
  1861.             sendto_one(sptr, rpl_str(RPL_NAMREPLY),
  1862.                    me.name, parv[0], buf);
  1863.         }
  1864.     if (!BadPtr(para))
  1865.         {
  1866.         sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0],
  1867.                para);
  1868.         return(1);
  1869.         }
  1870.  
  1871.     /* Second, do all non-public, non-secret channels in one big sweep */
  1872.  
  1873.     (void)strncpy(buf, "* * :", 6);
  1874.     idx = 5;
  1875.     flag = 0;
  1876.     for (c2ptr = client; c2ptr; c2ptr = c2ptr->next)
  1877.         {
  1878.               aChannel *ch3ptr;
  1879.         int    showflag = 0, secret = 0;
  1880.  
  1881.         if (!IsPerson(c2ptr) || IsInvisible(c2ptr))
  1882.             continue;
  1883.         lp = c2ptr->user->channel;
  1884.         /*
  1885.          * dont show a client if they are on a secret channel or
  1886.          * they are on a channel sptr is on since they have already
  1887.          * been show earlier. -avalon
  1888.          */
  1889.         while (lp)
  1890.             {
  1891.             ch3ptr = lp->value.chptr;
  1892.             if (PubChannel(ch3ptr) || IsMember(sptr, ch3ptr))
  1893.                 showflag = 1;
  1894.             if (SecretChannel(ch3ptr))
  1895.                 secret = 1;
  1896.             lp = lp->next;
  1897.             }
  1898.         if (showflag) /* have we already shown them ? */
  1899.             continue;
  1900.         if (secret) /* on any secret channels ? */
  1901.             continue;
  1902.         (void)strncat(buf, c2ptr->name, NICKLEN);
  1903.         idx += strlen(c2ptr->name) + 1;
  1904.         (void)strcat(buf," ");
  1905.         flag = 1;
  1906.         if (mlen + idx + NICKLEN > BUFSIZE - 2)
  1907.             {
  1908.             sendto_one(sptr, rpl_str(RPL_NAMREPLY),
  1909.                    me.name, parv[0], buf);
  1910.             (void)strncpy(buf, "* * :", 6);
  1911.             idx = 5;
  1912.             flag = 0;
  1913.             }
  1914.         }
  1915.     if (flag)
  1916.         sendto_one(sptr, rpl_str(RPL_NAMREPLY), me.name, parv[0], buf);
  1917.     sendto_one(sptr, rpl_str(RPL_ENDOFNAMES), me.name, parv[0], "*");
  1918.     return(1);
  1919.     }
  1920.  
  1921.  
  1922. void    send_user_joins(cptr, user)
  1923. aClient    *cptr, *user;
  1924. {
  1925.     Reg1    Link    *lp;
  1926.     Reg2    aChannel *chptr;
  1927.     Reg3    int    cnt = 0, len = 0, clen;
  1928.     char     *mask;
  1929.  
  1930.     *buf = ':';
  1931.     (void)strcpy(buf+1, user->name);
  1932.     (void)strcat(buf, " JOIN ");
  1933.     len = strlen(user->name) + 7;
  1934.  
  1935.     for (lp = user->user->channel; lp; lp = lp->next)
  1936.         {
  1937.         chptr = lp->value.chptr;
  1938.         if ((mask = index(chptr->chname, ':')))
  1939.             if (matches(++mask, cptr->name))
  1940.                 continue;
  1941.         if (*chptr->chname == '&')
  1942.             continue;
  1943.         clen = strlen(chptr->chname);
  1944.         if (clen > (size_t) BUFSIZE - 4 - len)
  1945.             {
  1946.             if (cnt)
  1947.                 sendto_one(cptr, "%s", buf);
  1948.             *buf = ':';
  1949.             (void)strcpy(buf+1, user->name);
  1950.             (void)strcat(buf, " JOIN ");
  1951.             len = strlen(user->name) + 7;
  1952.             cnt = 0;
  1953.             }
  1954.         (void)strcpy(buf + len, chptr->chname);
  1955.         cnt++;
  1956.         len += clen;
  1957.         if (lp->next)
  1958.             {
  1959.             len++;
  1960.             (void)strcat(buf, ",");
  1961.             }
  1962.         }
  1963.     if (*buf && cnt)
  1964.         sendto_one(cptr, "%s", buf);
  1965.  
  1966.     return;
  1967. }
  1968.