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-7.2/src/channel.c (file contents), Revision 885 by michael, Wed Oct 31 18:09:24 2007 UTC vs.
ircd-hybrid-8/src/channel.c (file contents), Revision 1474 by michael, Sun Jul 22 14:44:07 2012 UTC

# Line 25 | Line 25
25   */
26  
27   #include "stdinc.h"
28 < #include "tools.h"
28 > #include "list.h"
29   #include "channel.h"
30   #include "channel_mode.h"
31   #include "client.h"
32 #include "common.h"
32   #include "hash.h"
33   #include "hostmask.h"
34   #include "irc_string.h"
35   #include "sprintf_irc.h"
36   #include "ircd.h"
38 #include "list.h"
37   #include "numeric.h"
38   #include "s_serv.h"             /* captab */
39   #include "s_user.h"
40   #include "send.h"
41 < #include "s_conf.h"             /* ConfigFileEntry, ConfigChannel */
41 > #include "conf.h"             /* ConfigFileEntry, ConfigChannel */
42   #include "event.h"
43   #include "memory.h"
44   #include "balloc.h"
# Line 49 | Line 47 | struct config_channel_entry ConfigChanne
47   dlink_list global_channel_list = { NULL, NULL, 0 };
48   BlockHeap *ban_heap;    /*! \todo ban_heap shouldn't be a global var */
49  
52 static BlockHeap *topic_heap = NULL;
50   static BlockHeap *member_heap = NULL;
51   static BlockHeap *channel_heap = NULL;
52  
# Line 69 | Line 66 | init_channels(void)
66  
67    channel_heap = BlockHeapCreate("channel", sizeof(struct Channel), CHANNEL_HEAP_SIZE);
68    ban_heap = BlockHeapCreate("ban", sizeof(struct Ban), BAN_HEAP_SIZE);
72  topic_heap = BlockHeapCreate("topic", TOPICLEN+1 + USERHOST_REPLYLEN, TOPIC_HEAP_SIZE);
69    member_heap = BlockHeapCreate("member", sizeof(struct Membership), CHANNEL_HEAP_SIZE*2);
70   }
71  
# Line 141 | Line 137 | remove_user_from_channel(struct Membersh
137  
138    BlockHeapFree(member_heap, member);
139  
140 <  if (dlink_list_length(&chptr->members) == 0)
140 >  if (chptr->members.head == NULL)
141      destroy_channel(chptr);
142   }
143  
# Line 184 | Line 180 | send_members(struct Client *client_p, st
180      /* space will be converted into CR, but we also need space for LF..
181       * That's why we use '- 1' here
182       * -adx */
183 <    if (t + tlen - buf > sizeof(buf) - 1)
183 >    if (t + tlen - buf > IRCD_BUFSIZE - 1)
184      {
185        *(t - 1) = '\0';  /* kill the space and terminate the string */
186        sendto_one(client_p, "%s", buf);
# Line 290 | Line 286 | send_mode_list(struct Client *client_p,
286   void
287   send_channel_modes(struct Client *client_p, struct Channel *chptr)
288   {
293  if (chptr->chname[0] != '#')
294    return;
295
289    *modebuf = *parabuf = '\0';
290    channel_modes(chptr, client_p, modebuf, parabuf);
291    send_members(client_p, chptr, modebuf, parabuf);
# Line 314 | Line 307 | int
307   check_channel_name(const char *name, int local)
308   {
309    const char *p = name;
310 <  int max_length = local ? LOCAL_CHANNELLEN : CHANNELLEN;
310 >  const int max_length = local ? LOCAL_CHANNELLEN : CHANNELLEN;
311    assert(name != NULL);
312  
313    if (!IsChanPrefix(*p))
# Line 408 | Line 401 | destroy_channel(struct Channel *chptr)
401    free_channel_list(&chptr->exceptlist);
402    free_channel_list(&chptr->invexlist);
403  
411  /* Free the topic */
412  free_topic(chptr);
413
404    dlinkDelete(&chptr->node, &global_channel_list);
405    hash_del_channel(chptr);
406  
# Line 422 | Line 412 | destroy_channel(struct Channel *chptr)
412   * \return string pointer "=" if public, "@" if secret else "*"
413   */
414   static const char *
415 < channel_pub_or_secret(struct Channel *chptr)
415 > channel_pub_or_secret(const struct Channel *chptr)
416   {
417    if (SecretChannel(chptr))
418      return "@";
# Line 448 | Line 438 | channel_member_names(struct Client *sour
438    char *t = NULL, *start = NULL;
439    int tlen = 0;
440    int is_member = IsMember(source_p, chptr);
441 <  int multi_prefix = (source_p->localClient->cap_active & CAP_MULTI_PREFIX) != 0;
441 >  int multi_prefix = HasCap(source_p, CAP_MULTI_PREFIX) != 0;
442  
443    if (PubChannel(chptr) || is_member)
444    {
# Line 463 | Line 453 | channel_member_names(struct Client *sour
453        ms       = ptr->data;
454        target_p = ms->client_p;
455  
456 <      if (IsInvisible(target_p) && !is_member)
456 >      if (HasUMode(target_p, UMODE_INVISIBLE) && !is_member)
457          continue;
458  
459        tlen = strlen(target_p->name) + 1;  /* nick + space */
# Line 603 | Line 593 | find_bmask(const struct Client *who, con
593  
594    DLINK_FOREACH(ptr, list->head)
595    {
596 <    struct Ban *bp = ptr->data;
596 >    const struct Ban *bp = ptr->data;
597  
598      if (match(bp->name, who->name) && match(bp->username, who->username))
599      {
# Line 640 | Line 630 | find_bmask(const struct Client *who, con
630   * \return 0 if not banned, 1 otherwise
631   */
632   int
633 < is_banned(struct Channel *chptr, struct Client *who)
633 > is_banned(const struct Channel *chptr, const struct Client *who)
634   {
635    if (find_bmask(who, &chptr->banlist))
636      if (!ConfigChannel.use_except || !find_bmask(who, &chptr->exceptlist))
# Line 662 | Line 652 | can_join(struct Client *source_p, struct
652    if (is_banned(chptr, source_p))
653      return ERR_BANNEDFROMCHAN;
654  
655 + #ifdef HAVE_LIBCRYPTO
656 +  if ((chptr->mode.mode & MODE_SSLONLY) && !source_p->localClient->fd.ssl)
657 +    return ERR_SSLONLYCHAN;
658 + #endif
659 +
660 +  if ((chptr->mode.mode & MODE_REGONLY) && !HasUMode(source_p, UMODE_REGISTERED))
661 +    return ERR_NEEDREGGEDNICK;
662 +
663 +  if ((chptr->mode.mode & MODE_OPERONLY) && !HasUMode(source_p, UMODE_OPER))
664 +    return ERR_OPERONLYCHAN;
665 +
666    if (chptr->mode.mode & MODE_INVITEONLY)
667      if (!dlinkFind(&source_p->localClient->invited, chptr))
668        if (!ConfigChannel.use_invex || !find_bmask(source_p, &chptr->invexlist))
669          return ERR_INVITEONLYCHAN;
670  
671 <  if (chptr->mode.key[0] && (!key || irccmp(chptr->mode.key, key)))
671 >  if (chptr->mode.key[0] && (!key || strcmp(chptr->mode.key, key)))
672      return ERR_BADCHANNELKEY;
673  
674    if (chptr->mode.limit && dlink_list_length(&chptr->members) >=
# Line 695 | Line 696 | find_channel_link(struct Client *client_
696  
697    DLINK_FOREACH(ptr, client_p->channel.head)
698      if (((struct Membership *)ptr->data)->chptr == chptr)
699 <      return (struct Membership *)ptr->data;
699 >      return ptr->data;
700  
701    return NULL;
702   }
# Line 706 | Line 707 | find_channel_link(struct Client *client_
707   * \param ms       pointer to Membership struct (can be NULL)
708   * \return CAN_SEND_OPV if op or voiced on channel\n
709   *         CAN_SEND_NONOP if can send to channel but is not an op\n
710 < *         CAN_SEND_NO if they cannot send to channel\n
710 > *         ERR_CANNOTSENDTOCHAN or ERR_NEEDREGGEDNICK if they cannot send to channel\n
711   */
712   int
713   can_send(struct Channel *chptr, struct Client *source_p, struct Membership *ms)
714   {
715 <  if (IsServer(source_p))
715 >  if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE))
716      return CAN_SEND_OPV;
717  
718    if (MyClient(source_p) && !IsExemptResv(source_p))
719 <    if (!(IsOper(source_p) && ConfigFileEntry.oper_pass_resv))
719 >    if (!(HasUMode(source_p, UMODE_OPER) && ConfigFileEntry.oper_pass_resv))
720        if (!hash_find_resv(chptr->chname) == ConfigChannel.restrict_channels)
721 <        return CAN_SEND_NO;
721 >        return ERR_CANNOTSENDTOCHAN;
722  
723    if (ms != NULL || (ms = find_channel_link(source_p, chptr)))
724    {
# Line 728 | Line 729 | can_send(struct Channel *chptr, struct C
729      if (ConfigChannel.quiet_on_ban && MyClient(source_p))
730      {
731        if (ms->flags & CHFL_BAN_SILENCED)
732 <        return CAN_SEND_NO;
732 >        return ERR_CANNOTSENDTOCHAN;
733  
734        if (!(ms->flags & CHFL_BAN_CHECKED))
735        {
736          if (is_banned(chptr, source_p))
737          {
738            ms->flags |= (CHFL_BAN_CHECKED|CHFL_BAN_SILENCED);
739 <          return CAN_SEND_NO;
739 >          return ERR_CANNOTSENDTOCHAN;
740          }
741  
742          ms->flags |= CHFL_BAN_CHECKED;
# Line 743 | Line 744 | can_send(struct Channel *chptr, struct C
744      }
745    }
746    else if (chptr->mode.mode & MODE_NOPRIVMSGS)
747 <    return CAN_SEND_NO;
747 >    return ERR_CANNOTSENDTOCHAN;
748  
749    if (chptr->mode.mode & MODE_MODERATED)
750 <    return CAN_SEND_NO;
750 >    return ERR_CANNOTSENDTOCHAN;
751  
752    return CAN_SEND_NONOP;
753   }
# Line 847 | Line 848 | check_splitmode(void *unused)
848    }
849   }
850  
850 /*! \brief Allocates a new topic
851 * \param chptr Channel to allocate a new topic for
852 */
853 static void
854 allocate_topic(struct Channel *chptr)
855 {
856  void *ptr = NULL;
857
858  if (chptr == NULL)
859    return;
860
861  ptr = BlockHeapAlloc(topic_heap);  
862
863  /* Basically we allocate one large block for the topic and
864   * the topic info.  We then split it up into two and shove it
865   * in the chptr
866   */
867  chptr->topic       = ptr;
868  chptr->topic_info  = (char *)ptr + TOPICLEN+1;
869  *chptr->topic      = '\0';
870  *chptr->topic_info = '\0';
871 }
872
873 void
874 free_topic(struct Channel *chptr)
875 {
876  void *ptr = NULL;
877  assert(chptr);
878  if (chptr->topic == NULL)
879    return;
880
881  /*
882   * If you change allocate_topic you MUST change this as well
883   */
884  ptr = chptr->topic;
885  BlockHeapFree(topic_heap, ptr);    
886  chptr->topic      = NULL;
887  chptr->topic_info = NULL;
888 }
889
851   /*! \brief Sets the channel topic for chptr
852   * \param chptr      Pointer to struct Channel
853   * \param topic      The topic string
# Line 897 | Line 858 | void
858   set_channel_topic(struct Channel *chptr, const char *topic,
859                    const char *topic_info, time_t topicts)
860   {
861 <  if (!EmptyString(topic))
862 <  {
863 <    if (chptr->topic == NULL)
903 <      allocate_topic(chptr);
904 <
905 <    strlcpy(chptr->topic, topic, TOPICLEN+1);
906 <    strlcpy(chptr->topic_info, topic_info, USERHOST_REPLYLEN);
907 <    chptr->topic_time = topicts;
908 <  }
909 <  else
910 <  {
911 <    /*
912 <     * Do not reset chptr->topic_time here, it's required for
913 <     * bursting topics properly.
914 <     */
915 <    if (chptr->topic != NULL)
916 <      free_topic(chptr);
917 <  }
861 >  strlcpy(chptr->topic, topic, sizeof(chptr->topic));
862 >  strlcpy(chptr->topic_info, topic_info, sizeof(chptr->topic_info));
863 >  chptr->topic_time = topicts;
864   }

Diff Legend

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