svsjoin, svsmode, svsnick, relay and simul added
[srvx.git] / src / opserv.c
index 0702a1072e9cebbf1783cc85429df6ab2271c1df..a899e2c0a6b97ca6b6531fc0af76fc9ca672e0ed 100644 (file)
@@ -22,6 +22,7 @@
 #include "gline.h"
 #include "global.h"
 #include "nickserv.h"
+#include "chanserv.h"
 #include "modcmd.h"
 #include "opserv.h"
 #include "timeq.h"
@@ -72,6 +73,7 @@
 #define KEY_EXPIRES "expires"
 #define KEY_STAFF_AUTH_CHANNEL "staff_auth_channel"
 #define KEY_STAFF_AUTH_CHANNEL_MODES "staff_auth_channel_modes"
+#define KEY_STAFF_AUTH_FORCE_OPS "staff_auth_force_opers"
 #define KEY_CLONE_GLINE_DURATION "clone_gline_duration"
 #define KEY_BLOCK_GLINE_DURATION "block_gline_duration"
 #define KEY_ISSUER "issuer"
@@ -262,6 +264,12 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_CSEARCH_CHANNEL_INFO", "%s [%d users] %s %s" },
     { "OSMSG_TRACE_MAX_CHANNELS", "You may not use the 'channel' criterion more than %d times." },
     { "OSMSG_FORCEKICK_LOCAL", "You cannot kick $b%s$b forcefully." },
+    { "OSMSG_SVSNONICK", "$b%s$b is not a valid nick." },
+    { "OSMSG_SVSNICKUSED", "$b%s$b is an already used nickname." },
+    { "OSMSG_SVSNICK", "You have renamed $b%s$b to $b%s$b." },
+    { "OSMSG_SVSJOIN", "$b%s$b joined $b%s$b." },
+    { "OSMSG_SVSMODE", "You have set mode $b%s$b for $b%s$b." },
+    { "OSMSG_SIMUL", "You have simuled $b%s$b: %s" },
     { "OSMSG_DEVNULL_USER" , "[%s] %s  %s" },
     { "OSMSG_DEVNULL_MATCH" , "%d Users found." },
     { "OSMSG_DEVNULL_CLASS" , "%s is not a valid DevNull class." },
@@ -323,6 +331,7 @@ static struct {
     struct chanNode *debug_channel;
     struct chanNode *alert_channel;
     struct chanNode *staff_auth_channel;
+    int staff_auth_force;
     struct policer_params *join_policer_params;
     struct policer new_user_policer;
     unsigned long untrusted_max;
@@ -4696,6 +4705,110 @@ struct devnull_class*
     return dict_find(opserv_devnull_classes, name, NULL);
 }
 
