added cmd_opme command to chanserv (based on new devnull privilege: OpMe)
[srvx.git] / src / chanserv.c
index 28db426c4807f229d4981851083b5a9964e59bd5..9b5468136f223b03e6346c44bd128d45366605ed 100644 (file)
@@ -22,7 +22,7 @@
 #include "conf.h"
 #include "global.h"
 #include "modcmd.h"
-#include "opserv.h" /* for opserv_bad_channel() */
+#include "opserv.h" /* for opserv_bad_channel() and devnull management */
 #include "nickserv.h" /* for oper_outranks() */
 #include "saxdb.h"
 #include "spamserv.h"
@@ -3236,6 +3236,45 @@ static CHANSERV_FUNC(cmd_devoice)
     return modify_users(CSFUNC_ARGS, NULL, MODE_REMOVE|MODE_VOICE, "CSMSG_DEVOICED_USERS");
 }
 
+static CHANSERV_FUNC(cmd_opme)
+{
+    struct mod_chanmode change;
+    struct userData *uData;
+    const char *errmsg;
+
+    mod_chanmode_init(&change);
+    change.argc = 1;
+    change.args[0].u.member = GetUserMode(channel, user);
+    if(!change.args[0].u.member)
+    {
+        if(argc)
+            reply("MSG_CHANNEL_ABSENT", channel->name);
+        return 0;
+    }
+
+    struct devnull_class *devnull;
+    if(user->handle_info->devnull && (devnull = devnull_get(user->handle_info->devnull)) && (devnull->modes & DEVNULL_MODE_OPME))
+    {
+        change.args[0].mode = MODE_CHANOP;
+        errmsg = "CSMSG_ALREADY_OPPED";
+    }
+    else
+    {
+        if(argc)
+            reply("CSMSG_NO_ACCESS");
+        return 0;
+    }
+    change.args[0].mode &= ~change.args[0].u.member->modes;
+    if(!change.args[0].mode)
+    {
+        if(argc)
+            reply(errmsg, channel->name);
+        return 0;
+    }
+    modcmd_chanmode_announce(&change);
+    return 1;
+}
+
 static int
 bad_channel_ban(struct chanNode *channel, struct userNode *user, const char *ban, unsigned int *victimCount, struct modeNode **victims)
 {
@@ -8663,6 +8702,8 @@ init_chanserv(const char *nick)
     DEFINE_COMMAND(endvote, 1, MODCMD_REQUIRE_AUTHED, NULL);
     DEFINE_COMMAND(voteresults, 1, MODCMD_REQUIRE_AUTHED, NULL);
 
+    DEFINE_COMMAND(opme, 1, MODCMD_REQUIRE_AUTHED|MODCMD_REQUIRE_CHANNEL, NULL);
+    
     /* Channel options */
     DEFINE_CHANNEL_OPTION(defaulttopic);
     DEFINE_CHANNEL_OPTION(topicmask);