step over ! if it's allowed on MODE_NOFLOOD
[srvx.git] / src / proto-p10.c
index e04d65650ceb16da3ad4c4c5db5bf1db4833ac27..c1271db0934dfca74cb5f6418ab4c72460016fe1 100644 (file)
@@ -40,6 +40,7 @@
 #define CMD_EOB_ACK             "EOB_ACK"
 #define CMD_ERROR               "ERROR"
 #define CMD_FAKEHOST            "FAKE"
+#define CMD_FAKEHOST2           "FAKE2"
 #define CMD_GET                 "GET"
 #define CMD_GLINE               "GLINE"
 #define CMD_HASH                "HASH"
 #define TOK_EOB_ACK             "EA"
 #define TOK_ERROR               "Y"
 #define TOK_FAKEHOST            "FA"
+#define TOK_FAKEHOST2           "FA2"
 #define TOK_GET                 "GET"
 #define TOK_GLINE               "GL"
 #define TOK_HASH                "HASH"
 #define P10_EOB_ACK             TYPE(EOB_ACK)
 #define P10_ERROR               TYPE(ERROR)
 #define P10_FAKEHOST            TYPE(FAKEHOST)
+#define P10_FAKEHOST2           TYPE(FAKEHOST2)
 #define P10_GET                 TYPE(GET)
 #define P10_GLINE               TYPE(GLINE)
 #define P10_HASH                TYPE(HASH)
@@ -502,14 +505,19 @@ irc_account(struct userNode *user, const char *stamp, unsigned long timestamp, u
 void
 irc_fakehost(struct userNode *user, const char *host, const char *ident, int force)
 {
-    putsock("%s " P10_FAKEHOST " %s %s %s%s", self->numeric, user->numeric, ident, host, force ? " FORCE" : "");
+    /* SRVX added the possibility for FAKE IDENTS
+     * but this is currently *NOT* supported by our IRCu
+     */
+    int useNewFakehost = 0;
+     
+    if(useNewFakehost) putsock("%s " P10_FAKEHOST2 " %s %s %s%s", self->numeric, user->numeric, ident, host, force ? " FORCE" : "");
+    else putsock("%s " P10_FAKEHOST " %s %s", self->numeric, user->numeric, host);
 }
 
 void 
 irc_relay(char *message)
 {
     putsock("%s " P10_RELAY " %s", self->numeric, message);
-    fprintf(stderr,"%s " P10_RELAY " %s", self->numeric, message);
 }
 
 void 
@@ -1746,9 +1754,10 @@ static CMD_FUNC(cmd_relay)
             //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))) {
+            char tmp[MAXLEN], tmp2[MAXLEN];
+            sprintf(tmp, "%s@%s",argv[7],argv[6]);
+            sprintf(tmp2, "%s@%s",argv[7],argv[5]);
+            if((hi = checklogin(argv[4],argv[argc-1],&argv[3][1],tmp,tmp2))) {
              //login ok
              struct devnull_class *th;
              char devnull[512];
@@ -1764,7 +1773,9 @@ static CMD_FUNC(cmd_relay)
              } else {
                 devnull[0] = 0;
              }
-             if(getfakehost(argv[4])) {
+             if(!HANDLE_FLAGGED(hi, AUTOHIDE)) {
+                sprintf(tmp,"%s LA %s 0 %s\n",argv[3],hi->handle,devnull);
+             } else 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;
@@ -2572,6 +2583,7 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
         case 'c': do_chan_mode(MODE_NOCOLORS); break;
         case 'M': do_chan_mode(MODE_NOAMSGS); break;
         case 'N': do_chan_mode(MODE_NONOTICES); break;
+        case 'u': do_chan_mode(MODE_AUDITORIUM); break;
         case 'i': do_chan_mode(MODE_INVITEONLY); break;
         case 'm': do_chan_mode(MODE_MODERATED); break;
         case 'n': do_chan_mode(MODE_NOPRIVMSGS); break;
@@ -2627,6 +2639,40 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
                 }
             }
             break;
+        case 'f':
+                   if (add) {
+                           if (in_arg >= argc)
+                    goto error;
+                char *mode = modes[in_arg++];
+                if(mode[0] == '!' && !(flags & MCP_OPERMODE)) //noflood flag also for overriders
+                   goto error;//only allow opers
+                else if(mode[0] == '!')
+                   mode++;
+                
+                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;
+                       }
+            break;
         case 'F':
             if (add) {
                 if (in_arg >= argc)
@@ -2819,12 +2865,14 @@ 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');
         DO_MODE_CHAR(NOCTCPS, 'C');
         DO_MODE_CHAR(NONOTICES, 'N');
         DO_MODE_CHAR(NOAMSGS, 'M');
+        DO_MODE_CHAR(AUDITORIUM, 'u');
         DO_MODE_CHAR(REGISTERED, 'z');
 #undef DO_MODE_CHAR
         if (change->modes_clear & channel->modes & MODE_KEY)
@@ -2870,6 +2918,7 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         DO_MODE_CHAR(NOCTCPS, 'C');
         DO_MODE_CHAR(NONOTICES, 'N');
         DO_MODE_CHAR(NOAMSGS, 'M');
+        DO_MODE_CHAR(AUDITORIUM, 'u');
         DO_MODE_CHAR(REGISTERED, 'z');
 #undef DO_MODE_CHAR
         if(change->modes_set & MODE_KEY)
@@ -2888,6 +2937,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)
@@ -2936,6 +2987,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');
@@ -2945,6 +2997,7 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(NOCTCPS, 'C');
         DO_MODE_CHAR(NONOTICES, 'N');
         DO_MODE_CHAR(NOAMSGS, 'M');
+        DO_MODE_CHAR(AUDITORIUM, 'u');
         DO_MODE_CHAR(REGISTERED, 'z');
 #undef DO_MODE_CHAR
     }
@@ -2963,11 +3016,13 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(NOCTCPS, 'C');
         DO_MODE_CHAR(NONOTICES, 'N');
                DO_MODE_CHAR(NOAMSGS, 'M');
+        DO_MODE_CHAR(AUDITORIUM, 'u');
         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, " %d", change->new_access);
-        DO_MODE_CHAR(KEY, 'F'), args_used += sprintf(args + args_used, " %s", change->new_altchan);
+        DO_MODE_CHAR(ACCESS, 'a'), args_used += sprintf(args + args_used, " %d", change->new_access);
+        DO_MODE_CHAR(ALTCHAN, 'F'), args_used += sprintf(args + args_used, " %s", change->new_altchan);
+        DO_MODE_CHAR(NOFLOOD, '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
@@ -2996,6 +3051,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';
@@ -3022,6 +3081,7 @@ clear_chanmode(struct chanNode *channel, const char *modes)
         case 'c': cleared |= MODE_NOCOLORS; break;
         case 'C': cleared |= MODE_NOCTCPS; break;
         case 'M': cleared |= MODE_NOAMSGS; break;
+        case 'u': cleared |= MODE_AUDITORIUM; break;
         case 'N': cleared |= MODE_NONOTICES; break;
         case 'z': cleared |= MODE_REGISTERED; break;
         }