src/logfile.c File Reference

#include <eggdrop/eggdrop.h>
#include <unistd.h>
#include "core_config.h"
#include "terminal.h"
#include "logfile.h"

Go to the source code of this file.

Functions

static int logfile_minutely ()
static int logfile_5minutely ()
static int logfile_cycle ()
static void check_logsizes ()
static void flushlog (logfile_t *log, char *timestamp)
static int on_putlog (int flags, const char *chan, const char *text, int len)
void logfile_init (void)
void logfile_shutdown (void)
char * logfile_add (char *modes, char *chan, char *fname)
int logfile_del (char *filename)
void flushlogs ()

Variables

static const char rcsid [] = "$Id: logfile.c,v 1.51 2006-11-14 14:51:24 sven Exp $"
static logfile_tlogfiles = NULL
static int nlogfiles = 0
int backgrd
int use_stderr
int terminal_mode
int terminal_enabled = 0
time_t now
static script_command_t log_script_cmds []


Function Documentation

static void check_logsizes (  )  [static]

Definition at line 298 of file logfile.c.

References _, core_config, egg_mprintf(), logfile_t::filename, logfile_t::fp, logging_t::keep_all, LOG_MISC, core_config_t::logging, logging_t::max_size, movefile(), nlogfiles, and putlog().

Referenced by logfile_5minutely(), and logfile_minutely().

00299 {
00300   int size, i;
00301   char *newfname;
00302 
00303   if (core_config.logging.keep_all || core_config.logging.max_size <= 0) return;
00304 
00305   for (i = 0; i < nlogfiles; i++) {
00306     logfile_t *log = &logfiles[i];
00307     
00308     size = ftell(log->fp) / 1024; /* Size in kilobytes. */
00309     if (size < core_config.logging.max_size) continue;
00310 
00311     /* It's too big. */
00312     putlog(LOG_MISC, "*", _("Cycling logfile %s: over max-logsize (%d kilobytes)."), log->filename, size);
00313     fclose(log->fp);
00314 
00315     newfname = egg_mprintf("%s.yesterday", log->filename);
00316     unlink(newfname);
00317     movefile(log->filename, newfname);
00318     free(newfname);
00319   }
00320 }

static void flushlog ( logfile_t log,
char *  timestamp 
) [static]

Definition at line 322 of file logfile.c.

References _, logfile_t::fp, logfile_t::last_msg, logfile_t::repeats, and str_redup().

Referenced by flushlogs(), and logfile_del().

00323 {
00324   if (log->repeats) {
00325     fprintf(log->fp, "%s", timestamp);
00326     fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
00327     log->repeats = 0;
00328     str_redup(&log->last_msg, "");
00329   }
00330   fflush(log->fp);
00331 }

void flushlogs (  ) 

Definition at line 335 of file logfile.c.

References flushlog(), nlogfiles, and timer_get_timestamp().

Referenced by fatal(), logfile_5minutely(), logfile_cycle(), logfile_minutely(), and logfile_shutdown().

00336 {
00337   char *ts;
00338   int i;
00339 
00340   ts = timer_get_timestamp();
00341   for (i = 0; i < nlogfiles; i++) {
00342     flushlog(&logfiles[i], ts);
00343   }
00344 }

static int logfile_5minutely (  )  [static]

Definition at line 115 of file logfile.c.

References check_logsizes(), core_config, flushlogs(), core_config_t::logging, and logging_t::quick.

Referenced by logfile_init(), and logfile_shutdown().

00116 {
00117   if (!core_config.logging.quick) {
00118     flushlogs();
00119     check_logsizes();
00120   }
00121   return(0);
00122 }

char* logfile_add ( char *  modes,
char *  chan,
char *  fname 
)

Definition at line 158 of file logfile.c.

References logfile_t::chname, logfile_t::filename, logfile_t::fp, logfile_t::last_msg, LOG_ALL, logfile_del(), logfile_t::mask, and nlogfiles.

Referenced by logfile_init().

00159 {
00160   FILE *fp;
00161   logfile_t *log;
00162 
00163   /* Get rid of any duplicates. */
00164   logfile_del(fname);
00165 
00166   /* Test the filename. */
00167   fp = fopen(fname, "a");
00168   if (!fp) return("");
00169   
00170   logfiles = realloc(logfiles, (nlogfiles + 1) * sizeof(*logfiles));
00171       
00172   log = &logfiles[nlogfiles++];
00173   memset(log, 0, sizeof(*log));
00174   log->filename = strdup(fname);
00175   log->chname = strdup(chan);
00176   log->last_msg = strdup("");
00177   log->mask = LOG_ALL;
00178   log->fp = fp;
00179 
00180   return (log->filename);
00181 }

static int logfile_cycle (  )  [static]

Definition at line 124 of file logfile.c.

References _, core_config, egg_mprintf(), logfile_t::filename, flushlogs(), logfile_t::fp, logging_t::keep_all, LOG_MISC, logfile_del(), core_config_t::logging, movefile(), nlogfiles, now, putlog(), and logging_t::suffix.

Referenced by logfile_minutely().

