X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/fd20b142fcf1d4bd7ee96b7d79a20fd54573cf16..8dc0685213ead3f8896c83cadc130143ccc4d181:/src/chanserv.c diff --git a/src/chanserv.c b/src/chanserv.c index 6021777..3b0986c 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -116,7 +116,9 @@ #define KEY_LEVEL "level" #define KEY_INFO "info" #define KEY_SEEN "seen" -#define KEY_EXPIRY "expiry" +#define KEY_ACCESSEXPIRY "accessexpiry" +#define KEY_CLVLEXPIRY "clvlexpiry" +#define KEY_LASTLEVEL "lastlevel" /* Ban data */ #define KEY_OWNER "owner" @@ -201,6 +203,7 @@ static const struct message_entry msgtab[] = { /* User management */ { "CSMSG_AUTO_DELETED", "Your %s access has expired in %s." }, + { "CSMSG_CLVL_EXPIRED", "Your CLVL access has expired in %s." }, { "CSMSG_ADDED_USER", "Added %s to the %s user list with access %s (%d)." }, { "CSMSG_DELETED_USER", "Deleted %s (with access %d) from the %s user list." }, { "CSMSG_BAD_RANGE", "Invalid access range; minimum (%d) must be greater than maximum (%d)." }, @@ -219,6 +222,7 @@ static const struct message_entry msgtab[] = { { "CSMSG_NO_SELF_CLVL", "You cannot change your own access." }, { "CSMSG_NO_BUMP_ACCESS", "You cannot give users access greater than or equal to your own." }, + { "CSMSG_NO_BUMP_EXPIRY", "You cannot give users timed $bCLVL$b's when they already have timed access." }, { "CSMSG_MULTIPLE_OWNERS", "There is more than one owner in %s; please use $bCLVL$b, $bDELOWNER$b and/or $bADDOWNER$b instead." }, { "CSMSG_NO_OWNER", "There is no owner for %s; please use $bCLVL$b and/or $bADDOWNER$b instead." }, { "CSMSG_TRANSFER_WAIT", "You must wait %s before you can give ownership of $b%s$b to someone else." }, @@ -232,7 +236,7 @@ static const struct message_entry msgtab[] = { { "CSMSG_BAN_DONE", "Banned $b%s$b from %s." }, { "CSMSG_REASON_CHANGE", "Reason for LAMER $b%s$b changed." }, { "CSMSG_LAMER_EXTENDED", "Extended LAMER for $b%s$b, now expires in %s." }, - { "CSMSG_BAN_REMOVED", "Matching ban(s) and LAMER(s) in $b%s$b were removed." }, + { "CSMSG_BAN_REMOVED", "Ban(s) and LAMER(s) matching $b%s$b were removed." }, { "CSMSG_TRIMMED_LAMERS", "Trimmed $b%d LAMERs$b from the %s LAMER list that were inactive for at least %s." }, { "CSMSG_REDUNDANT_BAN", "$b%s$b is already banned in %s." }, { "CSMSG_REDUNDANT_LAMER", "$b%s$b is already LAMER'd in %s." }, @@ -1240,7 +1244,7 @@ register_channel(struct chanNode *cNode, char *registrar) } static struct userData* -add_channel_user(struct chanData *channel, struct handle_info *handle, unsigned short access, time_t seen, const char *info, time_t expiry) +add_channel_user(struct chanData *channel, struct handle_info *handle, unsigned short access, time_t seen, const char *info, time_t accessexpiry) { struct userData *ud; @@ -1253,7 +1257,9 @@ add_channel_user(struct chanData *channel, struct handle_info *handle, unsigned ud->seen = seen; ud->access = access; ud->info = info ? strdup(info) : NULL; - ud->expiry = expiry; + ud->accessexpiry = accessexpiry ? accessexpiry : 0; + ud->clvlexpiry = 0; + ud->lastaccess = 0; ud->prev = NULL; ud->next = channel->users; @@ -1284,7 +1290,7 @@ chanserv_expire_tempuser(void *data) if (data) { handle = strdup(uData->handle->handle); - if (uData->expiry > 0) { + if (uData->accessexpiry > 0) { if (uData->present) { struct userNode *user, *next_un = NULL; struct handle_info *hi; @@ -1318,6 +1324,68 @@ chanserv_expire_tempuser(void *data) } } +static void +chanserv_expire_tempclvl(void *data) +{ + struct userData *uData = data; + char *handle; + + if (data) { + handle = strdup(uData->handle->handle); + if (uData->clvlexpiry > 0) { + int changemodes = 0; + unsigned int mode = 0; + + if (((uData->lastaccess == UL_PEON) || (uData->lastaccess == UL_HALFOP)) && (uData->access >= UL_OP)) { + changemodes = 1; + mode = MODE_REMOVE | MODE_CHANOP; + } else if ((uData->lastaccess == UL_PEON) && (uData->access == UL_HALFOP)) { + changemodes = 1; + mode = MODE_REMOVE | MODE_HALFOP; + } else + changemodes = 0; + + if (uData->present) { + struct userNode *user, *next_un = NULL; + struct handle_info *hi; + + hi = get_handle_info(handle); + for (user = hi->users; user; user = next_un) { + struct mod_chanmode *change; + struct modeNode *mn; + unsigned int count = 0; + + send_message(user, chanserv, "CSMSG_CLVL_EXPIRED", uData->channel->channel->name); + if (!(mn = GetUserMode(uData->channel->channel, user))) { + next_un = user->next_authed; + continue; + } + + if (changemodes == 0) { + next_un = user->next_authed; + continue; + } + + change = mod_chanmode_alloc(2); + change->args[count].mode = mode; + change->args[count++].u.member = mn; + + if (count) { + change->argc = count; + mod_chanmode_announce(chanserv, uData->channel->channel, change); + } + mod_chanmode_free(change); + next_un = user->next_authed; + } + } + + uData->access = uData->lastaccess; + uData->lastaccess = 0; + uData->clvlexpiry = 0; + } + } +} + void del_channel_user(struct userData *user, int do_gc) { @@ -1327,6 +1395,7 @@ del_channel_user(struct userData *user, int do_gc) userCount--; timeq_del(0, chanserv_expire_tempuser, user, TIMEQ_IGNORE_WHEN); + timeq_del(0, chanserv_expire_tempclvl, user, TIMEQ_IGNORE_WHEN); if(user->prev) user->prev->next = user->next; @@ -2697,18 +2766,18 @@ static CHANSERV_FUNC(cmd_adduser) return 0; } - time_t expiry = 0; + time_t accessexpiry = 0; unsigned int duration = 0; if (argc > 3) { if ((duration = ParseInterval(argv[3]))) - expiry = now + duration; + accessexpiry = now + duration; } - actee = add_channel_user(channel->channel_info, handle, access, 0, NULL, expiry); + actee = add_channel_user(channel->channel_info, handle, access, 0, NULL, accessexpiry); scan_user_presence(actee, NULL); if (duration > 0) - timeq_add(expiry, chanserv_expire_tempuser, actee); + timeq_add(accessexpiry, chanserv_expire_tempuser, actee); reply("CSMSG_ADDED_USER", handle->handle, channel->name, user_level_name_from_level(access), access); return 1; @@ -2761,6 +2830,24 @@ static CHANSERV_FUNC(cmd_clvl) return 0; } + time_t clvlexpiry = 0; + unsigned int duration = 0; + if (argc > 3) { + if ((duration = ParseInterval(argv[3]))) + clvlexpiry = now + duration; + } + + if (duration > 0) { + if (victim->accessexpiry > 0) { + reply("CSMSG_NO_BUMP_EXPIRY"); + return 0; + } + + victim->clvlexpiry = clvlexpiry; + victim->lastaccess = victim->access; + timeq_add(clvlexpiry, chanserv_expire_tempclvl, victim); + } + victim->access = new_access; reply("CSMSG_CHANGED_ACCESS", handle->handle, user_level_name_from_level(new_access), new_access, channel->name); return 1; @@ -2790,12 +2877,13 @@ static CHANSERV_FUNC(cmd_deluser) if(argc > 2) { access = user_level_from_name(argv[1], UL_OWNER); + char *useraccess = user_level_name_from_level(victim->access); if(!access) { reply("CSMSG_INVALID_ACCESS", argv[1]); return 0; } - if(access != victim->access) + if(strcasecmp(argv[1], useraccess)) { reply("CSMSG_INCORRECT_ACCESS", handle->handle, user_level_name_from_level(victim->access), argv[1]); return 0; @@ -4318,12 +4406,17 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg else ary[i++] = "Normal"; - if (uData->expiry > 0) { + if ((uData->accessexpiry > 0) || (uData->clvlexpiry > 0)) { char delay[INTERVALLEN]; time_t diff; - diff = uData->expiry - now; - intervalString(delay, diff, user->handle_info); + if (uData->accessexpiry > 0) { + diff = uData->accessexpiry - now; + intervalString(delay, diff, user->handle_info); + } else { + diff = uData->clvlexpiry - now; + intervalString(delay, diff, user->handle_info); + } ary[i++] = delay; } else ary[i++] = "Never"; @@ -7168,6 +7261,31 @@ handle_new_channel(struct chanNode *channel) SetChannelTopic(channel, chanserv, chanserv, channel->channel_info->topic, 1); } +int +trace_check_bans(struct userNode *user, struct chanNode *chan) +{ + struct banData *bData; + struct mod_chanmode *change; + + change = find_matching_bans(&chan->banlist, user, NULL); + if (change) + return 1; + + /* lamer list */ + if (chan->channel_info) { + for(bData = chan->channel_info->bans; bData; bData = bData->next) { + + if(!user_matches_glob(user, bData->mask, MATCH_USENICK)) + continue; + + if(bData) + return 1; + } + } + + return 0; +} + int check_bans(struct userNode *user, const char *channel) { @@ -8063,9 +8181,9 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan) { struct handle_info *handle; struct userData *uData; - char *seen, *inf, *flags, *expires, *expiry; + char *seen, *inf, *flags, *expires, *accessexpiry, *clvlexpiry, *lstacc; time_t last_seen; - unsigned short access; + unsigned short access, lastaccess = 0; if(rd->type != RECDB_OBJECT || !dict_size(rd->d.object)) { @@ -8085,7 +8203,11 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan) last_seen = seen ? (signed)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); - expiry = database_get_data(rd->d.object, KEY_EXPIRY, RECDB_QSTRING); + accessexpiry = database_get_data(rd->d.object, KEY_ACCESSEXPIRY, RECDB_QSTRING); + clvlexpiry = database_get_data(rd->d.object, KEY_CLVLEXPIRY, RECDB_QSTRING); + lstacc = database_get_data(rd->d.object, KEY_LASTLEVEL, RECDB_QSTRING); + lastaccess = lstacc ? atoi(lstacc) : 0; + handle = get_handle_info(key); if(!handle) { @@ -8096,9 +8218,16 @@ user_read_helper(const char *key, struct record_data *rd, struct chanData *chan) uData = add_channel_user(chan, handle, access, last_seen, inf, 0); uData->flags = flags ? strtoul(flags, NULL, 0) : 0; uData->expires = expires ? strtoul(expires, NULL, 0) : 0; - uData->expiry = expiry ? strtoul(expiry, NULL, 0) : 0; - if (uData->expiry > 0) - timeq_add(uData->expiry, chanserv_expire_tempuser, uData); + + uData->accessexpiry = accessexpiry ? strtoul(accessexpiry, NULL, 0) : 0; + if (uData->accessexpiry > 0) + timeq_add(uData->accessexpiry, chanserv_expire_tempuser, uData); + + uData->clvlexpiry = clvlexpiry ? strtoul(clvlexpiry, NULL, 0) : 0; + if (uData->clvlexpiry > 0) + timeq_add(uData->clvlexpiry, chanserv_expire_tempclvl, uData); + + uData->lastaccess = lastaccess; if((uData->flags & USER_SUSPENDED) && uData->expires) { @@ -8498,7 +8627,9 @@ chanserv_write_users(struct saxdb_context *ctx, struct userData *uData) saxdb_start_record(ctx, uData->handle->handle, 0); saxdb_write_int(ctx, KEY_LEVEL, uData->access); saxdb_write_int(ctx, KEY_SEEN, uData->seen); - saxdb_write_int(ctx, KEY_EXPIRY, uData->expiry); + saxdb_write_int(ctx, KEY_ACCESSEXPIRY, uData->accessexpiry); + saxdb_write_int(ctx, KEY_CLVLEXPIRY, uData->clvlexpiry); + saxdb_write_int(ctx, KEY_LASTLEVEL, uData->lastaccess); if(uData->flags) saxdb_write_int(ctx, KEY_FLAGS, uData->flags); if(uData->expires) @@ -8970,3 +9101,4 @@ init_chanserv(const char *nick) reg_exit_func(chanserv_db_cleanup); message_register_table(msgtab); } +