tidied up m_relay.c
[ircu2.10.12-pk.git] / ircd / m_relay.c
index 12bf74183400996d425ec10de4559068b19e3a17..96676cd33fab8d3fb4d0c25b6607e248ee8ee25f 100644 (file)
 
 static void loc_handler_LR(const char *num, char *parv[], signed int parc) {
     if(num[0] != '!') return;
-       if(parc > 0)
-               auth_loc_reply(&num[3], NULL, NULL, NULL, 0);
-       else
-               auth_loc_reply(&num[3], NULL, NULL, &parv[0] , parc);
+    if(parc > 0)
+        auth_loc_reply(&num[3], NULL, NULL, NULL, 0);
+    else
+        auth_loc_reply(&num[3], NULL, NULL, &parv[0] , parc);
 }
 
 static void loc_handler_LA(const char *num, char *parv[], signed int parc) {
     if(num[0] != '!' || parc < 1) return;
-       char *fakehost = NULL;
-       if (parc > 1 && parv[1] != "0")
-               fakehost=parv[1];
-               
+    char *fakehost = NULL;
+    if (parc > 1 && strcmp(parv[1], "0") != 0) // 0 = no fakehost
+        fakehost=parv[1];
+
     if(parc > 2)
         auth_loc_reply(&num[3], parv[0], fakehost, &parv[2] , parc - 2);
     else if(parc > 1)
@@ -55,37 +55,77 @@ static void mode_a_join(struct Client* cptr, char *channel, int flags) {
     struct Channel *chptr;
     if (!(chptr = FindChannel(channel))) {
         if (((channel[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS)) || strlen(channel) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) {
-         //we don't send an error message here - that would be very strange for the user, because they normaly don't know that mode +F is set
+            //we don't send an error message here - that would be very strange for the user, because they normaly don't know that mode +F is set
         } else if ((chptr = get_channel(cptr, channel, CGT_CREATE))) {
-           struct JoinBuf create;
-           joinbuf_init(&create, cptr, cptr, JOINBUF_TYPE_CREATE, 0, TStime());
-           joinbuf_join(&create, chptr, CHFL_CHANOP | CHFL_CHANNEL_MANAGER);
-                  do_names(cptr, chptr, NAMES_ALL|NAMES_EON);
-           joinbuf_flush(&create);
-               }
-       } else {
+            struct JoinBuf create;
+            joinbuf_init(&create, cptr, cptr, JOINBUF_TYPE_CREATE, 0, TStime());
+            joinbuf_join(&create, chptr, CHFL_CHANOP | CHFL_CHANNEL_MANAGER);
+            do_names(cptr, chptr, NAMES_ALL|NAMES_EON);
+            joinbuf_flush(&create);
+        }
+    } else {
         struct JoinBuf join;
         joinbuf_init(&join, cptr, cptr, JOINBUF_TYPE_JOIN, 0, 0);
-               joinbuf_join(&join, chptr, flags);
-               del_invite(cptr, chptr);
+        joinbuf_join(&join, chptr, flags);
+        del_invite(cptr, chptr);
         if (chptr->topic[0]) {
             send_reply(cptr, RPL_TOPIC, chptr->chname, chptr->topic);
             send_reply(cptr, RPL_TOPICWHOTIME, chptr->chname, chptr->topic_nick, chptr->topic_time);
         }
         do_names(cptr, chptr, NAMES_ALL|NAMES_EON); /* send /names list */
         joinbuf_flush(&join);
-       }
+    }
 }
 
