general support for Channel Mode +NMFa and User Mode +SDXHst
authorpk910 <philipp@zoelle1.de>
Thu, 7 Jul 2011 20:37:06 +0000 (22:37 +0200)
committerpk910 <philipp@zoelle1.de>
Thu, 7 Jul 2011 20:40:22 +0000 (22:40 +0200)
src/hash.h
src/proto-common.c
src/proto-p10.c
src/proto.h

index 582561fd5f37292638933ae3fc0595ed096b07ea..510f5f78463af91607c79ddbb6e93c510bc845d0 100644 (file)
 #define MODE_REGISTERED     0x8000 /* Bahamut +r */
 #define MODE_APASS          0x10000 /* +A adminpass */
 #define MODE_UPASS          0x20000 /* +U userpass */
+#define MODE_NONOTICES      0x40000 /* +N */
+#define MODE_NOAMSGS        0x80000 /* +M */
+#define MODE_ALTCHAN        0x100000 /* +F */
+#define MODE_ACCESS         0x200000 /* +a */
 #define MODE_REMOVE         0x80000000
 
-#define FLAGS_OPER          0x0001 /* global operator +o */
-#define FLAGS_INVISIBLE     0x0004 /* invisible +i */
-#define FLAGS_WALLOP        0x0008 /* receives wallops +w */
-#define FLAGS_DEAF          0x0020 /* deaf +d */
-#define FLAGS_SERVICE       0x0040 /* cannot be kicked, killed or deoped +k */
-#define FLAGS_GLOBAL        0x0080 /* receives global messages +g */
-#define FLAGS_NOCHAN        0x0100 /* hide channels in whois +n */
+#define FLAGS_OPER          0x0001 /* +o global operator */
+#define FLAGS_INVISIBLE     0x0004 /* +i invisible */
+#define FLAGS_WALLOP        0x0008 /* +w receives wallops */
+#define FLAGS_DEAF          0x0020 /* +d deaf */
+#define FLAGS_SERVICE       0x0040 /* +k cannot be kicked, killed or deoped */
+#define FLAGS_GLOBAL        0x0080 /* +g receives global messages */
+#define FLAGS_NOCHAN        0x0100 /* +n hide channels in whois */
 #define FLAGS_PERSISTENT    0x0200 /* for reserved nicks, this isn't just one-shot */
 #define FLAGS_GAGGED        0x0400 /* for gagged users */
 #define FLAGS_AWAY          0x0800 /* for away users */
 #define FLAGS_STAMPED       0x1000 /* for users who have been stamped */
-#define FLAGS_HIDDEN_HOST   0x2000 /* user's host is masked by their account */
-#define FLAGS_REGNICK       0x4000 /* user owns their current nick */
+#define FLAGS_HIDDEN_HOST   0x2000 /* +x user's host is masked by their account */
+#define FLAGS_REGNICK       0x4000 /* +r user owns their current nick */
 #define FLAGS_REGISTERING   0x8000 /* user has issued account register command, is waiting for email cookie */
 #define FLAGS_DUMMY         0x10000 /* user is not announced to other servers */
-#define FLAGS_NOIDLE        0x20000 /* hide idle time in whois +I */
+#define FLAGS_NOIDLE        0x20000 /* +I hide idle time in whois */
+#define FLAGS_NETSERV       0x40000 /* +S */
+#define FLAGS_SECURITYSERV  0x80000 /* +D */
+#define FLAGS_XTRAOP        0x100000 /* +X */
+#define FLAGS_HIDDENOPER    0x200000 /* +H */
+#define FLAGS_SERVERNOTICE  0x400000 /* +s */
+#define FLAGS_SEENOIDLE     0x800000 /* +t */
 
 #define IsOper(x)               ((x)->modes & FLAGS_OPER)
 #define IsService(x)            ((x)->modes & FLAGS_SERVICE)
 #define IsRegistering(x)        ((x)->modes & FLAGS_REGISTERING)
 #define IsDummy(x)              ((x)->modes & FLAGS_DUMMY)
 #define IsNoIdle(x)             ((x)->modes & FLAGS_NOIDLE)
+#define IsSecurityServ(x)       ((x)->modes & FLAGS_SECURITYSERV)
+#define IsNetServ(x)            ((x)->modes & FLAGS_NETSERV)
+#define IsXtraOp(x)             ((x)->modes & FLAGS_XTRAOP)
+#define IsServerNotice(x)       ((x)->modes & FLAGS_SERVERNOTICE)
+#define IsHiddenOper(x)         ((x)->modes & FLAGS_HIDDENOPER)
+#define IsSeeNoIdle(x)          ((x)->modes & FLAGS_SEENOIDLE)
 #define IsFakeHost(x)           ((x)->fakehost[0] != '\0')
 #define IsFakeIdent(x)          ((x)->fakeident[0] != '\0')
 #define IsLocal(x)              ((x)->uplink == self)
