X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flog.c;h=c7c43c876a8f5a7ed9d497246ada8e45faf9abc0;hb=refs%2Fheads%2Fmaster;hp=7c04f23772b3c47cab7e2f9a47c3bd7158aff2cf;hpb=8a3aac5f5287422699c9c7c5ee8969561da7317f;p=sympathy.git diff --git a/src/log.c b/src/log.c index 7c04f23..c7c43c8 100644 --- a/src/log.c +++ b/src/log.c @@ -1,15 +1,51 @@ -/* +/* * log.c: * - * Copyright (c) 2008 James McKenzie , + * Copyright (c) 2008 James McKenzie , * All rights reserved. * */ -static char rcsid[] = "$Id$"; +static char rcsid[] = "$Id: log.c,v 1.17 2011/02/04 16:14:16 james Exp $"; -/* - * $Log$ +/* + * $Log: log.c,v $ + * Revision 1.17 2011/02/04 16:14:16 james + * *** empty log message *** + * + * Revision 1.16 2010/07/27 14:49:35 james + * add support for byte logging + * + * Revision 1.15 2010/07/16 11:04:10 james + * ignore tedious return values + * + * Revision 1.14 2008/03/11 17:56:04 james + * *** empty log message *** + * + * Revision 1.13 2008/03/11 16:56:29 james + * *** empty log message *** + * + * Revision 1.12 2008/03/10 11:49:33 james + * *** empty log message *** + * + * Revision 1.11 2008/03/07 13:16:02 james + * *** empty log message *** + * + * Revision 1.10 2008/03/07 12:37:04 james + * *** empty log message *** + * + * Revision 1.9 2008/03/03 06:20:14 james + * *** empty log message *** + * + * Revision 1.8 2008/03/03 06:04:42 james + * *** empty log message *** + * + * Revision 1.7 2008/03/03 06:04:18 james + * *** empty log message *** + * + * Revision 1.6 2008/03/02 10:37:56 james + * *** empty log message *** + * * Revision 1.5 2008/02/27 01:31:14 james * *** empty log message *** * @@ -29,15 +65,93 @@ static char rcsid[] = "$Id$"; #include "project.h" -typedef struct -{ +typedef struct { LOG_SIGNATURE; int do_close; + int rotate; FILE *fp; + char *filename; + int needs_newline; } File_Log; + +static Log *loggers = NULL; + + static void -flog_log (Log * _l, char *buf) +sighup (int dummy) +{ + Log *l; + + for (l = loggers; l; l = l->next) { + if (l->sighup) + l->sighup (l); + } +} + + +void +log_register_handlers (void) +{ + struct sigaction sa = { 0 }; + + sa.sa_handler = sighup; + sa.sa_flags = SA_RESTART; + sigaction (SIGHUP, &sa, NULL); +} + + +void +log_add (Log * l) +{ + log_register_handlers (); + + l->next = loggers; + loggers = l; +} + +void +log_remove (Log * l) +{ + Log **ptr = &loggers; + + /* Take out of sighup list */ + while (*ptr && (*ptr != l)) + ptr = &((*ptr)->next); + + if (*ptr) + *ptr = l->next; +} + +static void flog_newline(Log *_l,int force) +{ + File_Log *l = (File_Log *) _l; + + if (force || !l->needs_newline) return; + + l->needs_newline=0; + + fputc ('\n', l->fp); + fflush (l->fp); +} + + +static void +flog_sighup (Log * _l) +{ + File_Log *l = (File_Log *) _l; + if (!l->fp) + return; + + log_f (_l, ""); + fclose (l->fp); + + l->fp = fopen (l->filename, "a+"); + log_f (_l, ""); +} + +static void +flog_emit_stamp(Log *_l) { File_Log *l = (File_Log *) _l; struct timeval tv = { 0 }; @@ -54,16 +168,66 @@ flog_log (Log * _l, char *buf) if (!l->fp) return; + flog_newline(_l,0); + gettimeofday (&tv, NULL); t = tv.tv_sec; tm = localtime (&t); fprintf (l->fp, "%s %2d %02d:%02d:%02d.%06d ", months[tm->tm_mon], - tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); + tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,(int) tv.tv_usec); +} + + +static void flog_check_rotate(Log *_l) +{ + File_Log *l = (File_Log *) _l; + + if (l->rotate && rotate_check (l->filename)) { + fclose (l->fp); + rotate (l->filename); + l->fp = fopen (l->filename, "a+"); + } +} + + +static void +flog_log_bytes (Log * _l, void *_buf,int len) +{ + File_Log *l = (File_Log *) _l; + uint8_t *buf=(uint8_t *) _buf; + + if (!l->fp) + return; + + while (len--) { + if (*buf=='\n') { + flog_newline(_l,1); + flog_check_rotate(_l); + flog_emit_stamp(_l); + } else { + l->needs_newline++; + fputc (*buf, l->fp); + } + buf++; + } +} + +static void +flog_log (Log * _l, char *buf) +{ + File_Log *l = (File_Log *) _l; + + if (!l->fp) + return; + + flog_emit_stamp(_l); fputs (buf, l->fp); fputc ('\n', l->fp); fflush (l->fp); + + flog_check_rotate(_l); } @@ -75,36 +239,44 @@ flog_close (Log * _l) File_Log *l = (File_Log *) _l; if (l->fp && l->do_close) fclose (l->fp); + if (l->filename) + free (l->filename); free (l); } Log * -file_log_new (char *fn) +file_log_new (char *fn, int rotate) { File_Log *l; - FILE *f; int dc = 1; - if (fn && strcmp (fn, "-")) - { - f = fopen (fn, "a+"); - if (!f) - return NULL; - } - else - { - f = stderr; - dc = 0; + l = xmalloc (sizeof (File_Log)); + + if (fn && strcmp (fn, "-")) { + l->fp = fopen (fn, "a+"); + if (!l->fp) { + free (l); + return NULL; } + l->sighup = flog_sighup; + } else { + l->fp = stderr; + dc = 0; + } - l = malloc (sizeof (File_Log)); l->log = flog_log; + l->log_bytes = flog_log_bytes; l->close = flog_close; - l->fp = f; l->do_close = dc; + l->rotate = rotate; + l->filename = strdup (fn); + + l->needs_newline=0; + + fput_cp (l->fp, 0xffef); - fput_cp (f, 0xffef); + log_add ((Log *) l); return (Log *) l; } @@ -121,35 +293,32 @@ log_f (Log * log, char *fmt, ...) if (!log) return; - if (!size) - { - size = 128; - buf = malloc (size); - } + if (!size) { + size = 128; + buf = malloc (size); + } if (!buf) return; - while (1) - { - va_start (ap, fmt); - n = vsnprintf (buf, size, fmt, ap); - va_end (ap); + while (1) { + va_start (ap, fmt); + n = vsnprintf (buf, size, fmt, ap); + va_end (ap); - if (n > -1 && n < size) - { - log->log (log, buf); - return; - } + if (n > -1 && n < size) { + log->log (log, buf); + return; + } - if (n > -1) /* glibc 2.1 */ - size = n + 1; - else /* glibc 2.0 */ - size *= 2; /* twice the old size */ + if (n > -1) /* glibc 2.1 */ + size = n + 1; + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ - buf = realloc (buf, size); + buf = xrealloc (buf, size); - if (!buf) - return; - } + if (!buf) + return; + } }