general support for Channel Mode +NMFa and User Mode +SDXHst
[srvx.git] / src / proto-p10.c
index d2f20a07796bc67e1e11ca0059e2fdd6383200bd..e29db35e6d42aab48d0c51c2daadea4fa3c01efe 100644 (file)
@@ -293,8 +293,8 @@ static const char *his_servername;
 static const char *his_servercomment;
 static struct channelList dead_channels;
 
-/* These correspond to 1 << X:      012345678901234567 */
-const char irc_user_mode_chars[] = "o iw dkgn    x   I";
+/* These correspond to 1 << X:      012345678901234567890123 */
+const char irc_user_mode_chars[] = "o iw dkgn    x   ISDXHst";
 
 static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, unsigned long timestamp, const char *realip);
 
@@ -1289,7 +1289,7 @@ static CMD_FUNC(cmd_burst)
             int n_modes;
             for (pos=argv[next], n_modes = 1; *pos; pos++)
                 if ((*pos == 'k') || (*pos == 'l') || (*pos == 'A')
-                    || (*pos == 'U'))
+                    || (*pos == 'U') || (*pos == 'a') || (*pos == 'F'))
                     n_modes++;
             if (next + n_modes > argc)
                 n_modes = argc - next;
@@ -2320,6 +2320,12 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
         case 'g': do_user_mode(FLAGS_GLOBAL); break;
         case 'n': do_user_mode(FLAGS_NOCHAN); break;
         case 'I': do_user_mode(FLAGS_NOIDLE); break;
+        case 'S': do_user_mode(FLAGS_NETSERV); break;
+        case 'D': do_user_mode(FLAGS_SECURITYSERV); break;
+        case 'X': do_user_mode(FLAGS_XTRAOP); break;
+        case 's': do_user_mode(FLAGS_SERVERNOTICE); break;
+        case 'H': do_user_mode(FLAGS_HIDDENOPER); break;
+        case 't': do_user_mode(FLAGS_SEENOIDLE); break;
         case 'x': do_user_mode(FLAGS_HIDDEN_HOST); break;
         case 'r':
             if (*word) {
@@ -2419,6 +2425,8 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
         case 'C': do_chan_mode(MODE_NOCTCPS); break;
         case 'D': do_chan_mode(MODE_DELAYJOINS); break;
         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 'i': do_chan_mode(MODE_INVITEONLY); break;
         case 'm': do_chan_mode(MODE_MODERATED); break;
         case 'n': do_chan_mode(MODE_NOPRIVMSGS); break;
@@ -2448,6 +2456,17 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
                 change->modes_clear |= MODE_LIMIT;
             }
             break;
+        case 'a':
+            if (add) {
+                if (in_arg >= argc)
+                    goto error;
+                change->modes_set |= MODE_ACCESS;
+                change->new_access = atoi(modes[in_arg++]);
+            } else {
+                change->modes_set &= ~MODE_ACCESS;
+                change->modes_clear |= MODE_ACCESS;
+            }
+            break;
         case 'k':
             if (add) {
                 if ((in_arg >= argc)
@@ -2463,6 +2482,16 @@ mod_chanmode_parse(struct chanNode *channel, char **modes, unsigned int argc, un
                 }
             }
             break;
+        case 'F':
+            if (add) {
+                if (in_arg >= argc)
+                    goto error;
+                change->modes_set |= MODE_ALTCHAN;
+                safestrncpy(change->new_altchan, modes[in_arg++], sizeof(change->new_altchan));
+            } else {
+                change->modes_clear |= MODE_ALTCHAN;
+            }
+            break;
         case 'U':
             if (flags & MCP_NO_APASS)
                 goto error;
@@ -2643,10 +2672,14 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         DO_MODE_CHAR(INVITEONLY, 'i');
         DO_MODE_CHAR(NOPRIVMSGS, 'n');
         DO_MODE_CHAR(LIMIT, 'l');
+        DO_MODE_CHAR(ACCESS, 'a');
+        DO_MODE_CHAR(ALTCHAN, '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(REGISTERED, 'z');
 #undef DO_MODE_CHAR
         if (change->modes_clear & channel->modes & MODE_KEY)
@@ -2690,6 +2723,8 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
         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(REGISTERED, 'z');
 #undef DO_MODE_CHAR
         if(change->modes_set & MODE_KEY)
@@ -2702,6 +2737,12 @@ mod_chanmode_announce(struct userNode *who, struct chanNode *channel, struct mod
             sprintf(int_buff, "%d", change->new_limit);
             mod_chanmode_append(&chbuf, 'l', int_buff);
         }
+        if(change->modes_set & MODE_ACCESS) {
+            sprintf(int_buff, "%d", change->new_access);
+            mod_chanmode_append(&chbuf, 'a', int_buff);
+        }
+        if (change->modes_set & MODE_ALTCHAN)
+            mod_chanmode_append(&chbuf, 'F', change->new_altchan);
     }
     for (arg = 0; arg < change->argc; ++arg) {
         if (change->args[arg].mode & MODE_REMOVE)
@@ -2748,6 +2789,8 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         DO_MODE_CHAR(INVITEONLY, 'i');
         DO_MODE_CHAR(NOPRIVMSGS, 'n');
         DO_MODE_CHAR(LIMIT, 'l');
+        DO_MODE_CHAR(ACCESS, 'a');
+        DO_MODE_CHAR(ALTCHAN, 'F');
         DO_MODE_CHAR(KEY, 'k');
         DO_MODE_CHAR(UPASS, 'U');
         DO_MODE_CHAR(APASS, 'A');
@@ -2755,6 +2798,8 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         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(REGISTERED, 'z');
 #undef DO_MODE_CHAR
     }
@@ -2771,9 +2816,13 @@ mod_chanmode_format(struct mod_chanmode *change, char *outbuff)
         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(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, 'F'), args_used += sprintf(args + args_used, " %s", change->new_altchan);
         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
@@ -2798,6 +2847,10 @@ clear_chanmode(struct chanNode *channel, const char *modes)
         case 't': cleared |= MODE_TOPICLIMIT; break;
         case 'i': cleared |= MODE_INVITEONLY; break;
         case 'n': cleared |= MODE_NOPRIVMSGS; break;
+        case 'F':
+            cleared |= MODE_ALTCHAN;
+            channel->altchan[0] = '\0';
+            break;
         case 'k':
             cleared |= MODE_KEY;
             channel->key[0] = '\0';
@@ -2814,11 +2867,17 @@ clear_chanmode(struct chanNode *channel, const char *modes)
             cleared |= MODE_LIMIT;
             channel->limit = 0;
             break;
+        case 'a':
+            cleared |= MODE_ACCESS;
+            channel->access = 0;
+            break;
         case 'b': cleared |= MODE_BAN; break;
         case 'D': cleared |= MODE_DELAYJOINS; break;
         case 'r': cleared |= MODE_REGONLY; break;
         case 'c': cleared |= MODE_NOCOLORS; break;
         case 'C': cleared |= MODE_NOCTCPS; break;
+        case 'M': cleared |= MODE_NOAMSGS; break;
+        case 'N': cleared |= MODE_NONOTICES; break;
         case 'z': cleared |= MODE_REGISTERED; break;
         }
     }