@@ -131,8 +147,10 @@ struct userNode {
 struct chanNode {
     chan_mode_t modes;
     unsigned int limit;
+    unsigned int access;
     unsigned int locks;
     char key[KEYLEN + 1];
+    char altchan[CHANNELLEN + 1];
     char upass[KEYLEN + 1];
     char apass[KEYLEN + 1];
     unsigned long timestamp; /* creation time */
index 26087308bd4fcbac7828890f625aa446195f8787..e71bacd6959323c24896f048f382338c66d6f8a0 100644 (file)
@@ -599,6 +599,8 @@ mod_chanmode_dup(struct mod_chanmode *orig, unsigned int extra)
         res->modes_set = orig->modes_set;
         res->modes_clear = orig->modes_clear;
         res->new_limit = orig->new_limit;
+        res->new_access = orig->new_access;
+        memcpy(res->new_altchan, orig->new_altchan, sizeof(res->new_altchan));
         memcpy(res->new_key, orig->new_key, sizeof(res->new_key));
         memcpy(res->new_upass, orig->new_upass, sizeof(res->new_upass));
         memcpy(res->new_apass, orig->new_apass, sizeof(res->new_apass));
@@ -618,8 +620,12 @@ mod_chanmode_apply(struct userNode *who, struct chanNode *channel, struct mod_ch
     channel->modes = (channel->modes & ~change->modes_clear) | change->modes_set;
     if (change->modes_set & MODE_LIMIT)
         channel->limit = change->new_limit;
+    if (change->modes_set & MODE_ACCESS)
+        channel->access = change->new_access;
     if (change->modes_set & MODE_KEY)
         strcpy(channel->key, change->new_key);
+    if (change->modes_set & MODE_ALTCHAN)
+        strcpy(channel->altchan, change->new_altchan);
     if (change->modes_set & MODE_UPASS)
        strcpy(channel->upass, change->new_upass);
     if (change->modes_set & MODE_APASS)
@@ -716,6 +722,8 @@ irc_make_chanmode(struct chanNode *chan, char *out)
     mod_chanmode_init(&change);
     change.modes_set = chan->modes;
     change.new_limit = chan->limit;
+    change.new_access = chan->access;
+    safestrncpy(change.new_altchan, chan->altchan, sizeof(change.new_altchan));
     safestrncpy(change.new_key, chan->key, sizeof(change.new_key));
     safestrncpy(change.new_upass, chan->upass, sizeof(change.new_upass));
     safestrncpy(change.new_apass, chan->apass, sizeof(change.new_apass));
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;
         }
     }
index 99ca1099703fddf03aa3fd6b69d0e93de99dea48..92bd7ed6ed37177c3825a39bf65bfc56684e5484 100644 (file)
@@ -181,6 +181,7 @@ unsigned int irc_user_modes(const struct userNode *user, char modes[], size_t le
 
 /* Channel mode manipulation */
 #define KEYLEN          23
+#define CHANNELLEN      200
 typedef unsigned long chan_mode_t;
 /* Rules for struct mod_chanmode:
  * For a membership mode change, args[n].mode can contain more than
@@ -189,11 +190,12 @@ typedef unsigned long chan_mode_t;
  */
 struct mod_chanmode {
     chan_mode_t modes_set, modes_clear;
-    unsigned int new_limit, argc;
+    unsigned int new_limit, new_access, argc;
 #ifndef NDEBUG
     unsigned int alloc_argc;
 #endif
     char new_key[KEYLEN + 1];
+    char new_altchan[CHANNELLEN + 1];
     char new_upass[KEYLEN + 1];
     char new_apass[KEYLEN + 1];
     struct {
@@ -204,15 +206,16 @@ struct mod_chanmode {
         } u;
     } args[1];
 };
-#define MCP_ALLOW_OVB     0x0001 /* allow op, voice, ban manipulation */
-#define MCP_FROM_SERVER   0x0002 /* parse as from a server */
-#define MCP_KEY_FREE      0x0004 /* -k without a key argument */
-#define MCP_REGISTERED    0x0008 /* chan is already registered; do not allow changes to MODE_REGISTERED */
-#define MCP_UPASS_FREE    0x0010 /* -U without a key argument */
-#define MCP_APASS_FREE    0x0020 /* -A without a key argument */
-#define MCP_NO_APASS      0x0040 /* Do not allow +/-A or +/-U */
-#define MC_ANNOUNCE       0x0100 /* send a mod_chanmode() change out */
-#define MC_NOTIFY         0x0200 /* make local callbacks to announce */
+#define MCP_ALLOW_OVB      0x0001 /* allow op, voice, ban manipulation */
+#define MCP_FROM_SERVER    0x0002 /* parse as from a server */
+#define MCP_KEY_FREE       0x0004 /* -k without a key argument */
+#define MCP_REGISTERED     0x0008 /* chan is already registered; do not allow changes to MODE_REGISTERED */
+#define MCP_UPASS_FREE     0x0010 /* -U without a key argument */
+#define MCP_APASS_FREE     0x0020 /* -A without a key argument */
+#define MCP_NO_APASS       0x0040 /* Do not allow +/-A or +/-U */
+#define MCP_IGN_REGISTERED 0x0080 /* chan is already registered; ignore changes to MODE_REGISTERED */
+#define MC_ANNOUNCE        0x0100 /* send a mod_chanmode() change out */
+#define MC_NOTIFY          0x0200 /* make local callbacks to announce */
 #ifdef NDEBUG
 #define mod_chanmode_init(CHANMODE) do { memset((CHANMODE), 0, sizeof(*CHANMODE)); } while (0)
 #else