automatic arch-version.h update; CTCP support; helpfile fixes; disk-out-of-space...
[srvx.git] / src / mod-helpserv.c
index 145acd2ac1586eb495365a26c400ae661574dcba..177e11e53708f0a2ef4e479fc9b0bdc4cde4519b 100644 (file)
@@ -1,11 +1,12 @@
-/* helpserv.c - Support Helper assistant service
+/* mod-helpserv.c - Support Helper assistant service
  * Copyright 2002-2003 srvx Development Team
  *
- * This program is free software; you can redistribute it and/or modify
+ * This file is part of srvx.
+ *
+ * srvx is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.  Important limitations are
- * listed in the COPYING file that accompanies this software.
+ * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,7 +14,8 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, email srvx-maintainers@srvx.net.
+ * along with srvx; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 
 /* Wishlist for helpserv.c
@@ -287,6 +289,12 @@ static const struct message_entry msgtab[] = {
     { "HSMSG_STATS_TIME", "$uTime spent helping in %s:$u" },
     { "HSMSG_STATS_REQS", "$uRequest activity statistics:$u" },
 
+/* Status report headers */
+    { "HSMSG_STATS_REPORT_0", "Stats report for current week" },
+    { "HSMSG_STATS_REPORT_1", "Stats report for one week ago" },
+    { "HSMSG_STATS_REPORT_2", "Stats report for two weeks ago" },
+    { "HSMSG_STATS_REPORT_3", "Stats report for three weeks ago" },
+
 /* Responses to user commands */
     { "HSMSG_YOU_BEING_HELPED", "You are already being helped." },
     { "HSMSG_YOU_BEING_HELPED_BY", "You are already being helped by $b%s$b." },
