ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/channel.c
(Generate patch)

Comparing ircd-hybrid/trunk/src/channel.c (file contents):
Revision 1954 by michael, Mon May 6 18:51:19 2013 UTC vs.
Revision 3183 by michael, Thu Mar 20 16:49:21 2014 UTC

# Line 1 | Line 1
1   /*
2 < *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
2 > *  ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3   *
4 < *  Copyright (C) 2002 by the past and present ircd coders, and others.
4 > *  Copyright (c) 1997-2014 ircd-hybrid development team
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
# Line 35 | Line 35
35   #include "irc_string.h"
36   #include "ircd.h"
37   #include "numeric.h"
38 < #include "s_serv.h"             /* captab */
39 < #include "s_user.h"
38 > #include "s_serv.h"
39   #include "send.h"
40   #include "event.h"
41   #include "memory.h"
# Line 44 | Line 43
43   #include "s_misc.h"
44   #include "resv.h"
45  
47 struct config_channel_entry ConfigChannel;
46   dlink_list global_channel_list = { NULL, NULL, 0 };
47   mp_pool_t *ban_pool;    /*! \todo ban_pool shouldn't be a global var */
48  
# Line 52 | Line 50 | static mp_pool_t *member_pool = NULL;
50   static mp_pool_t *channel_pool = NULL;
51  
52   static char buf[IRCD_BUFSIZE];
55 static char modebuf[MODEBUFLEN];
56 static char parabuf[MODEBUFLEN];
53  
54  
55   /*! \brief Initializes the channel blockheap, adds known channel CAPAB
# Line 63 | Line 59 | channel_init(void)
59   {
60    add_capability("EX", CAP_EX, 1);
61    add_capability("IE", CAP_IE, 1);
66  add_capability("CHW", CAP_CHW, 1);
62  
63    channel_pool = mp_pool_new(sizeof(struct Channel), MP_CHUNK_SIZE_CHANNEL);
64    ban_pool = mp_pool_new(sizeof(struct Ban), MP_CHUNK_SIZE_BAN);
# Line 152 | Line 147 | remove_user_from_channel(struct Membersh
147   */
148   static void
149   send_members(struct Client *client_p, struct Channel *chptr,
150 <             char *lmodebuf, char *lparabuf)
150 >             char *modebuf, char *parabuf)
151   {
152    const dlink_node *ptr = NULL;
153    int tlen;              /* length of text to append */
154    char *t, *start;       /* temp char pointer */
155  
156    start = t = buf + snprintf(buf, sizeof(buf), ":%s SJOIN %lu %s %s %s:",
157 <                             ID_or_name(&me, client_p),
158 <                             (unsigned long)chptr->channelts,
164 <                             chptr->chname, lmodebuf, lparabuf);
157 >                             me.id, (unsigned long)chptr->channelts,
158 >                             chptr->chname, modebuf, parabuf);
159  
160    DLINK_FOREACH(ptr, chptr->members.head)
161    {
162      const struct Membership *ms = ptr->data;
163  
164 <    tlen = strlen(IsCapable(client_p, CAP_TS6) ?
171 <      ID(ms->client_p) : ms->client_p->name) + 1;  /* nick + space */
164 >    tlen = strlen(ID(ms->client_p)) + 1;  /* nick + space */
165  
166      if (ms->flags & CHFL_CHANOP)
167        tlen++;
168   #ifdef HALFOPS
169 <    else if (ms->flags & CHFL_HALFOP)
169 >    if (ms->flags & CHFL_HALFOP)
170        tlen++;
171   #endif
172      if (ms->flags & CHFL_VOICE)
# Line 189 | Line 182 | send_members(struct Client *client_p, st
182        t = start;
183      }
184  
185 <    if ((ms->flags & (CHFL_CHANOP | CHFL_HALFOP)))
186 <      *t++ = (!(ms->flags & CHFL_CHANOP) && IsCapable(client_p, CAP_HOPS)) ?
187 <        '%' : '@';
188 <    if ((ms->flags & CHFL_VOICE))
185 >    if (ms->flags & CHFL_CHANOP)
186 >      *t++ = '@';
187 >    if (ms->flags & CHFL_HALFOP)
188 >      *t++ = '%';
189 >    if (ms->flags & CHFL_VOICE)
190        *t++ = '+';
191  
192 <    if (IsCapable(client_p, CAP_TS6))
193 <      strcpy(t, ID(ms->client_p));
200 <    else
201 <      strcpy(t, ms->client_p->name);
192 >    strcpy(t, ID(ms->client_p));
193 >
194      t += strlen(t);
195      *t++ = ' ';
196    }
# Line 220 | Line 212 | static void
212   send_mode_list(struct Client *client_p, struct Channel *chptr,
213                 const dlink_list *top, char flag)
214   {
223  int ts5 = !IsCapable(client_p, CAP_TS6);
215    const dlink_node *lp = NULL;
216    char pbuf[IRCD_BUFSIZE];
217    int tlen, mlen, cur_len, count = 0;
218 <  char *mp = NULL, *pp = pbuf;
218 >  char *pp = pbuf;
219  
220    if (top == NULL || top->length == 0)
221      return;
222  
223 <  if (ts5)
224 <    mlen = snprintf(buf, sizeof(buf), ":%s MODE %s +", me.name, chptr->chname);
225 <  else
235 <    mlen = snprintf(buf, sizeof(buf), ":%s BMASK %lu %s %c :", me.id,
236 <                   (unsigned long)chptr->channelts, chptr->chname, flag);
237 <
238 <  /* MODE needs additional one byte for space between buf and pbuf */
239 <  cur_len = mlen + ts5;
240 <  mp = buf + mlen;
223 >  mlen = snprintf(buf, sizeof(buf), ":%s BMASK %lu %s %c :", me.id,
224 >                  (unsigned long)chptr->channelts, chptr->chname, flag);
225 >  cur_len = mlen;
226  
227    DLINK_FOREACH(lp, top->head)
228    {
229      const struct Ban *banptr = lp->data;
230  
231 <    /* must add another b/e/I letter if we use MODE */
247 <    tlen = banptr->len + 3 + ts5;
231 >    tlen = banptr->len + 3;
232  
233      /*
234       * send buffer and start over if we cannot fit another ban,
235       * or if the target is non-ts6 and we have too many modes in
236       * in this line.
237       */
238 <    if (cur_len + (tlen - 1) > IRCD_BUFSIZE - 2 ||
255 <        (!IsCapable(client_p, CAP_TS6) &&
256 <         (count >= MAXMODEPARAMS || pp - pbuf >= MODEBUFLEN)))
238 >    if (cur_len + (tlen - 1) > IRCD_BUFSIZE - 2)
239      {
240        *(pp - 1) = '\0';  /* get rid of trailing space on buffer */
241 <      sendto_one(client_p, "%s%s%s", buf, ts5 ? " " : "", pbuf);
241 >      sendto_one(client_p, "%s%s", buf, pbuf);
242  
243 <      cur_len = mlen + ts5;
262 <      mp = buf + mlen;
243 >      cur_len = mlen;
244        pp = pbuf;
245        count = 0;
246      }
247  
248      count++;
249 <    if (ts5)
269 <    {
270 <      *mp++ = flag;
271 <      *mp = '\0';
272 <    }
273 <
274 <    pp += sprintf(pp, "%s!%s@%s ", banptr->name, banptr->username,
249 >    pp += sprintf(pp, "%s!%s@%s ", banptr->name, banptr->user,
250                    banptr->host);
251      cur_len += tlen;
252    }
253  
254    *(pp - 1) = '\0';  /* get rid of trailing space on buffer */
255 <  sendto_one(client_p, "%s%s%s", buf, ts5 ? " " : "", pbuf);
255 >  sendto_one(client_p, "%s%s", buf, pbuf);
256   }
257  
258   /*! \brief send "client_p" a full list of the modes for channel chptr
# Line 287 | Line 262 | send_mode_list(struct Client *client_p,
262   void
263   send_channel_modes(struct Client *client_p, struct Channel *chptr)
264   {
265 <  *modebuf = *parabuf = '\0';
265 >  char modebuf[MODEBUFLEN] = "";
266 >  char parabuf[MODEBUFLEN] = "";
267 >
268    channel_modes(chptr, client_p, modebuf, parabuf);
269    send_members(client_p, chptr, modebuf, parabuf);
270  
# Line 333 | Line 310 | remove_ban(struct Ban *bptr, dlink_list
310    dlinkDelete(&bptr->node, list);
311  
312    MyFree(bptr->name);
313 <  MyFree(bptr->username);
313 >  MyFree(bptr->user);
314    MyFree(bptr->host);
315    MyFree(bptr->who);
316  
# Line 437 | Line 414 | channel_member_names(struct Client *sour
414    int tlen = 0;
415    int is_member = IsMember(source_p, chptr);
416    int multi_prefix = HasCap(source_p, CAP_MULTI_PREFIX) != 0;
417 +  int uhnames = HasCap(source_p, CAP_UHNAMES) != 0;
418  
419    if (PubChannel(chptr) || is_member)
420    {
421 <    t = lbuf + snprintf(lbuf, sizeof(lbuf), form_str(RPL_NAMREPLY),
421 >    t = lbuf + snprintf(lbuf, sizeof(lbuf), numeric_form(RPL_NAMREPLY),
422                          me.name, source_p->name,
423                          channel_pub_or_secret(chptr), chptr->chname);
424      start = t;
# Line 452 | Line 430 | channel_member_names(struct Client *sour
430        if (HasUMode(ms->client_p, UMODE_INVISIBLE) && !is_member)
431          continue;
432  
433 <      tlen = strlen(ms->client_p->name) + 1;  /* nick + space */
433 >      if (!uhnames)
434 >        tlen = strlen(ms->client_p->name) + 1;  /* nick + space */
435 >      else
436 >        tlen = strlen(ms->client_p->name) + strlen(ms->client_p->username) +
437 >               strlen(ms->client_p->host) + 3;
438  
439        if (!multi_prefix)
440        {
# Line 476 | Line 458 | channel_member_names(struct Client *sour
458          t = start;
459        }
460  
461 <      t += sprintf(t, "%s%s ", get_member_status(ms, multi_prefix),
462 <                   ms->client_p->name);
461 >      if (!uhnames)
462 >        t += sprintf(t, "%s%s ", get_member_status(ms, multi_prefix),
463 >                     ms->client_p->name);
464 >      else
465 >        t += sprintf(t, "%s%s!%s@%s ", get_member_status(ms, multi_prefix),
466 >                     ms->client_p->name, ms->client_p->username,
467 >                     ms->client_p->host);
468      }
469  
470      if (tlen != 0)
# Line 488 | Line 475 | channel_member_names(struct Client *sour
475    }
476  
477    if (show_eon)
478 <    sendto_one(source_p, form_str(RPL_ENDOFNAMES),
492 <               me.name, source_p->name, chptr->chname);
478 >    sendto_one_numeric(source_p, &me, RPL_ENDOFNAMES, chptr->chname);
479   }
480  
481   /*! \brief adds client to invite list
# Line 544 | Line 530 | del_invite(struct Channel *chptr, struct
530   * (like in get_client_name)
531   */
532   const char *
533 < get_member_status(const struct Membership *ms, int combine)
533 > get_member_status(const struct Membership *ms, const int combine)
534   {
535    static char buffer[4];
536    char *p = buffer;
# Line 587 | Line 573 | find_bmask(const struct Client *who, con
573    {
574      const struct Ban *bp = ptr->data;
575  
576 <    if (!match(bp->name, who->name) && !match(bp->username, who->username))
576 >    if (!match(bp->name, who->name) && !match(bp->user, who->username))
577      {
578        switch (bp->type)
579        {
# Line 633 | Line 619 | is_banned(const struct Channel *chptr, c
619  
620   /*!
621   * \param source_p pointer to client attempting to join
622 < * \param chptr    pointer to channel
622 > * \param chptr    pointer to channel
623   * \param key      key sent by client attempting to join if present
624   * \return ERR_BANNEDFROMCHAN, ERR_INVITEONLYCHAN, ERR_CHANNELISFULL
625   *         or 0 if allowed to join.
# Line 641 | Line 627 | is_banned(const struct Channel *chptr, c
627   int
628   can_join(struct Client *source_p, struct Channel *chptr, const char *key)
629   {
630 <  if (is_banned(chptr, source_p))
645 <    return ERR_BANNEDFROMCHAN;
646 <
647 < #ifdef HAVE_LIBCRYPTO
648 <  if ((chptr->mode.mode & MODE_SSLONLY) && !source_p->localClient->fd.ssl)
630 >  if ((chptr->mode.mode & MODE_SSLONLY) && !HasUMode(source_p, UMODE_SSL))
631      return ERR_SSLONLYCHAN;
650 #endif
632  
633    if ((chptr->mode.mode & MODE_REGONLY) && !HasUMode(source_p, UMODE_REGISTERED))
634      return ERR_NEEDREGGEDNICK;
# Line 667 | Line 648 | can_join(struct Client *source_p, struct
648        chptr->mode.limit)
649      return ERR_CHANNELISFULL;
650  
651 +  if (is_banned(chptr, source_p))
652 +    return ERR_BANNEDFROMCHAN;
653 +
654    return 0;
655   }
656  
# Line 686 | Line 670 | find_channel_link(struct Client *client_
670    if (!IsClient(client_p))
671      return NULL;
672  
673 <  DLINK_FOREACH(ptr, client_p->channel.head)
674 <    if (((struct Membership *)ptr->data)->chptr == chptr)
675 <      return ptr->data;
673 >  if (dlink_list_length(&chptr->members) < dlink_list_length(&client_p->channel))
674 >  {
675 >    DLINK_FOREACH(ptr, chptr->members.head)
676 >      if (((struct Membership *)ptr->data)->client_p == client_p)
677 >        return ptr->data;
678 >  }
679 >  else
680 >  {
681 >    DLINK_FOREACH(ptr, client_p->channel.head)
682 >      if (((struct Membership *)ptr->data)->chptr == chptr)
683 >        return ptr->data;
684 >  }
685  
686    return NULL;
687   }
# Line 749 | Line 742 | can_send(struct Channel *chptr, struct C
742    if (ms || (ms = find_channel_link(source_p, chptr)))
743      if (ms->flags & (CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE))
744        return CAN_SEND_OPV;
745 +  if (!ms && (chptr->mode.mode & MODE_NOPRIVMSGS))
746 +    return ERR_CANNOTSENDTOCHAN;
747    if (chptr->mode.mode & MODE_MODERATED)
748      return ERR_CANNOTSENDTOCHAN;
749    if ((chptr->mode.mode & MODE_MODREG) && !HasUMode(source_p, UMODE_REGISTERED))
# Line 892 | Line 887 | set_channel_topic(struct Channel *chptr,
887      strlcpy(chptr->topic, topic, sizeof(chptr->topic));
888  
889    strlcpy(chptr->topic_info, topic_info, sizeof(chptr->topic_info));
890 <  chptr->topic_time = topicts;
890 >  chptr->topic_time = topicts;
891   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)