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;
 }
 
     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;
 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);
     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(!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;
     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;
     }
     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);
     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;
 {
     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;
 
     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);
     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);
     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 = 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;
     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);
         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)
         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;
 
     char                *info;
     unsigned long       seen;
+    time_t             expires; /* suspend */
     unsigned short      access;
     unsigned int        present : 1;
     unsigned int        flags : USER_FLAGS_SIZE;
     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");
 "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.",
         "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.");
         "$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.");