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);
}
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;
}
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);
{
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;
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);
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;
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)
"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.");