+void operpart(struct chanNode *chan, struct userNode *user)
+{
+    if(opserv_conf.alert_channel && opserv_conf.staff_auth_force > 0 &&
+      !(irccasecmp(chan->name,opserv_conf.alert_channel->name))) {
+        struct mod_chanmode *change;
+        change = find_matching_bans(&chan->banlist, user, NULL); //don't join them if they're banned (exceptions from forced join)
+        if(change)
+            return;
+        irc_svsjoin(opserv,user,chan);
+    }
+}
+
+void operadd(struct userNode *user)
+{
+    if(opserv_conf.alert_channel && opserv_conf.staff_auth_force > 0)
+        irc_svsjoin(opserv,user,opserv_conf.alert_channel);
+}
+
+void operdel(struct userNode *user)
+{
+    if(opserv_conf.alert_channel && opserv_conf.staff_auth_force == 2)
+        irc_kick(opserv, user, opserv_conf.alert_channel, "mode -o");
+}
+
+static MODCMD_FUNC(cmd_svsjoin)
+{
+    struct userNode *target;
+    if(!(target=GetUserH(argv[1]))) {
+        reply("OSMSG_SVSNONICK", argv[1]);
+        return 0;
+    }
+    if(!IsChannelName(argv[2]))
+    {
+        reply("MSG_NOT_CHANNEL_NAME");
+        return 0;
+    }
+    irc_svsjoinchan(opserv,target,argv[2]);
+    reply("OSMSG_SVSJOIN",target->nick,argv[2]);
+    return 1;
+}
+
+static MODCMD_FUNC(cmd_svsnick)
+{
+    struct userNode *target;
+    if(!(target=GetUserH(argv[1]))) {
+        reply("OSMSG_SVSNONICK", argv[1]);
+        return 0;
+    }
+    if(GetUserH(argv[2]))
+    {
+        reply("OSMSG_SVSNICKUSED",argv[2]);
+        return 0;
+    }
+    irc_svsnick(opserv,target,argv[2]);
+    reply("OSMSG_SVSNICK",target->nick,argv[2]);
+    return 1;
+}
+
+static MODCMD_FUNC(cmd_svsmode)
+{
+    struct userNode *target;
+    char *modestr;
+    if(!(target=GetUserH(argv[1]))) {
+        reply("OSMSG_SVSNONICK", argv[1]);
+        return 0;
+    }
+    modestr = unsplit_string(argv + 2, argc - 2, NULL);
+    irc_svsmode(opserv,target,modestr);
+    reply("OSMSG_SVSMODE",modestr,target->nick);
+    return 1;
+}
+
+static MODCMD_FUNC(cmd_simul)
+{
+    struct userNode *target;
+    char *line;
+    if(!(target=GetUserH(argv[1]))) {
+        reply("OSMSG_SVSNONICK", argv[1]);
+        return 0;
+    }
+    line = unsplit_string(argv + 2, argc - 2, NULL);
+    irc_simul(target,line);
+    reply("OSMSG_SIMUL",target->nick,line);
+    return 1;
+}
+
+static MODCMD_FUNC(cmd_relay)
+{
+    struct userNode *target;
+    char *line;
+    if(!(target=GetUserH(argv[1]))) {
+        reply("OSMSG_SVSNONICK", argv[1]);
+        return 0;
+    }
+    line = unsplit_string(argv + 2, argc - 2, NULL);
+    char sendline[512];
+    if(channel)
+        sprintf(sendline, "relay %s %s :%s",user->nick,channel->name,line);
+    else
+        sprintf(sendline, "relay %s query :%s",user->nick,line);
+    irc_privmsg(opserv,target->numeric,sendline);
+    return 1;
+}
+
 static void
 opserv_conf_read(void)
 {
@@ -4738,8 +4851,11 @@ opserv_conf_read(void)
             str2 = "+timns";
         opserv_conf.staff_auth_channel = AddChannel(str, now, str2, NULL);
         AddChannelUser(opserv, opserv_conf.staff_auth_channel)->modes |= MODE_CHANOP;
+        str2 = database_get_data(conf_node, KEY_STAFF_AUTH_FORCE_OPS, RECDB_QSTRING);
+        opserv_conf.staff_auth_force = str2 ? atoi(str2) : 0;
     } else {
         opserv_conf.staff_auth_channel = NULL;
+        opserv_conf.staff_auth_force = 0;
     }
     str = database_get_data(conf_node, KEY_UNTRUSTED_MAX, RECDB_QSTRING);
     opserv_conf.untrusted_max = str ? strtoul(str, NULL, 0) : 5;
@@ -4939,6 +5055,11 @@ init_opserv(const char *nick)
     opserv_define_func("DEVNULL RENAME", cmd_renamedevnull, 200, 0, 3);
     opserv_define_func("DEVNULL SET", cmd_setdevnull, 200, 0, 2);
     opserv_define_func("DEVNULL LIST", cmd_listdevnull, 200, 0, 0);
+    opserv_define_func("SVSJOIN", cmd_svsjoin, 800, 0, 3);
+    opserv_define_func("SVSMODE", cmd_svsmode, 800, 0, 3);
+    opserv_define_func("SVSNICK", cmd_svsnick, 800, 0, 3);
+    opserv_define_func("RELAY", cmd_relay, 800, 0, 0);
+    opserv_define_func("SIMUL", cmd_simul, 999, 0, 2);
     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);