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-8/src/channel.c (file contents), Revision 1219 by michael, Sun Sep 18 09:02:38 2011 UTC vs.
ircd-hybrid/trunk/src/channel.c (file contents), Revision 1858 by michael, Thu Apr 25 15:00:52 2013 UTC

# Line 29 | Line 29
29   #include "channel.h"
30   #include "channel_mode.h"
31   #include "client.h"
32 #include "common.h"
32   #include "hash.h"
33 + #include "conf.h"
34   #include "hostmask.h"
35   #include "irc_string.h"
36 #include "sprintf_irc.h"
36   #include "ircd.h"
37   #include "numeric.h"
38   #include "s_serv.h"             /* captab */
39   #include "s_user.h"
40   #include "send.h"
42 #include "s_conf.h"             /* ConfigFileEntry, ConfigChannel */
41   #include "event.h"
42   #include "memory.h"
43 < #include "balloc.h"
43 > #include "mempool.h"
44 > #include "s_misc.h"
45 > #include "resv.h"
46  
47   struct config_channel_entry ConfigChannel;
48   dlink_list global_channel_list = { NULL, NULL, 0 };
49 < BlockHeap *ban_heap;    /*! \todo ban_heap shouldn't be a global var */
49 > mp_pool_t *ban_pool;    /*! \todo ban_pool shouldn't be a global var */
50  
51 < static BlockHeap *member_heap = NULL;
52 < static BlockHeap *channel_heap = NULL;
51 > static mp_pool_t *member_pool = NULL;
52 > static mp_pool_t *channel_pool = NULL;
53  
54   static char buf[IRCD_BUFSIZE];
55   static char modebuf[MODEBUFLEN];
# Line 59 | Line 59 | static char parabuf[MODEBUFLEN];
59   /*! \brief Initializes the channel blockheap, adds known channel CAPAB
60   */
61   void
62 < init_channels(void)
62 > channel_init(void)
63   {
64    add_capability("EX", CAP_EX, 1);
65    add_capability("IE", CAP_IE, 1);
66    add_capability("CHW", CAP_CHW, 1);
67  
68 <  channel_heap = BlockHeapCreate("channel", sizeof(struct Channel), CHANNEL_HEAP_SIZE);
69 <  ban_heap = BlockHeapCreate("ban", sizeof(struct Ban), BAN_HEAP_SIZE);
70 <  member_heap = BlockHeapCreate("member", sizeof(struct Membership), CHANNEL_HEAP_SIZE*2);
68 >  channel_pool = mp_pool_new(sizeof(struct Channel), MP_CHUNK_SIZE_CHANNEL);
69 >  ban_pool = mp_pool_new(sizeof(struct Ban), MP_CHUNK_SIZE_BAN);
70 >  member_pool = mp_pool_new(sizeof(struct Membership), MP_CHUNK_SIZE_MEMBER);
71   }
72  
73   /*! \brief adds a user to a channel by adding another link to the
# Line 104 | Line 104 | add_user_to_channel(struct Channel *chpt
104        if (!IsSetJoinFloodNoticed(chptr))
105        {
106          SetJoinFloodNoticed(chptr);
107 <        sendto_realops_flags(UMODE_BOTS, L_ALL,
107 >        sendto_realops_flags(UMODE_BOTS, L_ALL, SEND_NOTICE,
108                               "Possible Join Flooder %s on %s target: %s",
109                               get_client_name(who, HIDE_IP),
110                               who->servptr->name, chptr->chname);
# Line 114 | Line 114 | add_user_to_channel(struct Channel *chpt
114      chptr->last_join_time = CurrentTime;
115    }
116  
117 <  ms = BlockHeapAlloc(member_heap);
117 >  ms = mp_pool_get(member_pool);
118 >  memset(ms, 0, sizeof(*ms));
119 >
120    ms->client_p = who;
121    ms->chptr = chptr;
122    ms->flags = flags;
# Line 136 | Line 138 | remove_user_from_channel(struct Membersh
138    dlinkDelete(&member->channode, &chptr->members);
139    dlinkDelete(&member->usernode, &client_p->channel);
140  
141 <  BlockHeapFree(member_heap, member);
141 >  mp_pool_release(member);
142  
143    if (chptr->members.head == NULL)
144      destroy_channel(chptr);
# Line 152 | Line 154 | static void
154   send_members(struct Client *client_p, struct Channel *chptr,
155               char *lmodebuf, char *lparabuf)
156   {
157 <  struct Membership *ms;
156 <  dlink_node *ptr;
157 >  const dlink_node *ptr = NULL;
158    int tlen;              /* length of text to append */
159    char *t, *start;       /* temp char pointer */
160  
161 <  start = t = buf + ircsprintf(buf, ":%s SJOIN %lu %s %s %s:",
162 <                               ID_or_name(&me, client_p),
163 <                               (unsigned long)chptr->channelts,
164 <                               chptr->chname, lmodebuf, lparabuf);
161 >  start = t = buf + snprintf(buf, sizeof(buf), ":%s SJOIN %lu %s %s %s:",
162 >                             ID_or_name(&me, client_p),
163 >                             (unsigned long)chptr->channelts,
164 >                             chptr->chname, lmodebuf, lparabuf);
165  
166    DLINK_FOREACH(ptr, chptr->members.head)
167    {
168 <    ms = ptr->data;
168 >    const struct Membership *ms = ptr->data;
169  
170      tlen = strlen(IsCapable(client_p, CAP_TS6) ?
171        ID(ms->client_p) : ms->client_p->name) + 1;  /* nick + space */
# Line 181 | Line 182 | send_members(struct Client *client_p, st
182      /* space will be converted into CR, but we also need space for LF..
183       * That's why we use '- 1' here
184       * -adx */
185 <    if (t + tlen - buf > sizeof(buf) - 1)
185 >    if (t + tlen - buf > IRCD_BUFSIZE - 1)
186      {
187        *(t - 1) = '\0';  /* kill the space and terminate the string */
188        sendto_one(client_p, "%s", buf);
# Line 217 | Line 218 | send_members(struct Client *client_p, st
218   */
219   static void
220   send_mode_list(struct Client *client_p, struct Channel *chptr,
221 <               dlink_list *top, char flag)
221 >               const dlink_list *top, char flag)
222   {
223    int ts5 = !IsCapable(client_p, CAP_TS6);
224 <  dlink_node *lp;
224 <  struct Ban *banptr;
224 >  const dlink_node *lp = NULL;
225    char pbuf[IRCD_BUFSIZE];
226    int tlen, mlen, cur_len, count = 0;
227    char *mp = NULL, *pp = pbuf;
# Line 230 | Line 230 | send_mode_list(struct Client *client_p,
230      return;
231  
232    if (ts5)
233 <    mlen = ircsprintf(buf, ":%s MODE %s +", me.name, chptr->chname);
233 >    mlen = snprintf(buf, sizeof(buf), ":%s MODE %s +", me.name, chptr->chname);
234    else
235 <    mlen = ircsprintf(buf, ":%s BMASK %lu %s %c :", me.id,
236 <                      (unsigned long)chptr->channelts, chptr->chname, flag);
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;
# Line 241 | Line 241 | send_mode_list(struct Client *client_p,
241  
242    DLINK_FOREACH(lp, top->head)
243    {
244 <    banptr = lp->data;
244 >    const struct Ban *banptr = lp->data;
245  
246      /* must add another b/e/I letter if we use MODE */
247      tlen = banptr->len + 3 + ts5;
# Line 271 | Line 271 | send_mode_list(struct Client *client_p,
271        *mp = '\0';
272      }
273  
274 <    pp += ircsprintf(pp, "%s!%s@%s ", banptr->name, banptr->username,
275 <                     banptr->host);
274 >    pp += sprintf(pp, "%s!%s@%s ", banptr->name, banptr->username,
275 >                  banptr->host);
276      cur_len += tlen;
277    }
278  
# Line 287 | Line 287 | send_mode_list(struct Client *client_p,
287   void
288   send_channel_modes(struct Client *client_p, struct Channel *chptr)
289   {
290  if (chptr->chname[0] != '#')
291    return;
292
290    *modebuf = *parabuf = '\0';
291    channel_modes(chptr, client_p, modebuf, parabuf);
292    send_members(client_p, chptr, modebuf, parabuf);
293  
294    send_mode_list(client_p, chptr, &chptr->banlist, 'b');
295 <
296 <  if (IsCapable(client_p, CAP_EX))
300 <    send_mode_list(client_p, chptr, &chptr->exceptlist, 'e');
301 <  if (IsCapable(client_p, CAP_IE))
302 <    send_mode_list(client_p, chptr, &chptr->invexlist, 'I');
295 >  send_mode_list(client_p, chptr, &chptr->exceptlist, 'e');
296 >  send_mode_list(client_p, chptr, &chptr->invexlist, 'I');
297   }
298  
299   /*! \brief check channel name for invalid characters
# Line 308 | Line 302 | send_channel_modes(struct Client *client
302   * \return 0 if invalid, 1 otherwise
303   */
304   int
305 < check_channel_name(const char *name, int local)
305 > check_channel_name(const char *name, const int local)
306   {
307    const char *p = name;
308 <  int max_length = local ? LOCAL_CHANNELLEN : CHANNELLEN;
308 >  const int max_length = local ? LOCAL_CHANNELLEN : CHANNELLEN;
309    assert(name != NULL);
310  
311    if (!IsChanPrefix(*p))
# Line 343 | Line 337 | remove_ban(struct Ban *bptr, dlink_list
337    MyFree(bptr->host);
338    MyFree(bptr->who);
339  
340 <  BlockHeapFree(ban_heap, bptr);
340 >  mp_pool_release(bptr);
341   }
342  
343   /* free_channel_list()
# Line 375 | Line 369 | make_channel(const char *chname)
369  
370    assert(!EmptyString(chname));
371  
372 <  chptr = BlockHeapAlloc(channel_heap);
372 >  chptr = mp_pool_get(channel_pool);
373 >
374 >  memset(chptr, 0, sizeof(*chptr));
375  
376    /* doesn't hurt to set it here */
377    chptr->channelts = CurrentTime;
# Line 408 | Line 404 | destroy_channel(struct Channel *chptr)
404    dlinkDelete(&chptr->node, &global_channel_list);
405    hash_del_channel(chptr);
406  
407 <  BlockHeapFree(channel_heap, chptr);
407 >  mp_pool_release(chptr);
408   }
409  
410   /*!
# Line 435 | Line 431 | void
431   channel_member_names(struct Client *source_p, struct Channel *chptr,
432                       int show_eon)
433   {
434 <  struct Client *target_p = NULL;
439 <  struct Membership *ms = NULL;
440 <  dlink_node *ptr = NULL;
434 >  const dlink_node *ptr = NULL;
435    char lbuf[IRCD_BUFSIZE + 1];
436    char *t = NULL, *start = NULL;
437    int tlen = 0;
# Line 446 | Line 440 | channel_member_names(struct Client *sour
440  
441    if (PubChannel(chptr) || is_member)
442    {
443 <    t = lbuf + ircsprintf(lbuf, form_str(RPL_NAMREPLY),
444 <                          me.name, source_p->name,
445 <                          channel_pub_or_secret(chptr),
452 <                          chptr->chname);
443 >    t = lbuf + snprintf(lbuf, sizeof(lbuf), form_str(RPL_NAMREPLY),
444 >                        me.name, source_p->name,
445 >                        channel_pub_or_secret(chptr), chptr->chname);
446      start = t;
447  
448      DLINK_FOREACH(ptr, chptr->members.head)
449      {
450 <      ms       = ptr->data;
458 <      target_p = ms->client_p;
450 >      const struct Membership *ms = ptr->data;
451  
452 <      if (HasUMode(target_p, UMODE_INVISIBLE) && !is_member)
452 >      if (HasUMode(ms->client_p, UMODE_INVISIBLE) && !is_member)
453          continue;
454  
455 <      tlen = strlen(target_p->name) + 1;  /* nick + space */
455 >      tlen = strlen(ms->client_p->name) + 1;  /* nick + space */
456  
457        if (!multi_prefix)
458        {
# Line 484 | Line 476 | channel_member_names(struct Client *sour
476          t = start;
477        }
478  
479 <      t += ircsprintf(t, "%s%s ", get_member_status(ms, multi_prefix),
480 <                      target_p->name);
479 >      t += sprintf(t, "%s%s ", get_member_status(ms, multi_prefix),
480 >                   ms->client_p->name);
481      }
482  
483      if (tlen != 0)
# Line 597 | Line 589 | find_bmask(const struct Client *who, con
589  
590    DLINK_FOREACH(ptr, list->head)
591    {
592 <    struct Ban *bp = ptr->data;
592 >    const struct Ban *bp = ptr->data;
593  
594 <    if (match(bp->name, who->name) && match(bp->username, who->username))
594 >    if (!match(bp->name, who->name) && !match(bp->username, who->username))
595      {
596        switch (bp->type)
597        {
598          case HM_HOST:
599 <          if (match(bp->host, who->host) || match(bp->host, who->sockhost))
599 >          if (!match(bp->host, who->host) || !match(bp->host, who->sockhost))
600              return 1;
601            break;
602          case HM_IPV4:
# Line 637 | Line 629 | int
629   is_banned(const struct Channel *chptr, const struct Client *who)
630   {
631    if (find_bmask(who, &chptr->banlist))
632 <    if (!ConfigChannel.use_except || !find_bmask(who, &chptr->exceptlist))
632 >    if (!find_bmask(who, &chptr->exceptlist))
633        return 1;
634  
635    return 0;
# Line 669 | Line 661 | can_join(struct Client *source_p, struct
661  
662    if (chptr->mode.mode & MODE_INVITEONLY)
663      if (!dlinkFind(&source_p->localClient->invited, chptr))
664 <      if (!ConfigChannel.use_invex || !find_bmask(source_p, &chptr->invexlist))
664 >      if (!find_bmask(source_p, &chptr->invexlist))
665          return ERR_INVITEONLYCHAN;
666  
667 <  if (chptr->mode.key[0] && (!key || irccmp(chptr->mode.key, key)))
667 >  if (chptr->mode.key[0] && (!key || strcmp(chptr->mode.key, key)))
668      return ERR_BADCHANNELKEY;
669  
670    if (chptr->mode.limit && dlink_list_length(&chptr->members) >=
# Line 683 | Line 675 | can_join(struct Client *source_p, struct
675   }
676  
677   int
678 < has_member_flags(struct Membership *ms, unsigned int flags)
678 > has_member_flags(const struct Membership *ms, const unsigned int flags)
679   {
680    if (ms != NULL)
681      return ms->flags & flags;
# Line 716 | Line 708 | find_channel_link(struct Client *client_
708   int
709   can_send(struct Channel *chptr, struct Client *source_p, struct Membership *ms)
710   {
711 +  struct MaskItem *conf = NULL;
712 +
713    if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE))
714      return CAN_SEND_OPV;
715  
716    if (MyClient(source_p) && !IsExemptResv(source_p))
717      if (!(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv))
718 <      if (!hash_find_resv(chptr->chname) == ConfigChannel.restrict_channels)
718 >      if ((conf = match_find_resv(chptr->chname)) && !resv_find_exempt(source_p, conf))
719          return ERR_CANNOTSENDTOCHAN;
720  
721    if (ms != NULL || (ms = find_channel_link(source_p, chptr)))
# Line 781 | Line 775 | check_spambot_warning(struct Client *sou
775      {
776        /* Its already known as a possible spambot */
777        if (name != NULL)
778 <        sendto_realops_flags(UMODE_BOTS, L_ALL,
778 >        sendto_realops_flags(UMODE_BOTS, L_ALL, SEND_NOTICE,
779                               "User %s (%s@%s) trying to join %s is a possible spambot",
780                               source_p->name, source_p->username,
781                               source_p->host, name);
782        else
783 <        sendto_realops_flags(UMODE_BOTS, L_ALL,
783 >        sendto_realops_flags(UMODE_BOTS, L_ALL, SEND_NOTICE,
784                               "User %s (%s@%s) is a possible spambot",
785                               source_p->name, source_p->username,
786                               source_p->host);
# Line 837 | Line 831 | check_splitmode(void *unused)
831      {
832        splitmode = 1;
833  
834 <      sendto_realops_flags(UMODE_ALL,L_ALL,
834 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
835                             "Network split, activating splitmode");
836        eventAddIsh("check_splitmode", check_splitmode, NULL, 10);
837      }
# Line 845 | Line 839 | check_splitmode(void *unused)
839      {
840        splitmode = 0;
841  
842 <      sendto_realops_flags(UMODE_ALL, L_ALL,
842 >      sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
843                             "Network rejoined, deactivating splitmode");
844        eventDelete(check_splitmode, NULL);
845      }
# Line 860 | Line 854 | check_splitmode(void *unused)
854   */
855   void
856   set_channel_topic(struct Channel *chptr, const char *topic,
857 <                  const char *topic_info, time_t topicts)
857 >                  const char *topic_info, time_t topicts, int local)
858   {
859 <  strlcpy(chptr->topic, topic, sizeof(chptr->topic));
859 >  if (local)
860 >    strlcpy(chptr->topic, topic, IRCD_MIN(sizeof(chptr->topic), ServerInfo.max_topic_length + 1));
861 >  else
862 >    strlcpy(chptr->topic, topic, sizeof(chptr->topic));
863 >
864    strlcpy(chptr->topic_info, topic_info, sizeof(chptr->topic_info));
865    chptr->topic_time = topicts;
866   }

Diff Legend

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