also check for forward dependences on RELAY (after +a request)
authorpk910 <philipp@zoelle1.de>
Tue, 28 Jun 2011 16:26:42 +0000 (18:26 +0200)
committerpk910 <philipp@zoelle1.de>
Tue, 28 Jun 2011 16:26:42 +0000 (18:26 +0200)
ircd/m_relay.c

index 30731fb58c3fe066543cfd9516d78e001648b78e..3a02764832873307f5d655b0adf0af69e319a884 100644 (file)
@@ -77,15 +77,44 @@ static void mode_a_join(struct Client* cptr, char *channel, int flags) {
        }
 }
 
-
-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) {
+       static Channel *chptrb;
+       if (!(chptrb = FindChannel(channel))) {
+      if (((channel[0] == '&') && !feature_bool(FEAT_LOCAL_CHANNELS)) || strlen(altchan) > 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, altchan, CGT_CREATE))) {
+        joinbuf_join(&create, chptrb, CHFL_CHANOP | CHFL_CHANNEL_MANAGER);
+               do_names(sptr, chptrb, NAMES_ALL|NAMES_EON);
+         }
+       } else {
+         //first of all check if we may even join this channel
+         int err2 = 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 (find_ban(sptr, chptrb->banlist))
+        err2 = ERR_BANNEDFROMCHAN;
+      else if (*chptrb->mode.key && (!key || strcmp(key, chptrb->mode.key)))
+        err2 = ERR_BADCHANNELKEY;
+         if(!err2) {
+           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 */
+         }
+   }
 }
 
 /** RELAY
@@ -192,8 +221,11 @@ signed int ms_relay(struct Client* cptr, struct Client* sptr, signed int parc, c
         }
        } else if(strcmp("JAR", parv[2]) == 0 && parc > 2) {
         struct Client *acptr;
+        struct Channel *chptr;
         if(acptr = findNUser(parv[1])) {
-      mode_a_check_altchan(acptr,parv[3]);
+         if(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]);
         }
        }