]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/opserv.c
whoops
[irc/evilnet/x3.git] / src / opserv.c
index 33e92ae4a306fa6e432eddc25eb5a18c71cafef8..62a5de40933ab8125b483f85aaa24eed2cc55e58 100644 (file)
@@ -55,6 +55,7 @@
 #define KEY_NICK "nick"
 #define KEY_JOIN_POLICER "join_policer"
 #define KEY_NEW_USER_POLICER "new_user_policer"
+#define KEY_AUTOJOIN_CHANNELS "autojoin_channels"
 #define KEY_REASON "reason"
 #define KEY_RESERVES "reserves"
 #define KEY_IDENT "username" /* for compatibility with 1.0 DBs */
@@ -83,6 +84,7 @@
 #define KEY_ISSUER "issuer"
 #define KEY_ISSUED "issued"
 #define KEY_ADMIN_LEVEL "admin_level"
+#define KEY_SILENT_LEVEL "silent_level"
 
 #define IDENT_FORMAT            "%s [%s@%s/%s]"
 #define IDENT_DATA(user)        user->nick, user->ident, user->hostname, irc_ntoa(&user->ip)
@@ -290,6 +292,7 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_CSEARCH_CHANNEL_INFO", "%s [%d users] %s %s" },
     { "OSMSG_INVALID_REGEX", "Invalid regex: %s: %s (%d)" },
     { "OSMSG_TRACK_DISABLED", "Tracking is not currently compiled into X3" },
+    { "OSMSG_MAXUSERS_RESET", "Max clients has been reset to $b%d$b" },
     { NULL, NULL }
 };
 
@@ -314,6 +317,7 @@ static struct module *opserv_module;
 static struct log_type *OS_LOG;
 static unsigned int new_user_flood;
 static char *level_strings[1001];
