X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/d82cf2f04a924c6531bde34c6557038880da9c73..8dc0685213ead3f8896c83cadc130143ccc4d181:/src/opserv.c diff --git a/src/opserv.c b/src/opserv.c index d8eed23..7f3e0cc 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -18,6 +18,8 @@ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include "config.h" +#include "chanserv.h" #include "conf.h" #include "common.h" #include "gline.h" @@ -205,6 +207,7 @@ static const struct message_entry msgtab[] = { { "OSMSG_WHOIS_CHANNELS", "Channels : %s" }, { "OSMSG_WHOIS_HIDECHANS", "Channel list omitted for your sanity." }, { "OSMSG_WHOIS_VERSION", "Version : %s" }, + { "OSMSG_WHOIS_MARK", "Mark : %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." }, @@ -523,7 +526,7 @@ opserv_free_waiting_connection(void *data) typedef struct opservDiscrim { struct chanNode *channel; - char *mask_nick, *mask_ident, *mask_host, *mask_info, *mask_version, *server, *reason, *accountmask, *chantarget, *mark; + char *mask_nick, *mask_ident, *mask_host, *mask_info, *mask_version, *server, *reason, *accountmask, *chantarget, *mark, *mask_mark; irc_in_addr_t ip_mask; unsigned long limit; time_t min_ts, max_ts; @@ -537,6 +540,7 @@ typedef struct opservDiscrim { unsigned int intra_scmp : 2, intra_dcmp : 2; unsigned int use_regex : 1; unsigned int silent : 1; + unsigned int checkrestrictions : 2; } *discrim_t; struct discrim_and_source { @@ -1370,7 +1374,7 @@ opserv_mark(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG(ch } static void -opserv_svsjoin(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG(char *reason), char *channame) +opserv_svsjoin(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG(char *reason), char *channame, unsigned int checkrestrictions) { struct chanNode *channel; @@ -1387,6 +1391,26 @@ opserv_svsjoin(struct userNode *target, UNUSED_ARG(char *src_handle), UNUSED_ARG return; } + if (checkrestrictions) { + if (trace_check_bans(target, channel) == 1) { + return; /* found on lamer list */ + } + + if (channel->modes & MODE_INVITEONLY) { + return; /* channel is invite only */ + } + + if (channel->limit > 0) { + if (channel->members.used >= channel->limit) { + return; /* channel is invite on */ + } + } + + if (*channel->key) { + return; /* channel is password protected */ + } + } + irc_svsjoin(opserv, target, channel); /* Should we tell the user they got joined? -Rubin*/ } @@ -2015,6 +2039,9 @@ static MODCMD_FUNC(cmd_whois) if(target->version_reply) { reply("OSMSG_WHOIS_VERSION", target->version_reply); } + if(target->mark) { + reply("OSMSG_WHOIS_MARK", target->mark); + } reply("OSMSG_WHOIS_NO_NOTICE", target->no_notice ? "YES":"NO"); if (target->modes) { @@ -2784,7 +2811,7 @@ opserv_notice_handler(struct userNode *user, struct userNode *bot, char *text, U if(text[0] == '\001') { text++; cmd = mysep(&text, " "); - if(!irccasecmp(cmd, "VERSION")) { + if(cmd && !irccasecmp(cmd, "VERSION")) { char *version = mysep(&text, "\n"); if(!version) version = ""; @@ -5173,12 +5200,24 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int } discrim->accountmask = argv[++i]; discrim->authed = 1; + } else if (irccasecmp(argv[i], "marked") == 0) { + discrim->mask_mark = argv[++i]; } else if (irccasecmp(argv[i], "chantarget") == 0) { if(!IsChannelName(argv[i+1])) { send_message(user, bot, "MSG_NOT_CHANNEL_NAME"); goto fail; } discrim->chantarget = argv[++i]; + } else if (irccasecmp(argv[i], "checkrestrictions") == 0) { + i++; + if (true_string(argv[i])) { + discrim->checkrestrictions = 1; + } else if (false_string(argv[i])) { + discrim->checkrestrictions = 0; + } else { + send_message(user, bot, "MSG_INVALID_BINARY", argv[i]); + goto fail; + } } else if (irccasecmp(argv[i], "mark") == 0) { if(!is_valid_mark(argv[i+1])) { send_message(user, bot, "OSMSG_MARK_INVALID"); @@ -5458,6 +5497,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->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)) ) @@ -5682,6 +5722,7 @@ trace_svsjoin_func(struct userNode *match, void *extra) struct discrim_and_source *das = extra; char *channame = das->discrim->chantarget; + int checkrestrictions = das->discrim->checkrestrictions; struct chanNode *channel; if(!channame || !IsChannelName(channame)) { @@ -5692,6 +5733,27 @@ trace_svsjoin_func(struct userNode *match, void *extra) if (!(channel = GetChannel(channame))) { channel = AddChannel(channame, now, NULL, NULL, NULL); } + + if (checkrestrictions) { + if (trace_check_bans(match, channel) == 1) { + return 1; /* found on lamer list */ + } + + if (channel->modes & MODE_INVITEONLY) { + return 1; /* channel is invite only */ + } + + if (channel->limit > 0) { + if (channel->members.used >= channel->limit) { + return 1; /* channel is invite on */ + } + } + + if (*channel->key) { + return 1; /* channel is password protected */ + } + } + if (GetUserMode(channel, match)) { // reply("OSMSG_ALREADY_THERE", channel->name); return 1; @@ -6366,7 +6428,7 @@ alert_check_user(const char *key, void *data, void *extra) opserv_shun(user, alert->owner, alert->discrim->reason, alert->discrim->duration); return 1; case REACT_SVSJOIN: - opserv_svsjoin(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget); + opserv_svsjoin(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget, alert->discrim->checkrestrictions); break; case REACT_SVSPART: opserv_svspart(user, alert->owner, alert->discrim->reason, alert->discrim->chantarget);