/* opserv.c - IRC Operator assistance service
* Copyright 2000-2004 srvx Development Team
*
- * This file is part of srvx.
+ * This file is part of x3.
*
* srvx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#define KEY_BLOCK_GLINE_DURATION "block_gline_duration"
#define KEY_ISSUER "issuer"
#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 OSMSG_GAG_REQUESTED "Gag requested by %s."
static const struct message_entry msgtab[] = {
+ { "OSMSG_BAR", "----------------------------------------" },
{ "OSMSG_USER_ACCESS_IS", "$b%s$b (account $b%s$b) has %d access." },
{ "OSMSG_LEVEL_TOO_LOW", "You lack sufficient access to use this command." },
{ "OSMSG_NEED_CHANNEL", "You must specify a channel for $b%s$b." },
{ "OSMSG_MAX_CLIENTS", "Max clients: %d at %s" },
{ "OSMSG_NETWORK_INFO", "Total users: %d (%d invisible, %d opers)" },
{ "OSMSG_RESERVED_LIST", "List of reserved nicks:" },
- { "OSMSG_TRUSTED_LIST", "List of trusted hosts:" },
- { "OSMSG_HOST_IS_TRUSTED", "%s (%s; set %s ago by %s; expires %s: %s)" },
+ { "OSMSG_TRUSTED_LIST", "$bTrusted Hosts$b" },
+ { "OSMSG_TRUSTED_LIST_HEADER", "IP Address Limit By Time" },
+ { "OSMSG_HOST_IS_TRUSTED", "%-15s %-5s %-10s set %s ago, expires %s" },
+ { "OSMSG_HOST_IS_TRUSTED_DESC", " Reason: %s" },
+ { "OSMSG_TRUSTED_LIST_BAR", "----------------------------------------" },
+ { "OSMSG_TRUSTED_LIST_END", "----------End of Trusted Hosts----------" },
{ "OSMSG_HOST_NOT_TRUSTED", "%s does not have a special trust." },
{ "OSMSG_UPTIME_STATS", "Uptime: %s (%u lines processed, CPU time %.2fu/%.2fs)" },
{ "OSMSG_LINE_DUMPED", "Raw line sent." },
{ "OSMSG_SETTIME_SUCCESS", "Set time for servers named like $b%s$b." },
{ "OSMSG_BAD_ACTION", "Unrecognized trace action $b%s$b." },
{ "OSMSG_USER_SEARCH_RESULTS", "The following users were found:" },
+ { "OSMSG_USER_SEARCH_HEADER", "Nick User@Host (Account)" },
+ { "OSMSG_USER_SEARCH_BAR", "-------------------------------------------" },
+ { "OSMSG_USER_SEARCH_COUNT", "There were %4u matches" },
+ { "OSMSG_USER_SEARCH_COUNT_BAR", "------------ Found %4u matches -----------" },
{ "OSMSG_CHANNEL_SEARCH_RESULTS", "The following channels were found:" },
{ "OSMSG_GLINE_SEARCH_RESULTS", "The following glines were found:" },
{ "OSMSG_LOG_SEARCH_RESULTS", "The following log entries were found:" },
{ "OSMSG_ADDED_ALERT", "Added alert named $b%s$b." },
{ "OSMSG_REMOVED_ALERT", "Removed alert named $b%s$b." },
{ "OSMSG_NO_SUCH_ALERT", "No alert named $b%s$b could be found." },
- { "OSMSG_ALERT_IS", "%s (by %s, reaction %s): %s" },
- { "OSMSG_ALERTS_LIST", "Current $O alerts:" },
+ { "OSMSG_ALERTS_LIST", "$bCurrent $O alerts$b" },
+ { "OSMSG_ALERTS_BAR", "----------------------------------------------" },
+ { "OSMSG_ALERTS_HEADER", "Name Action (by Oper)" },
+ { "OSMSG_ALERTS_DESC", " Criteria: %s" },
+ { "OSMSG_ALERT_IS", "$b%-20s$b %-6s (by %s)" },
+ { "OSMSG_ALERT_END", "----------------End of Alerts-----------------" },
{ "OSMSG_REHASH_COMPLETE", "Completed rehash of configuration database." },
{ "OSMSG_REHASH_FAILED", "Rehash of configuration database failed, previous configuration is intact." },
{ "OSMSG_REOPEN_COMPLETE", "Closed and reopened all log files." },
{ "OSMSG_SERVER_JUPED", "Added new jupe server %s." },
{ "OSMSG_SERVER_NOT_JUPE", "That server is not a juped server." },
{ "OSMSG_SERVER_UNJUPED", "Server jupe removed." },
+ /*
{ "OSMSG_WARN_ADDED", "Added channel activity warning for $b%s$b (%s)" },
{ "OSMSG_WARN_EXISTS", "Channel activity warning for $b%s$b already exists." },
{ "OSMSG_WARN_DELETED", "Removed channel activity warning for $b%s$b" },
{ "OSMSG_WARN_LISTSTART", "Channel activity warnings:" },
{ "OSMSG_WARN_LISTENTRY", "%s (%s)" },
{ "OSMSG_WARN_LISTEND", "End of activity warning list." },
+ */
{ "OSMSG_UPLINK_CONNECTING", "Establishing connection with %s (%s:%d)." },
{ "OSMSG_CURRENT_UPLINK", "$b%s$b is already the current uplink." },
{ "OSMSG_INVALID_UPLINK", "$b%s$b is not a valid uplink name." },
{ "OSMSG_CHANINFO_TOPIC_UNKNOWN", "Topic: (none / not gathered)" },
{ "OSMSG_CHANINFO_BAN_COUNT", "Bans (%d):" },
{ "OSMSG_CHANINFO_BAN", "%%s by %%s (%a %b %d %H:%M:%S %Y)" },
+ { "OSMSG_CHANINFO_EXEMPT_COUNT", "Exempts (%d):" },
+ { "OSMSG_CHANINFO_EXEMPT", "%%s by %%s (%a %b %d %H:%M:%S %Y)" },
{ "OSMSG_CHANINFO_MANY_USERS", "%d users (\"/msg $S %s %s users\" for the list)" },
{ "OSMSG_CHANINFO_USER_COUNT", "Users (%d):" },
{ "OSMSG_CSEARCH_CHANNEL_INFO", "%s [%d users] %s %s" },
{ NULL, NULL }
};
-#define OPSERV_SYNTAX() svccmd_send_help(user, opserv, cmd)
+#define OPSERV_SYNTAX() svccmd_send_help_brief(user, opserv, cmd)
typedef int (*discrim_search_func)(struct userNode *match, void *extra);
struct userNode *opserv;
-static dict_t opserv_chan_warn; /* data is char* */
+/*static dict_t opserv_chan_warn; */ /* data is char* */
static dict_t opserv_reserved_nick_dict; /* data is struct userNode* */
static struct string_list *opserv_bad_words;
static dict_t opserv_exempt_channels; /* data is not used */
unsigned long purge_lock_delay;
unsigned long join_flood_moderate;
unsigned long join_flood_moderate_threshold;
+ unsigned long admin_level;
} opserv_conf;
struct trusted_host {
change.argc = 1;
change.args[0].mode = MODE_BAN;
if (is_ircmask(argv[1]))
- change.args[0].hostmask = strdup(argv[1]);
+ change.args[0].u.hostmask = strdup(argv[1]);
else if ((victim = GetUserH(argv[1])))
- change.args[0].hostmask = generate_hostmask(victim, 0);
+ change.args[0].u.hostmask = generate_hostmask(victim, 0);
else {
reply("OSMSG_INVALID_IRCMASK", argv[1]);
return 0;
}
modcmd_chanmode_announce(&change);
- reply("OSMSG_ADDED_BAN", change.args[0].hostmask, channel->name);
- free((char*)change.args[0].hostmask);
+ reply("OSMSG_ADDED_BAN", change.args[0].u.hostmask, channel->name);
+ free((char*)change.args[0].u.hostmask);
return 1;
}
char buffer[MAXLEN];
const char *fmt;
struct banNode *ban;
+ struct exemptNode *exempt;
struct modeNode *moden;
unsigned int n;
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);
+ fmt = user_find_message(user, "OSMSG_CHANINFO_EXEMPT");
+ for (n = 0; n < channel->exemptlist.used; n++) {
+ exempt = channel->exemptlist.list[n];
+ strftime(buffer, sizeof(buffer), fmt, localtime(&exempt->set));
+ send_message_type(4, user, cmd->parent->bot, buffer, exempt->exempt, exempt->who);
+ }
+ }
if ((argc < 2) && (channel->members.used >= 50)) {
/* early out unless they ask for users */
reply("OSMSG_CHANINFO_MANY_USERS", channel->members.used, argv[0], channel->name);
return 1;
}
+/* This command has been replaced by 'alert notice channel #foo' */
+/*
static MODCMD_FUNC(cmd_warn)
{
char *reason, *message;
reply("OSMSG_WARN_DELETED", argv[1]);
return 1;
}
+*/
static MODCMD_FUNC(cmd_clearbans)
{
change = mod_chanmode_alloc(channel->banlist.used);
for (ii=0; ii<channel->banlist.used; ii++) {
change->args[ii].mode = MODE_REMOVE | MODE_BAN;
- change->args[ii].hostmask = channel->banlist.list[ii]->ban;
+ change->args[ii].u.hostmask = strdup(channel->banlist.list[ii]->ban);
}
modcmd_chanmode_announce(change);
+ for (ii=0; ii<change->argc; ++ii)
+ free((char*)change->args[ii].u.hostmask);
mod_chanmode_free(change);
reply("OSMSG_CLEARBANS_DONE", channel->name);
return 1;
|| !(mn->modes & MODE_CHANOP))
continue;
change->args[count].mode = MODE_REMOVE | MODE_CHANOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
|| !(mn->modes & MODE_HALFOP))
continue;
change->args[count].mode = MODE_REMOVE | MODE_HALFOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
if (IsService(mn->user) || !(mn->modes & MODE_CHANOP))
continue;
change->args[count].mode = MODE_REMOVE | MODE_CHANOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
if (IsService(mn->user) || !(mn->modes & MODE_HALFOP))
continue;
change->args[count].mode = MODE_REMOVE | MODE_HALFOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
return 0;
}
if (GetUserMode(opserv_conf.debug_channel, user)) {
- reply("OSMSG_ALREADY_THERE", channel->name);
+ reply("OSMSG_ALREADY_THERE", opserv_conf.debug_channel->name);
return 0;
}
irc_invite(cmd->parent->bot, target, opserv_conf.debug_channel);
reply("MSG_NOT_CHANNEL_NAME");
return 0;
} else if (!(channel = GetChannel(argv[1]))) {
- channel = AddChannel(argv[1], now, NULL, NULL);
+ channel = AddChannel(argv[1], now, NULL, NULL, NULL);
AddChannelUser(bot, channel)->modes |= MODE_CHANOP;
} else if (GetUserMode(channel, bot)) {
reply("OSMSG_ALREADY_JOINED", channel->name);
mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_CHANOP;
- change.args[0].member = AddChannelUser(bot, channel);
+ change.args[0].u.member = AddChannelUser(bot, channel);
modcmd_chanmode_announce(&change);
}
irc_fetchtopic(bot, channel->name);
struct mod_chanmode change;
mod_chanmode_init(&change);
change.args[0].mode = MODE_CHANOP;
- change.args[0].member = AddChannelUser(bot, channel);
+ change.args[0].u.member = AddChannelUser(bot, channel);
modcmd_chanmode_announce(&change);
}
if (argc < 2) {
mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_BAN;
- change.args[0].hostmask = mask = generate_hostmask(target, 0);
+ change.args[0].u.hostmask = mask = generate_hostmask(target, 0);
modcmd_chanmode_announce(&change);
KickChannelUser(target, channel, cmd->parent->bot, reason);
free(mask);
if (!(inchan = GetUserMode(channel, bot) ? 1 : 0)) {
change = mod_chanmode_alloc(2);
change->args[0].mode = MODE_CHANOP;
- change->args[0].member = AddChannelUser(bot, channel);
+ change->args[0].u.member = AddChannelUser(bot, channel);
change->args[1].mode = MODE_BAN;
- change->args[1].hostmask = "*!*@*";
+ change->args[1].u.hostmask = "*!*@*";
} else {
change = mod_chanmode_alloc(1);
change->args[0].mode = MODE_BAN;
- change->args[0].hostmask = "*!*@*";
+ change->args[0].u.hostmask = "*!*@*";
}
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);
if (mn->modes & MODE_CHANOP)
continue;
change->args[count].mode = MODE_CHANOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
if (mn->modes & MODE_HALFOP)
continue;
change->args[count].mode = MODE_HALFOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
if (mn->modes & MODE_CHANOP)
continue;
change->args[count].mode = MODE_CHANOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
if (mn->modes & MODE_HALFOP)
continue;
change->args[count].mode = MODE_HALFOP;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
if (argv[1][0] == '*')
target = GetUserN(argv[1]+1);
else
- target = GetUserH(argv[1]);
-#else
- target = GetUserH(argv[1]);
#endif
+ target = GetUserH(argv[1]);
if (!target) {
reply("MSG_NICK_UNKNOWN", argv[1]);
return 0;
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)");
mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_REMOVE | MODE_BAN;
- change.args[0].hostmask = argv[1];
+ change.args[0].u.hostmask = argv[1];
modcmd_chanmode_announce(&change);
reply("OSMSG_UNBAN_DONE", channel->name);
return 1;
if (mn->modes & (MODE_CHANOP|MODE_HALFOP|MODE_VOICE))
continue;
change->args[count].mode = MODE_VOICE;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
if (!(mn->modes & MODE_VOICE))
continue;
change->args[count].mode = MODE_REMOVE | MODE_VOICE;
- change->args[count++].member = mn;
+ change->args[count++].u.member = mn;
}
if (count) {
change->argc = count;
char buffer[400];
/* Show the bad word list.. */
+ /* TODO: convert nonprinting chars like bold to $b etc in a usable way */
for (ii=end=0; ii<opserv_bad_words->used; ii++) {
here_len = strlen(opserv_bad_words->list[ii]);
+ /* If the line is full output it & start again */
if ((end + here_len + 2) > sizeof(buffer)) {
buffer[end] = 0;
reply("OSMSG_BADWORD_LIST", buffer);
struct trusted_host *th;
char length[INTERVALLEN], issued[INTERVALLEN], limit[32];
+ reply("OSMSG_TRUSTED_LIST");
+ reply("OSMSG_TRUSTED_LIST_BAR");
+ reply("OSMSG_TRUSTED_LIST_HEADER");
+ reply("OSMSG_TRUSTED_LIST_BAR");
if (argc > 1) {
th = dict_find(opserv_trusted_hosts, argv[1], NULL);
if (th) {
if (th->expires)
intervalString(length, th->expires - now, user->handle_info);
if (th->limit)
- sprintf(limit, "limit %lu", th->limit);
+ sprintf(limit, "%lu", th->limit);
reply("OSMSG_HOST_IS_TRUSTED",
th->ipaddr,
- (th->limit ? limit : "no limit"),
- (th->issued ? issued : "some time"),
+ (th->limit ? limit : "none"),
(th->issuer ? th->issuer : "<unknown>"),
- (th->expires ? length : "never"),
- (th->reason ? th->reason : "<unknown>"));
+ (th->issued ? issued : "some time"),
+ (th->expires ? length : "never"));
+ reply("OSMSG_HOST_IS_TRUSTED_DESC", (th->reason ? th->reason : "<unknown>"));
} else {
reply("OSMSG_HOST_NOT_TRUSTED", argv[1]);
}
} else {
- reply("OSMSG_TRUSTED_LIST");
for (it = dict_first(opserv_trusted_hosts); it; it = iter_next(it)) {
th = iter_data(it);
if (th->issued)
if (th->expires)
intervalString(length, th->expires - now, user->handle_info);
if (th->limit)
- sprintf(limit, "limit %lu", th->limit);
+ sprintf(limit, "%lu", th->limit);
reply("OSMSG_HOST_IS_TRUSTED", iter_key(it),
- (th->limit ? limit : "no limit"),
- (th->issued ? issued : "some time"),
+ (th->limit ? limit : "none"),
(th->issuer ? th->issuer : "<unknown>"),
- (th->expires ? length : "never"),
- (th->reason ? th->reason : "<unknown>"));
+ (th->issued ? issued : "some time"),
+ (th->expires ? length : "never"));
+ reply("OSMSG_HOST_IS_TRUSTED_DESC", (th->reason ? th->reason : "<unknown>"));
}
}
+ reply("OSMSG_TRUSTED_LIST_END");
return 1;
}
const char *reaction;
reply("OSMSG_ALERTS_LIST");
+ reply("OSMSG_ALERTS_BAR");
+ reply("OSMSG_ALERTS_HEADER");
+ reply("OSMSG_ALERTS_BAR");
for (it = dict_first(opserv_user_alerts); it; it = iter_next(it)) {
alert = iter_data(it);
switch (alert->reaction) {
case REACT_GLINE: reaction = "gline"; break;
default: reaction = "<unknown>"; break;
}
- reply("OSMSG_ALERT_IS", iter_key(it), alert->owner, reaction, alert->text_discrim);
+ reply("OSMSG_ALERT_IS", iter_key(it), reaction, alert->owner);
+ reply("OSMSG_ALERTS_DESC", alert->text_discrim);
}
+ reply("OSMSG_ALERT_END");
return 1;
}
return 1;
}
+/*
static MODCMD_FUNC(cmd_stats_warn) {
dict_iterator_t it;
reply("OSMSG_WARN_LISTEND");
return 1;
}
+*/
+
+#if defined(WITH_MALLOC_X3)
+static MODCMD_FUNC(cmd_stats_memory) {
+ extern unsigned long alloc_count, alloc_size;
+ send_message_type(MSG_TYPE_NOXLATE, user, cmd->parent->bot,
+ "%u allocations totalling %u bytes.",
+ alloc_count, alloc_size);
+ return 1;
+}
+#elif defined(WITH_MALLOC_SLAB)
+static MODCMD_FUNC(cmd_stats_memory) {
+ extern unsigned long slab_alloc_count, slab_count, slab_alloc_size;
+ extern unsigned long big_alloc_count, big_alloc_size;
+ send_message_type(MSG_TYPE_NOXLATE, user, cmd->parent->bot,
+ "%u allocations in %u slabs totalling %u bytes.",
+ slab_alloc_count, slab_count, slab_alloc_size);
+/* send_message_type(MSG_TYPE_NOXLATE, user, cmd->parent->bot,
+ "%u big allocations totalling %u bytes.",
+ */
+ return 1;
+}
+#endif
static MODCMD_FUNC(cmd_dump)
{
- char linedup[MAXLEN], *original;
+ char linedup[MAXLEN], original[MAXLEN];
- original = unsplit_string(argv+1, argc-1, NULL);
+ unsplit_string(argv+1, argc-1, original);
safestrncpy(linedup, original, sizeof(linedup));
/* assume it's only valid IRC if we can parse it */
if (parse_line(linedup, 1)) {
static MODCMD_FUNC(cmd_raw)
{
- char linedup[MAXLEN], *original;
+ char linedup[MAXLEN], original[MAXLEN];
- original = unsplit_string(argv+1, argc-1, NULL);
+ unsplit_string(argv+1, argc-1, original);
safestrncpy(linedup, original, sizeof(linedup));
/* Try to parse the line before sending it; if it's too wrong,
* maybe it will core us instead of our uplink. */
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))
change = mod_chanmode_alloc(2);
change->modes_set = MODE_SECRET | MODE_INVITEONLY;
change->args[0].mode = MODE_CHANOP;
- change->args[0].member = AddChannelUser(opserv, channel);
+ change->args[0].u.member = AddChannelUser(opserv, channel);
change->args[1].mode = MODE_BAN;
- change->args[1].hostmask = "*!*@*";
+ change->args[1].u.hostmask = "*!*@*";
mod_chanmode_announce(opserv, channel, change);
mod_chanmode_free(change);
for (nn=channel->members.used; nn>0; ) {
static void
opserv_channel_check(struct chanNode *newchan)
{
- char *warning;
+ /*char *warning; */
if (!newchan->join_policer.params) {
newchan->join_policer.last_req = now;
newchan->join_policer.params = opserv_conf.join_policer_params;
}
+ /*
if ((warning = dict_find(opserv_chan_warn, newchan->name, NULL))) {
char message[MAXLEN];
snprintf(message, sizeof(message), "Channel activity warning for channel %s: %s", newchan->name, warning);
global_message(MESSAGE_RECIPIENT_OPERS, message);
}
+ */
/* Wait until the join check to shut channels down. */
newchan->bad_channel = opserv_bad_channel(newchan->name);
if (!GetUserMode(channel, opserv)) {
/* If we aren't in the channel, join it. */
change.args[0].mode = MODE_CHANOP;
- change.args[0].member = AddChannelUser(opserv, channel);
+ change.args[0].u.member = AddChannelUser(opserv, channel);
change.argc++;
}
if (!(channel->modes & MODE_MODERATED))
channel = GetChannel(argv[3]);
if (!irccasecmp(argv[1], "JOIN")) {
if (!channel
- && !(channel = AddChannel(argv[3], now, NULL, NULL))) {
+ && !(channel = AddChannel(argv[3], now, NULL, NULL, NULL))) {
reply("MSG_CHANNEL_UNKNOWN", argv[3]);
return 0;
}
mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_CHANOP;
- change.args[0].member = GetUserMode(channel, clone);
- if (!change.args[0].member) {
+ change.args[0].u.member = GetUserMode(channel, clone);
+ if (!change.args[0].u.member) {
reply("OSMSG_NOT_ON_CHANNEL", clone->nick, channel->name);
return 0;
}
mod_chanmode_init(&change);
change.argc = 1;
change.args[0].mode = MODE_HALFOP;
- change.args[0].member = GetUserMode(channel, clone);
- if (!change.args[0].member) {
+ change.args[0].u.member = GetUserMode(channel, clone);
+ if (!change.args[0].u.member) {
reply("OSMSG_NOT_ON_CHANNEL", clone->nick, channel->name);
return 0;
}
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;
}
+/*
static int
add_chan_warn(const char *key, void *data, UNUSED_ARG(void *extra))
{
struct record_data *rd = data;
char *reason = GET_RECORD_QSTRING(rd);
- /* i hope this can't happen */
+ * i hope this can't happen *
if (!reason)
reason = "No Reason";
dict_insert(opserv_chan_warn, strdup(key), strdup(reason));
return 0;
}
+*/
static int
add_user_alert(const char *key, void *data, UNUSED_ARG(void *extra))
dict_foreach(object, add_gag_helper, NULL);
if ((object = database_get_data(conf_db, KEY_ALERTS, RECDB_OBJECT)))
dict_foreach(object, add_user_alert, NULL);
+/*
if ((object = database_get_data(conf_db, KEY_WARN, RECDB_OBJECT)))
dict_foreach(object, add_chan_warn, NULL);
+*/
return 0;
}
saxdb_end_record(ctx);
}
/* channel warnings */
+ /*
if (dict_size(opserv_chan_warn)) {
saxdb_start_record(ctx, KEY_WARN, 0);
for (it = dict_first(opserv_chan_warn); it; it = iter_next(it)) {
}
saxdb_end_record(ctx);
}
+ */
/* alerts */
if (dict_size(opserv_user_alerts)) {
saxdb_start_record(ctx, KEY_ALERTS, 1);
send_message(user, opserv, "MSG_CHANNEL_UNKNOWN", argv[i]);
goto fail;
} else {
- discrim->channel = AddChannel(argv[i]+j, now, NULL, NULL);
+ discrim->channel = AddChannel(argv[i]+j, now, NULL, NULL, NULL);
}
}
LockChannel(discrim->channel);
{
struct discrim_and_source *das = extra;
if (match->handle_info) {
- send_message_type(4, das->source, opserv, "%s!%s@%s %s", match->nick, match->ident, match->hostname, match->handle_info->handle);
+ 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);
} else {
- send_message_type(4, das->source, opserv, "%s!%s@%s", match->nick, match->ident, match->hostname);
+ send_message_type(4, das->source, opserv, "%-15s\002 \002%10s\002@\002%s", match->nick, match->ident, match->hostname);
}
return 0;
}
return 0;
if (action == trace_print_func)
- reply("OSMSG_USER_SEARCH_RESULTS");
+ {
+ reply("OSMSG_USER_SEARCH_RESULTS");
+ reply("OSMSG_USER_SEARCH_BAR");
+ reply("OSMSG_USER_SEARCH_HEADER");
+ reply("OSMSG_USER_SEARCH_BAR");
+ }
else if (action == trace_count_func)
das.discrim->limit = INT_MAX;
else if ((action == trace_gline_func) && !das.discrim->duration)
dict_foreach(das.dict, opserv_show_hostinfo, &das);
if (matches)
- reply("MSG_MATCH_COUNT", matches);
+ {
+ if(action == trace_print_func)
+ 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);
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);
+ 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;
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);
+ 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;
str2 = database_get_data(conf_node, KEY_STAFF_AUTH_CHANNEL_MODES, RECDB_QSTRING);
if (!str2)
str2 = "+timns";
- opserv_conf.staff_auth_channel = AddChannel(str, now, str2, NULL);
+ opserv_conf.staff_auth_channel = AddChannel(str, now, str2, NULL, NULL);
AddChannelUser(opserv, opserv_conf.staff_auth_channel)->modes |= MODE_CHANOP;
} else {
opserv_conf.staff_auth_channel = NULL;
}
+
+ str = database_get_data(conf_node, KEY_ADMIN_LEVEL, RECDB_QSTRING);
+ opserv_conf.admin_level = str ? strtoul(str, NULL, 0): 800;
+
str = database_get_data(conf_node, KEY_UNTRUSTED_MAX, RECDB_QSTRING);
opserv_conf.untrusted_max = str ? strtoul(str, NULL, 0) : 5;
str = database_get_data(conf_node, KEY_PURGE_LOCK_DELAY, RECDB_QSTRING);
dict_foreach(child, set_policer_param, pp);
}
+/* lame way to export opserv_conf value to nickserv.c ... */
+unsigned int
+opserv_conf_admin_level()
+{
+ return(opserv_conf.admin_level);
+}
+
static void
opserv_db_init(void) {
/* set up opserv_trusted_hosts dict */
opserv_trusted_hosts = dict_new();
dict_set_free_data(opserv_trusted_hosts, free_trusted_host);
/* set up opserv_chan_warn dict */
+
+/* alert trace notice channel #x replaces warnings
dict_delete(opserv_chan_warn);
opserv_chan_warn = dict_new();
dict_set_free_keys(opserv_chan_warn, free);
dict_set_free_data(opserv_chan_warn, free);
+*/
/* set up opserv_user_alerts */
dict_delete(opserv_channel_alerts);
opserv_channel_alerts = dict_new();
{
unsigned int nn;
- dict_delete(opserv_chan_warn);
+/* dict_delete(opserv_chan_warn); */
dict_delete(opserv_reserved_nick_dict);
free_string_list(opserv_bad_words);
dict_delete(opserv_exempt_channels);
init_opserv(const char *nick)
{
OS_LOG = log_register_type("OpServ", "file:opserv.log");
- if (nick)
- opserv = AddService(nick, "Oper Services", NULL);
+ if (nick) {
+ const char *modes = conf_get_data("services/opserv/modes", RECDB_QSTRING);
+ opserv = AddService(nick, modes ? modes : NULL, "Oper Services", NULL);
+ }
conf_register_reload(opserv_conf_read);
memset(level_strings, 0, sizeof(level_strings));
opserv_define_func("STATS TRUSTED", cmd_stats_trusted, 0, 0, 0);
opserv_define_func("STATS UPLINK", cmd_stats_uplink, 0, 0, 0);
opserv_define_func("STATS UPTIME", cmd_stats_uptime, 0, 0, 0);
- opserv_define_func("STATS WARN", cmd_stats_warn, 0, 0, 0);
+/* opserv_define_func("STATS WARN", cmd_stats_warn, 0, 0, 0); */
+#if defined(WITH_MALLOC_X3) || defined(WITH_MALLOC_SLAB)
+ opserv_define_func("STATS MEMORY", cmd_stats_memory, 0, 0, 0);
+#endif
opserv_define_func("TRACE", cmd_trace, 100, 0, 3);
opserv_define_func("TRACE PRINT", NULL, 0, 0, 0);
opserv_define_func("TRACE COUNT", NULL, 0, 0, 0);
modcmd_register(opserv_module, "GTRACE UNGLINE", NULL, 0, 0, "template", "ungline", NULL);
opserv_define_func("UNJUPE", cmd_unjupe, 900, 0, 2);
opserv_define_func("UNRESERVE", cmd_unreserve, 800, 0, 2);
- opserv_define_func("UNWARN", cmd_unwarn, 800, 0, 0);
+/* opserv_define_func("UNWARN", cmd_unwarn, 800, 0, 0); */
opserv_define_func("VOICEALL", cmd_voiceall, 300, 2, 0);
- opserv_define_func("WARN", cmd_warn, 800, 0, 2);
+/* opserv_define_func("WARN", cmd_warn, 800, 0, 2); */
opserv_define_func("WHOIS", cmd_whois, 0, 0, 2);
opserv_reserved_nick_dict = dict_new();
reg_new_user_func(opserv_new_user_check);
reg_nick_change_func(opserv_alert_check_nick);
reg_del_user_func(opserv_user_cleanup);
- reg_new_channel_func(opserv_channel_check);
+ reg_new_channel_func(opserv_channel_check);
reg_del_channel_func(opserv_channel_delete);
reg_join_func(opserv_join_check);
reg_auth_func(opserv_staff_alert);