]> jfr.im git - irc/evilnet/x3.git/commitdiff
Added support for multiple MARK marks
authorMatthew Beeching <redacted>
Sun, 23 Mar 2014 12:19:21 +0000 (12:19 +0000)
committerMatthew Beeching <redacted>
Sun, 23 Mar 2014 12:19:21 +0000 (12:19 +0000)
src/hash.h
src/opserv.c
src/proto-p10.c

index 42112de4a6adca7fecd8f56a26f225f88a375bf0..9f1f5e47bda097077ec441c24cccf29dfcac1bb3 100644 (file)
@@ -24,6 +24,7 @@
 #include "common.h"
 #include "dict.h"
 #include "policer.h"
+#include "recdb.h"
 
 #define MODE_CHANOP            0x00000001 /* +o USER */
 #define MODE_VOICE             0x00000002 /* +v USER */
@@ -246,6 +247,8 @@ struct userNode {
     char *version_reply;          /* only filled in if a version query was triggered */
     char *sslfp;                  /* only filled in if a mark SSLCLIFP is received */
 
+    struct string_list *marks;    /* list of user's marks */
+
     time_t timestamp;             /* Time of last nick change */
     time_t idle_since;
     struct server *uplink;        /* Server that user is connected to */
index f518b39dbdb047c7a2cc79b0c26a855a0826e42a..7a675b4de97794e0a03c4b64fd7fdc475bb9b9de 100644 (file)
@@ -218,7 +218,8 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_WHOIS_HIDECHANS",  "Channel list omitted for your sanity." },
     { "OSMSG_WHOIS_VERSION",    "Version      : %s" },  
     { "OSMSG_WHOIS_SSLFP",      "SSL f/print  : %s" },
-    { "OSMSG_WHOIS_MARK",       "Mark         : %s" },  
+    { "OSMSG_WHOIS_MARK",       "Mark         : %s" },
+    { "OSMSG_WHOIS_MARKS",      "Marks        : %s" },
     { "OSMSG_WHOIS_NO_NOTICE",  "No_notices   : %s" },
     { "OSMSG_UNBAN_DONE", "Ban(s) removed from channel %s." },
     { "OSMSG_CHANNEL_VOICED", "All users on %s voiced." },
@@ -2193,6 +2194,28 @@ static MODCMD_FUNC(cmd_whois)
     if(target->mark) {
         reply("OSMSG_WHOIS_MARK", target->mark);
     }
+    if(target->marks) {
+        char markbuf[MAXLEN] = "";
+        unsigned int ii = 0;
+
+        string_list_sort(user->marks);
+
+        for (ii=0; ii<user->marks->used; ii++)
+        {
+            if (markbuf[0] && strlen(markbuf) + strlen(user->marks->list[ii]) + 4 > 70) {
+                reply("OSMSG_WHOIS_MARKS", markbuf);
+                memset(&markbuf, 0, MAXLEN);
+            }
+
+            if (markbuf[0])
+                strcat(markbuf, ", ");
+            strcat(markbuf, user->marks->list[ii]);
+        }
+
+        if (markbuf[0])
+            reply("OSMSG_WHOIS_MARKS", markbuf);
+    }
+
     reply("OSMSG_WHOIS_NO_NOTICE", target->no_notice ? "YES":"NO");
   
     if (target->modes) {
@@ -5680,6 +5703,20 @@ discrim_match(discrim_t discrim, struct userNode *user)
 {
     unsigned int level, i;
     char *scmp=NULL, *dcmp=NULL;
+    int markmatched = 0;
+
+    if (discrim->mask_mark)
+    {
+        unsigned int ii = 0;
+
+        if (user->mark && match_ircglob(user->mark, discrim->mask_mark))
+            markmatched = 1;
+
+        if (user->marks)
+            for (ii=0; ii<user->marks->used; ii++)
+                if (match_ircglob(user->marks->list[ii], discrim->mask_mark))
+                    markmatched = 1;
+    }
 
     if ((user->timestamp < discrim->min_ts)
         || (user->timestamp > discrim->max_ts)
@@ -5690,7 +5727,7 @@ discrim_match(discrim_t discrim, struct userNode *user)
         || (discrim->info_space == 0 && user->info[0] == ' ')
         || (discrim->info_space == 1 && user->info[0] != ' ')
         || (discrim->server && !match_ircglob(user->uplink->name, discrim->server))
-        || (discrim->mask_mark && (!user->mark || !match_ircglob(user->mark, discrim->mask_mark)))
+        || (discrim->mask_mark && !markmatched)
         || (discrim->accountmask && (!user->handle_info || !match_ircglob(user->handle_info->handle, discrim->accountmask)))
         || (discrim->ip_mask_bits && !irc_check_mask(&user->ip, &discrim->ip_mask, discrim->ip_mask_bits))
         )
index d3b5dd0d0bfc82e59551719f3f43934ce264ce62..0cb26091b7b7ce5a65caff3ffab2faee4652ed7e 100644 (file)
@@ -1183,10 +1183,8 @@ irc_mark(struct userNode *user, char *mark)
     char *host = user->hostname;
     int type = 4;
     const char *tstr = NULL;
-
-    /* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */
-    if(user->mark)
-        return;
+    unsigned int ii = 0;
+    int markfound = 0;
 
     tstr = conf_get_data("server/type", RECDB_QSTRING);
     if(tstr)
@@ -1194,12 +1192,28 @@ irc_mark(struct userNode *user, char *mark)
     else
         type = 4;
 
+    if (user->marks)
+        for (ii=0; ii<user->marks->used; ii++)
+            if (!irccasecmp(user->marks->list[ii], mark))
+                markfound = 1;
+
+    if (!markfound)
+    {
+        if (!user->marks)
+            user->marks = alloc_string_list(1);
+        string_list_append(user->marks, strdup(mark));
+    }
+
     if (type >= 9)
     {
         putsock("%s " CMD_MARK " %s MARK %s", self->numeric, user->nick, mark);
         return;
     }
 
+    /* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */
+    if(user->mark)
+        return;
+
     /* if the mark will put us over the  host length, clip some off the left hand side
      * to make room...
      */
@@ -1992,25 +2006,47 @@ static CMD_FUNC(cmd_burst)
  */
 static CMD_FUNC(cmd_mark)
 {
+    const char *tstr;
+    int type = 4;
     struct userNode *target;
     /* 
      * log_module(MAIN_LOG, LOG_ERROR, "DEBUG: mark, user %s, type %s, arg %s", argv[1], argv[2], argv[3]);
      */
 
+    tstr = conf_get_data("server/type", RECDB_QSTRING);
+    if(tstr)
+       type = atoi(tstr);
+    else
+       type = 4;/* default to 040 style topics */
+
     if(argc < 4)
         return 0;
     if(!strcasecmp(argv[2], "DNSBL")) {
         /* DNSBL <modes> */
         return 1;
     }
-    else if(!strcasecmp(argv[2], "DNSBL_DATA")) {
+    else if(!strcasecmp(argv[2], "DNSBL_DATA") || !strcasecmp(argv[2], "MARK")) {
+        int markfound = 0;
+        unsigned int ii = 0;
         /* DNSBL_DATA name */
         target = GetUserH(argv[1]);
         if(!target) {
             log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose dnsbl mark is changing.", argv[1]);
             return 0;
         }
-        target->mark = strdup(argv[3]);
+        if (type >= 9) {
+            if (target->marks)
+                for (ii=0; ii<target->marks->used; ii++)
+                    if (!irccasecmp(target->marks->list[ii], argv[3]))
+                         markfound = 1;
+            if (!markfound)
+            {
+                if (!target->marks)
+                    target->marks = alloc_string_list(1);
+                string_list_append(target->marks, strdup(argv[3]));
+            }
+        } else
+            target->mark = strdup(argv[3]);
         return 1;
         
     }
@@ -3256,6 +3292,8 @@ DelUser(struct userNode* user, struct userNode *killer, int announce, const char
         free(user->mark);
         user->mark = NULL;
     }
+    free_string_list(user->marks);
+    user->marks = NULL;
 
     /* clean up geoip data if any */
     if(user->country_code) free(user->country_code);