X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/9a75756eaec94f829e44129141f13ee01d050e8e..0f3e9cfc4b5d0f13085c975e10c0e6c4c8e5fbc3:/src/opserv.c diff --git a/src/opserv.c b/src/opserv.c index a344b2f..71fa774 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -369,6 +369,7 @@ typedef struct opservDiscrim { unsigned int match_opers : 1, option_log : 1; unsigned int chan_req_modes : 2, chan_no_modes : 2; int authed : 2, info_space : 2; + unsigned int intra_scmp : 2, intra_dcmp : 2; time_t min_ts, max_ts; unsigned int use_regex : 1; } *discrim_t; @@ -2757,6 +2758,8 @@ foreach_matching_user(const char *hostmask, discrim_search_func func, void *extr discrim->max_channels = INT_MAX; discrim->authed = -1; discrim->info_space = -1; + discrim->intra_scmp = 0; + discrim->intra_dcmp = 0; discrim->use_regex = 0; dupmask = strdup(hostmask); if (split_ircmask(dupmask, &discrim->mask_nick, &discrim->mask_ident, &discrim->mask_host)) { @@ -3231,6 +3234,8 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int discrim->max_channels = INT_MAX; discrim->authed = -1; discrim->info_space = -1; + discrim->intra_dcmp = 0; + discrim->intra_scmp = 0; for (i=0; iintra_dcmp = 1; + else if (!strcasecmp(tmp, "ident")) + discrim->intra_dcmp = 2; + else if (!strcasecmp(tmp, "info")) + discrim->intra_dcmp = 3; + } + } if (irccasecmp(argv[i], "mask") == 0) { if (!is_ircmask(argv[++i])) { send_message(user, bot, "OSMSG_INVALID_IRCMASK", argv[i]); @@ -3255,13 +3272,25 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int goto fail; } } else if (irccasecmp(argv[i], "nick") == 0) { - discrim->mask_nick = argv[++i]; + i++; + if (discrim->intra_dcmp > 0) + discrim->intra_scmp = 1; + else + discrim->mask_nick = argv[i]; } else if (irccasecmp(argv[i], "ident") == 0) { - discrim->mask_ident = argv[++i]; + i++; + if (discrim->intra_dcmp > 0) + discrim->intra_scmp = 2; + else + discrim->mask_ident = argv[i]; } else if (irccasecmp(argv[i], "host") == 0) { discrim->mask_host = argv[++i]; } else if (irccasecmp(argv[i], "info") == 0) { - discrim->mask_info = argv[++i]; + i++; + if (discrim->intra_dcmp > 0) + discrim->intra_scmp = 3; + else + discrim->mask_info = argv[i]; } else if (irccasecmp(argv[i], "server") == 0) { discrim->server = argv[++i]; } else if (irccasecmp(argv[i], "ip") == 0) { @@ -3507,6 +3536,7 @@ static int discrim_match(discrim_t discrim, struct userNode *user) { unsigned int access; + char *scmp=NULL, *dcmp=NULL; if ((user->timestamp < discrim->min_ts) || (user->timestamp > discrim->max_ts) @@ -3541,6 +3571,31 @@ discrim_match(discrim_t discrim, struct userNode *user) } } + if ((discrim->intra_scmp > 0 && discrim->intra_dcmp > 0)) { + switch(discrim->intra_scmp) { + case 1: scmp=user->nick; break; + case 2: scmp=user->ident; break; + case 3: + scmp=user->info; + if (discrim->info_space == 1) scmp++; + break; + } + switch(discrim->intra_dcmp) { + case 1: dcmp=user->nick; break; + case 2: dcmp=user->ident; break; + case 3: /* When checking INFO, and info_space is enabled + * ignore the first character in a search + * XXX: Should we ignore ALL leading whitespace? + * Also, what about ignoring ~ in ident? + */ + dcmp=user->info; + if (discrim->info_space == 1) dcmp++; + break; + } + if (irccasecmp(scmp,dcmp)) + return 0; + } + if (discrim->channel && !GetUserMode(discrim->channel, user)) return 0; access = user->handle_info ? user->handle_info->opserv_level : 0; if ((access < discrim->min_level)