]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/opserv.c
this never ends...
[irc/evilnet/x3.git] / src / opserv.c
index 74d1074b4158dd604fa8e9602994dcdf3d215e79..e95c18cb3bef460787636ac9a70743f89c9b7e1e 100644 (file)
@@ -1,7 +1,7 @@
 /* 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
@@ -249,6 +249,8 @@ static const struct message_entry msgtab[] = {
     { "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" },
@@ -407,16 +409,16 @@ static MODCMD_FUNC(cmd_ban)
     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;
 }
 
@@ -425,6 +427,7 @@ static MODCMD_FUNC(cmd_chaninfo)
     char buffer[MAXLEN];
     const char *fmt;
     struct banNode *ban;
+    struct exemptNode *exempt;
     struct modeNode *moden;
     unsigned int n;
 
@@ -454,6 +457,15 @@ static MODCMD_FUNC(cmd_chaninfo)
            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);
@@ -532,9 +544,11 @@ 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;
@@ -569,7 +583,7 @@ static MODCMD_FUNC(cmd_deop)
             || !(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;
@@ -594,7 +608,7 @@ static MODCMD_FUNC(cmd_dehop)
             || !(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;
@@ -616,7 +630,7 @@ static MODCMD_FUNC(cmd_deopall)
        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;
@@ -638,7 +652,7 @@ static MODCMD_FUNC(cmd_dehopall)
         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;
@@ -945,7 +959,7 @@ static MODCMD_FUNC(cmd_inviteme)
        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);
@@ -972,7 +986,7 @@ static MODCMD_FUNC(cmd_join)
         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);
@@ -982,7 +996,7 @@ static MODCMD_FUNC(cmd_join)
         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);
@@ -1027,7 +1041,7 @@ static MODCMD_FUNC(cmd_kickall)
         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) {
@@ -1077,7 +1091,7 @@ static MODCMD_FUNC(cmd_kickban)
     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);
@@ -1097,15 +1111,16 @@ static MODCMD_FUNC(cmd_kickbanall)
     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);
@@ -1175,7 +1190,7 @@ static MODCMD_FUNC(cmd_op)
         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;
@@ -1202,7 +1217,7 @@ static MODCMD_FUNC(cmd_hop)
         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;
@@ -1224,7 +1239,7 @@ static MODCMD_FUNC(cmd_opall)
        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;
@@ -1246,7 +1261,7 @@ static MODCMD_FUNC(cmd_hopall)
         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;
@@ -1267,10 +1282,8 @@ static MODCMD_FUNC(cmd_whois)
     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;
@@ -1295,6 +1308,7 @@ static MODCMD_FUNC(cmd_whois)
 
        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)");
@@ -1323,7 +1337,7 @@ static MODCMD_FUNC(cmd_unban)
     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;
@@ -1340,7 +1354,7 @@ static MODCMD_FUNC(cmd_voiceall)
        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;
@@ -1362,7 +1376,7 @@ static MODCMD_FUNC(cmd_devoiceall)
        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;
@@ -1691,6 +1705,28 @@ static MODCMD_FUNC(cmd_stats_warn) {
     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;
@@ -1914,9 +1950,9 @@ opserv_shutdown_channel(struct chanNode *channel, const char *reason)
     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; ) {
@@ -1995,7 +2031,7 @@ opserv_join_check(struct modeNode *mNode)
             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))
@@ -2367,7 +2403,7 @@ static MODCMD_FUNC(cmd_clone)
     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;
        }
@@ -2397,8 +2433,8 @@ static MODCMD_FUNC(cmd_clone)
         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;
        }
@@ -2415,8 +2451,8 @@ static MODCMD_FUNC(cmd_clone)
         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;
         }
@@ -3113,7 +3149,7 @@ opserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[], in
                     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);
@@ -4039,7 +4075,7 @@ 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);
+       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;
@@ -4049,7 +4085,7 @@ opserv_conf_read(void)
         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;
@@ -4059,7 +4095,7 @@ opserv_conf_read(void)
         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;
@@ -4158,8 +4194,10 @@ void
 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));
@@ -4240,6 +4278,9 @@ init_opserv(const char *nick)
     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);
+#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);