ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/log.c
(Generate patch)

Comparing:
ircd-hybrid-7.2/src/s_log.c (file contents), Revision 581 by michael, Tue May 2 07:50:39 2006 UTC vs.
ircd-hybrid/trunk/src/log.c (file contents), Revision 1831 by michael, Mon Apr 15 10:57:05 2013 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_log.c: Logger functions.
3 > *  log.c: Logger functions.
4   *
5   *  Copyright (C) 2002 by the past and present ircd coders, and others.
6   *
# Line 24 | Line 24
24  
25   #include "stdinc.h"
26  
27 < #ifdef USE_SYSLOG
28 < # ifdef HAVE_SYS_SYSLOG_H
29 < #  include <sys/syslog.h>
30 < # else
31 < #  ifdef HAVE_SYSLOG_H
32 < #   include <syslog.h>
33 < #  endif
34 < # endif
35 < #endif
36 <
37 < #include "client.h"     /* Needed for struct Client */
38 < #include "common.h"
39 < #include "s_log.h"
40 < #include "fileio.h"
27 > #include "log.h"
28   #include "irc_string.h"
42 #include "sprintf_irc.h"
29   #include "ircd.h"
30 + #include "conf.h"
31   #include "s_misc.h"
45 #include "event.h"      /* Needed for EVH etc. */
46 #include "s_conf.h"
47 #include "memory.h"
32  
49 /* some older syslogs would overflow at 2024 */
50 #define LOG_BUFSIZE 2000
33  
34 < static FBFILE *logFile;
35 < static int logLevel = INIT_LOG_LEVEL;
34 > static struct {
35 >  char path[HYB_PATH_MAX + 1];
36 >  size_t size;
37 >  FILE *file;
38 > } log_type_table[LOG_TYPE_LAST];
39  
55 #ifndef SYSLOG_USERS
56 static EVH user_log_resync;
57 static FBFILE *user_log_fb = NULL;
58 #endif
40  
41 <
42 < #ifdef USE_SYSLOG
62 < static const int sysLogLevel[] =
63 < {
64 <  LOG_CRIT,
65 <  LOG_ERR,
66 <  LOG_WARNING,
67 <  LOG_NOTICE,
68 <  LOG_INFO,
69 <  LOG_INFO,
70 <  LOG_INFO
71 < };
72 < #endif
73 <
74 < static const char *logLevelToString[] =
75 < {
76 <  "L_CRIT",
77 <  "L_ERROR",
78 <  "L_WARN",
79 <  "L_NOTICE",
80 <  "L_TRACE",
81 <  "L_INFO",
82 <  "L_DEBUG"
83 < };
84 <
85 < /*
86 < * open_log - open ircd logging file
87 < * returns true (1) if successful, false (0) otherwise
88 < */
89 < static int
90 < open_log(const char *filename)
41 > void
42 > log_set_file(enum log_type type, size_t size, const char *path)
43   {
44 <  logFile = fbopen(filename, "a");
44 >  strlcpy(log_type_table[type].path, path, sizeof(log_type_table[type].path));
45 >  log_type_table[type].size = size;
46  
47 <  if (logFile == NULL)
48 <  {
96 < #ifdef USE_SYSLOG
97 <    syslog(LOG_ERR, "Unable to open log file: %s: %s",
98 <           filename, strerror(errno));
99 < #endif
100 <    return (0);
101 <  }
102 <
103 <  return (1);
47 >  if (type == LOG_TYPE_IRCD)
48 >    log_type_table[type].file = fopen(log_type_table[type].path, "a");
49   }
50  
106 static void
107 write_log(const char *message)
108 {
109  char buf[LOG_BUFSIZE];
110  size_t nbytes = 0;
111
112  if (logFile == NULL)
113    return;
114
115 #ifdef _WIN32
116  nbytes = snprintf(buf, sizeof(buf), "[%s] %s\r\n",
117                    smalldate(CurrentTime), message);
118 #else
119  nbytes = snprintf(buf, sizeof(buf), "[%s] %s\n",
120                    smalldate(CurrentTime), message);
121 #endif
122  fbputs(buf, logFile, nbytes);
123 }
124  
51   void
52 < ilog(const int priority, const char *fmt, ...)
52 > log_del_all(void)
53   {
54 <  char buf[LOG_BUFSIZE];
129 <  va_list args;
130 <
131 <  assert(priority > -1);
132 <
133 <  if (fmt == NULL)
134 <    return;
135 <
136 <  if (priority > logLevel)
137 <    return;
138 <
139 <  va_start(args, fmt);
140 <  vsprintf(buf, fmt, args);
141 <  va_end(args);
54 >  unsigned int type = 0;
55  
56 < #ifdef USE_SYSLOG  
57 <  if (priority <= L_DEBUG)
145 <    syslog(sysLogLevel[priority], "%s", buf);
146 < #endif
147 <  if (ConfigLoggingEntry.use_logging)
148 <    write_log(buf);
149 < }
150 <  
151 < void
152 < init_log(const char *filename)
153 < {
154 <  open_log(filename);
155 < #ifdef USE_SYSLOG
156 <  openlog("ircd", LOG_PID | LOG_NDELAY, LOG_FACILITY);
157 < #endif
158 < #ifndef SYSLOG_USERS
159 <  eventAddIsh("user_log_resync", user_log_resync, NULL, 60);
160 < #endif
56 >  while (++type < LOG_TYPE_LAST)
57 >    log_type_table[type].path[0] = '\0';
58   }
59  
60   void
61 < reopen_log(const char *filename)
61 > log_reopen_all(void)
62   {
63 <  if (logFile != NULL)
167 <    fbclose(logFile);
168 <  open_log(filename);
169 < }
63 >  unsigned int type = 0;
64  
65 < void
66 < set_log_level(const int level)
67 < {
68 <  if (L_ERROR < level && level <= L_DEBUG)
69 <    logLevel = level;
70 < }
65 >  while (++type < LOG_TYPE_LAST)
66 >  {
67 >    if (log_type_table[type].file)
68 >    {
69 >      fclose(log_type_table[type].file);
70 >      log_type_table[type].file = NULL;
71 >    }
72  
73 < int
74 < get_log_level(void)
75 < {
181 <  return(logLevel);
73 >    if (log_type_table[type].path[0])
74 >      log_type_table[type].file = fopen(log_type_table[type].path, "a");
75 >  }
76   }
77  
78 < const char *
79 < get_log_level_as_string(int level)
78 > static int
79 > log_exceed_size(unsigned int type)
80   {
81 <  if (level > L_DEBUG)
188 <    level = L_DEBUG;
189 <  else if (level < L_ERROR)
190 <    level = L_ERROR;
81 >  struct stat sb;
82  
83 <  return(logLevelToString[level]);
84 < }
83 >  if (!log_type_table[type].size)
84 >    return 0;
85  
86 < /* log_user_exit()
87 < *
197 < * inputs       - pointer to connecting client
198 < * output       - NONE
199 < * side effects - Current exiting client is logged to
200 < *                either SYSLOG or to file.
201 < */
202 < void
203 < log_user_exit(struct Client *source_p)
204 < {
205 <  time_t on_for = CurrentTime - source_p->firsttime;
206 < #ifdef SYSLOG_USERS
207 <  if (IsClient(source_p))
208 <  {
209 <    ilog(L_INFO, "%s (%3u:%02u:%02u): %s!%s@%s %llu/%llu",
210 <         myctime(source_p->firsttime), on_for / 3600,
211 <         (on_for % 3600)/60, on_for % 60,
212 <         source_p->name, source_p->username, source_p->host,
213 <         source_p->localClient->send.bytes>>10,
214 <         source_p->localClient->recv.bytes>>10);
215 <    }
216 < #else
217 <  {
218 <    char linebuf[BUFSIZ];
86 >  if (stat(log_type_table[type].path, &sb) < 0)
87 >    return -1;
88  
89 <    /*
221 <     * This conditional makes the logfile active only after
222 <     * it's been created - thus logging can be turned off by
223 <     * removing the file.
224 <     * -Taner
225 <     */
226 <    if (IsClient(source_p))
227 <    {
228 <      if (user_log_fb == NULL)
229 <      {
230 <        if ((ConfigLoggingEntry.userlog[0] != '\0') &&
231 <           (user_log_fb = fbopen(ConfigLoggingEntry.userlog, "r")) != NULL)
232 <        {
233 <          fbclose(user_log_fb);
234 <          user_log_fb = fbopen(ConfigLoggingEntry.userlog, "a");
235 <        }
236 <      }
237 <
238 <      if (user_log_fb != NULL)
239 <      {
240 <        size_t nbytes = ircsprintf(linebuf,
241 <                   "%s (%3u:%02u:%02u): %s!%s@%s %llu/%llu\n",
242 <                   myctime(source_p->firsttime),
243 <                   on_for / 3600,
244 <                   (on_for % 3600)/60,
245 <                   on_for % 60,
246 <                   source_p->name, source_p->username, source_p->host,
247 <                   source_p->localClient->send.bytes>>10,
248 <                   source_p->localClient->recv.bytes>>10);
249 <        fbputs(linebuf, user_log_fb, nbytes);
250 <      }
251 <    }
252 <  }
253 < #endif
89 >  return (size_t)sb.st_size > log_type_table[type].size;
90   }
91  
92 < #ifndef SYSLOG_USERS
93 < /* user_log_resync()
258 < *
259 < * inputs       - NONE
260 < * output       - NONE
261 < * side effects -
262 < */
263 < static void
264 < user_log_resync(void *notused)
92 > static void
93 > log_write(enum log_type type, const char *message)
94   {
95 <  if (user_log_fb != NULL)
96 <  {
97 <    fbclose(user_log_fb);
98 <    user_log_fb = NULL;
99 <  }
95 >  char buf[IRCD_BUFSIZE];
96 >
97 >  strftime(buf, sizeof(buf), "[%FT%H:%M:%S%z]", localtime(&CurrentTime));
98 >
99 >  fprintf(log_type_table[type].file, "%s %s\n", buf, message);
100 >  fflush(log_type_table[type].file);
101   }
272 #endif
102  
274 /* log_oper_action()
275 *
276 * inputs       - type of oper log entry
277 *              - pointer to oper
278 *              - const char *pattern == format string
279 *              - var args for format string
280 * output       - none
281 * side effects - corresponding log is written to, if its present.
282 *
283 * rewritten sept 5 2005 - Dianora
284 */
103   void
104 < log_oper_action(int log_type, const struct Client *source_p,
287 <                const char *pattern, ...)
104 > ilog(enum log_type type, const char *fmt, ...)
105   {
106 +  char buf[LOG_BUFSIZE];
107    va_list args;
290  char linebuf[IRCD_BUFSIZE];
291  FBFILE *log_fb;
292  char *logfile;
293  const char *log_message;
294  size_t nbytes;
295  size_t n_preamble;
296  char *p;
108  
109 <  switch(log_type)
299 <  {
300 <  case LOG_OPER_TYPE:
301 <    logfile = ConfigLoggingEntry.operlog;
302 <    log_message = "OPER";
303 <    break;
304 <  case LOG_FAILED_OPER_TYPE:
305 <    logfile = ConfigLoggingEntry.failed_operlog;
306 <    log_message = "FAILED OPER";
307 <    break;
308 <  case LOG_KLINE_TYPE:
309 <    logfile = ConfigLoggingEntry.klinelog;
310 <    log_message = "KLINE";
311 <    break;
312 <  case LOG_RKLINE_TYPE:
313 <    logfile = ConfigLoggingEntry.klinelog;
314 <    log_message = "RKLINE";
315 <    break;
316 <  case LOG_DLINE_TYPE:
317 <    logfile = ConfigLoggingEntry.klinelog;
318 <    log_message = "DLINE";
319 <    break;
320 <  case LOG_TEMP_DLINE_TYPE:
321 <    logfile = ConfigLoggingEntry.klinelog;
322 <    log_message = "TEMP DLINE";
323 <    break;
324 <  case LOG_TEMP_KLINE_TYPE:
325 <    logfile = ConfigLoggingEntry.klinelog;
326 <    log_message = "TEMP KLINE";
327 <    break;
328 <  case LOG_GLINE_TYPE:
329 <    logfile = ConfigLoggingEntry.glinelog;
330 <    log_message = "GLINE";
331 <    break;
332 <  case LOG_KILL_TYPE:
333 <    logfile = ConfigLoggingEntry.killlog;
334 <    log_message = "KILL";
335 <    break;
336 <  case LOG_IOERR_TYPE:
337 <    logfile = ConfigLoggingEntry.ioerrlog;
338 <    log_message = "IO ERR";
339 <    break;
340 <  default:
109 >  if (!log_type_table[type].file || !ConfigLoggingEntry.use_logging)
110      return;
342  }
111  
112 <  if (*logfile == '\0')
113 <    return;
112 >  va_start(args, fmt);
113 >  vsnprintf(buf, sizeof(buf), fmt, args);
114 >  va_end(args);
115  
116 <  p = linebuf;
348 <  if (source_p != NULL)
349 <  {
350 <    n_preamble = ircsprintf(linebuf, "%s %s by (%s!%s@%s) :",
351 <                            myctime(CurrentTime), log_message,
352 <                            source_p->name, source_p->username, source_p->host);
116 >  log_write(type, buf);
117  
118 <  }
119 <  else
356 <  {
357 <    n_preamble = ircsprintf(linebuf, "%s %s :",
358 <                            myctime(CurrentTime), log_message);
359 <  }
118 >  if (log_exceed_size(type) <= 0)
119 >    return;
120  
121 <  p += n_preamble;
121 >  snprintf(buf, sizeof(buf), "Rotating logfile %s",
122 >           log_type_table[type].path);
123 >  log_write(type, buf);
124 >
125 >  fclose(log_type_table[type].file);
126 >  log_type_table[type].file = NULL;
127 >
128 >  snprintf(buf, sizeof(buf), "%s.old", log_type_table[type].path);
129 >  unlink(buf);
130 >  rename(log_type_table[type].path, buf);
131  
132 <  if ((log_fb = fbopen(logfile, "r")) != NULL)
133 <  {
365 <    fbclose(log_fb);
366 <    log_fb = fbopen(logfile, "a");
367 <    if (log_fb == NULL)
368 <      return;
369 <    va_start(args, pattern);
370 <    /* XXX add check for IRCD_BUFSIZE-(n_preamble+1) < 0 ? -db */
371 <    nbytes = vsnprintf(p, IRCD_BUFSIZE-(n_preamble+1), pattern, args);
372 <    nbytes += n_preamble;
373 <    va_end(args);
374 <    fbputs(linebuf, log_fb, nbytes);
375 <    fbclose(log_fb);
376 <  }
132 >  log_set_file(type, log_type_table[type].size, log_type_table[type].path);
133 >  log_type_table[type].file = fopen(log_type_table[type].path, "a");
134   }

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)