Crossfire Server, Branch 1.12  R12190
logger.c
Go to the documentation of this file.
00001 /*
00002  * static char *rcsid_loger_c =
00003  *   "$Id: logger.c 11578 2009-02-23 22:02:27Z lalo $ ";
00004  */
00005 
00006 int reopen_logfile = 0; /* May be set in SIGHUP handler */
00007 
00008 /*
00009     CrossFire, A Multiplayer game for X-windows
00010 
00011     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
00012     Copyright (C) 1992 Frank Tore Johansen
00013 
00014     This program is free software; you can redistribute it and/or modify
00015     it under the terms of the GNU General Public License as published by
00016     the Free Software Foundation; either version 2 of the License, or
00017     (at your option) any later version.
00018 
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022     GNU General Public License for more details.
00023 
00024     You should have received a copy of the GNU General Public License
00025     along with this program; if not, write to the Free Software
00026     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00027 
00028     The authors can be reached via e-mail at crossfire-devel@real-time.com
00029 */
00030 
00036 #include <stdarg.h>
00037 #include <global.h>
00038 #include <sproto.h>
00039 
00043 static const char *const loglevel_names[] = {
00044     "[Error]   ",
00045     "[Info]    ",
00046     "[Debug]   ",
00047     "[Monster] "
00048 };
00049 
00063 void LOG(LogLevel logLevel, const char *format, ...) {
00064     char buf[20480];  /* This needs to be really really big - larger
00065                        * than any other buffer, since that buffer may
00066                        * need to be put in this one.
00067                        */
00068 
00069     char time_buf[2048];
00070 
00071     va_list ap;
00072     va_start(ap, format);
00073 
00074     buf[0] = '\0';
00075     if (logLevel <= settings.debug) {
00076         time_buf[0] = '\0';
00077         if (settings.log_timestamp == TRUE) {
00078             struct tm *time_tmp;
00079             time_t now = time((time_t *)NULL);
00080 
00081             time_tmp = localtime(&now);
00082             if (time_tmp != NULL) {
00083                 if (strftime(time_buf, sizeof(time_buf), settings.log_timestamp_format, time_tmp) == 0) {
00084                     time_buf[0] = '\0';
00085                 }
00086             }
00087         }
00088 
00089         vsnprintf(buf, sizeof(buf), format, ap);
00090 #ifdef WIN32 /* ---win32 change log handling for win32 */
00091         if (time_buf[0] != 0) {
00092             fputs(time_buf, logfile);
00093             fputs(" ", logfile);
00094         }
00095         fputs(loglevel_names[logLevel], logfile);    /* wrote to file or stdout */
00096         fputs(buf, logfile);    /* wrote to file or stdout */
00097 #ifdef DEBUG    /* if we have a debug version, we want see ALL output */
00098         fflush(logfile);    /* so flush this! */
00099 #endif
00100         if (logfile != stderr) {  /* if was it a logfile wrote it to screen too */
00101             fputs(loglevel_names[logLevel], stderr);
00102             fputs(buf, stderr);
00103             if (time_buf[0] != 0) {
00104                 fputs(time_buf, stderr);
00105                 fputs(" ", stderr);
00106             }
00107         }
00108 #else /* not WIN32 */
00109         if (reopen_logfile) {
00110             reopen_logfile = 0;
00111             if (fclose(logfile) != 0) {
00112                 /* stderr has been closed if -detach was used, but it's better
00113                  * to try to report about this anyway. */
00114                 perror("tried to close log file after SIGHUP in logger.c:LOG()");
00115             }
00116             if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
00117                 /* There's likely to be something very wrong with the OS anyway
00118                  * if reopening fails. */
00119                 perror("tried to open log file after SIGHUP in logger.c:LOG()");
00120                 emergency_save(0);
00121                 clean_tmp_files();
00122                 exit(1);
00123             }
00124             setvbuf(logfile, NULL, _IOLBF, 0);
00125             LOG(llevInfo, "logfile reopened\n");
00126         }
00127 
00128         if (time_buf[0] != 0) {
00129             fputs(time_buf, logfile);
00130             fputs(" ", logfile);
00131         }
00132         fputs(loglevel_names[logLevel], logfile);
00133         fputs(buf, logfile);
00134 #endif
00135     }
00136     if (!exiting
00137     && !trying_emergency_save
00138     && logLevel == llevError
00139     && ++nroferrors > MAX_ERRORS) {
00140         exiting = 1;
00141         if (!trying_emergency_save)
00142             emergency_save(0);
00143     }
00144     va_end(ap);
00145 }