00125 {
00126   logfile_t *log;
00127   int i;
00128   char suffix[32];
00129   char *newfname;
00130 
00131   putlog(LOG_MISC, "*", _("Cycling logfiles..."));
00132   flushlogs();
00133 
00134   /* Determine suffix for cycled logfiles. */
00135   if (core_config.logging.keep_all) {
00136     strftime(suffix, 32, core_config.logging.suffix, localtime(&now));
00137   }
00138 
00139   for (i = nlogfiles - 1; i >= 0; i--) {
00140     log = &logfiles[i];
00141 
00142     fclose(log->fp);
00143 
00144     if (core_config.logging.keep_all) newfname = egg_mprintf("%s%s", log->filename, suffix);
00145     else newfname = egg_mprintf("%s.yesterday", log->filename);
00146 
00147     unlink(newfname);
00148     movefile(log->filename, newfname);
00149     free(newfname);
00150 
00151     log->fp = fopen(log->filename, "a");
00152     if (!log->fp) logfile_del(log->filename);
00153   }
00154   
00155   return(0);
00156 }

int logfile_del ( char *  filename  ) 

Definition at line 183 of file logfile.c.

References logfile_t::filename, flushlog(), logfile_t::fp, logfile_t::last_msg, nlogfiles, NULL, and timer_get_timestamp().

Referenced by logfile_add(), and logfile_cycle().

00184 {
00185   logfile_t *log;
00186   int i;
00187 
00188   log = NULL;
00189   for (i = 0; i < nlogfiles; i++) {
00190     log = &logfiles[i];
00191     if (!strcmp(log->filename, filename)) break;
00192     log = NULL;
00193   }
00194 
00195   if (log == NULL) return(-1);
00196     
00197   if (log->fp) {
00198     flushlog(log, timer_get_timestamp());
00199     fclose(log->fp);
00200   }
00201 
00202   if (log->last_msg) free(log->last_msg);
00203   if (log->filename) free(log->filename);
00204 
00205   if (nlogfiles == 1) {
00206     free(logfiles);
00207     logfiles = NULL;
00208   } else {    
00209     memmove(logfiles + i, logfiles + i + 1, (nlogfiles - i - 1) * sizeof(logfile_t));
00210     logfiles = realloc(logfiles, (nlogfiles - 1) * sizeof(logfile_t));
00211   }
00212 
00213   nlogfiles--;
00214 
00215   return(0);
00216 }

void logfile_init ( void   ) 

Definition at line 54 of file logfile.c.

References bind_add_simple(), config_get_root(), config_get_str(), config_lookup_section(), logfile_5minutely(), logfile_add(), logfile_minutely(), NULL, on_putlog(), and script_create_commands().

Referenced by core_init().

00055 {
00056   void *root, *node;
00057   char *filename, *chname, *mask;
00058   int i;
00059 
00060   script_create_commands(log_script_cmds);
00061   bind_add_simple("log", NULL, NULL, on_putlog);
00062   bind_add_simple("event", NULL, "minutely", logfile_minutely);
00063   bind_add_simple("event", NULL, "5minutely", logfile_5minutely);
00064 
00065   root = config_get_root("eggdrop");
00066   node = config_lookup_section(root, "eggdrop.logging.logfiles", 0, NULL);
00067   for (i = 0; ; i++) {
00068     config_get_str(&filename, node, "logfile", i, "filename", 0, NULL);
00069     config_get_str(&chname, node, "logfile", i, "channel", 0, NULL);
00070     config_get_str(&mask, node, "logfile", i, "mask", 0, NULL);
00071     if (!filename || !chname || !mask) break;
00072     logfile_add(mask, chname, filename);
00073   }
00074 }

static int logfile_minutely (  )  [static]

Definition at line 97 of file logfile.c.

References check_logsizes(), core_config, flushlogs(), logfile_cycle(), core_config_t::logging, now, nowtm, logging_t::quick, and logging_t::switch_at.

Referenced by logfile_init(), and logfile_shutdown().

00098 {
00099   struct tm *nowtm;
00100   int miltime;
00101 
00102   if (core_config.logging.quick) {
00103     flushlogs();
00104     check_logsizes();
00105   }
00106 
00107   nowtm = localtime(&now);
00108   miltime = 100 * nowtm->tm_hour + nowtm->tm_min;
00109 
00110   if (miltime == core_config.logging.switch_at) logfile_cycle();
00111 
00112   return(0);
00113 }

void logfile_shutdown ( void   ) 

Definition at line 76 of file logfile.c.

References bind_rem_simple(), config_get_root(), config_lookup_section(), config_set_str(), flushlogs(), logfile_5minutely(), logfile_minutely(), nlogfiles, NULL, on_putlog(), and script_delete_commands().

Referenced by core_shutdown_or_restart().