+struct string_list *autojoin_channels;
 
 static struct {
     struct chanNode *debug_channel;
@@ -329,6 +333,7 @@ static struct {
     unsigned long join_flood_moderate;
     unsigned long join_flood_moderate_threshold;
     unsigned long admin_level;
+    unsigned long silent_level;
 } opserv_conf;
 
 struct trusted_host {
@@ -378,6 +383,7 @@ typedef struct opservDiscrim {
     int authed : 2, info_space : 2;
     unsigned int intra_scmp : 2, intra_dcmp : 2;
     unsigned int use_regex : 1;
+    unsigned int silent : 1;
 } *discrim_t;
 
 struct discrim_and_source {
@@ -396,7 +402,7 @@ static int ungag_helper_func(struct userNode *match, void *extra);
 typedef enum {
     REACT_NOTICE,
     REACT_KILL,
-    REACT_SILENT,
+//    REACT_SILENT,
     REACT_GLINE,
     REACT_TRACK,
     REACT_SHUN
@@ -435,6 +441,7 @@ opserv_free_user_alert(void *data)
 #define opserv_debug(format...) do { if (opserv_conf.debug_channel) send_channel_notice(opserv_conf.debug_channel , opserv , ## format); } while (0)
 #define opserv_alert(format...) do { if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel , opserv , ## format); } while (0)
 
+
 /* A lot of these commands are very similar to what ChanServ can do,
  * but OpServ can do them even on channels that aren't registered.
  */
@@ -727,6 +734,14 @@ static MODCMD_FUNC(cmd_dehopall)
     return 1;
 }
 
+static MODCMD_FUNC(cmd_resetmax)
+{
+    max_clients = dict_size(clients);
+    max_clients_time = now;
+    reply("OSMSG_MAXUSERS_RESET", max_clients);
+    return 1;
+}
+
 static MODCMD_FUNC(cmd_rehash)
 {
     extern char *services_config;
@@ -1815,7 +1830,7 @@ static MODCMD_FUNC(cmd_stats_alerts) {
         switch (alert->reaction) {
         case REACT_NOTICE: reaction = "notice"; break;
         case REACT_KILL: reaction = "kill"; break;
-        case REACT_SILENT: reaction = "silent"; break;
+//        case REACT_SILENT: reaction = "silent"; break;
         case REACT_GLINE: reaction = "gline"; break;
         case REACT_TRACK: reaction = "track"; break;
         case REACT_SHUN: reaction = "shun"; break;
@@ -1901,9 +1916,9 @@ static MODCMD_FUNC(cmd_stats_memory) {
     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,
+    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
@@ -2738,8 +2753,10 @@ opserv_define_func(const char *name, modcmd_func_t *func, int min_level, int req
 
 int add_reserved(const char *key, void *data, void *extra)
 {
+    struct chanNode *chan;
     struct record_data *rd = data;
     const char *ident, *hostname, *desc;
+    unsigned int i;
     struct userNode *reserve;
     ident = database_get_data(rd->d.object, KEY_IDENT, RECDB_QSTRING);
     if (!ident) {
@@ -2760,6 +2777,14 @@ int add_reserved(const char *key, void *data, void *extra)
         reserve->modes |= FLAGS_PERSISTENT;
         dict_insert(extra, reserve->nick, reserve);
     }
+
+    if (autojoin_channels && reserve) {
+        for (i = 0; i < autojoin_channels->used; i++) {
+            chan = AddChannel(autojoin_channels->list[i], now, "+nt", NULL, NULL);
+            AddChannelUser(reserve, chan)->modes |= MODE_VOICE;
+        }
+    }
+
     return 0;
 }
 
@@ -2781,6 +2806,7 @@ foreach_matching_user(const char *hostmask, discrim_search_func func, void *extr
     discrim->intra_scmp = 0;
     discrim->intra_dcmp = 0;
     discrim->use_regex = 0;
+    discrim->silent = 0;
     dupmask = strdup(hostmask);
     if (split_ircmask(dupmask, &discrim->mask_nick, &discrim->mask_ident, &discrim->mask_host)) {
         if (!irc_pton(&discrim->ip_mask, &discrim->ip_mask_bits, discrim->mask_host))
@@ -2938,8 +2964,10 @@ add_user_alert(const char *key, void *data, UNUSED_ARG(void *extra))
         reaction = REACT_NOTICE;
     else if (!irccasecmp(react, "kill"))
         reaction = REACT_KILL;
+    /*
     else if (!irccasecmp(react, "silent"))
         reaction = REACT_SILENT;
+    */
     else if (!irccasecmp(react, "gline"))
         reaction = REACT_GLINE;
     else if (!irccasecmp(react, "track"))
@@ -3132,7 +3160,7 @@ opserv_saxdb_write(struct saxdb_context *ctx)
             switch (alert->reaction) {
             case REACT_NOTICE: reaction = "notice"; break;
             case REACT_KILL: reaction = "kill"; break;
-            case REACT_SILENT: reaction = "silent"; break;
+//            case REACT_SILENT: reaction = "silent"; break;
             case REACT_GLINE: reaction = "gline"; break;
             case REACT_TRACK: reaction = "track"; break;
             case REACT_SHUN: reaction = "shun"; break;
@@ -3252,6 +3280,8 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int
     discrim->info_space = -1;
     discrim->intra_dcmp = 0;
     discrim->intra_scmp = 0;
+    discrim->use_regex = 0;
+    discrim->silent = 0;
 
     for (i=0; i<argc; i++) {
         if (irccasecmp(argv[i], "log") == 0) {
@@ -3358,6 +3388,18 @@ opserv_discrim_create(struct userNode *user, struct userNode *bot, unsigned int
             send_message(user, opserv, "MSG_INVALID_BINARY", argv[i]);
             goto fail;
         }
+    } else if (irccasecmp(argv[i], "silent") == 0) {
+        i++;
+        if(!oper_has_access(user, opserv, opserv_conf.silent_level, 0)) {
+            goto fail;
+        } else if (true_string(argv[i])) {
+            discrim->silent = 1;
+        } else if (false_string(argv[i])) {
+            discrim->silent = 0;
+        } else {
+            send_message(user, opserv, "MSG_INVALID_BINARY", argv[i]);
+            goto fail;
+        }
     } else if (irccasecmp(argv[i], "duration") == 0) {
         discrim->duration = ParseInterval(argv[++i]);
         } else if (irccasecmp(argv[i], "channel") == 0) {
@@ -3733,7 +3775,7 @@ trace_gline_func(struct userNode *match, void *extra)
     struct discrim_and_source *das = extra;
 
     if (is_oper_victim(das->source, match, das->discrim->match_opers)) {
-        opserv_block(match, das->source->handle_info->handle, das->discrim->reason, das->discrim->duration, 0);
+        opserv_block(match, das->source->handle_info->handle, das->discrim->reason, das->discrim->duration, das->discrim->silent);
     }
 
     return 0;
@@ -4375,11 +4417,13 @@ alert_check_user(const char *key, void *data, void *extra)
     case REACT_KILL:
         DelUser(user, opserv, 1, alert->discrim->reason);
         return 1;
+/*
     case REACT_SILENT:
         opserv_block(user, alert->owner, alert->discrim->reason, alert->discrim->duration, 1);
         return 1;
+*/
     case REACT_GLINE:
-        opserv_block(user, alert->owner, alert->discrim->reason, alert->discrim->duration, 0);
+        opserv_block(user, alert->owner, alert->discrim->reason, alert->discrim->duration, alert->discrim->silent);
         return 1;
     case REACT_SHUN:
         opserv_shun(user, alert->owner, alert->discrim->reason, alert->discrim->duration);
@@ -4553,8 +4597,10 @@ static MODCMD_FUNC(cmd_addalert)
         reaction = REACT_NOTICE;
     else if (!irccasecmp(argv[2], "kill"))
         reaction = REACT_KILL;
+/*
     else if (!irccasecmp(argv[2], "silent"))
         reaction = REACT_SILENT;
+*/
     else if (!irccasecmp(argv[2], "gline"))
         reaction = REACT_GLINE;
     else if (!irccasecmp(argv[2], "track")) {
@@ -4594,6 +4640,8 @@ static MODCMD_FUNC(cmd_delalert)
 static void
 opserv_conf_read(void)
 {
+    struct chanNode *chan;
+    unsigned int i;
     struct record_data *rd;
     dict_t conf_node, child;
     const char *str, *str2;
@@ -4640,6 +4688,9 @@ opserv_conf_read(void)
     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_SILENT_LEVEL, RECDB_QSTRING);
+    opserv_conf.silent_level = str ? strtoul(str, NULL, 0): 700;
+
     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);
@@ -4657,6 +4708,19 @@ opserv_conf_read(void)
     str = database_get_data(conf_node, KEY_BLOCK_GLINE_DURATION, RECDB_QSTRING);
     opserv_conf.block_gline_duration = str ? ParseInterval(str) : 3600;
 
+    free_string_list(autojoin_channels);
+    autojoin_channels = database_get_data(conf_node, KEY_AUTOJOIN_CHANNELS, RECDB_STRING_LIST);
+
+    if(autojoin_channels)
+        autojoin_channels = string_list_copy(autojoin_channels);
+
+    if (autojoin_channels && opserv) {
+        for (i = 0; i < autojoin_channels->used; i++) {
+            chan = AddChannel(autojoin_channels->list[i], now, "+nt", NULL, NULL);
+            AddChannelUser(opserv, chan)->modes |= MODE_CHANOP;
+        }
+    }
+
     str = database_get_data(conf_node, KEY_BLOCK_SHUN_DURATION, RECDB_QSTRING);
     opserv_conf.block_shun_duration = str ? ParseInterval(str) : 3600;
 
@@ -4824,6 +4888,7 @@ init_opserv(const char *nick)
     opserv_define_func("REFRESHS", cmd_refreshs, 600, 0, 0);
     opserv_define_func("REHASH", cmd_rehash, 900, 0, 0);
     opserv_define_func("REOPEN", cmd_reopen, 900, 0, 0);
+    opserv_define_func("RESETMAX", cmd_resetmax, 900, 0, 0);
     opserv_define_func("RESERVE", cmd_reserve, 800, 0, 5);
     opserv_define_func("RESTART", cmd_restart, 900, 0, 2);
     opserv_define_func("SET", cmd_set, 900, 0, 3);