]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/core/m_join.c
Argh, wrong replace caused by MS VS 2005 interface.
[irc/rqf/shadowircd.git] / modules / core / m_join.c
index c3cc39d018a4a11ca01a7413278f64434e87d2a7..fbb2e4adfecbb149b02f88fb34fcb8af9570512a 100644 (file)
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *  USA
  *
- *  $Id: m_join.c 3486 2007-05-27 05:44:35Z nenolod $
+ *  $Id: m_join.c 3494 2007-05-27 13:07:27Z jilles $
  */
 
 #include "stdinc.h"
-#include "tools.h"
 #include "channel.h"
 #include "client.h"
 #include "common.h"
@@ -62,8 +61,9 @@ mapi_hlist_av1 join_hlist[] = {
        { NULL, NULL },
 };
 
-DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3486 $");
+DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3494 $");
 
+static void do_join_0(struct Client *client_p, struct Client *source_p);
 static int check_channel_name_loc(struct Client *source_p, const char *name);
 
 static void set_final_mode(struct Mode *mode, struct Mode *oldmode);
@@ -148,6 +148,13 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
                        continue;
                }
 
+               /* join 0 parts all channels */
+               if(*name == '0' && (name[1] == ',' || name[1] == '\0') && name == chanlist)
+               {
+                       (void) strcpy(jbuf, "0");
+                       continue;
+               }
+
                /* check it begins with # or &, and local chans are disabled */
                else if(!IsChannelName(name))
                {
@@ -201,6 +208,16 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
        {
                hook_data_channel_activity hook_info;
 
+               /* JOIN 0 simply parts all channels the user is in */
+               if(*name == '0' && !atoi(name))
+               {
+                       if(source_p->user->channel.head == NULL)
+                               continue;
+
+                       do_join_0(&me, source_p);
+                       continue;
+               }
+
                /* look for the channel */
                if((chptr = find_channel(name)) != NULL)
                {
@@ -218,7 +235,7 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
 
                        call_hook(h_can_create_channel, &moduledata);
 
-                       if(moduledata.approved != 0 && !IsOper(source_p))
+                       if(moduledata.approved != 0)
                        {
                                sendto_one(source_p, form_str(moduledata.approved),
                                           me.name, source_p->name, name);
@@ -236,10 +253,10 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
                        flags = CHFL_CHANOP;
                }
 
-               if((dlink_list_length(&source_p->user->channel) >=
+               if((rb_dlink_list_length(&source_p->user->channel) >=
                    (unsigned long) ConfigChannel.max_chans_per_user) &&
                   (!IsOper(source_p) ||
-                   (dlink_list_length(&source_p->user->channel) >=
+                   (rb_dlink_list_length(&source_p->user->channel) >=
                     (unsigned long) ConfigChannel.max_chans_per_user * 3)))
                {
                        sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
@@ -382,7 +399,14 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
        int isnew;
        int keep_our_modes = YES;
        int keep_new_modes = YES;
-       dlink_node *ptr, *next_ptr;
+       rb_dlink_node *ptr, *next_ptr;
+
+       /* special case for join 0 */
+       if((parv[1][0] == '0') && (parv[1][1] == '\0') && parc == 2)
+       {
+               do_join_0(client_p, source_p);
+               return 0;
+       }
 
        if(parc < 4)
                return 0;
@@ -445,7 +469,7 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
                set_final_mode(&mode, &chptr->mode);
                chptr->mode = mode;
                remove_our_modes(chptr, source_p);
-               DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
+               RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
                {
                        del_invite(chptr, ptr->data);
                }
@@ -486,12 +510,52 @@ ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *
                      source_p->id, (long) chptr->channelts, chptr->chname);
        sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
                      ":%s SJOIN %ld %s %s :%s",
-                     source_p->user->server, (long) chptr->channelts,
+                     source_p->servptr->name, (long) chptr->channelts,
                      chptr->chname, keep_new_modes ? "+" : "0",
                      source_p->name);
        return 0;
 }
 
+/*
+ * do_join_0
+ *
+ * inputs      - pointer to client doing join 0
+ * output      - NONE
+ * side effects        - Use has decided to join 0. This is legacy
+ *               from the days when channels were numbers not names. *sigh*
+ *               There is a bunch of evilness necessary here due to
+ *               anti spambot code.
+ */
+static void
+do_join_0(struct Client *client_p, struct Client *source_p)
+{
+       struct membership *msptr;
+       struct Channel *chptr = NULL;
+       rb_dlink_node *ptr;
+
+       /* Finish the flood grace period... */
+       if(MyClient(source_p) && !IsFloodDone(source_p))
+               flood_endgrace(source_p);
+
+
+       sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s JOIN 0", use_id(source_p));
+       sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s JOIN 0", source_p->name);
+
+       if(source_p->user->channel.head && MyConnect(source_p) &&
+          !IsOper(source_p) && !IsExemptSpambot(source_p))
+               check_spambot_warning(source_p, NULL);
+
+       while((ptr = source_p->user->channel.head))
+       {
+               msptr = ptr->data;
+               chptr = msptr->chptr;
+               sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
+                                    source_p->name,
+                                    source_p->username, source_p->host, chptr->chname);
+               remove_user_from_channel(msptr);
+       }
+}
+
 static int
 check_channel_name_loc(struct Client *source_p, const char *name)
 {
@@ -519,30 +583,6 @@ check_channel_name_loc(struct Client *source_p, const char *name)
        return 1;
 }
 
-struct mode_letter
-{
-       int mode;
-       char letter;
-};
-
-static struct mode_letter flags[] = {
-       {MODE_NOPRIVMSGS, 'n'},
-       {MODE_TOPICLIMIT, 't'},
-       {MODE_SECRET, 's'},
-       {MODE_MODERATED, 'm'},
-       {MODE_INVITEONLY, 'i'},
-       {MODE_PRIVATE, 'p'},
-       {MODE_REGONLY, 'r'},
-       {MODE_EXLIMIT, 'L'},
-       {MODE_PERMANENT, 'P'},
-       {MODE_NOCOLOR, 'c'},
-       {MODE_FREEINVITE, 'g'},
-       {MODE_OPMODERATE, 'z'},
-       {MODE_FREETARGET, 'F'},
-       {MODE_DISFORWARD, 'Q'},
-       {0, 0}
-};
-
 static void
 set_final_mode(struct Mode *mode, struct Mode *oldmode)
 {
@@ -552,30 +592,30 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode)
        int i;
 
        /* ok, first get a list of modes we need to add */
-       for(i = 0; flags[i].letter; i++)
+       for(i = 0; chmode_flags[i].letter; i++)
        {
-               if((mode->mode & flags[i].mode) && !(oldmode->mode & flags[i].mode))
+               if((mode->mode & chmode_flags[i].mode) && !(oldmode->mode & chmode_flags[i].mode))
                {
                        if(dir != MODE_ADD)
                        {
                                *mbuf++ = '+';
                                dir = MODE_ADD;
                        }
-                       *mbuf++ = flags[i].letter;
+                       *mbuf++ = chmode_flags[i].letter;
                }
        }
 
        /* now the ones we need to remove. */
-       for(i = 0; flags[i].letter; i++)
+       for(i = 0; chmode_flags[i].letter; i++)
        {
-               if((oldmode->mode & flags[i].mode) && !(mode->mode & flags[i].mode))
+               if((oldmode->mode & chmode_flags[i].mode) && !(mode->mode & chmode_flags[i].mode))
                {
                        if(dir != MODE_DEL)
                        {
                                *mbuf++ = '-';
                                dir = MODE_DEL;
                        }
-                       *mbuf++ = flags[i].letter;
+                       *mbuf++ = chmode_flags[i].letter;
                }
        }
 
@@ -596,7 +636,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode)
                        dir = MODE_DEL;
                }
                *mbuf++ = 'k';
-               len = ircsprintf(pbuf, "%s ", oldmode->key);
+               len = rb_sprintf(pbuf, "%s ", oldmode->key);
                pbuf += len;
        }
        if(oldmode->join_num && !mode->join_num)
