added channel expire setting
authorpk910 <philipp@zoelle1.de>
Thu, 7 Jul 2011 18:57:00 +0000 (20:57 +0200)
committerpk910 <philipp@zoelle1.de>
Thu, 7 Jul 2011 18:57:00 +0000 (20:57 +0200)
src/chanserv.c
src/chanserv.h

index 130e8298d0dea5dc6d447b0454589828587e8ef3..b24f7c3c4a9f1b468f171483349aa32e254edfa2 100644 (file)
 #define KEY_NOTES           "notes"
 #define KEY_TOPIC_MASK      "topic_mask"
 #define KEY_OWNER_TRANSFER  "owner_transfer"
+#define KEY_EXPIRE          "expire"
 
 /* User data */
 #define KEY_LEVEL   "level"
@@ -281,6 +282,8 @@ static const struct message_entry msgtab[] = {
     { "CSMSG_SET_CTCPREACTION",  "$bCTCPReaction$b %d - %s" },
     { "CSMSG_SET_TOPICREFRESH",  "$bTopicRefresh$b %d - %s" },
     { "CSMSG_SET_UNREVIEWED",    "$bUnreviewed  $b %s" },
+    { "CSMSG_SET_EXPIRE",        "$bExpire      $b %s" },
+    { "CSMSG_SET_EXPIRE_OFF",    "$bExpire      $b off" },
     { "CSMSG_USET_NOAUTOOP",     "$bNoAutoOp    $b %s" },
     { "CSMSG_USET_NOAUTOVOICE",  "$bNoAutoVoice $b %s" },
     { "CSMSG_USET_AUTOINVITE",   "$bAutoInvite  $b %s" },
@@ -1028,6 +1031,65 @@ static MODCMD_FUNC(cmd_removenote) {
     return 1;
 }
 
+static void
+chanserv_expire_channel(void *data)
+{
+    struct chanData *channel = data;
+    char reason[MAXLEN];
+    sprintf(reason, "channel expired.");
+    channel->expiry = 0;
+    spamserv_cs_unregister(NULL, channel->channel, expire, NULL);
+    unregister_channel(channel, reason);
+}
+
+static MODCMD_FUNC(chan_opt_expire)
+{
+    struct chanData *cData = channel->channel_info;
+    unsigned long value = cData->expiry;
+
+    if(argc > 1)
+    {
+        if((!IsOper(user) || !user->handle_info || (user->handle_info->opserv_level < chanserv_conf.nodelete_level)))
+        {
+            reply("MSG_SETTING_PRIVILEGED", argv[0]);
+            return 0;
+        }
+        unsigned long expiry,duration;
+
+        /* The two directions can have different ACLs. */
+        if(!strcmp(argv[1], "0"))
+            expiry = 0;
+        else if((duration = ParseInterval(argv[1])))
+            expiry = now + duration;
+        else
+        {
+            reply("MSG_INVALID_DURATION", argv[1]);
+            return 0;
+        }
+
+        if (expiry != value)
+        {
+            if(value) {
+                //unset old timer
+                timeq_del(value, chanserv_expire_channel, cData, 0);
+            }
+            value = expiry;
+            cData->expiry = value;
+            if(value > 0) {
+                //New timer!
+                timeq_add(expiry, chanserv_expire_channel, cData);
+            }
+        }
+    }
+
+    if(cData->expiry > now) {
+        char expirestr[INTERVALLEN];
+        reply("CSMSG_SET_EXPIRE", intervalString(expirestr, cData->expiry - now, user->handle_info));
+    } else
+        reply("CSMSG_SET_EXPIRE_OFF");
+    return 1;
+}
+
 static int
 mode_lock_violated(const struct mod_chanmode *orig, const struct mod_chanmode *change)
 {
@@ -1160,8 +1222,6 @@ add_channel_user(struct chanData *channel, struct handle_info *handle, unsigned
     return ud;
 }
 
-static void unregister_channel(struct chanData *channel, const char *reason);
-
 void
 del_channel_user(struct userData *user, int do_gc)
 {
@@ -1362,6 +1422,8 @@ unregister_channel(struct chanData *channel, const char *reason)
         if(cNode)
             cNode->channel_info = NULL;
     }
+    if(channel->expiry)
+        timeq_del(channel->expiry, chanserv_expire_channel, channel, 0);
     channel->channel->channel_info = NULL;
 
     dict_delete(channel->notes);
@@ -7170,7 +7232,7 @@ chanserv_conf_read(void)
             /* multiple choice options */
             "CtcpReaction", "Protect", "Toys", "TopicRefresh",
             /* binary options */
-            "DynLimit", "NoDelete",
+            "DynLimit", "NoDelete", "expire",
             /* delimiter */
             NULL
         };
@@ -7452,6 +7514,20 @@ chanserv_channel_read(const char *key, struct record_data *hir)
             cData->chOpts[chOpt] = ((count <= charOptions[chOpt].old_idx) ? str : CHANNEL_DEFAULT_OPTIONS)[charOptions[chOpt].old_idx];
     }
 
+    if((str = database_get_data(hir->d.object, KEY_EXPIRE, RECDB_QSTRING)))
+    {
+        cData->expiry = atoi(str);
+        if(cData->expiry > 0) {
+            if(cData->expiry > now) {
+                timeq_add(cData->expiry, chanserv_expire_channel, cData);
+            } else {
+                timeq_add(1, chanserv_expire_channel, cData);
+            }
+        }
+    } else {
+        cData->expiry = 0;
+    }
+
     if((obj = database_get_data(hir->d.object, KEY_SUSPENDED, RECDB_OBJECT)))
     {
         suspended = chanserv_read_suspended(obj);
@@ -7714,6 +7790,8 @@ chanserv_write_channel(struct saxdb_context *ctx, struct chanData *channel)
         saxdb_write_string(ctx, KEY_TOPIC_MASK, channel->topic_mask);
     if(channel->suspended)
         chanserv_write_suspended(ctx, "suspended", channel->suspended);
+    if(channel->expiry)
+        saxdb_write_int(ctx, KEY_EXPIRE, channel->expiry);
 
     saxdb_start_record(ctx, KEY_OPTIONS, 0);
     saxdb_write_int(ctx, KEY_FLAGS, channel->flags);
@@ -8029,6 +8107,7 @@ init_chanserv(const char *nick)
     DEFINE_CHANNEL_OPTION(ctcpreaction);
     DEFINE_CHANNEL_OPTION(inviteme);
     DEFINE_CHANNEL_OPTION(unreviewed);
+    modcmd_register(chanserv_module, "set expire", chan_opt_expire, 1, 0, "flags", "+helping", NULL);
     modcmd_register(chanserv_module, "set unreviewed on", NULL, 0, 0, "flags", "+helping", NULL);
     modcmd_register(chanserv_module, "set unreviewed off", NULL, 0, 0, "flags", "+oper", NULL);
     if(off_channel > 1)
index 9a7b08e140f3b16a78c7520542fb8a785015dcab..d6470e2455c653a4d32a0eaa151204932c7d3008 100644 (file)
@@ -83,6 +83,7 @@ struct chanData
     unsigned long       visited;
     unsigned long       limitAdjusted;
     unsigned long       ownerTransfer;
+    unsigned long       expiry;
 
     char    *topic;
     char    *greeting;