X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=src%2Fchanserv.c;h=a2f6175f5ef619b936f9064435ffcda8f9daba31;hb=95ca19dd93fa5ef8d8756d0ef0ec1c39fe398650;hp=d50c9147fbe56909b65f776179f763e99bb2ca8d;hpb=1bf0d430020a45aa7dc3b098234eb9df2c5ba294;p=srvx.git diff --git a/src/chanserv.c b/src/chanserv.c index d50c914..a2f6175 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -43,6 +43,7 @@ #define KEY_DNR_EXPIRE_FREQ "dnr_expire_freq" #define KEY_MAX_CHAN_USERS "max_chan_users" #define KEY_MAX_CHAN_BANS "max_chan_bans" +#define KEY_MIN_TIME_BANS "min_time_bans" #define KEY_NICK "nick" #define KEY_OLD_CHANSERV_NAME "old_chanserv_name" #define KEY_8BALL_RESPONSES "8ball" @@ -140,7 +141,7 @@ #define KEY_EXPIRES "expires" #define KEY_TRIGGERED "triggered" -#define CHANNEL_DEFAULT_FLAGS (CHANNEL_OFFCHANNEL | CHANNEL_UNREVIEWED) +#define CHANNEL_DEFAULT_FLAGS (CHANNEL_UNREVIEWED) #define CHANNEL_PRESERVED_FLAGS (CHANNEL_UNREVIEWED) #define CHANNEL_DEFAULT_OPTIONS "lmoooanpcnat" @@ -522,6 +523,9 @@ static const struct message_entry msgtab[] = { { NULL, NULL } }; +#define CSMSG_ALERT_REGISTERED "%s registered to %s by %s." +#define CSMSG_ALERT_UNREGISTERED "%s %s" + /* eject_user and unban_user flags */ #define ACTION_KICK 0x0001 #define ACTION_BAN 0x0002 @@ -547,6 +551,9 @@ static const struct message_entry msgtab[] = { DECLARE_LIST(dnrList, struct do_not_register *); DEFINE_LIST(dnrList, struct do_not_register *) +#define chanserv_notice(target, format...) send_message(target , chanserv , ## format) +#define chanserv_oper_message(format...) do { if(chanserv_conf.oper_channel) send_channel_message(chanserv_conf.oper_channel , chanserv , ## format); } while(0) + static int eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, char *argv[], struct svccmd *cmd, int action); struct userNode *chanserv; @@ -581,6 +588,7 @@ static struct unsigned int max_owned; unsigned int max_chan_users; unsigned int max_chan_bans; + unsigned int min_time_bans; unsigned int max_userinfo_length; unsigned int revoke_mode_a; @@ -599,6 +607,8 @@ static struct const char *new_channel_authed; const char *new_channel_unauthed; const char *new_channel_msg; + + struct chanNode *oper_channel; } chanserv_conf; struct listData @@ -1513,12 +1523,12 @@ unregister_channel(struct chanData *channel, const char *reason) if(channel->expiry) timeq_del(channel->expiry, chanserv_expire_channel, channel, 0); channel->channel->channel_info = NULL; - - dict_delete(channel->notes); sprintf(msgbuf, "%s %s", channel->channel->name, reason); + dict_delete(channel->notes); if(!IsSuspended(channel)) DelChannelUser(chanserv, channel->channel, msgbuf, 0); - global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, msgbuf); + + chanserv_oper_message(CSMSG_ALERT_UNREGISTERED, channel->channel->name, reason); UnlockChannel(channel->channel); free(channel); registered_channels--; @@ -2158,7 +2168,6 @@ static CHANSERV_FUNC(cmd_register) struct handle_info *handle; struct chanData *cData; struct modeNode *mn; - char reason[MAXLEN]; char *chan_name; unsigned int new_channel, force=0; struct do_not_register *dnr; @@ -2269,8 +2278,7 @@ static CHANSERV_FUNC(cmd_register) else reply("CSMSG_REG_SUCCESS", channel->name); - sprintf(reason, "%s registered to %s by %s.", channel->name, handle->handle, user->handle_info->handle); - global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, reason); + chanserv_oper_message(CSMSG_ALERT_REGISTERED, channel->name, handle->handle, user->handle_info->handle); return 1; } @@ -3476,7 +3484,7 @@ eject_user(struct userNode *user, struct chanNode *channel, unsigned int argc, c { duration = ParseInterval(argv[2]); - if(duration < 15) + if(duration < chanserv_conf.min_time_bans) { reply("CSMSG_DURATION_TOO_LOW"); free(ban); @@ -4167,6 +4175,8 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg ary[1] = uData->handle->handle; if(uData->present) ary[2] = "Here"; + else if(HANDLE_FLAGGED(uData->handle, NETWORK)) + ary[2] = "Here"; else if(!uData->seen) ary[2] = "Never"; else @@ -4174,6 +4184,12 @@ cmd_list_users(struct userNode *user, struct chanNode *channel, unsigned int arg ary[2] = strdup(ary[2]); if(IsUserSuspended(uData)) ary[3] = "Suspended"; + else if(HANDLE_FLAGGED(uData->handle, OPER)) + ary[3] = "Operator"; + else if(HANDLE_FLAGGED(uData->handle, HELPING)) + ary[3] = "Staff"; + else if(HANDLE_FLAGGED(uData->handle, NETWORK)) + ary[3] = "Network"; else if(HANDLE_FLAGGED(uData->handle, FROZEN)) ary[3] = "Vacation"; else if(HANDLE_FLAGGED(uData->handle, BOT)) @@ -4421,10 +4437,10 @@ static CHANSERV_FUNC(cmd_topic) if(!isdigit(topic[pos])) break; } - if(advtopic_index < 0 || advtopic_index > MAXADVTOPICENTRIES) + if(advtopic_index < 0 || advtopic_index >= MAXADVTOPICENTRIES) { //invalid id! - reply("CSMSG_ADVTOPIC_INVALID_ID", advtopic_index); + reply("CSMSG_ADVTOPIC_INVALID_ID", advtopic_index+1); return 0; } if(cData->advtopic[advtopic_index]) @@ -4446,7 +4462,6 @@ static CHANSERV_FUNC(cmd_topic) new_topic[dpos++] = *ptr; //is % again break; } - ptr--; advtopic_index--; //no zero base if(!cData->advtopic[advtopic_index]) break; //just leave it empty @@ -4458,11 +4473,12 @@ static CHANSERV_FUNC(cmd_topic) break; case '\\': ptr++; /* and fall through */ + if(!*ptr) break; default: new_topic[dpos++] = *ptr; + ptr++; break; } - ptr++; } } else { while((tchar = topic_mask[pos++]) && (dpos <= TOPICLEN)) @@ -6573,13 +6589,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); @@ -6605,6 +6631,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; @@ -6637,6 +6681,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); @@ -7849,6 +7894,8 @@ chanserv_conf_read(void) chanserv_conf.max_chan_users = str ? atoi(str) : 512; str = database_get_data(conf_node, KEY_MAX_CHAN_BANS, RECDB_QSTRING); chanserv_conf.max_chan_bans = str ? atoi(str) : 512; + str = database_get_data(conf_node, KEY_MIN_TIME_BANS, RECDB_QSTRING); + chanserv_conf.min_time_bans = str ? atoi(str) : 5; str = database_get_data(conf_node, KEY_MAX_USERINFO_LENGTH, RECDB_QSTRING); chanserv_conf.max_userinfo_length = str ? atoi(str) : 400; str = database_get_data(conf_node, KEY_NICK, RECDB_QSTRING); @@ -7939,6 +7986,16 @@ chanserv_conf_read(void) chanserv_conf.old_ban_names = strlist; str = database_get_data(conf_node, "off_channel", RECDB_QSTRING); off_channel = str ? atoi(str) : 0; + + str = database_get_data(conf_node, "oper_channel", RECDB_QSTRING); + if(str) + { + chanserv_conf.oper_channel = AddChannel(str, now, "+tinms", NULL); + } + else + { + chanserv_conf.oper_channel = NULL; + } } static void @@ -8023,7 +8080,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; @@ -8044,6 +8101,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); @@ -8055,6 +8113,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; @@ -8472,6 +8539,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)