Crossfire Server, Branches 1.12  R18729
logger.c
Go to the documentation of this file.
1 /*
2  * static char *rcsid_loger_c =
3  * "$Id: logger.c 11578 2009-02-23 22:02:27Z lalo $ ";
4  */
5 
6 int reopen_logfile = 0; /* May be set in SIGHUP handler */
7 
8 /*
9  CrossFire, A Multiplayer game for X-windows
10 
11  Copyright (C) 2002 Mark Wedel & Crossfire Development Team
12  Copyright (C) 1992 Frank Tore Johansen
13 
14  This program is free software; you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation; either version 2 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program; if not, write to the Free Software
26  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 
28  The authors can be reached via e-mail at crossfire-devel@real-time.com
29 */
30 
36 #include <stdarg.h>
37 #include <global.h>
38 #include <sproto.h>
39 
43 static const char *const loglevel_names[] = {
44  "[Error] ",
45  "[Info] ",
46  "[Debug] ",
47  "[Monster] "
48 };
49 
63 void LOG(LogLevel logLevel, const char *format, ...) {
64  char buf[20480]; /* This needs to be really really big - larger
65  * than any other buffer, since that buffer may
66  * need to be put in this one.
67  */
68 
69  char time_buf[2048];
70 
71  va_list ap;
72  va_start(ap, format);
73 
74  buf[0] = '\0';
75  if (logLevel <= settings.debug) {
76  time_buf[0] = '\0';
77  if (settings.log_timestamp == TRUE) {
78  struct tm *time_tmp;
79  time_t now = time((time_t *)NULL);
80 
81  time_tmp = localtime(&now);
82  if (time_tmp != NULL) {
83  if (strftime(time_buf, sizeof(time_buf), settings.log_timestamp_format, time_tmp) == 0) {
84  time_buf[0] = '\0';
85  }
86  }
87  }
88 
89  vsnprintf(buf, sizeof(buf), format, ap);
90 #ifdef WIN32 /* ---win32 change log handling for win32 */
91  if (time_buf[0] != 0) {
92  fputs(time_buf, logfile);
93  fputs(" ", logfile);
94  }
95  fputs(loglevel_names[logLevel], logfile); /* wrote to file or stdout */
96  fputs(buf, logfile); /* wrote to file or stdout */
97 #ifdef DEBUG /* if we have a debug version, we want see ALL output */
98  fflush(logfile); /* so flush this! */
99 #endif
100  if (logfile != stderr) { /* if was it a logfile wrote it to screen too */
101  fputs(loglevel_names[logLevel], stderr);
102  fputs(buf, stderr);
103  if (time_buf[0] != 0) {
104  fputs(time_buf, stderr);
105  fputs(" ", stderr);
106  }
107  }
108 #else /* not WIN32 */
109  if (reopen_logfile) {
110  reopen_logfile = 0;
111  if (fclose(logfile) != 0) {
112  /* stderr has been closed if -detach was used, but it's better
113  * to try to report about this anyway. */
114  perror("tried to close log file after SIGHUP in logger.c:LOG()");
115  }
116  if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
117  /* There's likely to be something very wrong with the OS anyway
118  * if reopening fails. */
119  perror("tried to open log file after SIGHUP in logger.c:LOG()");
120  emergency_save(0);
121  clean_tmp_files();
122  exit(1);
123  }
124  setvbuf(logfile, NULL, _IOLBF, 0);
125  LOG(llevInfo, "logfile reopened\n");
126  }
127 
128  if (time_buf[0] != 0) {
129  fputs(time_buf, logfile);
130  fputs(" ", logfile);
131  }
132  fputs(loglevel_names[logLevel], logfile);
133  fputs(buf, logfile);
134 #endif
135  }
136  if (!exiting
138  && logLevel == llevError
139  && ++nroferrors > MAX_ERRORS) {
140  exiting = 1;
142  emergency_save(0);
143  }
144  va_end(ap);
145 }
EXTERN FILE * logfile
Definition: global.h:220
void clean_tmp_files(void)
Definition: standalone.c:194
static const char *const loglevel_names[]
Definition: logger.c:43
int reopen_logfile
Definition: logger.c:6
LogLevel debug
Definition: global.h:327
const char * logfilename
Definition: global.h:325
char * log_timestamp_format
Definition: global.h:408
#define TRUE
Definition: exp.c:41
EXTERN long nroferrors
Definition: global.h:212
void emergency_save(int flag)
Definition: standalone.c:191
LogLevel
Definition: logger.h:37
int log_timestamp
Definition: global.h:407
#define vsnprintf
Definition: win32.h:72
EXTERN int exiting
Definition: global.h:222
struct Settings settings
Definition: init.c:48
EXTERN long trying_emergency_save
Definition: global.h:211
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
#define MAX_ERRORS
Definition: config.h:590