From 565b871f7cd94c40eca88a05d60bd6d9acae0be5 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Thu, 22 Jul 2004 04:03:22 +0000 Subject: [PATCH] Channel suspension, transfer and line wrap changes * Treat half-unsuspended channels as unsuspended, to avoid crashes caused by sysadmins editing chanserv.db in screwy ways. * Add a srvx.conf option to limit how often channel owners can give away channel ownership. * Limit most output line expansions to just one line. * Remove unnecessary assert(hs_user) checks from mod-helpserv.c. * Don't run_empty_interval() in HelpServ when the user's server is still bursting. git-archimport-id: srvx@srvx.net--2004-srvx/srvx--devo--1.3--patch-74 --- ChangeLog | 26 ++++++++++++++++++++++++++ languages/de/strings.db | 1 + src/chanserv.c | 28 ++++++++++++++++++++++++---- src/chanserv.h | 1 + src/helpfile.c | 26 +++++++++++++++++++------- src/helpfile.h | 6 ++++++ src/mod-helpserv.c | 6 +----- srvx.conf.example | 2 ++ 8 files changed, 80 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1650de..0370654 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,32 @@ # arch-tag: automatic-ChangeLog--srvx@srvx.net--2004-srvx/srvx--devo--1.3 # +2004-07-22 04:03:22 GMT Michael Poole patch-74 + + Summary: + Channel suspension, transfer and line wrap changes + Revision: + srvx--devo--1.3--patch-74 + + * Treat half-unsuspended channels as unsuspended, to avoid crashes + caused by sysadmins editing chanserv.db in screwy ways. + + * Add a srvx.conf option to limit how often channel owners can give + away channel ownership. + + * Limit most output line expansions to just one line. + + * Remove unnecessary assert(hs_user) checks from mod-helpserv.c. + + * Don't run_empty_interval() in HelpServ when the user's server is + still bursting. + + modified files: + ChangeLog languages/de/strings.db src/chanserv.c + src/chanserv.h src/helpfile.c src/helpfile.h + src/mod-helpserv.c srvx.conf.example + + 2004-07-19 03:38:09 GMT Michael Poole patch-73 Summary: diff --git a/languages/de/strings.db b/languages/de/strings.db index 99ed5d3..9727d26 100644 --- a/languages/de/strings.db +++ b/languages/de/strings.db @@ -233,6 +233,7 @@ "CSMSG_TOYS_DISABLED" "Toys sind vollständig abgeschaltet."; "CSMSG_TOYS_PRIVATE" "Toys werden nur dem User direkt beantwortet."; "CSMSG_TOYS_PUBLIC" "Toys werden im Channel beantwortet."; +"CSMSG_TRANSFER_WAIT" "Du musst %s warten, bis du jemand anderem Ownership in $b%s$b geben kannst." "CSMSG_TRIMMED_BANS" "Es wurden $b%d Bans$b von der %s Banliste gelöscht, welche für mindestens %s inaktiv waren."; "CSMSG_TRIMMED_USERS" "Es wurden $b%d User$b mit dem Access Level von %d bis %d von der %s Userliste gelöscht, welche für mindestens %s inaktiv waren."; "CSMSG_UNF_RESPONSE" "Ich will kein Teil deiner versauten Phantasien sein !"; diff --git a/src/chanserv.c b/src/chanserv.c index 2979451..7b7a788 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -42,8 +42,6 @@ #define KEY_MAX_CHAN_BANS "max_chan_bans" #define KEY_NICK "nick" #define KEY_OLD_CHANSERV_NAME "old_chanserv_name" -#define KEY_MAX_SWITCH_LOAD "max_switch_load" -#define KEY_SWITCH_TIMEOUT "switch_timeout" #define KEY_8BALL_RESPONSES "8ball" #define KEY_OLD_BAN_NAMES "old_ban_names" #define KEY_REFRESH_PERIOD "refresh_period" @@ -55,6 +53,7 @@ #define KEY_SUPPORT_HELPER_EPITHET "support_helper_epithet" #define KEY_NODELETE_LEVEL "nodelete_level" #define KEY_MAX_USERINFO_LENGTH "max_userinfo_length" +#define KEY_GIVEOWNERSHIP_PERIOD "giveownership_timeout" /* ChanServ database */ #define KEY_CHANNELS "channels" @@ -100,6 +99,7 @@ #define KEY_MAX "max" #define KEY_NOTES "notes" #define KEY_TOPIC_MASK "topic_mask" +#define KEY_OWNER_TRANSFER "owner_transfer" /* User data */ #define KEY_LEVEL "level" @@ -195,6 +195,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_MULTIPLE_OWNERS", "There is more than one owner in %s; please use $bCLVL$b, $bDELOWNER$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." }, { "CSMSG_NO_TRANSFER_SELF", "You cannot give ownership to your own account." }, { "CSMSG_OWNERSHIP_GIVEN", "Ownership of $b%s$b has been transferred to account $b%s$b." }, @@ -494,6 +495,7 @@ static struct unsigned int greeting_length; unsigned int refresh_period; + unsigned int giveownership_period; unsigned int max_owned; unsigned int max_chan_users; @@ -1080,6 +1082,7 @@ register_channel(struct chanNode *cNode, char *registrar) channel->registered = now; channel->visited = now; channel->limitAdjusted = now; + channel->ownerTransfer = now; channel->flags = CHANNEL_DEFAULT_FLAGS; for(lvlOpt = 0; lvlOpt < NUM_LEVEL_OPTIONS; ++lvlOpt) channel->lvlOpts[lvlOpt] = levelOptions[lvlOpt].default_value; @@ -5449,6 +5452,13 @@ static CHANSERV_FUNC(cmd_giveownership) } curr_user = owner; } + else if (!force && (now < (time_t)(cData->ownerTransfer + chanserv_conf.giveownership_period))) + { + char delay[INTERVALLEN]; + intervalString(delay, cData->ownerTransfer + chanserv_conf.giveownership_period - now, user->handle_info); + reply("CSMSG_TRANSFER_WAIT", delay, channel->name); + return 0; + } if(!(new_owner_hi = modcmd_get_handle_info(user, argv[1]))) return 0; if(new_owner_hi == user->handle_info) @@ -5481,6 +5491,7 @@ static CHANSERV_FUNC(cmd_giveownership) new_owner->access = UL_OWNER; if(curr_user) curr_user->access = co_access; + cData->ownerTransfer = now; reply("CSMSG_OWNERSHIP_GIVEN", channel->name, new_owner_hi->handle); sprintf(reason, "%s ownership transferred to %s by %s.", channel->name, new_owner_hi->handle, user->handle_info->handle); global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, reason); @@ -6367,6 +6378,8 @@ chanserv_conf_read(void) NickChange(chanserv, str, 0); str = database_get_data(conf_node, KEY_REFRESH_PERIOD, RECDB_QSTRING); chanserv_conf.refresh_period = str ? ParseInterval(str) : 3*60*60; + str = database_get_data(conf_node, KEY_GIVEOWNERSHIP_PERIOD, RECDB_QSTRING); + chanserv_conf.giveownership_period = str ? ParseInterval(str) : 0; str = database_get_data(conf_node, KEY_CTCP_SHORT_BAN_DURATION, RECDB_QSTRING); chanserv_conf.ctcp_short_ban_duration = str ? str : "3m"; str = database_get_data(conf_node, KEY_CTCP_LONG_BAN_DURATION, RECDB_QSTRING); @@ -6697,14 +6710,14 @@ chanserv_channel_read(const char *key, struct record_data *hir) /* We could use suspended->expires and suspended->revoked to * set the CHANNEL_SUSPENDED flag, but we don't. */ } - else if(IsSuspended(cData)) + else if(IsSuspended(cData) && (str = database_get_data(hir->d.object, KEY_SUSPENDER, RECDB_QSTRING))) { suspended = calloc(1, sizeof(*suspended)); suspended->issued = 0; suspended->revoked = 0; + suspended->suspender = strdup(str); str = database_get_data(hir->d.object, KEY_SUSPEND_EXPIRES, RECDB_QSTRING); suspended->expires = str ? atoi(str) : 0; - suspended->suspender = strdup(database_get_data(hir->d.object, KEY_SUSPENDER, RECDB_QSTRING)); str = database_get_data(hir->d.object, KEY_SUSPEND_REASON, RECDB_QSTRING); suspended->reason = strdup(str ? str : "No reason"); suspended->previous = NULL; @@ -6712,7 +6725,10 @@ chanserv_channel_read(const char *key, struct record_data *hir) suspended->cData = cData; } else + { + cData->flags &= ~CHANNEL_SUSPENDED; suspended = NULL; /* to squelch a warning */ + } if(IsSuspended(cData)) { if(suspended->expires > now) @@ -6734,6 +6750,8 @@ chanserv_channel_read(const char *key, struct record_data *hir) cData->registered = str ? (time_t)strtoul(str, NULL, 0) : now; str = database_get_data(channel, KEY_VISITED, RECDB_QSTRING); cData->visited = str ? (time_t)strtoul(str, NULL, 0) : now; + str = database_get_data(channel, KEY_OWNER_TRANSFER, RECDB_QSTRING); + cData->ownerTransfer = str ? (time_t)strtoul(str, NULL, 0) : 0; str = database_get_data(channel, KEY_MAX, RECDB_QSTRING); cData->max = str ? atoi(str) : 0; str = database_get_data(channel, KEY_GREETING, RECDB_QSTRING); @@ -6976,6 +6994,8 @@ chanserv_write_channel(struct saxdb_context *ctx, struct chanData *channel) saxdb_end_record(ctx); } + if(channel->ownerTransfer) + saxdb_write_int(ctx, KEY_OWNER_TRANSFER, channel->ownerTransfer); saxdb_write_int(ctx, KEY_VISITED, high_present ? now : channel->visited); saxdb_end_record(ctx); } diff --git a/src/chanserv.h b/src/chanserv.h index bd437a8..d094595 100644 --- a/src/chanserv.h +++ b/src/chanserv.h @@ -81,6 +81,7 @@ struct chanData time_t registered; time_t visited; time_t limitAdjusted; + time_t ownerTransfer; char *topic; char *greeting; diff --git a/src/helpfile.c b/src/helpfile.c index a08c7b7..2529408 100644 --- a/src/helpfile.c +++ b/src/helpfile.c @@ -407,7 +407,8 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle #endif } message_source = src; - if (!(msg_type & 4) && !(format = handle_find_message(handle, format))) + if (!(msg_type & MSG_TYPE_NOXLATE) + && !(format = handle_find_message(handle, format))) return 0; /* fill in a buffer with the string */ input.used = 0; @@ -531,7 +532,18 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle case 'H': value = handle ? handle->handle : "Account"; break; -#define SEND_LINE() do { line[pos] = 0; if (pos > 0) irc_send(src, dest, line); chars_sent += pos; pos = 0; newline_ipos = ipos; } while (0) +#define SEND_LINE(TRUNCED) do { \ + line[pos] = 0; \ + if (pos > 0) { \ + if (!(msg_type & MSG_TYPE_MULTILINE) && (pos > 1) && TRUNCED) \ + line[pos-2] = line[pos-1] = '.'; \ + irc_send(src, dest, line); \ + } \ + chars_sent += pos; \ + pos = 0; \ + newline_ipos = ipos; \ + if (!(msg_type & MSG_TYPE_MULTILINE)) return chars_sent; \ +} while (0) /* Custom expansion handled by helpfile-specific function. */ case '{': case '(': { @@ -568,7 +580,7 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle break; case HF_TABLE: /* Must send current line, then emit table. */ - SEND_LINE(); + SEND_LINE(0); table_send(src, (message_dest ? message_dest->nick : dest), 0, irc_send, exp.value.table); value = ""; break; @@ -606,7 +618,7 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle /* word to send is too big to send now.. what to do? */ if (pos > 0) { /* try to put it on a separate line */ - SEND_LINE(); + SEND_LINE(1); } else { /* already at start of line; only send part of it */ strncpy(line, value, avail); @@ -619,7 +631,7 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle } /* if we're looking at a newline, send the accumulated text */ if (*value == '\n') { - SEND_LINE(); + SEND_LINE(0); value++; } } @@ -636,7 +648,7 @@ vsend_message(const char *dest, struct userNode *src, struct handle_info *handle send_line: expand_pos = pos; expand_ipos = ipos; - SEND_LINE(); + SEND_LINE(0); #undef SEND_LINE } return chars_sent; @@ -686,7 +698,7 @@ _send_help(struct userNode *dest, struct userNode *src, expand_func_t expand, co va_list ap; va_start(ap, format); - res = vsend_message(dest->nick, src, dest->handle_info, 4, expand, format, ap); + res = vsend_message(dest->nick, src, dest->handle_info, 12, expand, format, ap); va_end(ap); return res; } diff --git a/src/helpfile.h b/src/helpfile.h index d7102ed..c547f5e 100644 --- a/src/helpfile.h +++ b/src/helpfile.h @@ -72,6 +72,12 @@ struct language extern struct language *lang_C; extern struct dict *languages; +#define MSG_TYPE_NOTICE 0 +#define MSG_TYPE_PRIVMSG 1 +#define MSG_TYPE_WALLCHOPS 2 +#define MSG_TYPE_NOXLATE 4 +#define MSG_TYPE_MULTILINE 8 + int send_message(struct userNode *dest, struct userNode *src, const char *message, ...); int send_message_type(int msg_type, struct userNode *dest, struct userNode *src, const char *message, ...); int send_target_message(int msg_type, const char *dest, struct userNode *src, const char *format, ...); diff --git a/src/mod-helpserv.c b/src/mod-helpserv.c index 1412021..5e8a513 100644 --- a/src/mod-helpserv.c +++ b/src/mod-helpserv.c @@ -958,7 +958,7 @@ static struct helpserv_request * create_request(struct userNode *user, struct he else send_message_type(4, user, hs->helpserv, "%s %s %s", lbuf[0], lbuf[1], lbuf[2]); - if (hs->req_on_join && req == hs->unhandled && hs->helpchan_empty) { + if (hs->req_on_join && req == hs->unhandled && hs->helpchan_empty && !user->uplink->burst) { timeq_del(0, run_empty_interval, hs, TIMEQ_IGNORE_WHEN); run_empty_interval(hs); } @@ -1904,8 +1904,6 @@ static HELPSERV_FUNC(cmd_show) { REQUIRE_PARMS(2); - assert(hs_user); - if (!(req = smart_get_request(hs, hs_user, argv[1], &num_requests))) { helpserv_notice(user, "HSMSG_REQ_INVALID", argv[1]); return 0; @@ -1990,8 +1988,6 @@ static HELPSERV_FUNC(cmd_addnote) { REQUIRE_PARMS(3); - assert(hs_user); - if (!(req = smart_get_request(hs, hs_user, argv[1], &num_requests))) { helpserv_notice(user, "HSMSG_REQ_INVALID", argv[1]); return 0; diff --git a/srvx.conf.example b/srvx.conf.example index 28b9790..e7464e9 100644 --- a/srvx.conf.example +++ b/srvx.conf.example @@ -239,6 +239,8 @@ "default_modes" "+nt"; // minimum opserv access to set, clear or override nodelete setting? "nodelete_level" "1"; + // how long before a new channel owner can give ownership away? + "giveownership_timeout" "1w"; }; "global" { -- 2.20.1