From: Matthew Beeching Date: Sun, 23 Mar 2014 12:19:21 +0000 (+0000) Subject: Added support for multiple MARK marks X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/commitdiff_plain/df7819d997edca47cb4632196e4fa2a1fbbe14ef Added support for multiple MARK marks --- diff --git a/src/hash.h b/src/hash.h index 42112de..9f1f5e4 100644 --- a/src/hash.h +++ b/src/hash.h @@ -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 */ diff --git a/src/opserv.c b/src/opserv.c index f518b39..7a675b4 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -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; iimarks->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; iimarks->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)) ) diff --git a/src/proto-p10.c b/src/proto-p10.c index d3b5dd0..0cb2609 100644 --- a/src/proto-p10.c +++ b/src/proto-p10.c @@ -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; iimarks->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 */ 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; iimarks->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);