/* saxdb.c - srvx database manager
* Copyright 2002-2004 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
* 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.
*/
#include "conf.h"
#include "saxdb.h"
#include "timeq.h"
-DECLARE_LIST(int_list, int);
DEFINE_LIST(int_list, int);
struct saxdb {
struct saxdb *prev;
};
-struct saxdb_context {
- FILE *output;
- unsigned int indent;
- struct int_list complex;
- jmp_buf jbuf;
- /* XXX: If jbuf is ever used, places that use saxdb_open_context() and
- * saxdb_close_context() must be modified to fill it in */
-};
-
#define COMPLEX(CTX) ((CTX)->complex.used ? ((CTX)->complex.list[(CTX)->complex.used-1]) : 1)
static struct saxdb *last_db;
assert(db);
assert(db->filename);
data = parse_database(db->filename);
- if (!data) return;
+ if (!data)
+ return;
if (db->writer == saxdb_mondo_writer) {
mondo_db = data;
} else {
start = time(NULL);
if ((res = setjmp(ctx.jbuf)) || (res2 = db->writer(&ctx))) {
if (res) {
- log_module(MAIN_LOG, LOG_ERROR, "Exception %d caught while writing to %s", res, tmp_fname);
+ log_module(MAIN_LOG, LOG_ERROR, "Error writing to %s: %s", tmp_fname, strerror(res));
} else {
log_module(MAIN_LOG, LOG_ERROR, "Internal error %d while writing to %s", res2, tmp_fname);
}
for (it = dict_first(saxdbs); it; it = iter_next(it)) {
db = iter_data(it);
- if (!db->mondo_section) saxdb_write_db(db);
+ if (!db->mondo_section)
+ saxdb_write_db(db);
}
}
-#define saxdb_put_char(DEST, CH) fputc(CH, (DEST)->output)
-#define saxdb_put_string(DEST, CH) fputs(CH, (DEST)->output)
+#define saxdb_put_char(DEST, CH) do { \
+ if (fputc(CH, (DEST)->output) == EOF) \
+ longjmp((DEST)->jbuf, errno); \
+ } while (0)
+#define saxdb_put_string(DEST, CH) do { \
+ if (fputs(CH, (DEST)->output) == EOF) \
+ longjmp((DEST)->jbuf, errno); \
+ } while (0)
static inline void
saxdb_put_nchars(struct saxdb_context *dest, const char *name, int len) {
- while (len--) {
- fputc(*name++, dest->output);
- }
+ while (len--)
+ if (fputc(*name++, dest->output) == EOF)
+ longjmp(dest->jbuf, errno);
}
static void
assert(str);
saxdb_put_char(dest, '"');
while ((esc = strpbrk(str, "\\\a\b\t\n\v\f\r\""))) {
- if (esc != str) saxdb_put_nchars(dest, str, esc-str);
+ if (esc != str)
+ saxdb_put_nchars(dest, str, esc-str);
saxdb_put_char(dest, '\\');
switch (*esc) {
case '\a': saxdb_put_char(dest, 'a'); break;
}
}
#else
-#define saxdb_pre_object(DEST)
+#define saxdb_pre_object(DEST)
#endif
static inline void
void
saxdb_write_int(struct saxdb_context *dest, const char *name, unsigned long value) {
- unsigned char buf[16];
+ char buf[16];
/* we could optimize this to take advantage of the fact that buf will never need escapes */
snprintf(buf, sizeof(buf), "%lu", value);
saxdb_write_string(dest, name, buf);
}
+void
+saxdb_write_sint(struct saxdb_context *dest, const char *name, long value) {
+ char buf[16];
+ /* we could optimize this to take advantage of the fact that buf will never need escapes */
+ snprintf(buf, sizeof(buf), "%ld", value);
+ saxdb_write_string(dest, name, buf);
+}
+
static void
saxdb_free(void *data) {
struct saxdb *db = data;
tbl.contents[0][4] = "Last Duration";
for (ii=1, it=dict_first(saxdbs); it; it=iter_next(it), ++ii) {
struct saxdb *db = iter_data(it);
+ if (db->mondo_section) {
+ --ii;
+ continue;
+ }
char *buf = malloc(INTERVALLEN*3);
tbl.contents[ii] = calloc(tbl.width, sizeof(tbl.contents[ii][0]));
tbl.contents[ii][0] = db->name;
tbl.contents[ii][1] = db->mondo_section ? db->mondo_section : db->filename;
if (db->write_interval) {
- intervalString(buf, db->write_interval);
+ intervalString(buf, db->write_interval, user->handle_info);
} else {
strcpy(buf, "Never");
}
tbl.contents[ii][2] = buf;
if (db->last_write) {
- intervalString(buf+INTERVALLEN, now - db->last_write);
- intervalString(buf+INTERVALLEN*2, db->last_write_duration);
+ intervalString(buf+INTERVALLEN, now - db->last_write, user->handle_info);
+ intervalString(buf+INTERVALLEN*2, db->last_write_duration, user->handle_info);
} else {
strcpy(buf+INTERVALLEN, "Never");
strcpy(buf+INTERVALLEN*2, "Never");
tbl.contents[ii][3] = buf+INTERVALLEN;
tbl.contents[ii][4] = buf+INTERVALLEN*2;
}
+ tbl.length = ii;
table_send(cmd->parent->bot, user->nick, 0, 0, tbl);
free(tbl.contents[0]);
for (ii=1; ii<tbl.length; ++ii) {