-
-static void mode_a_check_altchan(struct Client* cptr, char *channel) {
-    struct Channel *chptr;
-    if (!(chptr = FindChannel(channel)))
-        return;
-    
-    if(chptr->mode.altchan && IsChannelName(chptr->mode.altchan) && strIsIrcCh(chptr->mode.altchan)) {
-               mode_a_join(cptr,chptr->mode.altchan,CHFL_DEOPPED);
-       }
+static void mode_a_check_altchan(struct Client* sptr, char *channel) {
+    struct Channel *chptrb;
+    if (!(chptrb = FindChannel(channel))) {
+        if (((channel[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS)) || strlen(channel) > IRCD_MIN(CHANNELLEN, feature_int(FEAT_CHANNELLEN))) {
+            //we don't send an error message here - that would be very strange for the user, because they normaly don't know that mode +F is set
+        } else if ((chptrb = get_channel(sptr, channel, CGT_CREATE))) {
+            struct JoinBuf create;
+            joinbuf_init(&create, sptr, sptr, JOINBUF_TYPE_CREATE, 0, TStime());
+            joinbuf_join(&create, chptrb, CHFL_CHANOP | CHFL_CHANNEL_MANAGER);
+            do_names(sptr, chptrb, NAMES_ALL|NAMES_EON);
+            joinbuf_flush(&create);
+        }
+    } else {
+        if(find_member_link(chptrb, sptr))
+            return; //we have already joined this channel
+        //first of all check if we may even join this channel
+        int err2 = 0;
+        int flags = 0;
+        if (chptrb->users == 0 && !chptrb->mode.apass[0] && !(chptrb->mode.mode & MODE_PERSIST)) {
+            /* Joining a zombie channel (zannel): give ops and increment TS. */
+            flags = CHFL_CHANOP;
+            chptrb->creationtime++;
+        } else if (IsInvited(sptr, chptrb)) {
+             /* Invites and key=OVERRIDE bypass these other checks. */
+        } else if (chptrb->mode.mode & MODE_INVITEONLY)
+            err2 = ERR_INVITEONLYCHAN;
+        else if (chptrb->mode.limit && (chptrb->users >= chptrb->mode.limit))
+            err2 = ERR_CHANNELISFULL;
+        else if ((chptrb->mode.mode & MODE_REGONLY) && !IsAccount(sptr))
+            err2 = ERR_NEEDREGGEDNICK;
+        else if ((chptrb->mode.mode & MODE_SSLCHAN) && !IsSSL(sptr))
+            err2 = ERR_SSLCHANNEL;
+        else if (find_ban(sptr, chptrb->banlist))
+            err2 = ERR_BANNEDFROMCHAN;
+        else if (*chptrb->mode.key) //Fix this!
+            err2 = ERR_BADCHANNELKEY;
+        if(!err2) {
+            struct JoinBuf join;
+            joinbuf_init(&join, sptr, sptr, JOINBUF_TYPE_JOIN, 0, 0);
+            joinbuf_join(&join, chptrb, flags);
+            del_invite(sptr, chptrb);
+            if (chptrb->topic[0]) {
+                send_reply(sptr, RPL_TOPIC, chptrb->chname, chptrb->topic);
+                send_reply(sptr, RPL_TOPICWHOTIME, chptrb->chname, chptrb->topic_nick, chptrb->topic_time);
+            }
+            do_names(sptr, chptrb, NAMES_ALL|NAMES_EON); /* send /names list */
+            joinbuf_flush(&join);
+        }
+    }
 }
 
 /** RELAY
@@ -141,6 +181,7 @@ signed int ms_relay(struct Client* cptr, struct Client* sptr, signed int parc, c
             return 0;
     }
 
+    if(!server) return 0;
     if(server != &me) {
         if(parc > 3) {
             act = buffer;
@@ -159,43 +200,45 @@ signed int ms_relay(struct Client* cptr, struct Client* sptr, signed int parc, c
     }
 
     /* Call subcommand handler. */
-    if(strcmp("LR", parv[2]) == 0) loc_handler_LR(parv[1], &parv[3], parc - 3);
-    else if(strcmp("LA", parv[2]) == 0 && parc > 3) loc_handler_LA(parv[1], &parv[3], parc - 3);
-       else if(strcmp("SM", parv[2]) == 0 && parc > 3) {
-     #ifndef UNRESTRICTED_SERV
-        struct Client *acptr;
-        if(acptr = findNUser(parv[3])) {
-         if (IsChannelPrefix(*parv[4])) {
-       relay_channel_message(acptr, parv[4], parv[parc - 1], 1);
-      } else {
-          relay_private_message(acptr, parv[4], parv[parc - 1]);
-         }
-        }
-     #endif
-       } else if(strcmp("UC", parv[2]) == 0 && parc > 3) {
-        struct Client *acptr;
-        if(acptr = findNUser(parv[3])) {
-         send_reply(acptr, ERR_UNKNOWNCOMMAND, parv[4]);
-        }
-       } else if(strcmp("SI", parv[2]) == 0 && parc > 3) {
-     #ifndef UNRESTRICTED_SERV
-        struct Client *acptr;
-        if(acptr = findNUser(parv[3])) {
-         parse_simul_client(acptr, parv[parc - 1]);
-        }
-     #endif
-       } else if(strcmp("JAA", parv[2]) == 0 && parc > 2) {
-        struct Client *acptr;
-        if(acptr = findNUser(parv[1])) {
-         mode_a_join(acptr,parv[3],strtoul(parv[4], 0, 10));
-        }
-       } else if(strcmp("JAR", parv[2]) == 0 && parc > 2) {
-        struct Client *acptr;
-        if(acptr = findNUser(parv[1])) {
-      mode_a_check_altchan(acptr,parv[3]);
-         send_reply(acptr, ERR_JOINACCESS, parv[3]);
-        }
-       }
+    if(strcmp("LR", parv[2]) == 0) 
+        loc_handler_LR(parv[1], &parv[3], parc - 3);
+    else if(strcmp("LA", parv[2]) == 0 && parc > 3) 
+        loc_handler_LA(parv[1], &parv[3], parc - 3);
+    else if(strcmp("SM", parv[2]) == 0 && parc > 3) {
+#ifndef UNRESTRICTED_SERV
+        struct Client *acptr;
+        if(acptr = findNUser(parv[3])) {
+            if (IsChannelPrefix(*parv[4]))
+                relay_channel_message(acptr, parv[4], parv[parc - 1], 1);
+            else
+                relay_private_message(acptr, parv[4], parv[parc - 1]);
+        }
+#endif
+    } else if(strcmp("UC", parv[2]) == 0 && parc > 3) {
+        struct Client *acptr;
+        if(acptr = findNUser(parv[3]))
+            send_reply(acptr, ERR_UNKNOWNCOMMAND, parv[4]);
+    } else if(strcmp("SI", parv[2]) == 0 && parc > 3) {
+#ifndef UNRESTRICTED_SERV
+        struct Client *acptr;
+        if(acptr = findNUser(parv[3]))
+            parse_simul_client(acptr, parv[parc - 1]);
+#endif
+    } else if(strcmp("JAA", parv[2]) == 0 && parc > 2) {
+        struct Client *acptr;
+        if(acptr = findNUser(parv[1]))
+            mode_a_join(acptr,parv[3],strtoul(parv[4], 0, 10));
+    } else if(strcmp("JAR", parv[2]) == 0 && parc > 2) {
+        struct Client *acptr;
+        struct Channel *chptr;
+        if(acptr = findNUser(parv[1])) {
+            if(IsChannelName(parv[3]) && strIsIrcCh(parv[3]) && 
+              (chptr = FindChannel(parv[3])) && chptr->mode.altchan && 
+              IsChannelName(chptr->mode.altchan) && strIsIrcCh(chptr->mode.altchan))
+                mode_a_check_altchan(acptr,chptr->mode.altchan);
+            send_reply(acptr, ERR_JOINACCESS, parv[3], feature_str(FEAT_ERR_JOINACCESS));
+        }
+    }
 
     return 0;
 }