@@ -625,7 +665,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode)
                        dir = MODE_ADD;
                }
                *mbuf++ = 'l';
-               len = ircsprintf(pbuf, "%d ", mode->limit);
+               len = rb_sprintf(pbuf, "%d ", mode->limit);
                pbuf += len;
        }
        if(mode->key[0] && strcmp(oldmode->key, mode->key))
@@ -636,7 +676,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode)
                        dir = MODE_ADD;
                }
                *mbuf++ = 'k';
-               len = ircsprintf(pbuf, "%s ", mode->key);
+               len = rb_sprintf(pbuf, "%s ", mode->key);
                pbuf += len;
        }
        if(mode->join_num && (oldmode->join_num != mode->join_num || oldmode->join_time != mode->join_time))
@@ -647,7 +687,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode)
                        dir = MODE_ADD;
                }
                *mbuf++ = 'j';
-               len = ircsprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time);
+               len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time);
                pbuf += len;
        }
        if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward)
@@ -658,7 +698,7 @@ set_final_mode(struct Mode *mode, struct Mode *oldmode)
                        dir = MODE_ADD;
                }
                *mbuf++ = 'f';
-               len = ircsprintf(pbuf, "%s ", mode->forward);
+               len = rb_sprintf(pbuf, "%s ", mode->forward);
                pbuf += len;
        }
        *mbuf = '\0';
@@ -675,7 +715,7 @@ static void
 remove_our_modes(struct Channel *chptr, struct Client *source_p)
 {
        struct membership *msptr;
-       dlink_node *ptr;
+       rb_dlink_node *ptr;
        char lmodebuf[MODEBUFLEN];
        char *lpara[MAXMODEPARAMS];
        int count = 0;
@@ -687,7 +727,7 @@ remove_our_modes(struct Channel *chptr, struct Client *source_p)
        for(i = 0; i < MAXMODEPARAMS; i++)
                lpara[i] = NULL;
 
-       DLINK_FOREACH(ptr, chptr->members.head)
+       RB_DLINK_FOREACH(ptr, chptr->members.head)
        {
                msptr = ptr->data;