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 1951 by michael, Sun May 5 18:03:29 2013 UTC vs.
Revision 3235 by michael, Sat Mar 29 19:34:16 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  
46 < struct config_channel_entry ConfigChannel;
47 < dlink_list global_channel_list = { NULL, NULL, 0 };
46 >
47 > dlink_list global_channel_list;
48   mp_pool_t *ban_pool;    /*! \todo ban_pool shouldn't be a global var */
49  
50   static mp_pool_t *member_pool = NULL;
51   static mp_pool_t *channel_pool = NULL;
52  
53   static char buf[IRCD_BUFSIZE];
55 static char modebuf[MODEBUFLEN];
56 static char parabuf[MODEBUFLEN];
54  
55  
56   /*! \brief Initializes the channel blockheap, adds known channel CAPAB
# Line 63 | Line 60 | channel_init(void)
60   {
61    add_capability("EX", CAP_EX, 1);
62    add_capability("IE", CAP_IE, 1);
66  add_capability("CHW", CAP_CHW, 1);
63  
64    channel_pool = mp_pool_new(sizeof(struct Channel), MP_CHUNK_SIZE_CHANNEL);
65    ban_pool = mp_pool_new(sizeof(struct Ban), MP_CHUNK_SIZE_BAN);
# Line 152 | Line 148 | remove_user_from_channel(struct Membersh
148   */
149   static void
150   send_members(struct Client *client_p, struct Channel *chptr,
151 <             char *lmodebuf, char *lparabuf)
151 >             char *modebuf, char *parabuf)
152   {
153    const dlink_node *ptr = NULL;
154    int tlen;              /* length of text to append */
155    char *t, *start;       /* temp char pointer */
156  
157    start = t = buf + snprintf(buf, sizeof(buf), ":%s SJOIN %lu %s %s %s:",
158 <                             ID_or_name(&me, client_p),
159 <                             (unsigned long)chptr->channelts,
164 <                             chptr->chname, lmodebuf, lparabuf);
158 >                             me.id, (unsigned long)chptr->channelts,
159 >                             chptr->chname, modebuf, parabuf);
160  
161    DLINK_FOREACH(ptr, chptr->members.head)
162    {
163      const struct Membership *ms = ptr->data;
164  
165 <    tlen = strlen(IsCapable(client_p, CAP_TS6) ?
171 <      ID(ms->client_p) : ms->client_p->name) + 1;  /* nick + space */
165 >    tlen = strlen(ms->client_p->id) + 1;  /* nick + space */
166  
167      if (ms->flags & CHFL_CHANOP)
168        tlen++;
169   #ifdef HALFOPS
170 <    else if (ms->flags & CHFL_HALFOP)
170 >    if (ms->flags & CHFL_HALFOP)
171        tlen++;
172   #endif
173      if (ms->flags & CHFL_VOICE)
# Line 189 | Line 183 | send_members(struct Client *client_p, st
183        t = start;
184      }
185  
186 <    if ((ms->flags & (CHFL_CHANOP | CHFL_HALFOP)))
187 <      *t++ = (!(ms->flags & CHFL_CHANOP) && IsCapable(client_p, CAP_HOPS)) ?
188 <        '%' : '@';
189 <    if ((ms->flags & CHFL_VOICE))
186 >    if (ms->flags & CHFL_CHANOP)
187 >      *t++ = '@';
188 >    if (ms->flags & CHFL_HALFOP)
189 >      *t++ = '%';
190 >    if (ms->flags & CHFL_VOICE)
191        *t++ = '+';
192  
193 <    if (IsCapable(client_p, CAP_TS6))
194 <      strcpy(t, ID(ms->client_p));
200 <    else
201 <      strcpy(t, ms->client_p->name);
193 >    strcpy(t, ms->client_p->id);
194 >
195      t += strlen(t);
196      *t++ = ' ';
197    }
198  
199    /* should always be non-NULL unless we have a kind of persistent channels */
200 <  if (chptr->members.head != NULL)
200 >  if (chptr->members.head)
201      t--;  /* take the space out */
202    *t = '\0';
203    sendto_one(client_p, "%s", buf);
# Line 220 | Line 213 | static void
213   send_mode_list(struct Client *client_p, struct Channel *chptr,
214                 const dlink_list *top, char flag)
215   {
223  int ts5 = !IsCapable(client_p, CAP_TS6);
216    const dlink_node *lp = NULL;
217 <  char pbuf[IRCD_BUFSIZE];
217 >  char pbuf[IRCD_BUFSIZE] = "";
218    int tlen, mlen, cur_len, count = 0;
219 <  char *mp = NULL, *pp = pbuf;
219 >  char *pp = pbuf;
220  
221 <  if (top == NULL || top->length == 0)
221 >  if (top->length == 0)
222      return;
223  
224 <  if (ts5)
225 <    mlen = snprintf(buf, sizeof(buf), ":%s MODE %s +", me.name, chptr->chname);
226 <  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;
224 >  mlen = snprintf(buf, sizeof(buf), ":%s BMASK %lu %s %c :", me.id,
225 >                  (unsigned long)chptr->channelts, chptr->chname, flag);
226 >  cur_len = mlen;
227  
228    DLINK_FOREACH(lp, top->head)
229    {
230      const struct Ban *banptr = lp->data;
231  
232 <    /* must add another b/e/I letter if we use MODE */
247 <    tlen = banptr->len + 3 + ts5;
232 >    tlen = banptr->len + 3;
233  
234      /*
235       * send buffer and start over if we cannot fit another ban,
236       * or if the target is non-ts6 and we have too many modes in
237       * in this line.
238       */
239 <    if (cur_len + (tlen - 1) > IRCD_BUFSIZE - 2 ||
255 <        (!IsCapable(client_p, CAP_TS6) &&
256 <         (count >= MAXMODEPARAMS || pp - pbuf >= MODEBUFLEN)))
239 >    if (cur_len + (tlen - 1) > IRCD_BUFSIZE - 2)
240      {
241        *(pp - 1) = '\0';  /* get rid of trailing space on buffer */
242 <      sendto_one(client_p, "%s%s%s", buf, ts5 ? " " : "", pbuf);
242 >      sendto_one(client_p, "%s%s", buf, pbuf);
243  
244 <      cur_len = mlen + ts5;
262 <      mp = buf + mlen;
244 >      cur_len = mlen;
245        pp = pbuf;
246        count = 0;
247      }
248  
249      count++;
250 <    if (ts5)
269 <    {
270 <      *mp++ = flag;
271 <      *mp = '\0';
272 <    }
273 <
274 <    pp += sprintf(pp, "%s!%s@%s ", banptr->name, banptr->username,
250 >    pp += sprintf(pp, "%s!%s@%s ", banptr->name, banptr->user,
251                    banptr->host);
252      cur_len += tlen;
253    }
254  
255    *(pp - 1) = '\0';  /* get rid of trailing space on buffer */
256 <  sendto_one(client_p, "%s%s%s", buf, ts5 ? " " : "", pbuf);
256 >  sendto_one(client_p, "%s%s", buf, pbuf);
257   }
258  
259   /*! \brief send "client_p" a full list of the modes for channel chptr
# Line 287 | Line 263 | send_mode_list(struct Client *client_p,
263   void
264   send_channel_modes(struct Client *client_p, struct Channel *chptr)
265   {
266 <  *modebuf = *parabuf = '\0';
266 >  char modebuf[MODEBUFLEN] = "";
267 >  char parabuf[MODEBUFLEN] = "";
268 >
269    channel_modes(chptr, client_p, modebuf, parabuf);
270    send_members(client_p, chptr, modebuf, parabuf);
271  
# Line 333 | Line 311 | remove_ban(struct Ban *bptr, dlink_list
311    dlinkDelete(&bptr->node, list);
312  
313    MyFree(bptr->name);
314 <  MyFree(bptr->username);
314 >  MyFree(bptr->user);
315    MyFree(bptr->host);
316    MyFree(bptr->who);
317  
# Line 432 | Line 410 | channel_member_names(struct Client *sour
410                       int show_eon)
411   {
412    const dlink_node *ptr = NULL;
413 <  char lbuf[IRCD_BUFSIZE + 1];
413 >  char lbuf[IRCD_BUFSIZE + 1] = "";
414    char *t = NULL, *start = NULL;
415    int tlen = 0;
416    int is_member = IsMember(source_p, chptr);
417    int multi_prefix = HasCap(source_p, CAP_MULTI_PREFIX) != 0;
418 +  int uhnames = HasCap(source_p, CAP_UHNAMES) != 0;
419  
420    if (PubChannel(chptr) || is_member)
421    {
422 <    t = lbuf + snprintf(lbuf, sizeof(lbuf), form_str(RPL_NAMREPLY),
422 >    t = lbuf + snprintf(lbuf, sizeof(lbuf), numeric_form(RPL_NAMREPLY),
423                          me.name, source_p->name,
424                          channel_pub_or_secret(chptr), chptr->chname);
425      start = t;
# Line 452 | Line 431 | channel_member_names(struct Client *sour
431        if (HasUMode(ms->client_p, UMODE_INVISIBLE) && !is_member)
432          continue;
433  
434 <      tlen = strlen(ms->client_p->name) + 1;  /* nick + space */
434 >      if (!uhnames)
435 >        tlen = strlen(ms->client_p->name) + 1;  /* nick + space */
436 >      else
437 >        tlen = strlen(ms->client_p->name) + strlen(ms->client_p->username) +
438 >               strlen(ms->client_p->host) + 3;
439  
440        if (!multi_prefix)
441        {
# Line 476 | Line 459 | channel_member_names(struct Client *sour
459          t = start;
460        }
461  
462 <      t += sprintf(t, "%s%s ", get_member_status(ms, multi_prefix),
463 <                   ms->client_p->name);
462 >      if (!uhnames)
463 >        t += sprintf(t, "%s%s ", get_member_status(ms, multi_prefix),
464 >                     ms->client_p->name);
465 >      else
466 >        t += sprintf(t, "%s%s!%s@%s ", get_member_status(ms, multi_prefix),
467 >                     ms->client_p->name, ms->client_p->username,
468 >                     ms->client_p->host);
469      }
470  
471 <    if (tlen != 0)
471 >    if (tlen)
472      {
473        *(t - 1) = '\0';
474        sendto_one(source_p, "%s", lbuf);
# Line 488 | Line 476 | channel_member_names(struct Client *sour
476    }
477  
478    if (show_eon)
479 <    sendto_one(source_p, form_str(RPL_ENDOFNAMES),
492 <               me.name, source_p->name, chptr->chname);
479 >    sendto_one_numeric(source_p, &me, RPL_ENDOFNAMES, chptr->chname);
480   }
481  
482   /*! \brief adds client to invite list
# Line 544 | Line 531 | del_invite(struct Channel *chptr, struct
531   * (like in get_client_name)
532   */
533   const char *
534 < get_member_status(const struct Membership *ms, int combine)
534 > get_member_status(const struct Membership *ms, const int combine)
535   {
536    static char buffer[4];
537    char *p = buffer;
# Line 587 | Line 574 | find_bmask(const struct Client *who, con
574    {
575      const struct Ban *bp = ptr->data;
576  
577 <    if (!match(bp->name, who->name) && !match(bp->username, who->username))
577 >    if (!match(bp->name, who->name) && !match(bp->user, who->username))
578      {
579        switch (bp->type)
580        {
# Line 633 | Line 620 | is_banned(const struct Channel *chptr, c
620  
621   /*!
622   * \param source_p pointer to client attempting to join
623 < * \param chptr    pointer to channel
623 > * \param chptr    pointer to channel
624   * \param key      key sent by client attempting to join if present
625   * \return ERR_BANNEDFROMCHAN, ERR_INVITEONLYCHAN, ERR_CHANNELISFULL
626   *         or 0 if allowed to join.
# Line 641 | Line 628 | is_banned(const struct Channel *chptr, c
628   int
629   can_join(struct Client *source_p, struct Channel *chptr, const char *key)
630   {
631 <  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)
631 >  if ((chptr->mode.mode & MODE_SSLONLY) && !HasUMode(source_p, UMODE_SSL))
632      return ERR_SSLONLYCHAN;
650 #endif
633  
634    if ((chptr->mode.mode & MODE_REGONLY) && !HasUMode(source_p, UMODE_REGISTERED))
635      return ERR_NEEDREGGEDNICK;
# Line 667 | Line 649 | can_join(struct Client *source_p, struct
649        chptr->mode.limit)
650      return ERR_CHANNELISFULL;
651  
652 +  if (is_banned(chptr, source_p))
653 +    return ERR_BANNEDFROMCHAN;
654 +
655    return 0;
656   }
657  
658   int
659   has_member_flags(const struct Membership *ms, const unsigned int flags)
660   {
661 <  if (ms != NULL)
677 <    return ms->flags & flags;
678 <  return 0;
661 >  return ms && (ms->flags & flags);
662   }
663  
664   struct Membership *
# Line 686 | Line 669 | find_channel_link(struct Client *client_
669    if (!IsClient(client_p))
670      return NULL;
671  
672 <  DLINK_FOREACH(ptr, client_p->channel.head)
673 <    if (((struct Membership *)ptr->data)->chptr == chptr)
674 <      return ptr->data;
672 >  if (dlink_list_length(&chptr->members) < dlink_list_length(&client_p->channel))
673 >  {
674 >    DLINK_FOREACH(ptr, chptr->members.head)
675 >      if (((struct Membership *)ptr->data)->client_p == client_p)
676 >        return ptr->data;
677 >  }
678 >  else
679 >  {
680 >    DLINK_FOREACH(ptr, client_p->channel.head)
681 >      if (((struct Membership *)ptr->data)->chptr == chptr)
682 >        return ptr->data;
683 >  }
684  
685    return NULL;
686   }
# Line 749 | Line 741 | can_send(struct Channel *chptr, struct C
741    if (ms || (ms = find_channel_link(source_p, chptr)))
742      if (ms->flags & (CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE))
743        return CAN_SEND_OPV;
744 +  if (!ms && (chptr->mode.mode & MODE_NOPRIVMSGS))
745 +    return ERR_CANNOTSENDTOCHAN;
746    if (chptr->mode.mode & MODE_MODERATED)
747      return ERR_CANNOTSENDTOCHAN;
748 <  if ((chptr->mode.mode & MODE_REGONLY) && !HasUMode(source_p, UMODE_REGISTERED))
748 >  if ((chptr->mode.mode & MODE_MODREG) && !HasUMode(source_p, UMODE_REGISTERED))
749      return ERR_NEEDREGGEDNICK;
750  
751    /* cache can send if banned */
# Line 804 | Line 798 | check_spambot_warning(struct Client *sou
798      if (source_p->localClient->oper_warn_count_down == 0)
799      {
800        /* Its already known as a possible spambot */
801 <      if (name != NULL)
801 >      if (name)
802          sendto_realops_flags(UMODE_BOTS, L_ALL, SEND_NOTICE,
803                               "User %s (%s@%s) trying to join %s is a possible spambot",
804                               source_p->name, source_p->username,
# Line 838 | Line 832 | check_spambot_warning(struct Client *sou
832        }
833      }
834  
835 <    if (name != NULL)
835 >    if (name)
836        source_p->localClient->last_join_time = CurrentTime;
837      else
838        source_p->localClient->last_leave_time = CurrentTime;
# Line 892 | Line 886 | set_channel_topic(struct Channel *chptr,
886      strlcpy(chptr->topic, topic, sizeof(chptr->topic));
887  
888    strlcpy(chptr->topic_info, topic_info, sizeof(chptr->topic_info));
889 <  chptr->topic_time = topicts;
889 >  chptr->topic_time = topicts;
890   }

Diff Legend

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