Clarify NickServ REGISTER help messages; fix ?raw and ?dump errors.
[srvx.git] / src / opserv.c
index a63c0e148141ec2dd45c3823c7f87f386a6d4d1d..a5d8c4ee53463a94faee8ce3e9cde5263dd170c6 100644 (file)
@@ -402,16 +402,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;
 }
 
@@ -522,9 +522,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;
@@ -559,7 +561,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;
@@ -581,7 +583,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;
@@ -886,7 +888,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);
@@ -923,7 +925,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);
@@ -968,7 +970,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) {
@@ -1018,7 +1020,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);
@@ -1038,15 +1040,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);
@@ -1116,7 +1119,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;
@@ -1138,7 +1141,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;
@@ -1159,10 +1162,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;
@@ -1211,7 +1212,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;
@@ -1228,7 +1229,7 @@ static MODCMD_FUNC(cmd_voiceall)
        if (mn->modes & (MODE_CHANOP|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;
@@ -1250,7 +1251,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;
@@ -1579,11 +1580,33 @@ static MODCMD_FUNC(cmd_stats_warn) {
     return 1;
 }
 
+#if defined(WITH_MALLOC_SRVX)
+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.",
+                      big_alloc_count, big_alloc_size);
+    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)) {
@@ -1596,9 +1619,9 @@ static MODCMD_FUNC(cmd_dump)
 
 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. */
@@ -1802,9 +1825,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; ) {
@@ -1883,11 +1906,10 @@ 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))
-                change.modes_set |= MODE_MODERATED;
+            change.modes_set = (MODE_MODERATED | MODE_DELAYJOINS) & ~channel->modes;
             if (change.modes_set || change.argc)
                 mod_chanmode_announce(opserv, channel, &change);
             send_target_message(0, channel->name, opserv, "OSMSG_FLOOD_MODERATE");
@@ -2285,8 +2307,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;
        }
@@ -4022,8 +4044,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));
@@ -4100,6 +4124,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_SRVX) || 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);