ChanServ.suspend duration
authorStricted <info@nexus-irc.de>
Mon, 20 May 2013 02:33:48 +0000 (04:33 +0200)
committerNurPech <nurpech@nurpech.de>
Mon, 20 May 2013 02:57:31 +0000 (04:57 +0200)
src/chanserv.c
src/chanserv.h
src/chanserv.help

index 7a620326a28578406bd18700c63f054a011acb1d..3ddfaf6874822d50451a596628451b53c73dcef1 100644 (file)
@@ -6583,13 +6583,23 @@ static CHANSERV_FUNC(cmd_giveownership)
     return 1;
 }
 
+static void
+chanserv_expire_user_suspension(void *data)
+{
+    struct userData *target = data;
+
+       target->expires = 0;
+       target->flags &= ~USER_SUSPENDED;       
+}
+
 static CHANSERV_FUNC(cmd_suspend)
 {
     struct handle_info *hi;
     struct userData *actor, *real_actor, *target;
     unsigned int override = 0;
+    time_t expiry;
 
-    REQUIRE_PARAMS(2);
+    REQUIRE_PARAMS(3);
     if(!(hi = modcmd_get_handle_info(user, argv[1]))) return 0;
     actor = GetChannelUser(channel->channel_info, user->handle_info);
     real_actor = GetChannelAccess(channel->channel_info, user->handle_info);
@@ -6615,6 +6625,24 @@ static CHANSERV_FUNC(cmd_suspend)
     }
     if(!real_actor || target->access >= real_actor->access)
         override = CMD_LOG_OVERRIDE;
+       if(!strcmp(argv[2], "0"))
+        expiry = 0;
+    else
+    {
+        unsigned int duration;
+        if(!(duration = ParseInterval(argv[2])))
+        {
+            reply("MSG_INVALID_DURATION", argv[2]);
+            return 0;
+        }
+        expiry = now + duration;
+    }
+
+       target->expires = expiry;
+
+       if(target->expires)
+               timeq_add(target->expires, chanserv_expire_user_suspension, target);
+
     target->flags |= USER_SUSPENDED;
     reply("CSMSG_USER_SUSPENDED", hi->handle, channel->name);
     return 1 | override;
@@ -6647,6 +6675,7 @@ static CHANSERV_FUNC(cmd_unsuspend)
     }
     if(!real_actor || target->access >= real_actor->access)
         override = CMD_LOG_OVERRIDE;
+    timeq_del(target->expires, chanserv_expire_user_suspension, target, 0);
     target->flags &= ~USER_SUSPENDED;
     scan_user_presence(target, NULL);
     reply("CSMSG_USER_UNSUSPENDED", hi->handle, channel->name);
@@ -8035,7 +8064,7 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 {
     struct handle_info *handle;
     struct userData *uData;
-    char *seen, *inf, *flags, *voted, *votefor;
+    char *seen, *inf, *flags, *voted, *votefor, *expires;
     unsigned long last_seen;
     unsigned short access_level;
 
@@ -8056,6 +8085,7 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
     seen = database_get_data(rd->d.object, KEY_SEEN, RECDB_QSTRING);
     last_seen = seen ? strtoul(seen, NULL, 0) : now;
     flags = database_get_data(rd->d.object, KEY_FLAGS, RECDB_QSTRING);
+    expires = database_get_data(rd->d.object, KEY_EXPIRES, RECDB_QSTRING);
     voted = database_get_data(rd->d.object, KEY_VOTE_VOTED, RECDB_QSTRING);
     votefor = database_get_data(rd->d.object, KEY_VOTE_VOTEDFOR, RECDB_QSTRING);
     handle = get_handle_info(key);
@@ -8067,6 +8097,15 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan)
 
     uData = add_channel_user(chan, handle, access_level, last_seen, inf);
     uData->flags = flags ? strtoul(flags, NULL, 0) : 0;
+       uData->expires = expires ? (signed)strtoul(expires, NULL, 0) : 0;
+
+       if((uData->flags & USER_SUSPENDED) && uData->expires)
+       {
+         if(uData->expires > now)
+                 timeq_add(uData->expires, chanserv_expire_user_suspension, uData);
+         else
+                 uData->flags &= ~USER_SUSPENDED;
+       }
     if(chan->vote) {
         uData->voted = voted ? strtoul(voted, NULL, 0) : 0;
         uData->votefor = votefor ? strtoul(votefor, NULL, 0) : 0;
@@ -8484,6 +8523,8 @@ chanserv_write_users(struct saxdb_context *ctx, struct userData *uData)
         saxdb_write_int(ctx, KEY_SEEN, uData->seen);
         if(uData->flags)
             saxdb_write_int(ctx, KEY_FLAGS, uData->flags);
+        if(uData->expires)
+            saxdb_write_int(ctx, KEY_EXPIRES, uData->expires);
         if(uData->channel->vote && uData->voted)
             saxdb_write_int(ctx, KEY_VOTE_VOTED, uData->voted);
         if(uData->channel->vote && uData->votefor)
index 638a77f2777eb93582fb7852cdc73af509deaf49..336671511d7159f576eca8772f711a366a18ddc1 100644 (file)
@@ -136,6 +136,7 @@ struct userData
 
     char                *info;
     unsigned long       seen;
+    time_t             expires; /* suspend */
     unsigned short      access;
     unsigned int        present : 1;
     unsigned int        flags : USER_FLAGS_SIZE;
index 0562477130b14fe4688b19d50e54cf681b14514a..e9fb42fdff198352021e4d61197c0b0906eb95c9 100644 (file)
 "STAFF" ("/msg $C STAFF",
         "Lists all the IRC operators and helpers currently online. Nicknames enclosed in parentheses are away, and likely unavailable.",
         "$uSee Also:$u helpers, ircops, netinfo");
-"SUSPEND" ("/msg $C SUSPEND <#channel> <nick|*account>",
+"SUSPEND" ("/msg $C SUSPEND <#channel> <nick|*account> <duration>",
         "This disables the target's access to the channel.  That access can be restored using the unsuspend command.",
+        "The duration may be \"0\" to make it never expire; otherwise, $C will automatically unsuspend the user after $uduration$u.",
         "$uSee Also:$u unsuspend, deluser");
 "TOPIC" ("/msg $C TOPIC <#channel> [topic]",
         "Sets the current topic for the specified channel.  If no topic is specified, then set the current topic to the default topic.");