X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/5a1daaaba65bb61921c1274fd8672cb91bae4268..f977edfa98c2e2e62bb302af7e97d8729c7d6202:/src/opserv.c diff --git a/src/opserv.c b/src/opserv.c index 6c8cd14..216c4d3 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -78,9 +78,9 @@ #define KEY_ISSUED "issued" #define KEY_ADMIN_LEVEL "admin_level" -#define IDENT_FORMAT "%s [%s@%s/%s]" -#define IDENT_DATA(user) user->nick, user->ident, user->hostname, inet_ntoa(user->ip) -#define MAX_CHANNELS_WHOIS 50 +#define IDENT_FORMAT "%s [%s@%s/%s]" +#define IDENT_DATA(user) user->nick, user->ident, user->hostname, inet_ntoa(user->ip) +#define MAX_CHANNELS_WHOIS 50 #define OSMSG_PART_REASON "%s has no reason." #define OSMSG_KICK_REQUESTED "Kick requested by %s." #define OSMSG_KILL_REQUESTED "Kill requested by %s." @@ -278,6 +278,7 @@ static const struct message_entry msgtab[] = { typedef int (*discrim_search_func)(struct userNode *match, void *extra); struct userNode *opserv; +static struct service *opserv_service; /*static dict_t opserv_chan_warn; */ /* data is char* */ static dict_t opserv_reserved_nick_dict; /* data is struct userNode* */ @@ -355,11 +356,12 @@ typedef struct opservDiscrim { struct discrim_and_source { discrim_t discrim; struct userNode *source; + struct userNode *destination; dict_t dict; unsigned int disp_limit; }; -static discrim_t opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], int allow_channel); +static discrim_t opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[], int allow_channel); static unsigned int opserv_discrim_search(discrim_t discrim, discrim_search_func dsf, void *data); static int gag_helper_func(struct userNode *match, void *extra); static int ungag_helper_func(struct userNode *match, void *extra); @@ -412,7 +414,7 @@ static MODCMD_FUNC(cmd_access) } if (!(hi = modcmd_get_handle_info(user, target))) return 0; - res = (argc > 2) ? oper_try_set_access(user, cmd->parent->bot, hi, strtoul(argv[2], NULL, 0)) : 0; + res = (argc > 2) ? oper_try_set_access(user, opserv_service->bot, hi, strtoul(argv[2], NULL, 0)) : 0; reply("OSMSG_USER_ACCESS_IS", target, hi->handle, hi->opserv_level); return res; } @@ -430,8 +432,8 @@ static MODCMD_FUNC(cmd_ban) else if ((victim = GetUserH(argv[1]))) change.args[0].u.hostmask = generate_hostmask(victim, 0); else { - reply("OSMSG_INVALID_IRCMASK", argv[1]); - return 0; + reply("OSMSG_INVALID_IRCMASK", argv[1]); + return 0; } modcmd_chanmode_announce(&change); reply("OSMSG_ADDED_BAN", change.args[0].u.hostmask, channel->name); @@ -462,17 +464,17 @@ static MODCMD_FUNC(cmd_chaninfo) strftime(buffer, sizeof(buffer), fmt, gmtime(&channel->topic_time)); send_message_type(4, user, cmd->parent->bot, buffer, channel->topic_nick, channel->topic); } else { - irc_fetchtopic(cmd->parent->bot, channel->name); - reply("OSMSG_CHANINFO_TOPIC_UNKNOWN"); + irc_fetchtopic(cmd->parent->bot, channel->name); + reply("OSMSG_CHANINFO_TOPIC_UNKNOWN"); } if (channel->banlist.used) { - reply("OSMSG_CHANINFO_BAN_COUNT", channel->banlist.used); + reply("OSMSG_CHANINFO_BAN_COUNT", channel->banlist.used); fmt = user_find_message(user, "OSMSG_CHANINFO_BAN"); - for (n = 0; n < channel->banlist.used; n++) { - ban = channel->banlist.list[n]; - strftime(buffer, sizeof(buffer), fmt, localtime(&ban->set)); - send_message_type(4, user, cmd->parent->bot, buffer, ban->ban, ban->who); - } + for (n = 0; n < channel->banlist.used; n++) { + ban = channel->banlist.list[n]; + strftime(buffer, sizeof(buffer), fmt, localtime(&ban->set)); + send_message_type(4, user, cmd->parent->bot, buffer, ban->ban, ban->who); + } } if (channel->exemptlist.used) { reply("OSMSG_CHANINFO_EXEMPT_COUNT", channel->exemptlist.used); @@ -490,8 +492,8 @@ static MODCMD_FUNC(cmd_chaninfo) } reply("OSMSG_CHANINFO_USER_COUNT", channel->members.used); for (n=0; nmembers.used; n++) { - moden = channel->members.list[n]; - if (moden->modes & MODE_CHANOP) + moden = channel->members.list[n]; + if (moden->modes & MODE_CHANOP) send_message_type(4, user, cmd->parent->bot, " @%s (%s@%s)", moden->user->nick, moden->user->ident, moden->user->hostname); } for (n=0; nmembers.used; n++) { @@ -500,13 +502,13 @@ static MODCMD_FUNC(cmd_chaninfo) send_message_type(4, user, cmd->parent->bot, " %s%s (%s@%s)", "%", moden->user->nick, moden->user->ident, moden->user->hostname); } for (n=0; nmembers.used; n++) { - moden = channel->members.list[n]; - if ((moden->modes & (MODE_CHANOP|MODE_HALFOP|MODE_VOICE)) == MODE_VOICE) + moden = channel->members.list[n]; + if ((moden->modes & (MODE_CHANOP|MODE_HALFOP|MODE_VOICE)) == MODE_VOICE) send_message_type(4, user, cmd->parent->bot, " +%s (%s@%s)", moden->user->nick, moden->user->ident, moden->user->hostname); } for (n=0; nmembers.used; n++) { - moden = channel->members.list[n]; - if ((moden->modes & (MODE_CHANOP|MODE_HALFOP|MODE_VOICE)) == 0) + moden = channel->members.list[n]; + if ((moden->modes & (MODE_CHANOP|MODE_HALFOP|MODE_VOICE)) == 0) send_message_type(4, user, cmd->parent->bot, " %s (%s@%s)", moden->user->nick, moden->user->ident, moden->user->hostname); } return 1; @@ -519,8 +521,8 @@ static MODCMD_FUNC(cmd_warn) char *reason, *message; if (!IsChannelName(argv[1])) { - reply("OSMSG_NEED_CHANNEL", argv[0]); - return 0; + reply("OSMSG_NEED_CHANNEL", argv[0]); + return 0; } reason = dict_find(opserv_chan_warn, argv[1], NULL); if (reason) { @@ -545,7 +547,7 @@ static MODCMD_FUNC(cmd_unwarn) { if ((argc < 2) || !IsChannelName(argv[1])) { reply("OSMSG_NEED_CHANNEL", argv[0]); - return 0; + return 0; } if (!dict_remove(opserv_chan_warn, argv[1])) { reply("OSMSG_WARN_NOEXIST", argv[1]); @@ -579,7 +581,7 @@ static MODCMD_FUNC(cmd_clearmodes) struct mod_chanmode change; if (!channel->modes) { - reply("OSMSG_NO_CHANNEL_MODES", channel->name); + reply("OSMSG_NO_CHANNEL_MODES", channel->name); return 0; } mod_chanmode_init(&change); @@ -598,7 +600,7 @@ static MODCMD_FUNC(cmd_deop) for (arg = 1, count = 0; arg < argc; ++arg) { struct userNode *victim = GetUserH(argv[arg]); struct modeNode *mn; - if (!victim || IsService(victim) + if (!victim || IsService(victim) || !(mn = GetUserMode(channel, victim)) || !(mn->modes & MODE_CHANOP)) continue; @@ -646,8 +648,8 @@ static MODCMD_FUNC(cmd_deopall) change = mod_chanmode_alloc(channel->members.used); for (ii = count = 0; ii < channel->members.used; ++ii) { - struct modeNode *mn = channel->members.list[ii]; - if (IsService(mn->user) || !(mn->modes & MODE_CHANOP)) + struct modeNode *mn = channel->members.list[ii]; + if (IsService(mn->user) || !(mn->modes & MODE_CHANOP)) continue; change->args[count].mode = MODE_REMOVE | MODE_CHANOP; change->args[count++].u.member = mn; @@ -688,9 +690,9 @@ static MODCMD_FUNC(cmd_rehash) extern char *services_config; if (conf_read(services_config)) - reply("OSMSG_REHASH_COMPLETE"); + reply("OSMSG_REHASH_COMPLETE"); else - reply("OSMSG_REHASH_FAILED"); + reply("OSMSG_REHASH_FAILED"); return 1; } @@ -775,14 +777,14 @@ static MODCMD_FUNC(cmd_jump) target = unsplit_string(argv+1, argc-1, NULL); if (!strcmp(cManager.uplink->name, target)) { - reply("OSMSG_CURRENT_UPLINK", cManager.uplink->name); - return 0; + reply("OSMSG_CURRENT_UPLINK", cManager.uplink->name); + return 0; } uplink = uplink_find(target); if (!uplink) { - reply("OSMSG_INVALID_UPLINK", target); - return 0; + reply("OSMSG_INVALID_UPLINK", target); + return 0; } if (uplink->flags & UPLINK_UNAVAILABLE) { reply("OSMSG_UPLINK_DISABLED", uplink->name); @@ -854,12 +856,12 @@ static MODCMD_FUNC(cmd_block) target = GetUserH(argv[1]); if (!target) { - reply("MSG_NICK_UNKNOWN", argv[1]); - return 0; + reply("MSG_NICK_UNKNOWN", argv[1]); + return 0; } if (IsService(target)) { - reply("MSG_SERVICE_IMMUNE", target->nick); - return 0; + reply("MSG_SERVICE_IMMUNE", target->nick); + return 0; } reason = (argc > 2) ? unsplit_string(argv+2, argc-2, NULL) : NULL; gline = opserv_block(target, user->handle_info->handle, reason, 0); @@ -875,8 +877,8 @@ static MODCMD_FUNC(cmd_gline) reason = unsplit_string(argv+3, argc-3, NULL); if (!is_gline(argv[1]) && !IsChannelName(argv[1]) && (argv[1][0] != '&')) { - reply("MSG_INVALID_GLINE", argv[1]); - return 0; + reply("MSG_INVALID_GLINE", argv[1]); + return 0; } if (!argv[1][strspn(argv[1], "#&*?@.")] && (strlen(argv[1]) < 10)) { reply("OSMSG_STUPID_GLINE", argv[1]); @@ -938,26 +940,26 @@ opserv_ison(struct userNode *tell, struct userNode *target, const char *message) if (!maxlen) maxlen = MAX_LINE_SIZE; for (n=count=0; nchannels.used; n++) { - mn = target->channels.list[n]; - here_len = strlen(mn->channel->name); - if ((count + here_len + 4) > maxlen) { - buff[count] = 0; + mn = target->channels.list[n]; + here_len = strlen(mn->channel->name); + if ((count + here_len + 4) > maxlen) { + buff[count] = 0; send_message(tell, opserv, message, buff); - count = 0; - } - if (mn->modes & MODE_CHANOP) + count = 0; + } + if (mn->modes & MODE_CHANOP) buff[count++] = '@'; if (mn->modes & MODE_HALFOP) buff[count++] = '%'; - if (mn->modes & MODE_VOICE) + if (mn->modes & MODE_VOICE) buff[count++] = '+'; - memcpy(buff+count, mn->channel->name, here_len); - count += here_len; - buff[count++] = ' '; + memcpy(buff+count, mn->channel->name, here_len); + count += here_len; + buff[count++] = ' '; } if (count) { - buff[count] = 0; - send_message(tell, opserv, message, buff); + buff[count] = 0; + send_message(tell, opserv, message, buff); } } @@ -966,17 +968,17 @@ static MODCMD_FUNC(cmd_inviteme) struct userNode *target; if (argc < 2) { - target = user; + target = user; } else { - target = GetUserH(argv[1]); - if (!target) { - reply("MSG_NICK_UNKNOWN", argv[1]); - return 0; - } + target = GetUserH(argv[1]); + if (!target) { + reply("MSG_NICK_UNKNOWN", argv[1]); + return 0; + } } if (opserv_conf.debug_channel == NULL) { - reply("OSMSG_NO_DEBUG_CHANNEL"); - return 0; + reply("OSMSG_NO_DEBUG_CHANNEL"); + return 0; } if (GetUserMode(opserv_conf.debug_channel, user)) { reply("OSMSG_ALREADY_THERE", opserv_conf.debug_channel->name); @@ -984,7 +986,7 @@ static MODCMD_FUNC(cmd_inviteme) } irc_invite(cmd->parent->bot, target, opserv_conf.debug_channel); if (target != user) - reply("OSMSG_INVITE_DONE", target->nick, opserv_conf.debug_channel->name); + reply("OSMSG_INVITE_DONE", target->nick, opserv_conf.debug_channel->name); return 1; } @@ -1030,19 +1032,19 @@ static MODCMD_FUNC(cmd_kick) char *reason; if (argc < 3) { - reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); - sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); + reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); + sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); } else { - reason = unsplit_string(argv+2, argc-2, NULL); + reason = unsplit_string(argv+2, argc-2, NULL); } target = GetUserH(argv[1]); if (!target) { - reply("MSG_NICK_UNKNOWN", argv[1]); - return 0; + reply("MSG_NICK_UNKNOWN", argv[1]); + return 0; } if (!GetUserMode(channel, target)) { - reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name); - return 0; + reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name); + return 0; } KickChannelUser(target, channel, cmd->parent->bot, reason); return 1; @@ -1065,20 +1067,20 @@ static MODCMD_FUNC(cmd_kickall) modcmd_chanmode_announce(&change); } if (argc < 2) { - reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); - sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); + reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); + sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); } else { - reason = unsplit_string(argv+1, argc-1, NULL); + reason = unsplit_string(argv+1, argc-1, NULL); } limit = user->handle_info->opserv_level; for (n=channel->members.used; n>0;) { - mn = channel->members.list[--n]; - if (IsService(mn->user) - || (mn->user->handle_info - && (mn->user->handle_info->opserv_level >= limit))) { - continue; - } - KickChannelUser(mn->user, channel, bot, reason); + mn = channel->members.list[--n]; + if (IsService(mn->user) + || (mn->user->handle_info + && (mn->user->handle_info->opserv_level >= limit))) { + continue; + } + KickChannelUser(mn->user, channel, bot, reason); } if (!inchan) DelChannelUser(bot, channel, "My work here is done", 0); @@ -1094,19 +1096,19 @@ static MODCMD_FUNC(cmd_kickban) char *mask; if (argc == 2) { - reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); - sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); + reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); + sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); } else { - reason = unsplit_string(argv+2, argc-2, NULL); + reason = unsplit_string(argv+2, argc-2, NULL); } target = GetUserH(argv[1]); if (!target) { - reply("MSG_NICK_UNKNOWN", argv[1]); - return 0; + reply("MSG_NICK_UNKNOWN", argv[1]); + return 0; } if (!GetUserMode(channel, target)) { - reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name); - return 0; + reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name); + return 0; } mod_chanmode_init(&change); change.argc = 1; @@ -1142,21 +1144,21 @@ static MODCMD_FUNC(cmd_kickbanall) modcmd_chanmode_announce(change); mod_chanmode_free(change); if (argc < 2) { - reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); - sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); + reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1); + sprintf(reason, OSMSG_KICK_REQUESTED, user->nick); } else { - reason = unsplit_string(argv+1, argc-1, NULL); + reason = unsplit_string(argv+1, argc-1, NULL); } /* now kick them */ limit = user->handle_info->opserv_level; for (n=channel->members.used; n>0; ) { - mn = channel->members.list[--n]; - if (IsService(mn->user) - || (mn->user->handle_info - && (mn->user->handle_info->opserv_level >= limit))) { - continue; - } - KickChannelUser(mn->user, channel, bot, reason); + mn = channel->members.list[--n]; + if (IsService(mn->user) + || (mn->user->handle_info + && (mn->user->handle_info->opserv_level >= limit))) { + continue; + } + KickChannelUser(mn->user, channel, bot, reason); } if (!inchan) DelChannelUser(bot, channel, "My work here is done", 0); @@ -1255,15 +1257,15 @@ static MODCMD_FUNC(cmd_opall) change = mod_chanmode_alloc(channel->members.used); for (ii = count = 0; ii < channel->members.used; ++ii) { - struct modeNode *mn = channel->members.list[ii]; - if (mn->modes & MODE_CHANOP) + struct modeNode *mn = channel->members.list[ii]; + if (mn->modes & MODE_CHANOP) continue; change->args[count].mode = MODE_CHANOP; change->args[count++].u.member = mn; } if (count) { change->argc = count; - modcmd_chanmode_announce(change); + modcmd_chanmode_announce(change); } mod_chanmode_free(change); reply("OSMSG_OPALL_DONE", channel->name); @@ -1314,26 +1316,26 @@ static MODCMD_FUNC(cmd_whois) reply("OSMSG_WHOIS_FAKEHOST", target->fakehost); reply("OSMSG_WHOIS_IP", inet_ntoa(target->ip)); if (target->modes) { - bpos = 0; + bpos = 0; #define buffer_cat(str) (herelen = strlen(str), memcpy(buffer+bpos, str, herelen), bpos += herelen) - if (IsInvisible(target)) buffer[bpos++] = 'i'; - if (IsWallOp(target)) buffer[bpos++] = 'w'; - if (IsOper(target)) buffer[bpos++] = 'o'; - if (IsGlobal(target)) buffer[bpos++] = 'g'; - if (IsServNotice(target)) buffer[bpos++] = 's'; - - // sethost - reed/apples - // if (IsHelperIrcu(target)) buffer[bpos++] = 'h'; - if (IsSetHost(target)) buffer[bpos++] = 'h'; - - if (IsService(target)) buffer[bpos++] = 'k'; - if (IsDeaf(target)) buffer[bpos++] = 'd'; + if (IsInvisible(target)) buffer[bpos++] = 'i'; + if (IsWallOp(target)) buffer[bpos++] = 'w'; + if (IsOper(target)) buffer[bpos++] = 'o'; + if (IsGlobal(target)) buffer[bpos++] = 'g'; + if (IsServNotice(target)) buffer[bpos++] = 's'; + + // sethost - reed/apples + // if (IsHelperIrcu(target)) buffer[bpos++] = 'h'; + if (IsSetHost(target)) buffer[bpos++] = 'h'; + + if (IsService(target)) buffer[bpos++] = 'k'; + if (IsDeaf(target)) buffer[bpos++] = 'd'; if (target->handle_info) buffer[bpos++] = 'r'; if (IsHiddenHost(target)) buffer[bpos++] = 'x'; if (IsGagged(target)) buffer_cat(" (gagged)"); - if (IsRegistering(target)) buffer_cat(" (registered account)"); - buffer[bpos] = 0; - if (bpos > 0) + if (IsRegistering(target)) buffer_cat(" (registered account)"); + buffer[bpos] = 0; + if (bpos > 0) reply("OSMSG_WHOIS_MODES", buffer); } reply("OSMSG_WHOIS_INFO", target->info); @@ -1345,9 +1347,9 @@ static MODCMD_FUNC(cmd_whois) intervalString(buffer, now - target->timestamp, user->handle_info); reply("OSMSG_WHOIS_NICK_AGE", buffer); if (target->channels.used <= MAX_CHANNELS_WHOIS) - opserv_ison(user, target, "OSMSG_WHOIS_CHANNELS"); + opserv_ison(user, target, "OSMSG_WHOIS_CHANNELS"); else - reply("OSMSG_WHOIS_HIDECHANS"); + reply("OSMSG_WHOIS_HIDECHANS"); return 1; } @@ -1370,15 +1372,15 @@ static MODCMD_FUNC(cmd_voiceall) change = mod_chanmode_alloc(channel->members.used); for (ii = count = 0; ii < channel->members.used; ++ii) { - struct modeNode *mn = channel->members.list[ii]; - if (mn->modes & (MODE_CHANOP|MODE_HALFOP|MODE_VOICE)) + struct modeNode *mn = channel->members.list[ii]; + if (mn->modes & (MODE_CHANOP|MODE_HALFOP|MODE_VOICE)) continue; change->args[count].mode = MODE_VOICE; change->args[count++].u.member = mn; } if (count) { change->argc = count; - modcmd_chanmode_announce(change); + modcmd_chanmode_announce(change); } mod_chanmode_free(change); reply("OSMSG_CHANNEL_VOICED", channel->name); @@ -1392,15 +1394,15 @@ static MODCMD_FUNC(cmd_devoiceall) change = mod_chanmode_alloc(channel->members.used); for (ii = count = 0; ii < channel->members.used; ++ii) { - struct modeNode *mn = channel->members.list[ii]; - if (!(mn->modes & MODE_VOICE)) + struct modeNode *mn = channel->members.list[ii]; + if (!(mn->modes & MODE_VOICE)) continue; change->args[count].mode = MODE_REMOVE | MODE_VOICE; change->args[count++].u.member = mn; } if (count) { change->argc = count; - modcmd_chanmode_announce(change); + modcmd_chanmode_announce(change); } mod_chanmode_free(change); reply("OSMSG_CHANNEL_DEVOICED", channel->name); @@ -1686,7 +1688,7 @@ static MODCMD_FUNC(cmd_stats_gags) { unsigned int nn; if (!gagList) { - reply("OSMSG_NO_GAGS"); + reply("OSMSG_NO_GAGS"); return 1; } for (nn=0, gag=gagList; gag; nn++, gag=gag->next) ; @@ -1768,10 +1770,10 @@ static MODCMD_FUNC(cmd_dump) safestrncpy(linedup, original, sizeof(linedup)); /* assume it's only valid IRC if we can parse it */ if (parse_line(linedup, 1)) { - irc_raw(original); - reply("OSMSG_LINE_DUMPED"); + irc_raw(original); + reply("OSMSG_LINE_DUMPED"); } else - reply("OSMSG_RAW_PARSE_ERROR"); + reply("OSMSG_RAW_PARSE_ERROR"); return 1; } @@ -1794,15 +1796,15 @@ opserv_add_reserve(struct svccmd *cmd, struct userNode *user, const char *nick, { struct userNode *resv = GetUserH(nick); if (resv) { - if (IsService(resv)) { - reply("MSG_SERVICE_IMMUNE", resv->nick); - return NULL; - } - if (resv->handle_info - && resv->handle_info->opserv_level > user->handle_info->opserv_level) { - reply("OSMSG_LEVEL_TOO_LOW"); - return NULL; - } + if (IsService(resv)) { + reply("MSG_SERVICE_IMMUNE", resv->nick); + return NULL; + } + if (resv->handle_info + && resv->handle_info->opserv_level > user->handle_info->opserv_level) { + reply("OSMSG_LEVEL_TOO_LOW"); + return NULL; + } } if ((resv = AddClone(nick, ident, host, desc))) { dict_insert(opserv_reserved_nick_dict, resv->nick, resv); @@ -1816,11 +1818,11 @@ static MODCMD_FUNC(cmd_collide) resv = opserv_add_reserve(cmd, user, argv[1], argv[2], argv[3], unsplit_string(argv+4, argc-4, NULL)); if (resv) { - reply("OSMSG_COLLIDED_NICK", resv->nick); - return 1; + reply("OSMSG_COLLIDED_NICK", resv->nick); + return 1; } else { reply("OSMSG_CLONE_FAILED", argv[1]); - return 0; + return 0; } } @@ -1830,12 +1832,12 @@ static MODCMD_FUNC(cmd_reserve) resv = opserv_add_reserve(cmd, user, argv[1], argv[2], argv[3], unsplit_string(argv+4, argc-4, NULL)); if (resv) { - resv->modes |= FLAGS_PERSISTENT; - reply("OSMSG_RESERVED_NICK", resv->nick); - return 1; + resv->modes |= FLAGS_PERSISTENT; + reply("OSMSG_RESERVED_NICK", resv->nick); + return 1; } else { reply("OSMSG_CLONE_FAILED", argv[1]); - return 0; + return 0; } } @@ -1861,9 +1863,9 @@ free_reserve(char *nick) static MODCMD_FUNC(cmd_unreserve) { if (free_reserve(argv[1])) - reply("OSMSG_NICK_UNRESERVED", argv[1]); + reply("OSMSG_NICK_UNRESERVED", argv[1]); else - reply("OSMSG_NOT_RESERVED", argv[1]); + reply("OSMSG_NOT_RESERVED", argv[1]); return 1; } @@ -1959,9 +1961,10 @@ int opserv_bad_channel(const char *name) { unsigned int found; + int present; - dict_find(opserv_exempt_channels, name, &found); - if (found) + dict_find(opserv_exempt_channels, name, &present); + if (present) return 0; if (gline_find(name)) @@ -2379,92 +2382,92 @@ static MODCMD_FUNC(cmd_clone) char *userinfo; char ident[USERLEN+1]; - if (argc < 5) { - reply("MSG_MISSING_PARAMS", argv[1]); - OPSERV_SYNTAX(); - return 0; - } - if (clone) { - reply("OSMSG_CLONE_EXISTS", argv[2]); - return 0; - } - userinfo = unsplit_string(argv+4, argc-4, NULL); - for (i=0; argv[3][i] && (inick); - return 1; + return 1; } if (!clone) { - reply("MSG_NICK_UNKNOWN", argv[2]); - return 0; + reply("MSG_NICK_UNKNOWN", argv[2]); + return 0; } if (clone->uplink != self || IsService(clone)) { - reply("OSMSG_NOT_A_CLONE", clone->nick); - return 0; + reply("OSMSG_NOT_A_CLONE", clone->nick); + return 0; } if (!irccasecmp(argv[1], "REMOVE")) { - const char *reason; - if (argc > 3) { - reason = unsplit_string(argv+3, argc-3, NULL); - } else { - char *tmp; - tmp = alloca(strlen(clone->nick) + strlen(OSMSG_PART_REASON)); - sprintf(tmp, OSMSG_PART_REASON, clone->nick); - reason = tmp; - } - DelUser(clone, NULL, 1, reason); - reply("OSMSG_CLONE_REMOVED", argv[2]); - return 1; + const char *reason; + if (argc > 3) { + reason = unsplit_string(argv+3, argc-3, NULL); + } else { + char *tmp; + tmp = alloca(strlen(clone->nick) + strlen(OSMSG_PART_REASON)); + sprintf(tmp, OSMSG_PART_REASON, clone->nick); + reason = tmp; + } + DelUser(clone, NULL, 1, reason); + reply("OSMSG_CLONE_REMOVED", argv[2]); + return 1; } if (argc < 4) { - reply("MSG_MISSING_PARAMS", argv[1]); - OPSERV_SYNTAX(); - return 0; + reply("MSG_MISSING_PARAMS", argv[1]); + OPSERV_SYNTAX(); + return 0; } channel = GetChannel(argv[3]); if (!irccasecmp(argv[1], "JOIN")) { - if (!channel - && !(channel = AddChannel(argv[3], now, NULL, NULL, NULL))) { - reply("MSG_CHANNEL_UNKNOWN", argv[3]); - return 0; - } - AddChannelUser(clone, channel); - reply("OSMSG_CLONE_JOINED", clone->nick, channel->name); - return 1; + if (!channel + && !(channel = AddChannel(argv[3], now, NULL, NULL, NULL))) { + reply("MSG_CHANNEL_UNKNOWN", argv[3]); + return 0; + } + AddChannelUser(clone, channel); + reply("OSMSG_CLONE_JOINED", clone->nick, channel->name); + return 1; } if (!irccasecmp(argv[1], "PART")) { - if (!channel) { - reply("MSG_CHANNEL_UNKNOWN", argv[3]); - return 0; - } - if (!GetUserMode(channel, clone)) { - reply("OSMSG_NOT_ON_CHANNEL", clone->nick, channel->name); - return 0; - } - reply("OSMSG_CLONE_PARTED", clone->nick, channel->name); - DelChannelUser(clone, channel, "Leaving.", 0); - return 1; + if (!channel) { + reply("MSG_CHANNEL_UNKNOWN", argv[3]); + return 0; + } + if (!GetUserMode(channel, clone)) { + reply("OSMSG_NOT_ON_CHANNEL", clone->nick, channel->name); + return 0; + } + reply("OSMSG_CLONE_PARTED", clone->nick, channel->name); + DelChannelUser(clone, channel, "Leaving.", 0); + return 1; } if (!irccasecmp(argv[1], "OP")) { struct mod_chanmode change; - if (!channel) { - reply("MSG_CHANNEL_UNKNOWN", argv[3]); - return 0; - } + if (!channel) { + reply("MSG_CHANNEL_UNKNOWN", argv[3]); + return 0; + } mod_chanmode_init(&change); change.argc = 1; change.args[0].mode = MODE_CHANOP; @@ -2472,10 +2475,10 @@ static MODCMD_FUNC(cmd_clone) if (!change.args[0].u.member) { reply("OSMSG_NOT_ON_CHANNEL", clone->nick, channel->name); return 0; - } + } modcmd_chanmode_announce(&change); - reply("OSMSG_OPS_GIVEN", channel->name, clone->nick); - return 1; + reply("OSMSG_OPS_GIVEN", channel->name, clone->nick); + return 1; } if (!irccasecmp(argv[1], "HOP")) { struct mod_chanmode change; @@ -2496,15 +2499,15 @@ static MODCMD_FUNC(cmd_clone) return 1; } if (argc < 5) { - reply("MSG_MISSING_PARAMS", argv[1]); - OPSERV_SYNTAX(); - return 0; + reply("MSG_MISSING_PARAMS", argv[1]); + OPSERV_SYNTAX(); + return 0; } if (!irccasecmp(argv[1], "SAY")) { - char *text = unsplit_string(argv+4, argc-4, NULL); - irc_privmsg(clone, argv[3], text); - reply("OSMSG_CLONE_SAID", clone->nick, argv[3]); - return 1; + char *text = unsplit_string(argv+4, argc-4, NULL); + irc_privmsg(clone, argv[3], text); + reply("OSMSG_CLONE_SAID", clone->nick, argv[3]); + return 1; } reply("OSMSG_UNKNOWN_SUBCOMMAND", argv[1], argv[0]); return 0; @@ -2587,18 +2590,18 @@ int add_reserved(const char *key, void *data, void *extra) struct userNode *reserve; ident = database_get_data(rd->d.object, KEY_IDENT, RECDB_QSTRING); if (!ident) { - log_module(OS_LOG, LOG_ERROR, "Missing ident for reserve of %s", key); - return 0; + log_module(OS_LOG, LOG_ERROR, "Missing ident for reserve of %s", key); + return 0; } hostname = database_get_data(rd->d.object, KEY_HOSTNAME, RECDB_QSTRING); if (!hostname) { - log_module(OS_LOG, LOG_ERROR, "Missing hostname for reserve of %s", key); - return 0; + log_module(OS_LOG, LOG_ERROR, "Missing hostname for reserve of %s", key); + return 0; } desc = database_get_data(rd->d.object, KEY_DESC, RECDB_QSTRING); if (!desc) { - log_module(OS_LOG, LOG_ERROR, "Missing description for reserve of %s", key); - return 0; + log_module(OS_LOG, LOG_ERROR, "Missing description for reserve of %s", key); + return 0; } if ((reserve = AddClone(key, ident, hostname, desc))) { reserve->modes |= FLAGS_PERSISTENT; @@ -2635,7 +2638,7 @@ foreach_matching_user(const char *hostmask, discrim_search_func func, void *extr } matched = opserv_discrim_search(discrim, func, extra); } else { - log_module(OS_LOG, LOG_ERROR, "Couldn't split IRC mask for gag %s!", hostmask); + log_module(OS_LOG, LOG_ERROR, "Couldn't split IRC mask for gag %s!", hostmask); matched = 0; } free(discrim); @@ -2719,15 +2722,15 @@ opserv_add_user_alert(struct userNode *req, const char *name, opserv_alert_react char *name_dup; if (dict_find(opserv_user_alerts, name, NULL)) { - send_message(req, opserv, "OSMSG_ALERT_EXISTS", name); - return NULL; + send_message(req, opserv, "OSMSG_ALERT_EXISTS", name); + return NULL; } alert = malloc(sizeof(*alert)); alert->owner = strdup(req->handle_info ? req->handle_info->handle : req->nick); alert->text_discrim = strdup(text_discrim); discrim_copy = strdup(text_discrim); /* save a copy of the discrim */ wordc = split_line(discrim_copy, false, ArrayLength(wordv), wordv); - alert->discrim = opserv_discrim_create(req, wordc, wordv, 0); + alert->discrim = opserv_discrim_create(req, opserv, wordc, wordv, 0); if (!alert->discrim) { free(alert->text_discrim); free(discrim_copy); @@ -2740,9 +2743,14 @@ opserv_add_user_alert(struct userNode *req, const char *name, opserv_alert_react alert->discrim->reason = strdup(name); alert->reaction = reaction; dict_insert(opserv_user_alerts, name_dup, alert); - if (alert->discrim->channel) + /* Stick the alert into the appropriate additional alert dict(s). + * For channel alerts, we only use channels and min_channels; + * max_channels would have to be checked on /part, which we do not + * yet do, and which seems of questionable value. + */ + if (alert->discrim->channel || alert->discrim->min_channels) dict_insert(opserv_channel_alerts, name_dup, alert); - else if (alert->discrim->mask_nick) + if (alert->discrim->mask_nick) dict_insert(opserv_nick_based_alerts, name_dup, alert); return alert; } @@ -3002,29 +3010,29 @@ static MODCMD_FUNC(cmd_query) char *nodename; if (argc < 2) { - reply("OSMSG_OPTION_ROOT"); - conf_enum_root(query_keys_helper, user); - return 1; + reply("OSMSG_OPTION_ROOT"); + conf_enum_root(query_keys_helper, user); + return 1; } nodename = unsplit_string(argv+1, argc-1, NULL); if (!(rd = conf_get_node(nodename))) { - reply("OSMSG_UNKNOWN_OPTION", nodename); - return 0; + reply("OSMSG_UNKNOWN_OPTION", nodename); + return 0; } if (rd->type == RECDB_QSTRING) - reply("OSMSG_OPTION_IS", nodename, rd->d.qstring); + reply("OSMSG_OPTION_IS", nodename, rd->d.qstring); else if (rd->type == RECDB_STRING_LIST) { - reply("OSMSG_OPTION_LIST", nodename); - if (rd->d.slist->used) - for (i=0; id.slist->used; i++) - send_message_type(4, user, cmd->parent->bot, "$b%s$b", rd->d.slist->list[i]); - else - reply("OSMSG_OPTION_LIST_EMPTY"); + reply("OSMSG_OPTION_LIST", nodename); + if (rd->d.slist->used) + for (i=0; id.slist->used; i++) + send_message_type(4, user, cmd->parent->bot, "$b%s$b", rd->d.slist->list[i]); + else + reply("OSMSG_OPTION_LIST_EMPTY"); } else if (rd->type == RECDB_OBJECT) { - reply("OSMSG_OPTION_KEYS", nodename); - dict_foreach(rd->d.object, query_keys_helper, user); + reply("OSMSG_OPTION_KEYS", nodename); + dict_foreach(rd->d.object, query_keys_helper, user); } return 1; @@ -3040,13 +3048,13 @@ static MODCMD_FUNC(cmd_set) invent a syntax for it. -Zoot */ if (!(rd = conf_get_node(argv[1]))) { - reply("OSMSG_SET_NOT_SET", argv[1]); - return 0; + reply("OSMSG_SET_NOT_SET", argv[1]); + return 0; } if (rd->type != RECDB_QSTRING) { - reply("OSMSG_SET_BAD_TYPE", argv[1]); - return 0; + reply("OSMSG_SET_BAD_TYPE", argv[1]); + return 0; } free(rd->d.qstring); @@ -3071,7 +3079,7 @@ static MODCMD_FUNC(cmd_settime) } static discrim_t -opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], int allow_channel) +opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[], int allow_channel) { unsigned int i, j; discrim_t discrim; @@ -3092,37 +3100,37 @@ opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], in } /* Assume all other criteria require arguments. */ if (i == argc - 1) { - send_message(user, opserv, "MSG_MISSING_PARAMS", argv[i]); + send_message(user, bot, "MSG_MISSING_PARAMS", argv[i]); goto fail; } - if (irccasecmp(argv[i], "mask") == 0) { - if (!is_ircmask(argv[++i])) { - send_message(user, opserv, "OSMSG_INVALID_IRCMASK", argv[i]); - goto fail; - } - if (!split_ircmask(argv[i], + if (irccasecmp(argv[i], "mask") == 0) { + if (!is_ircmask(argv[++i])) { + send_message(user, bot, "OSMSG_INVALID_IRCMASK", argv[i]); + goto fail; + } + if (!split_ircmask(argv[i], &discrim->mask_nick, &discrim->mask_ident, &discrim->mask_host)) { - send_message(user, opserv, "OSMSG_INVALID_IRCMASK", argv[i]); - goto fail; - } - } else if (irccasecmp(argv[i], "nick") == 0) { - discrim->mask_nick = argv[++i]; - } else if (irccasecmp(argv[i], "ident") == 0) { - 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]; - } else if (irccasecmp(argv[i], "server") == 0) { - discrim->server = argv[++i]; - } else if (irccasecmp(argv[i], "ip") == 0) { - j = parse_ipmask(argv[++i], &discrim->ip_addr, &discrim->ip_mask); - if (!j) discrim->ip_mask_str = argv[i]; + send_message(user, bot, "OSMSG_INVALID_IRCMASK", argv[i]); + goto fail; + } + } else if (irccasecmp(argv[i], "nick") == 0) { + discrim->mask_nick = argv[++i]; + } else if (irccasecmp(argv[i], "ident") == 0) { + 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]; + } else if (irccasecmp(argv[i], "server") == 0) { + discrim->server = argv[++i]; + } else if (irccasecmp(argv[i], "ip") == 0) { + j = parse_ipmask(argv[++i], &discrim->ip_addr, &discrim->ip_mask); + if (!j) discrim->ip_mask_str = argv[i]; } else if (irccasecmp(argv[i], "account") == 0) { if (discrim->authed == 0) { - send_message(user, opserv, "OSMSG_ACCOUNTMASK_AUTHED"); + send_message(user, bot, "OSMSG_ACCOUNTMASK_AUTHED"); goto fail; } discrim->accountmask = argv[++i]; @@ -3133,12 +3141,12 @@ opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], in discrim->authed = 1; } else if (false_string(argv[i])) { if (discrim->accountmask) { - send_message(user, opserv, "OSMSG_ACCOUNTMASK_AUTHED"); + send_message(user, bot, "OSMSG_ACCOUNTMASK_AUTHED"); goto fail; } discrim->authed = 0; } else { - send_message(user, opserv, "MSG_INVALID_BINARY", argv[i]); + send_message(user, bot, "MSG_INVALID_BINARY", argv[i]); goto fail; } } else if (irccasecmp(argv[i], "info_space") == 0) { @@ -3150,12 +3158,12 @@ opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], in } else if (false_string(argv[i])) { discrim->info_space = 0; } else { - send_message(user, opserv, "MSG_INVALID_BINARY", argv[i]); + send_message(user, bot, "MSG_INVALID_BINARY", argv[i]); goto fail; } } else if (irccasecmp(argv[i], "duration") == 0) { discrim->duration = ParseInterval(argv[++i]); - } else if (irccasecmp(argv[i], "channel") == 0) { + } else if (irccasecmp(argv[i], "channel") == 0) { for (j=0, i++; ; j++) { switch (argv[i][j]) { case '#': @@ -3177,27 +3185,27 @@ opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], in discrim->chan_req_modes |= MODE_CHANOP; break; case '\0': - send_message(user, opserv, "MSG_NOT_CHANNEL_NAME"); + send_message(user, bot, "MSG_NOT_CHANNEL_NAME"); goto fail; } } find_channel: discrim->chan_no_modes &= ~discrim->chan_req_modes; - if (!(discrim->channel = GetChannel(argv[i]+j))) { + if (!(discrim->channel = GetChannel(argv[i]+j))) { /* secretly "allow_channel" now means "if a channel name is * specified, require that it currently exist" */ if (allow_channel) { - send_message(user, opserv, "MSG_CHANNEL_UNKNOWN", argv[i]); + send_message(user, bot, "MSG_CHANNEL_UNKNOWN", argv[i]); goto fail; } else { discrim->channel = AddChannel(argv[i]+j, now, NULL, NULL, NULL); } - } + } LockChannel(discrim->channel); } else if (irccasecmp(argv[i], "numchannels") == 0) { discrim->min_channels = discrim->max_channels = strtoul(argv[++i], NULL, 10); - } else if (irccasecmp(argv[i], "limit") == 0) { - discrim->limit = strtoul(argv[++i], NULL, 10); + } else if (irccasecmp(argv[i], "limit") == 0) { + discrim->limit = strtoul(argv[++i], NULL, 10); } else if (irccasecmp(argv[i], "reason") == 0) { discrim->reason = strdup(unsplit_string(argv+i+1, argc-i-1, NULL)); i = argc; @@ -3249,19 +3257,19 @@ opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], in } else if (irccasecmp(argv[i], "clones") == 0) { discrim->min_clones = strtoul(argv[++i], NULL, 0); } else { - send_message(user, opserv, "MSG_INVALID_CRITERIA", argv[i]); + send_message(user, bot, "MSG_INVALID_CRITERIA", argv[i]); goto fail; } } if (discrim->mask_nick && !strcmp(discrim->mask_nick, "*")) { - discrim->mask_nick = 0; + discrim->mask_nick = 0; } if (discrim->mask_ident && !strcmp(discrim->mask_ident, "*")) { discrim->mask_ident = 0; } if (discrim->mask_info && !strcmp(discrim->mask_info, "*")) { - discrim->mask_info = 0; + discrim->mask_info = 0; } if (discrim->mask_host && !discrim->mask_host[strspn(discrim->mask_host, "*.")]) { discrim->mask_host = 0; @@ -3366,10 +3374,10 @@ opserv_discrim_search(discrim_t discrim, discrim_search_func dsf, void *data) log_module(OS_LOG, LOG_INFO, " %s!%s@%s", user->nick, user->ident, user->hostname); } if (dsf(user, data)) { - /* If a search function returns true, it ran into a - problem. Stop going through the list. */ - break; - } + /* If a search function returns true, it ran into a + problem. Stop going through the list. */ + break; + } } if (discrim->option_log) { log_module(OS_LOG, LOG_INFO, "End of matching users."); @@ -3384,9 +3392,9 @@ trace_print_func(struct userNode *match, void *extra) { struct discrim_and_source *das = extra; if (match->handle_info) { - send_message_type(4, das->source, opserv, "%-15s\002 \002%10s\002@\002%s (%s)", match->nick, match->ident, match->hostname, match->handle_info->handle); + send_message_type(4, das->source, das->destination, "%-15s\002 \002%10s\002@\002%s (%s)", match->nick, match->ident, match->hostname, match->handle_info->handle); } else { - send_message_type(4, das->source, opserv, "%-15s\002 \002%10s\002@\002%s", match->nick, match->ident, match->hostname); + send_message_type(4, das->source, das->destination, "%-15s\002 \002%10s\002@\002%s", match->nick, match->ident, match->hostname); } return 0; } @@ -3424,7 +3432,7 @@ trace_kill_func(struct userNode *match, void *extra) struct discrim_and_source *das = extra; if (is_oper_victim(das->source, match, das->discrim->match_opers)) { - char *reason; + char *reason; if (das->discrim->reason) { reason = das->discrim->reason; } else { @@ -3462,10 +3470,10 @@ trace_gag_func(struct userNode *match, void *extra) reason = alloca(strlen(OSMSG_GAG_REQUESTED)+strlen(das->source->nick)+1); sprintf(reason, OSMSG_GAG_REQUESTED, das->source->nick); } - masksize = 5+strlen(match->hostname); - mask = alloca(masksize); + masksize = 5+strlen(match->hostname); + mask = alloca(masksize); snprintf(mask, masksize, "*!*@%s", match->hostname); - if (!is_gagged(mask)) { + if (!is_gagged(mask)) { gag_create(mask, das->source->handle_info->handle, reason, das->discrim->duration ? (now + das->discrim->duration) : 0); } @@ -3522,7 +3530,7 @@ opserv_show_hostinfo(const char *key, void *data, void *extra) unsigned long *count = data; struct discrim_and_source *das = extra; - send_message_type(4, das->source, opserv, "%s %lu", key, *count); + send_message_type(4, das->source, das->destination, "%s %lu", key, *count); return !--das->disp_limit; } @@ -3535,11 +3543,11 @@ static MODCMD_FUNC(cmd_trace) char buf[MAXLEN]; sprintf(buf, "trace %s", argv[1]); - if (!(subcmd = dict_find(cmd->parent->commands, buf, NULL))) { - reply("OSMSG_BAD_ACTION", argv[1]); + if (!(subcmd = dict_find(opserv_service->commands, buf, NULL))) { + reply("OSMSG_BAD_ACTION", argv[1]); return 0; } - if (!svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, SVCCMD_NOISY)) + if (!svccmd_can_invoke(user, opserv_service->bot, subcmd, channel, SVCCMD_NOISY)) return 0; if (!irccasecmp(argv[1], "print")) action = trace_print_func; @@ -3554,8 +3562,8 @@ static MODCMD_FUNC(cmd_trace) else if (!irccasecmp(argv[1], "gag")) action = trace_gag_func; else { - reply("OSMSG_BAD_ACTION", argv[1]); - return 0; + reply("OSMSG_BAD_ACTION", argv[1]); + return 0; } if (user->handle_info->opserv_level < subcmd->min_opserv_level) { @@ -3565,7 +3573,8 @@ static MODCMD_FUNC(cmd_trace) das.dict = NULL; das.source = user; - das.discrim = opserv_discrim_create(user, argc-2, argv+2, 1); + das.destination = cmd->parent->bot; + das.discrim = opserv_discrim_create(user, cmd->parent->bot, argc-2, argv+2, 1); if (!das.discrim) return 0; @@ -3577,7 +3586,7 @@ static MODCMD_FUNC(cmd_trace) reply("OSMSG_USER_SEARCH_BAR"); } else if (action == trace_count_func) - das.discrim->limit = INT_MAX; + das.discrim->limit = INT_MAX; else if ((action == trace_gline_func) && !das.discrim->duration) das.discrim->duration = opserv_conf.block_gline_duration; else if (action == trace_domains_func) { @@ -3595,12 +3604,12 @@ static MODCMD_FUNC(cmd_trace) if (matches) { if(action == trace_print_func) - reply("OSMSG_USER_SEARCH_COUNT_BAR", matches); + reply("OSMSG_USER_SEARCH_COUNT_BAR", matches); else reply("OSMSG_USER_SEARCH_COUNT", matches); } else - reply("MSG_NO_MATCHES"); + reply("MSG_NO_MATCHES"); if (das.discrim->channel) UnlockChannel(das.discrim->channel); @@ -3610,7 +3619,7 @@ static MODCMD_FUNC(cmd_trace) return 1; } -typedef void (*cdiscrim_search_func)(struct chanNode *match, void *data); +typedef void (*cdiscrim_search_func)(struct chanNode *match, void *data, struct userNode *bot); typedef struct channel_discrim { char *name, *topic; @@ -3620,8 +3629,8 @@ typedef struct channel_discrim { unsigned int limit; } *cdiscrim_t; -static cdiscrim_t opserv_cdiscrim_create(struct userNode *user, unsigned int argc, char *argv[]); -static unsigned int opserv_cdiscrim_search(cdiscrim_t discrim, cdiscrim_search_func dsf, void *data); +static cdiscrim_t opserv_cdiscrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[]); +static unsigned int opserv_cdiscrim_search(cdiscrim_t discrim, cdiscrim_search_func dsf, void *data, struct userNode *bot); static time_t smart_parse_time(const char *str) { @@ -3631,7 +3640,7 @@ smart_parse_time(const char *str) { } static cdiscrim_t -opserv_cdiscrim_create(struct userNode *user, unsigned int argc, char *argv[]) +opserv_cdiscrim_create(struct userNode *user, struct userNode *bot, unsigned int argc, char *argv[]) { cdiscrim_t discrim; unsigned int i; @@ -3640,18 +3649,18 @@ opserv_cdiscrim_create(struct userNode *user, unsigned int argc, char *argv[]) discrim->limit = 25; for (i = 0; i < argc; i++) { - /* Assume all criteria require arguments. */ - if (i == (argc - 1)) { - send_message(user, opserv, "MSG_MISSING_PARAMS", argv[i]); - return NULL; - } - - if (!irccasecmp(argv[i], "name")) - discrim->name = argv[++i]; - else if (!irccasecmp(argv[i], "topic")) - discrim->topic = argv[++i]; - else if (!irccasecmp(argv[i], "users")) { - const char *cmp = argv[++i]; + /* Assume all criteria require arguments. */ + if (i == (argc - 1)) { + send_message(user, bot, "MSG_MISSING_PARAMS", argv[i]); + return NULL; + } + + if (!irccasecmp(argv[i], "name")) + discrim->name = argv[++i]; + else if (!irccasecmp(argv[i], "topic")) + discrim->topic = argv[++i]; + else if (!irccasecmp(argv[i], "users")) { + const char *cmp = argv[++i]; if (cmp[0] == '<') { if (cmp[1] == '=') discrim->max_users = strtoul(cmp+2, NULL, 0); @@ -3667,8 +3676,8 @@ opserv_cdiscrim_create(struct userNode *user, unsigned int argc, char *argv[]) } else { discrim->min_users = strtoul(cmp+2, NULL, 0); } - } else if (!irccasecmp(argv[i], "timestamp")) { - const char *cmp = argv[++i]; + } else if (!irccasecmp(argv[i], "timestamp")) { + const char *cmp = argv[++i]; if (cmp[0] == '<') { if (cmp[1] == '=') discrim->max_ts = smart_parse_time(cmp+2); @@ -3684,18 +3693,18 @@ opserv_cdiscrim_create(struct userNode *user, unsigned int argc, char *argv[]) } else { discrim->min_ts = smart_parse_time(cmp); } - } else if (!irccasecmp(argv[i], "limit")) { - discrim->limit = strtoul(argv[++i], NULL, 10); - } else { - send_message(user, opserv, "MSG_INVALID_CRITERIA", argv[i]); - goto fail; - } + } else if (!irccasecmp(argv[i], "limit")) { + discrim->limit = strtoul(argv[++i], NULL, 10); + } else { + send_message(user, bot, "MSG_INVALID_CRITERIA", argv[i]); + goto fail; + } } if (discrim->name && !strcmp(discrim->name, "*")) - discrim->name = 0; + discrim->name = 0; if (discrim->topic && !strcmp(discrim->topic, "*")) - discrim->topic = 0; + discrim->topic = 0; return discrim; fail: @@ -3712,40 +3721,40 @@ cdiscrim_match(cdiscrim_t discrim, struct chanNode *chan) (discrim->max_users && chan->members.used > discrim->max_users) || (discrim->min_ts && chan->timestamp < discrim->min_ts) || (discrim->max_ts && chan->timestamp > discrim->max_ts)) { - return 0; + return 0; } return 1; } -static unsigned int opserv_cdiscrim_search(cdiscrim_t discrim, cdiscrim_search_func dsf, void *data) +static unsigned int opserv_cdiscrim_search(cdiscrim_t discrim, cdiscrim_search_func dsf, void *data, struct userNode *bot) { unsigned int count = 0; dict_iterator_t it, next; for (it = dict_first(channels); it && count < discrim->limit ; it = next) { - struct chanNode *chan = iter_data(it); + struct chanNode *chan = iter_data(it); - /* Hold on to the next channel in case we decide to - add actions that destructively modify the channel. */ - next = iter_next(it); - if ((chan->members.used > 0) && cdiscrim_match(discrim, chan)) { - dsf(chan, data); - count++; - } + /* Hold on to the next channel in case we decide to + add actions that destructively modify the channel. */ + next = iter_next(it); + if ((chan->members.used > 0) && cdiscrim_match(discrim, chan)) { + dsf(chan, data, bot); + count++; + } } return count; } -void channel_count(UNUSED_ARG(struct chanNode *channel), UNUSED_ARG(void *data)) +void channel_count(UNUSED_ARG(struct chanNode *channel), UNUSED_ARG(void *data), UNUSED_ARG(struct userNode *bot)) { } -void channel_print(struct chanNode *channel, void *data) +void channel_print(struct chanNode *channel, void *data, struct userNode *bot) { char modes[MAXLEN]; irc_make_chanmode(channel, modes); - send_message(data, opserv, "OSMSG_CSEARCH_CHANNEL_INFO", channel->name, channel->members.used, modes, channel->topic); + send_message(data, bot, "OSMSG_CSEARCH_CHANNEL_INFO", channel->name, channel->members.used, modes, channel->topic); } static MODCMD_FUNC(cmd_csearch) @@ -3757,35 +3766,35 @@ static MODCMD_FUNC(cmd_csearch) char buf[MAXLEN]; if (!irccasecmp(argv[1], "count")) - action = channel_count; + action = channel_count; else if (!irccasecmp(argv[1], "print")) - action = channel_print; + action = channel_print; else { - reply("OSMSG_BAD_ACTION", argv[1]); - return 0; + reply("OSMSG_BAD_ACTION", argv[1]); + return 0; } sprintf(buf, "%s %s", argv[0], argv[0]); - if ((subcmd = dict_find(cmd->parent->commands, buf, NULL)) - && !svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, SVCCMD_NOISY)) { + if ((subcmd = dict_find(opserv_service->commands, buf, NULL)) + && !svccmd_can_invoke(user, opserv_service->bot, subcmd, channel, SVCCMD_NOISY)) { return 0; } - discrim = opserv_cdiscrim_create(user, argc - 2, argv + 2); + discrim = opserv_cdiscrim_create(user, cmd->parent->bot, argc - 2, argv + 2); if (!discrim) - return 0; + return 0; if (action == channel_print) - reply("OSMSG_CHANNEL_SEARCH_RESULTS"); + reply("OSMSG_CHANNEL_SEARCH_RESULTS"); else if (action == channel_count) - discrim->limit = INT_MAX; + discrim->limit = INT_MAX; - matches = opserv_cdiscrim_search(discrim, action, user); + matches = opserv_cdiscrim_search(discrim, action, user, cmd->parent->bot); if (matches) - reply("MSG_MATCH_COUNT", matches); + reply("MSG_MATCH_COUNT", matches); else - reply("MSG_NO_MATCHES"); + reply("MSG_NO_MATCHES"); free(discrim); return 1; @@ -3811,6 +3820,7 @@ static MODCMD_FUNC(cmd_gsync) struct gline_extra { struct userNode *user; struct string_list *glines; + struct userNode *bot; }; static void @@ -3821,7 +3831,7 @@ gtrace_print_func(struct gline *gline, void *extra) strftime(set_text, sizeof(set_text), "%Y-%m-%d", localtime(&gline->issued)); when_text = asctime(localtime(&gline->expires)); when_text[strlen(when_text)-1] = 0; /* strip lame \n */ - send_message(xtra->user, opserv, "OSMSG_GTRACE_FORMAT", gline->target, set_text, gline->issuer, when_text, gline->reason); + send_message(xtra->user, xtra->bot, "OSMSG_GTRACE_FORMAT", gline->target, set_text, gline->issuer, when_text, gline->reason); } static void @@ -3856,8 +3866,8 @@ static MODCMD_FUNC(cmd_gtrace) return 0; } sprintf(buf, "%s %s", argv[0], argv[0]); - if ((subcmd = dict_find(cmd->parent->commands, buf, NULL)) - && !svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, SVCCMD_NOISY)) { + if ((subcmd = dict_find(opserv_service->commands, buf, NULL)) + && !svccmd_can_invoke(user, opserv_service->bot, subcmd, channel, SVCCMD_NOISY)) { return 0; } @@ -3872,6 +3882,7 @@ static MODCMD_FUNC(cmd_gtrace) extra.user = user; extra.glines = alloc_string_list(4); + extra.bot = cmd->parent->bot; matches = gline_discrim_search(discrim, action, &extra); if (action == gtrace_ungline_func) @@ -3981,9 +3992,9 @@ static MODCMD_FUNC(cmd_log) matches = log_entry_search(discrim, log_report_entry, &report); if (matches) - reply("MSG_MATCH_COUNT", matches); + reply("MSG_MATCH_COUNT", matches); else - reply("MSG_NO_MATCHES"); + reply("MSG_NO_MATCHES"); free(discrim); return 1; @@ -4008,26 +4019,26 @@ static MODCMD_FUNC(cmd_gag) reason = unsplit_string(argv + 3, argc - 3, NULL); if (!is_ircmask(argv[1])) { - reply("OSMSG_INVALID_IRCMASK", argv[1]); + reply("OSMSG_INVALID_IRCMASK", argv[1]); return 0; } for (gag = gagList; gag; gag = gag->next) - if (match_ircglobs(gag->mask, argv[1])) + if (match_ircglobs(gag->mask, argv[1])) break; if (gag) { - reply("OSMSG_REDUNDANT_GAG", argv[1]); - return 0; + reply("OSMSG_REDUNDANT_GAG", argv[1]); + return 0; } duration = ParseInterval(argv[2]); gagged = gag_create(argv[1], user->handle_info->handle, reason, (duration?now+duration:0)); if (gagged) - reply("OSMSG_GAG_APPLIED", argv[1], gagged); + reply("OSMSG_GAG_APPLIED", argv[1], gagged); else - reply("OSMSG_GAG_ADDED", argv[1]); + reply("OSMSG_GAG_ADDED", argv[1]); return 1; } @@ -4044,21 +4055,21 @@ static MODCMD_FUNC(cmd_ungag) unsigned int ungagged; for (gag = gagList; gag; gag = gag->next) - if (!strcmp(gag->mask, argv[1])) + if (!strcmp(gag->mask, argv[1])) break; if (!gag) { - reply("OSMSG_GAG_NOT_FOUND", argv[1]); - return 0; + reply("OSMSG_GAG_NOT_FOUND", argv[1]); + return 0; } timeq_del(gag->expires, gag_expire, gag, 0); ungagged = gag_free(gag); if (ungagged) - reply("OSMSG_UNGAG_APPLIED", argv[1], ungagged); + reply("OSMSG_UNGAG_APPLIED", argv[1], ungagged); else - reply("OSMSG_UNGAG_ADDED", argv[1]); + reply("OSMSG_UNGAG_ADDED", argv[1]); return 1; } @@ -4071,9 +4082,9 @@ static MODCMD_FUNC(cmd_addalert) name = argv[1]; sprintf(buf, "addalert %s", argv[2]); - if (!(subcmd = dict_find(cmd->parent->commands, buf, NULL))) { - reply("OSMSG_UNKNOWN_REACTION", argv[2]); - return 0; + if (!(subcmd = dict_find(opserv_service->commands, buf, NULL))) { + reply("OSMSG_UNKNOWN_REACTION", argv[2]); + return 0; } if (!irccasecmp(argv[2], "notice")) reaction = REACT_NOTICE; @@ -4082,10 +4093,10 @@ static MODCMD_FUNC(cmd_addalert) else if (!irccasecmp(argv[2], "gline")) reaction = REACT_GLINE; else { - reply("OSMSG_UNKNOWN_REACTION", argv[2]); - return 0; + reply("OSMSG_UNKNOWN_REACTION", argv[2]); + return 0; } - if (!svccmd_can_invoke(user, cmd->parent->bot, subcmd, channel, SVCCMD_NOISY) + if (!svccmd_can_invoke(user, opserv_service->bot, subcmd, channel, SVCCMD_NOISY) || !opserv_add_user_alert(user, name, reaction, unsplit_string(argv + 3, argc - 3, NULL))) return 0; reply("OSMSG_ADDED_ALERT", name); @@ -4098,10 +4109,10 @@ static MODCMD_FUNC(cmd_delalert) for (i=1; itype != RECDB_OBJECT) { - log_module(OS_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", OPSERV_CONF_NAME); - return; + log_module(OS_LOG, LOG_ERROR, "config node `%s' is missing or has wrong type.", OPSERV_CONF_NAME); + return; } conf_node = rd->d.object; str = database_get_data(conf_node, KEY_DEBUG_CHANNEL, RECDB_QSTRING); @@ -4126,20 +4137,20 @@ opserv_conf_read(void) str2 = database_get_data(conf_node, KEY_DEBUG_CHANNEL_MODES, RECDB_QSTRING); if (!str2) str2 = "+tinms"; - opserv_conf.debug_channel = AddChannel(str, now, str2, NULL, NULL); + opserv_conf.debug_channel = AddChannel(str, now, str2, NULL, NULL); AddChannelUser(opserv, opserv_conf.debug_channel)->modes |= MODE_CHANOP; } else { - opserv_conf.debug_channel = NULL; + opserv_conf.debug_channel = NULL; } str = database_get_data(conf_node, KEY_ALERT_CHANNEL, RECDB_QSTRING); if (opserv && str) { str2 = database_get_data(conf_node, KEY_ALERT_CHANNEL_MODES, RECDB_QSTRING); if (!str2) str2 = "+tns"; - opserv_conf.alert_channel = AddChannel(str, now, str2, NULL, NULL); + opserv_conf.alert_channel = AddChannel(str, now, str2, NULL, NULL); AddChannelUser(opserv, opserv_conf.alert_channel)->modes |= MODE_CHANOP; } else { - opserv_conf.alert_channel = NULL; + opserv_conf.alert_channel = NULL; } str = database_get_data(conf_node, KEY_STAFF_AUTH_CHANNEL, RECDB_QSTRING); if (opserv && str) { @@ -4176,7 +4187,7 @@ opserv_conf_read(void) policer_params_set(opserv_conf.join_policer_params, "size", "20"); policer_params_set(opserv_conf.join_policer_params, "drain-rate", "1"); if ((child = database_get_data(conf_node, KEY_JOIN_POLICER, RECDB_OBJECT))) - dict_foreach(child, set_policer_param, opserv_conf.join_policer_params); + dict_foreach(child, set_policer_param, opserv_conf.join_policer_params); for (it = dict_first(channels); it; it = iter_next(it)) { struct chanNode *cNode = iter_data(it); @@ -4190,7 +4201,7 @@ opserv_conf_read(void) policer_params_set(pp, "size", "200"); policer_params_set(pp, "drain-rate", "3"); if ((child = database_get_data(conf_node, KEY_NEW_USER_POLICER, RECDB_OBJECT))) - dict_foreach(child, set_policer_param, pp); + dict_foreach(child, set_policer_param, pp); } /* lame way to export opserv_conf value to nickserv.c ... */ @@ -4380,7 +4391,10 @@ init_opserv(const char *nick) opserv_db_init(); saxdb_register("OpServ", opserv_saxdb_read, opserv_saxdb_write); if (nick) - service_register(opserv)->trigger = '?'; + { + opserv_service = service_register(opserv); + opserv_service->trigger = '?'; + } reg_exit_func(opserv_db_cleanup); message_register_table(msgtab);