added CMODE_AUDITORIUM & CMODE_NOFLOOD
[srvx.git] / src / proto-p10.c
index 278762f34535c6d7a304eff256cedbc5a7dad97f..f89586b9d24103572196aad73c6b847baf9a108a 100644 (file)
@@ -1197,6 +1197,8 @@ create_helper(char *name, void *data)
         return;
     }
 
+    handle_new_channel_created(name, cd->user);
+
     AddChannelUser(cd->user, AddChannel(name, cd->when, NULL, NULL));
 }
 
@@ -1587,6 +1589,8 @@ static CMD_FUNC(cmd_kick)
 {
     if (argc < 3)
         return 0;
+    if (GetUserN(argv[2]) && IsOper(GetUserN(argv[2])))
+        operpart(GetChannel(argv[1]), GetUserN(argv[2]));
     ChannelUserKicked(GetUserH(origin), GetUserN(argv[2]), GetChannel(argv[1]));
     return 1;
 }
@@ -1737,7 +1741,70 @@ static CMD_FUNC(cmd_relay)
     }
     if(sNode->numeric == self->numeric) {
         //ok  someone relayed something to us!
-        
+        if(strcmp("LQ", argv[2]) == 0) {
+            //oooh thats exciting - we've got a LOC Query! :D
+            //LQ !ABADE pk910 80.153.5.212 server.zoelle1.de ~watchcat :test
+            //ok  let's check the login datas
+            struct handle_info *hi;
+            char tmp[MAXLEN];
+            sprintf(tmp, "*!%s@%s",argv[7],argv[5]);
+            if((hi = checklogin(argv[4],argv[argc-1],&argv[3][1],tmp))) {
+             //login ok
+             struct devnull_class *th;
+             char devnull[512];
+             if(hi->devnull && (th = devnull_get(hi->devnull))) {
+                const char *devnull_modes = DEVNULL_MODES;
+                int ii, flen;
+                char flags[50];
+                for (ii=flen=0; devnull_modes[ii]; ++ii)
+                    if (th->modes & (1 << ii))
+                        flags[flen++] = devnull_modes[ii];
+                flags[flen] = 0;
+                sprintf(devnull, "+%s %s %lu %lu",flags,th->name,th->maxchan,th->maxsendq);
+             } else {
+                devnull[0] = 0;
+             }
+             if(getfakehost(argv[4])) {
+                sprintf(tmp,"%s LA %s %s %s\n",argv[3],hi->handle,getfakehost(argv[4]),devnull);
+             } else {
+                extern const char *hidden_host_suffix;
+                sprintf(tmp,"%s LA %s %s.%s %s\n",argv[3],hi->handle,hi->handle,hidden_host_suffix,devnull);
+             }
+             irc_relay(tmp);
+            } else {
+             //login rejected
+             sprintf(tmp,"%s LR\n",argv[3]);
+             irc_relay(tmp);
+            }
+        } else if(strcmp("UC", argv[2]) == 0) {
+            char tmp[MAXLEN];
+            sprintf(tmp,"%s UC %s %s",argv[3],argv[3],argv[4]);
+            irc_relay(tmp);
+        } else if(strcmp("JA", argv[2]) == 0) {
+            struct userData *uData;
+            struct chanNode *cn;
+            struct userNode *user;
+            char tmp[MAXLEN];
+            cn = GetChannel(argv[4]);
+            if (!cn) return 0;
+            if (!(user = GetUserN(argv[3]))) return 0;
+            if(!cn->channel_info) {
+                //channel not registered
+                sprintf(tmp,"%s JAA %s %s\n",argv[3],cn->name,argv[6]);
+            } else if((uData = GetChannelUser(cn->channel_info, user->handle_info))) {
+                if(uData->access >= atoi(argv[5])) {
+                    //we can join
+                    sprintf(tmp,"%s JAA %s %s\n",argv[3],cn->name,argv[6]);
+                } else {
+                    //access too low
+                    sprintf(tmp,"%s JAR %s %i %i\n",argv[3],cn->name,uData->access,uData->access);
+                }
+            } else {
+                //0 access
+                sprintf(tmp,"%s JAR %s %s %s\n",argv[3],cn->name,"0","0");
+            }
+            irc_relay(tmp);
+        }
     }
     return 1;
 }
@@ -2378,8 +2445,10 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
         case 'o':
             do_user_mode(FLAGS_OPER);
             if (!add) {
+                operdel(user);
                 userList_remove(&curr_opers, user);
             } else if (!userList_contains(&curr_opers, user)) {
+                operadd(user);
                 userList_append(&curr_opers, user);
                 call_oper_funcs(user);
             }
