X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/df7819d997edca47cb4632196e4fa2a1fbbe14ef..2ef76f048b192a0993af0ec5071383951b1de5e3:/src/opserv.c diff --git a/src/opserv.c b/src/opserv.c index 7a675b4..4480881 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -189,6 +189,7 @@ static const struct message_entry msgtab[] = { { "OSMSG_HOP_DONE", "Halfopped the requested lusers." }, { "OSMSG_HOPALL_DONE", "Halfopped everyone on $b%s$b." }, { "OMSG_BAD_SVSNICK", "$b%s$b is an invalid nickname." }, + { "OSMSG_BAD_SVSCMDTARGET", "$b%s$b is an invalid target for %s." }, { "OSMSG_WHOIS_IDENT", "%s (%s@%s) from %d.%d.%d.%d" }, { "OSMSG_WHOIS_NICK", "Nick : %s" }, @@ -585,6 +586,7 @@ typedef enum { REACT_GLINE, REACT_TRACK, REACT_SHUN, + REACT_TEMPSHUN, REACT_SVSJOIN, REACT_SVSPART, REACT_VERSION, @@ -1530,6 +1532,12 @@ opserv_shun(struct userNode *target, char *src_handle, char *reason, unsigned lo return shun_add(src_handle, mask, duration, reason, now, 1); } +static void +opserv_tempshun(struct userNode *target, char *src_handle, char *reason) +{ + irc_tempshun(opserv, target, 0, reason); +} + static MODCMD_FUNC(cmd_sblock) { struct userNode *target; @@ -1725,6 +1733,11 @@ static MODCMD_FUNC(cmd_svsjoin) return 0; } + if (IsLocal(target)) { + reply("OSMSG_BAD_SVSCMDTARGET", argv[1], "SVSJOIN"); + return 0; + } + if (!(channel = GetChannel(argv[2]))) { channel = AddChannel(argv[2], now, NULL, NULL, NULL); } @@ -1746,6 +1759,12 @@ static MODCMD_FUNC(cmd_svsnick) reply("MSG_NICK_UNKNOWN", argv[1]); return 0; } + + if (IsLocal(target)) { + reply("OSMSG_BAD_SVSCMDTARGET", argv[1], "SVSNICK"); + return 0; + } + if(!is_valid_nick(argv[2])) { reply("OMSG_BAD_SVSNICK", argv[2]); return 0; @@ -1971,6 +1990,11 @@ static MODCMD_FUNC(cmd_svspart) return 0; } + if (IsLocal(target)) { + reply("OSMSG_BAD_SVSCMDTARGET", argv[1], "SVSPART"); + return 0; + } + if (!GetUserMode(target_channel, target)) { reply("OSMSG_NOT_ON_CHANNEL", cmd->parent->bot->nick, target_channel->name); return 0; @@ -2570,6 +2594,7 @@ static MODCMD_FUNC(cmd_stats_alerts) { case REACT_GLINE: reaction = "gline"; break; case REACT_TRACK: reaction = "track"; break; case REACT_SHUN: reaction = "shun"; break; + case REACT_TEMPSHUN: reaction = "tempshun"; break; case REACT_SVSJOIN: reaction = "svsjoin"; break; case REACT_SVSPART: reaction = "svspart"; break; case REACT_VERSION: reaction = "version"; break; @@ -4902,6 +4927,8 @@ add_user_alert(const char *key, void *data, UNUSED_ARG(void *extra)) reaction = REACT_TRACK; else if (!irccasecmp(react, "shun")) reaction = REACT_SHUN; + else if (!irccasecmp(react, "tempshun")) + reaction = REACT_TEMPSHUN; else if (!irccasecmp(react, "svsjoin")) reaction = REACT_SVSJOIN; else if (!irccasecmp(react, "svspart")) @@ -5197,6 +5224,7 @@ opserv_saxdb_write(struct saxdb_context *ctx) case REACT_GLINE: reaction = "gline"; break; case REACT_TRACK: reaction = "track"; break; case REACT_SHUN: reaction = "shun"; break; + case REACT_TEMPSHUN: reaction = "tempshun"; break; case REACT_SVSJOIN: reaction = "svsjoin"; break; case REACT_SVSPART: reaction = "svspart"; break; case REACT_VERSION: reaction = "version"; break; @@ -5785,70 +5813,80 @@ discrim_match(discrim_t discrim, struct userNode *user) if (discrim->modes) { unsigned int ii, matches = 0; + unsigned int negate = 0; for (ii = 0; ii < strlen(discrim->modes); ii++) { switch(discrim->modes[ii]) { + case '+': + negate = 0; + matches++; + break; + case '-': + negate = 1; + matches++; + break; case 'O': - if(IsOper(user)) matches++; + if(IsOper(user) != 0 != negate) matches++; break; case 'o': - if(IsOper(user)) matches++; + if(IsOper(user) != 0 != negate) matches++; break; case 'i': - if(IsInvisible(user)) matches++; + if(IsInvisible(user) != 0 != negate) matches++; break; case 'w': - if(IsWallOp(user)) matches++; + if(IsWallOp(user) != 0 != negate) matches++; break; case 'd': - if(IsDeaf(user)) matches++; + if(IsDeaf(user) != 0 != negate) matches++; break; case 'k': - if(IsService(user)) matches++; + if(IsService(user) != 0 != negate) matches++; break; case 'g': - if(IsGlobal(user)) matches++; + if(IsGlobal(user) != 0 != negate) matches++; break; case 'h': - if(IsSetHost(user)) matches++; + if(IsSetHost(user) != 0 != negate) matches++; break; case 'B': - if(IsBotM(user)) matches++; + if(IsBotM(user) != 0 != negate) matches++; break; + case 'p': case 'n': - if(IsHideChans(user)) matches++; + if(IsHideChans(user) != 0 != negate) matches++; break; case 'I': - if(IsHideIdle(user)) matches++; + if(IsHideIdle(user) != 0 != negate) matches++; break; case 'X': - if(IsXtraOp(user)) matches++; + if(IsXtraOp(user) != 0 != negate) matches++; break; case 'x': - if(IsHiddenHost(user)) matches++; + if(IsHiddenHost(user) != 0 != negate) matches++; break; case 'a': - if(IsAdmin(user)) matches++; + if(IsAdmin(user) != 0 != negate) matches++; break; case 'z': - if(IsSSL(user)) matches++; + if(IsSSL(user) != 0 != negate) matches++; break; case 'D': - if(IsPrivDeaf(user)) matches++; + if(IsPrivDeaf(user) != 0 != negate) matches++; break; case 'R': - if(IsAccountOnly(user)) matches++; + if(IsAccountOnly(user) != 0 != negate) matches++; break; case 'W': - if(IsWhoisNotice(user)) matches++; + if(IsWhoisNotice(user) != 0 != negate) matches++; break; case 'H': - if(IsHideOper(user)) matches++; + if(IsHideOper(user) != 0 != negate) matches++; break; case 'L': - if(IsHideOper(user)) matches++; + if(IsHideOper(user) != 0 != negate) matches++; break; case 'q': - if(IsCommonChansOnly(user)) matches++; + if(IsCommonChansOnly(user) != 0 != negate) matches++; break; } } @@ -6048,6 +6086,18 @@ trace_shun_func(struct userNode *match, void *extra) return 0; } +static int +trace_tempshun_func(struct userNode *match, void *extra) +{ + struct discrim_and_source *das = extra; + + if (is_oper_victim(das->source, match, das->discrim->match_opers, 1) && is_trust_victim(match, das->discrim->match_trusted)) { + opserv_tempshun(match, das->source->handle_info->handle, das->discrim->reason); + } + + return 0; +} + static int trace_kill_func(struct userNode *match, void *extra) { @@ -6285,6 +6335,8 @@ static MODCMD_FUNC(cmd_trace) action = trace_gline_func; else if (!irccasecmp(argv[1], "shun")) action = trace_shun_func; + else if (!irccasecmp(argv[1], "tempshun")) + action = trace_tempshun_func; else if (!irccasecmp(argv[1], "kill")) action = trace_kill_func; else if (!irccasecmp(argv[1], "gag")) @@ -6848,6 +6900,9 @@ alert_check_user(const char *key, void *data, void *extra) case REACT_SHUN: opserv_shun(user, alert->owner, alert->discrim->reason, alert->discrim->duration); return 1; + case REACT_TEMPSHUN: + opserv_tempshun(user, alert->owner, alert->discrim->reason); + return 1; case REACT_SVSJOIN: opserv_svsjoin(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget, alert->discrim->checkrestrictions); break; @@ -7061,6 +7116,8 @@ static MODCMD_FUNC(cmd_addalert) #endif } else if (!irccasecmp(argv[2], "shun")) reaction = REACT_SHUN; + else if(!irccasecmp(argv[2], "tempshun")) + reaction = REACT_TEMPSHUN; else if(!irccasecmp(argv[2], "svsjoin")) reaction = REACT_SVSJOIN; else if(!irccasecmp(argv[2], "svspart")) @@ -7362,6 +7419,7 @@ init_opserv(const char *nick) opserv_define_func("ADDALERT SILENT", NULL, 900, 0, 0); opserv_define_func("ADDALERT GLINE", NULL, 900, 0, 0); opserv_define_func("ADDALERT SHUN", NULL, 900, 0, 0); + opserv_define_func("ADDALERT TEMPSHUN", NULL, 900, 0, 0); opserv_define_func("ADDALERT TRACK", NULL, 900, 0, 0); opserv_define_func("ADDALERT KILL", NULL, 900, 0, 0); opserv_define_func("ADDALERT SVSJOIN", NULL, 999, 0, 0); @@ -7475,6 +7533,7 @@ init_opserv(const char *nick) opserv_define_func("TRACE DOMAINS", NULL, 0, 0, 0); opserv_define_func("TRACE GLINE", NULL, 600, 0, 0); opserv_define_func("TRACE SHUN", NULL, 600, 0, 0); + opserv_define_func("TRACE TEMPSHUN", NULL, 600, 0, 0); opserv_define_func("TRACE GAG", NULL, 600, 0, 0); opserv_define_func("TRACE KILL", NULL, 600, 0, 0); opserv_define_func("TRACE VERSION", NULL, 999, 0, 0);