@@ -457,10 +465,10 @@ static const char *weekday_names[] = {
 };
 
 static const char *statsreport_week[] = {
-    "Stats report for current week",
-    "Stats report for one week ago",
-    "Stats report for two weeks ago",
-    "Stats report for three weeks ago"
+    "HSMSG_STATS_REPORT_0",
+    "HSMSG_STATS_REPORT_1",
+    "HSMSG_STATS_REPORT_2",
+    "HSMSG_STATS_REPORT_3"
 };
 
 static struct {
@@ -474,7 +482,6 @@ static struct {
 static time_t last_stats_update;
 static int shutting_down;
 static FILE *reqlog_f;
-static struct saxdb_context *reqlog_ctx;
 static struct log_type *HS_LOG;
 
 #define CMD_NEED_BOT            0x001
@@ -684,33 +691,38 @@ static struct helpserv_user *GetHSUser(struct helpserv_bot *hs, struct handle_in
 static void helpserv_log_request(struct helpserv_request *req, const char *reason) {
     char key[27+NICKLEN];
     char userhost[USERLEN+HOSTLEN+2];
+    struct saxdb_context *ctx;
+    int res;
 
-    if (!reqlog_ctx || !req)
+    assert(req != NULL);
+    assert(reason != NULL);
+    if (!(ctx = saxdb_open_context(reqlog_f)))
         return;
-    if (!reason)
-        reason = "";
-
     sprintf(key, "%s-" FMT_TIME_T "-%lu", req->hs->helpserv->nick, req->opened, req->id);
-    saxdb_start_record(reqlog_ctx, key, 1);
-    if (req->helper) {
-        saxdb_write_string(reqlog_ctx, KEY_REQUEST_HELPER, req->helper->handle->handle);
-        saxdb_write_int(reqlog_ctx, KEY_REQUEST_ASSIGNED, req->assigned);
-    }
-    if (req->handle) {
-        saxdb_write_string(reqlog_ctx, KEY_REQUEST_HANDLE, req->handle->handle);
-    }
-    if (req->user) {
-        saxdb_write_string(reqlog_ctx, KEY_REQUEST_NICK, req->user->nick);
-        sprintf(userhost, "%s@%s", req->user->ident, req->user->hostname);
-        saxdb_write_string(reqlog_ctx, KEY_REQUEST_USERHOST, userhost);
+    if ((res = setjmp(ctx->jbuf)) != 0) {
+        log_module(HS_LOG, LOG_ERROR, "Unable to log helpserv request: %s.", strerror(res));
+    } else {
+        saxdb_start_record(ctx, key, 1);
+        if (req->helper) {
+            saxdb_write_string(ctx, KEY_REQUEST_HELPER, req->helper->handle->handle);
+            saxdb_write_int(ctx, KEY_REQUEST_ASSIGNED, req->assigned);
+        }
+        if (req->handle) {
+            saxdb_write_string(ctx, KEY_REQUEST_HANDLE, req->handle->handle);
+        }
+        if (req->user) {
+            saxdb_write_string(ctx, KEY_REQUEST_NICK, req->user->nick);
+            sprintf(userhost, "%s@%s", req->user->ident, req->user->hostname);
+            saxdb_write_string(ctx, KEY_REQUEST_USERHOST, userhost);
+        }
+        saxdb_write_int(ctx, KEY_REQUEST_OPENED, req->opened);
+        saxdb_write_int(ctx, KEY_REQUEST_CLOSED, now);
+        saxdb_write_string(ctx, KEY_REQUEST_CLOSEREASON, reason);
+        saxdb_write_string_list(ctx, KEY_REQUEST_TEXT, req->text);
+        saxdb_end_record(ctx);
+        saxdb_close_context(ctx);
+        fflush(reqlog_f);
     }
-    saxdb_write_int(reqlog_ctx, KEY_REQUEST_OPENED, req->opened);
-    saxdb_write_int(reqlog_ctx, KEY_REQUEST_CLOSED, now);
-    saxdb_write_string(reqlog_ctx, KEY_REQUEST_CLOSEREASON, reason);
-    saxdb_write_string_list(reqlog_ctx, KEY_REQUEST_TEXT, req->text);
-    saxdb_end_record(reqlog_ctx);
-
-    fflush(reqlog_f);
 }
 
 /* Searches for a request by number, nick, or account (num|nick|*account).
@@ -1661,7 +1673,7 @@ static HELPSERV_FUNC(cmd_close) {
         struct modeNode *mn = GetUserMode(hs->helpchan, req_user);
         if ((!newest || !newest->helper) && mn && (mn->modes & MODE_VOICE)) {
             struct mod_chanmode change;
-            change.modes_set = change.modes_clear = 0;
+            mod_chanmode_init(&change);
             change.argc = 1;
             change.args[0].mode = MODE_REMOVE | MODE_VOICE;
             change.args[0].member = mn;
@@ -1865,7 +1877,7 @@ static int helpserv_assign(int from_opserv, struct helpserv_bot *hs, struct user
 
     if (req->user && hs->auto_voice) {
         struct mod_chanmode change;
-        change.modes_set = change.modes_clear = 0;
+        mod_chanmode_init(&change);
         change.argc = 1;
         change.args[0].mode = MODE_VOICE;
         if ((change.args[0].member = GetUserMode(hs->helpchan, req->user)))
@@ -2242,7 +2254,7 @@ static HELPSERV_FUNC(cmd_move) {
             AddChannelUser(hs->helpserv, hs->helpchan)->modes |= MODE_CHANOP;
         } else if (!helpserv_in_channel(hs, old_helpchan)) {
             struct mod_chanmode change;
-            change.modes_set = change.modes_clear = 0;
+            mod_chanmode_init(&change);
             change.argc = 1;
             change.args[0].mode = MODE_CHANOP;
             change.args[0].member = AddChannelUser(hs->helpserv, hs->helpchan);
@@ -2321,7 +2333,7 @@ static void helpserv_page_helper_gone(struct helpserv_bot *hs, struct helpserv_r
         helpserv_msguser(req->user, "HSMSG_REQ_UNASSIGNED", req->id, reason);
         if (hs->auto_devoice && mn && (mn->modes & MODE_VOICE)) {
             struct mod_chanmode change;
-            change.modes_set = change.modes_clear = 0;
+            mod_chanmode_init(&change);
             change.argc = 1;
             change.args[0].mode = MODE_REMOVE | MODE_VOICE;
             change.args[0].member = mn;
@@ -2603,7 +2615,7 @@ static struct helpserv_bot *register_helpserv(const char *nick, const char *help
         AddChannelUser(hs->helpserv, hs->helpchan)->modes |= MODE_CHANOP;
     } else {
         struct mod_chanmode change;
-        change.modes_set = change.modes_clear = 0;
+        mod_chanmode_init(&change);
         change.argc = 1;
         change.args[0].mode = MODE_CHANOP;
         change.args[0].member = AddChannelUser(hs->helpserv, hs->helpchan);
@@ -2860,7 +2872,7 @@ static void set_page_target(struct helpserv_bot *hs, enum page_source idx, const
         DelChannelUser(hs->helpserv, old_target, "Changing page target.", 0);
     if (new_target && !helpserv_in_channel(hs, new_target)) {
         struct mod_chanmode change;
-        change.modes_set = change.modes_clear = 0;
+        mod_chanmode_init(&change);
         change.argc = 1;
         change.args[0].mode = MODE_CHANOP;
         change.args[0].member = AddChannelUser(hs->helpserv, new_target);
@@ -3653,20 +3665,13 @@ static void helpserv_conf_read(void) {
     str = database_get_data(conf_node, "user_escape", RECDB_QSTRING);
     helpserv_conf.user_escape = str ? str[0] : '@';
 
-    if (reqlog_ctx) {
-        saxdb_close_context(reqlog_ctx);
-        reqlog_ctx = NULL;
-    }
     if (reqlog_f) {
         fclose(reqlog_f);
         reqlog_f = NULL;
     }
-    if (helpserv_conf.reqlogfile) {
-        if (!(reqlog_f = fopen(helpserv_conf.reqlogfile, "a"))) {
-            log_module(HS_LOG, LOG_ERROR, "Unable to open request logfile (%s): %s", helpserv_conf.reqlogfile, strerror(errno));
-        } else {
-            reqlog_ctx = saxdb_open_context(reqlog_f);
-        }
+    if (helpserv_conf.reqlogfile
+        && !(reqlog_f = fopen(helpserv_conf.reqlogfile, "a"))) {
+        log_module(HS_LOG, LOG_ERROR, "Unable to open request logfile (%s): %s", helpserv_conf.reqlogfile, strerror(errno));
     }
 }
 
@@ -3898,7 +3903,7 @@ static void associate_requests_bybot(struct helpserv_bot *hs, struct userNode *u
         if (hs->auto_voice && req->helper)
         {
             struct mod_chanmode change;
-            change.modes_set = change.modes_clear = 0;
+            mod_chanmode_init(&change);
             change.argc = 1;
             change.args[0].mode = MODE_VOICE;
             if ((change.args[0].member = GetUserMode(hs->helpchan, user)))
@@ -4453,8 +4458,6 @@ static void helpserv_db_cleanup(void) {
     dict_delete(helpserv_reqs_byhand_dict);
     dict_delete(helpserv_users_byhand_dict);
 
-    if (reqlog_ctx)
-        saxdb_close_context(reqlog_ctx);
     if (reqlog_f)
         fclose(reqlog_f);
 }