@@ -2513,12 +2582,12 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
         case 'z':
           if (!(flags & MCP_REGISTERED) && (!(flags & MCP_IGN_REGISTERED) || add)) {
             do_chan_mode(MODE_REGISTERED);
-+          } else if (flags & MCP_IGN_REGISTERED) {
-+           /* ignore the modechange but continue parsing */
-           } else {
+          } else if (flags & MCP_IGN_REGISTERED) {
+            /* ignore the modechange but continue parsing */
+          } else {
             mod_chanmode_free(change);
             return NULL;
-           }
+          }
           break;
 #undef do_chan_mode
         case 'l':
@@ -2558,6 +2627,38 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
                 }
             }
             break;
+        case 'f':
+                   if (add) {
+                           if (in_arg >= argc)
+                    goto error;
+                mode = modes[in_arg++];
+                if(mode[0] == '!' && !(flags & MCP_OPERMODE)) { //noflood flag also for overriders
+                    //only allow opers
+                    goto error;
+                }
+                if(mode[0] == '+' || mode[0] == '@') {
+                    mode++;
+                }
+                char *p;
+                int count = 0, time = 0;
+                for(p = mode; p[0]; p++) {
+                    if(p[0] == ':') {
+                        char tmpchar = p[0];
+                        p[0] = '\0';
+                        count = strtoul(mode,0,10);
+                        p[0] = tmpchar;
+                                               p++;
+                                               time = strtoul(p,0,10);
+                                               break;
+                               }
+                }
+                if(count <= 0 || time <= 0 || count > 100 || time > 600) 
+                                   goto error;
+                               change->modes_set |= MODE_NOFLOOD;
+                               safestrncpy(change->new_noflood, modes[in_arg - 1], sizeof(change->new_noflood));
+                       } else {
+                           change->modes_clear |= MODE_NOFLOOD;
+                       }
         case 'F':
             if (add) {
                 if (in_arg >= argc)
@@ -2750,6 +2851,7 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         DO_MODE_CHAR(LIMIT, 'l');
         DO_MODE_CHAR(ACCESS, 'a');
         DO_MODE_CHAR(ALTCHAN, 'F');
+        DO_MODE_CHAR(NOFLOOD, 'f');
         DO_MODE_CHAR(DELAYJOINS, 'D');
         DO_MODE_CHAR(REGONLY, 'r');
         DO_MODE_CHAR(NOCOLORS, 'c');
@@ -2819,6 +2921,8 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         }
         if (change->modes_set & MODE_ALTCHAN)
             mod_chanmode_append(&chbuf, 'F', change->new_altchan);
+        if (change->modes_set & MODE_NOFLOOD)
+            mod_chanmode_append(&chbuf, 'f', change->new_noflood);
     }
     for (arg = 0; arg < change->argc; ++arg) {
         if (change->args[arg].mode & MODE_REMOVE)
@@ -2867,6 +2971,7 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(LIMIT, 'l');
         DO_MODE_CHAR(ACCESS, 'a');
         DO_MODE_CHAR(ALTCHAN, 'F');
+        DO_MODE_CHAR(NOFLOOD, 'f');
         DO_MODE_CHAR(KEY, 'k');
         DO_MODE_CHAR(UPASS, 'U');
         DO_MODE_CHAR(APASS, 'A');
@@ -2897,8 +3002,9 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(REGISTERED, 'z');
         DO_MODE_CHAR(LIMIT, 'l'), args_used += sprintf(args + args_used, " %d", change->new_limit);
         DO_MODE_CHAR(KEY, 'k'), args_used += sprintf(args + args_used, " %s", change->new_key);
-        DO_MODE_CHAR(KEY, 'a'), args_used += sprintf(args + args_used, " %s", change->new_access);
+        DO_MODE_CHAR(KEY, 'a'), args_used += sprintf(args + args_used, " %d", change->new_access);
         DO_MODE_CHAR(KEY, 'F'), args_used += sprintf(args + args_used, " %s", change->new_altchan);
+        DO_MODE_CHAR(KEY, 'f'), args_used += sprintf(args + args_used, " %s", change->new_noflood);
         DO_MODE_CHAR(UPASS, 'U'), args_used += sprintf(args + args_used, " %s", change->new_upass);
         DO_MODE_CHAR(APASS, 'A'), args_used += sprintf(args + args_used, " %s", change->new_apass);
 #undef DO_MODE_CHAR
@@ -2927,6 +3033,10 @@ clear_chanmode(struct chanNode *channel, const char *modes)
             cleared |= MODE_ALTCHAN;
             channel->altchan[0] = '\0';
             break;
+        case 'f':
+            cleared |= MODE_NOFLOOD;
+            channel->noflood[0] = '\0';
+            break;
         case 'k':
             cleared |= MODE_KEY;
             channel->key[0] = '\0';