Channel suspension, transfer and line wrap changes
authorMichael Poole <mdpoole@troilus.org>
Thu, 22 Jul 2004 04:03:22 +0000 (04:03 +0000)
committerMichael Poole <mdpoole@troilus.org>
Thu, 22 Jul 2004 04:03:22 +0000 (04:03 +0000)
* 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
languages/de/strings.db
src/chanserv.c
src/chanserv.h
src/helpfile.c
src/helpfile.h
src/mod-helpserv.c
srvx.conf.example

index e1650de9aae18374871858e693f67e2e1566fad2..0370654461ac8e247debf844458f11834fc7908b 100644 (file)
--- 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 <mdpoole@troilus.org>     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 <mdpoole@troilus.org>     patch-73
 
     Summary:
index 99ed5d3a1f3184ecfbe250b173366445a53ec2d0..9727d26a605a2b3e98da98b0a159b4eaf8ee7545 100644 (file)
 "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 !";
index 2979451e9d59561251977e1ac7976b29670cc7e9..7b7a7881748af0216e37ebeffe3ad84c80453bbc 100644 (file)
@@ -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"
 #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);
 }
index bd437a8ce22de492a500c2b9a96a074121e23e26..d094595fbe6b50b7128b66516ecbd3be31478828 100644 (file)
@@ -81,6 +81,7 @@ struct chanData
     time_t             registered;
     time_t             visited;
     time_t             limitAdjusted;
+    time_t              ownerTransfer;
 
     char               *topic;
     char               *greeting;
index a08c7b7316f0a7abcbb3d8bb1014deb61fa25e91..2529408e72a7cde2b1e694baaf9f3dee6bea6bf4 100644 (file)
@@ -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;
 }
index d7102ed4534730d92aa226ac7831cda7059a1e0e..c547f5e76ca927d3fa3d4be8566d854389743c77 100644 (file)
@@ -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, ...);
index 14120215546a5ae173a98c9d44cebb355ecf5798..5e8a5139a5206415af674308475081973bbde587 100644 (file)
@@ -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;
index 28b97903b92a65b6ef4881127d3c5c416d7d401a..e7464e9f2108b5a117385a7cf204e1c4811bfa5a 100644 (file)
         "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" {