]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - src/channel.c
Remove dot_in_ip6_addr config option.
[irc/rqf/shadowircd.git] / src / channel.c
index 1888d9749bb63b18092819b284151057a508eed4..c0fdcc3d626909fdbbd7abc933d5e4064ece3e3c 100644 (file)
@@ -21,7 +21,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: channel.c 3173 2007-01-31 23:57:18Z jilles $
+ *  $Id: channel.c 3580 2007-11-07 23:45:14Z jilles $
  */
 
 #include "stdinc.h"
@@ -93,7 +93,7 @@ allocate_channel(const char *chname)
 {
        struct Channel *chptr;
        chptr = BlockHeapAlloc(channel_heap);
-       DupNString(chptr->chname, chname, CHANNELLEN);
+       DupString(chptr->chname, chname);
        return (chptr);
 }
 
@@ -109,8 +109,8 @@ allocate_ban(const char *banstr, const char *who)
 {
        struct Ban *bptr;
        bptr = BlockHeapAlloc(ban_heap);
-       DupNString(bptr->banstr, banstr, BANLEN);
-       DupNString(bptr->who, who, BANLEN);
+       DupString(bptr->banstr, banstr);
+       DupString(bptr->who, who);
 
        return (bptr);
 }
@@ -384,6 +384,7 @@ destroy_channel(struct Channel *chptr)
        free_channel_list(&chptr->banlist);
        free_channel_list(&chptr->exceptlist);
        free_channel_list(&chptr->invexlist);
+       free_channel_list(&chptr->quietlist);
 
        /* Free the topic */
        free_topic(chptr);
@@ -716,13 +717,14 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr,
 int
 can_join(struct Client *source_p, struct Channel *chptr, char *key)
 {
-       dlink_node *lp;
+       dlink_node *invite = NULL;
        dlink_node *ptr;
        struct Ban *invex = NULL;
        char src_host[NICKLEN + USERLEN + HOSTLEN + 6];
        char src_iphost[NICKLEN + USERLEN + HOSTLEN + 6];
        char src_althost[NICKLEN + USERLEN + HOSTLEN + 6];
        int use_althost = 0;
+       int i = 0;
        hook_data_channel moduledata;
 
        s_assert(source_p->localClient != NULL);
@@ -751,12 +753,12 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key)
 
        if(chptr->mode.mode & MODE_INVITEONLY)
        {
-               DLINK_FOREACH(lp, source_p->user->invited.head)
+               DLINK_FOREACH(invite, source_p->user->invited.head)
                {
-                       if(lp->data == chptr)
+                       if(invite->data == chptr)
                                break;
                }
-               if(lp == NULL)
+               if(invite == NULL)
                {
                        if(!ConfigChannel.use_invex)
                                return (ERR_INVITEONLYCHAN);
@@ -780,18 +782,28 @@ can_join(struct Client *source_p, struct Channel *chptr, char *key)
 
        if(chptr->mode.limit &&
           dlink_list_length(&chptr->members) >= (unsigned long) chptr->mode.limit)
-               return (ERR_CHANNELISFULL);
-
+               i = ERR_CHANNELISFULL;
        if(chptr->mode.mode & MODE_REGONLY && EmptyString(source_p->user->suser))
-               return ERR_NEEDREGGEDNICK;
-
+               i = ERR_NEEDREGGEDNICK;
        /* join throttling stuff --nenolod */
-       if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
+       else if(chptr->mode.join_num > 0 && chptr->mode.join_time > 0)
        {
                if ((CurrentTime - chptr->join_delta <= 
                        chptr->mode.join_time) && (chptr->join_count >=
                        chptr->mode.join_num))
-                       return ERR_THROTTLE;
+                       i = ERR_THROTTLE;
+       }
+
+       /* allow /invite to override +l/+r/+j also -- jilles */
+       if (i != 0 && invite == NULL)
+       {
+               DLINK_FOREACH(invite, source_p->user->invited.head)
+               {
+                       if(invite->data == chptr)
+                               break;
+               }
+               if (invite == NULL)
+                       return i;
        }
 
        moduledata.client = source_p;
@@ -1099,9 +1111,8 @@ static const struct mode_letter
  *
  * inputs       - pointer to channel
  *              - pointer to client
- * output       - NONE
- * side effects - write the "simple" list of channel modes for channel
- * chptr onto buffer mbuf with the parameters in pbuf.
+ * output       - string with simple modes
+ * side effects - result from previous calls overwritten
  *
  * Stolen from ShadowIRCd 4 --nenolod
  */
@@ -1126,38 +1137,39 @@ channel_modes(struct Channel *chptr, struct Client *client_p)
        {
                *mbuf++ = 'l';
 
-               if(IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
-                       pbuf += ircsprintf(pbuf, "%d ", chptr->mode.limit);
+               if(!IsClient(client_p) || IsMember(client_p, chptr))
+                       pbuf += ircsprintf(pbuf, " %d", chptr->mode.limit);
        }
 
        if(*chptr->mode.key)
        {
                *mbuf++ = 'k';
 
-               if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
-                       pbuf += ircsprintf(pbuf, "%s ", chptr->mode.key);
+               if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr))
+                       pbuf += ircsprintf(pbuf, " %s", chptr->mode.key);
        }
 
        if(chptr->mode.join_num)
        {
                *mbuf++ = 'j';
 
-               if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
-                       pbuf += ircsprintf(pbuf, "%d:%d ", chptr->mode.join_num,
+               if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr))
+                       pbuf += ircsprintf(pbuf, " %d:%d", chptr->mode.join_num,
                                           chptr->mode.join_time);
        }
 
-       if(*chptr->mode.forward && (ConfigChannel.use_forward || IsServer(client_p) || IsMe(client_p)))
+       if(*chptr->mode.forward && (ConfigChannel.use_forward || !IsClient(client_p)))
        {
                *mbuf++ = 'f';
 
-               if(*pbuf || IsMember(client_p, chptr) || IsServer(client_p) || IsMe(client_p))
-                       pbuf += ircsprintf(pbuf, "%s ", chptr->mode.forward);
+               if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr))
+                       pbuf += ircsprintf(pbuf, " %s", chptr->mode.forward);
        }
 
        *mbuf = '\0';
 
-       ircsprintf(final, "%s %s", buf1, buf2);
+       strlcpy(final, buf1, sizeof final);
+       strlcat(final, buf2, sizeof final);
        return final;
 }