00077 {
00078   void *root, *node;
00079   int i;
00080 
00081   flushlogs();
00082   
00083   root = config_get_root("eggdrop");
00084   node = config_lookup_section(root, "eggdrop.logging.logfiles", 0, NULL);
00085   for (i = 0; i < nlogfiles; i++) {
00086     config_set_str(logfiles[i].filename, node, "logfile", i, "filename", 0, NULL);
00087     config_set_str(logfiles[i].chname, node, "logfile", i, "channel", 0, NULL);
00088     config_set_str("*", node, "logfile", i, "mask", 0, NULL);
00089   }
00090 
00091   bind_rem_simple("log", NULL, NULL, on_putlog);
00092   bind_rem_simple("event", NULL, "minutely", logfile_minutely);
00093   bind_rem_simple("event", NULL, "5minutely", logfile_5minutely);
00094   script_delete_commands(log_script_cmds);
00095 }

static int on_putlog ( int  flags,
const char *  chan,
const char *  text,
int  len 
) [static]

Definition at line 218 of file logfile.c.

References _, backgrd, logfile_t::chname, logfile_t::filename, logfile_t::fname, logfile_t::fp, irccmp(), logfile_t::last_msg, LOG_MISC, LOG_STATE_DISABLED, LOG_STATE_ENABLED, logfile_t::mask, nlogfiles, now, NULL, partymember_lookup(), putlog(), logfile_t::repeats, logfile_t::state, str_redup(), terminal_enabled, terminal_mode, TERMINAL_NICK, timer_get_timestamp(), and use_stderr.

Referenced by logfile_init(), and logfile_shutdown().

00219 {
00220   char *ts;
00221   int i;
00222 
00223   ts = timer_get_timestamp();
00224   for (i = nlogfiles - 1; i >= 0; i--) {
00225     logfile_t *log = &logfiles[i];
00226     
00227     /* If this log is disabled, skip it */
00228     if (log->state != LOG_STATE_ENABLED)
00229       continue;
00230 
00231     /* If this log doesn't match, skip it. */
00232     if (!(log->mask & flags)) {
00233       continue;
00234     }
00235 
00236     if (chan[0] != '*' && log->chname[0] != '*' && irccmp(chan, log->chname)) continue;
00237     
00238     /* If it's a repeat message, don't write it again. */
00239     if (log->last_msg && !strcasecmp(text, log->last_msg)) {
00240       log->repeats++;
00241       continue;
00242     }
00243 
00244 
00245     /* If there was a repeated message, write the count. */
00246     if (log->repeats) {
00247       fprintf(log->fp, "%s", ts);
00248       fprintf(log->fp, _("Last message repeated %d time(s).\n"), log->repeats);
00249       log->repeats = 0;
00250     }
00251 
00252     /* Save this msg to check for repeats next time. */
00253     str_redup(&log->last_msg, text);
00254 
00255     if (log->fp == NULL) {
00256       if (log->fname == NULL) {
00257         char buf[1024];
00258         time_t now;
00259 
00260         now = time(NULL);
00261         strftime(buf, sizeof(buf), log->filename, localtime(&now));
00262         log->fname = strdup(buf);
00263       } 
00264 
00265       log->fp = fopen(log->fname, "a+");
00266       if (log->fp == NULL) {
00267         log->state = LOG_STATE_DISABLED;
00268         putlog(LOG_MISC, "*", _("Failed to open log file: %s"), log->fname);
00269         putlog(LOG_MISC, "*", _("  Check if directory (if any) exists and is read- and writeable."));
00270         continue;
00271       }
00272     }
00273 
00274     /* Now output to the file. */
00275     fprintf(log->fp, "%s%s\n", ts, text);
00276   }
00277 
00278   if (!backgrd || use_stderr) {
00279   
00280     if (terminal_mode) {
00281       /* check if HQ is on console. If yes we disable
00282        * output to stdout since otherwise everything would
00283        * be printed out twice. */   
00284       if (!terminal_enabled) {
00285         terminal_enabled = (partymember_lookup(TERMINAL_NICK, NULL, -1) != NULL);
00286       }
00287       if (terminal_enabled)
00288         return 0;
00289 
00290     }
00291     
00292     fprintf (stdout, "%s %s%s\n", chan, ts, text);
00293   }
00294     
00295   return(0);
00296 }


Variable Documentation

int backgrd

Definition at line 61 of file main.c.

Referenced by core_init(), do_args(), and on_putlog().

Initial value:

 {
  {"", "logfile", logfile_add, NULL, 3, "sss", "modes chan filename", SCRIPT_STRING, 0},  
  {0}
}

Definition at line 49 of file logfile.c.

logfile_t* logfiles = NULL [static]

Definition at line 32 of file logfile.c.

int nlogfiles = 0 [static]

time_t now

const char rcsid[] = "$Id: logfile.c,v 1.51 2006-11-14 14:51:24 sven Exp $" [static]

Definition at line 22 of file logfile.c.

Definition at line 36 of file logfile.c.

Referenced by on_putlog(), and terminal_shutdown().

Definition at line 63 of file main.c.

Referenced by core_init(), core_shutdown_or_restart(), do_args(), and on_putlog().

Definition at line 75 of file main.c.

Referenced by on_putlog().


Generated on Sun Nov 30 18:43:36 2008 for eggdrop1.9 by  doxygen 1.5.6