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/src/s_log.c (file contents), Revision 32 by knight, Sun Oct 2 20:41:23 2005 UTC vs.
ircd-hybrid-8/src/log.c (file contents), Revision 1309 by michael, Sun Mar 25 11:24:18 2012 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"
27 > #include "log.h"
28   #include "fileio.h"
29   #include "irc_string.h"
30   #include "sprintf_irc.h"
31   #include "ircd.h"
32   #include "s_misc.h"
33 < #include "event.h"      /* Needed for EVH etc. */
46 < #include "s_conf.h"
33 > #include "conf.h"
34   #include "memory.h"
35 + #include "send.h"
36  
37   /* some older syslogs would overflow at 2024 */
38   #define LOG_BUFSIZE 2000
39  
40 < static FBFILE *logFile;
41 < static int logLevel = INIT_LOG_LEVEL;
40 > static struct {
41 >  char path[PATH_MAX + 1];
42 >  size_t size;
43 >  FBFILE *file;
44 > } log_type_table[LOG_TYPE_LAST];
45  
55 #ifndef SYSLOG_USERS
56 static EVH user_log_resync;
57 static FBFILE *user_log_fb = NULL;
58 #endif
46  
47 <
48 < #ifdef USE_SYSLOG
62 < static const int sysLogLevel[] =
47 > int
48 > log_add_file(unsigned int type, size_t size, const char *path)
49   {
50 <  LOG_CRIT,
51 <  LOG_ERR,
66 <  LOG_WARNING,
67 <  LOG_NOTICE,
68 <  LOG_INFO,
69 <  LOG_INFO,
70 <  LOG_INFO
71 < };
72 < #endif
50 >  if (log_type_table[type].file)
51 >    fbclose(log_type_table[type].file);
52  
53 < static const char *logLevelToString[] =
54 < {
76 <  "L_CRIT",
77 <  "L_ERROR",
78 <  "L_WARN",
79 <  "L_NOTICE",
80 <  "L_TRACE",
81 <  "L_INFO",
82 <  "L_DEBUG"
83 < };
53 >  strlcpy(log_type_table[type].path, path, sizeof(log_type_table[type].path));
54 >  log_type_table[type].size = size;
55  
56 < /*
57 < * open_log - open ircd logging file
58 < * returns true (1) if successful, false (0) otherwise
59 < */
60 < static int
90 < open_log(const char *filename)
56 >  return (log_type_table[type].file = fbopen(path, "a")) != NULL;
57 > }
58 >
59 > void
60 > log_close_all(void)
61   {
62 <  logFile = fbopen(filename, "a");
62 >  unsigned int type = 0;
63  
64 <  if (logFile == NULL)
64 >  while (++type < LOG_TYPE_LAST)
65    {
66 < #ifdef USE_SYSLOG
67 <    syslog(LOG_ERR, "Unable to open log file: %s: %s",
68 <           filename, strerror(errno));
69 < #endif
70 <    return (0);
66 >    if (log_type_table[type].file == NULL)
67 >      continue;
68 >
69 >    fbclose(log_type_table[type].file);
70 >    log_type_table[type].file = NULL;
71    }
72 + }
73  
74 <  return (1);
74 > static int
75 > log_exceed_size(unsigned int type)
76 > {
77 >  struct stat sb;
78 >
79 >  if (!log_type_table[type].size)
80 >    return 0;
81 >
82 >  if (stat(log_type_table[type].path, &sb) < 0)
83 >    return -1;
84 >
85 >  return (size_t)sb.st_size > log_type_table[type].size;
86   }
87  
88 +
89   static void
90 < write_log(const char *message)
90 > write_log(unsigned int type, const char *message)
91   {
92    char buf[LOG_BUFSIZE];
93    size_t nbytes = 0;
94  
95 <  if (logFile == NULL)
95 >  if (log_type_table[type].file == NULL)
96      return;
97  
98 < #ifdef _WIN32
99 <  nbytes = snprintf(buf, sizeof(buf), "[%s] %s\r\n",
100 < #else
101 <  nbytes = snprintf(buf, sizeof(buf), "[%s] %s\n",
102 < #endif
103 <                    smalldate(CurrentTime), message);
104 <  fbputs(buf, logFile, nbytes);
98 >  if (ConfigLoggingEntry.timestamp)
99 >    nbytes = snprintf(buf, sizeof(buf), "[%s] %s\n",
100 >                      smalldate(CurrentTime), message);
101 >  else
102 >    nbytes = snprintf(buf, sizeof(buf), "%s\n", message);
103 >
104 >  fbputs(buf, log_type_table[type].file, nbytes);
105   }
106    
107   void
108 < ilog(const int priority, const char *fmt, ...)
108 > ilog(unsigned int type, const char *fmt, ...)
109   {
110    char buf[LOG_BUFSIZE];
111    va_list args;
112  
113 <  assert(priority > -1);
114 <
132 <  if (fmt == NULL)
133 <    return;
134 <
135 <  if (priority > logLevel)
136 <    return;
113 >  assert(fmt);
114 >  assert(type >= 0 && type < LOG_TYPE_LAST);
115  
116    va_start(args, fmt);
117 <  vsprintf(buf, fmt, args);
117 >  vsnprintf(buf, sizeof(buf), fmt, args);
118    va_end(args);
119  
142 #ifdef USE_SYSLOG  
143  if (priority <= L_DEBUG)
144    syslog(sysLogLevel[priority], "%s", buf);
145 #endif
120    if (ConfigLoggingEntry.use_logging)
147    write_log(buf);
148 }
149  
150 void
151 init_log(const char *filename)
152 {
153  open_log(filename);
154 #ifdef USE_SYSLOG
155  openlog("ircd", LOG_PID | LOG_NDELAY, LOG_FACILITY);
156 #endif
157 #ifndef SYSLOG_USERS
158  eventAddIsh("user_log_resync", user_log_resync, NULL, 60);
159 #endif
160 }
161
162 void
163 reopen_log(const char *filename)
164 {
165  if (logFile != NULL)
166    fbclose(logFile);
167  open_log(filename);
168 }
169
170 void
171 set_log_level(const int level)
172 {
173  if (L_ERROR < level && level <= L_DEBUG)
174    logLevel = level;
175 }
176
177 int
178 get_log_level(void)
179 {
180  return(logLevel);
181 }
182
183 const char *
184 get_log_level_as_string(int level)
185 {
186  if (level > L_DEBUG)
187    level = L_DEBUG;
188  else if (level < L_ERROR)
189    level = L_ERROR;
190
191  return(logLevelToString[level]);
192 }
193
194 /* log_user_exit()
195 *
196 * inputs       - pointer to connecting client
197 * output       - NONE
198 * side effects - Current exiting client is logged to
199 *                either SYSLOG or to file.
200 */
201 void
202 log_user_exit(struct Client *source_p)
203 {
204  time_t on_for = CurrentTime - source_p->firsttime;
205 #ifdef SYSLOG_USERS
206  if (IsClient(source_p))
207  {
208    ilog(L_INFO, "%s (%3ld:%02ld:%02ld): %s!%s@%s %llu/%llu\n",
209         myctime(source_p->firsttime),
210          (signed long) on_for / 3600,
211          (signed long) (on_for % 3600)/60,
212          (signed long) on_for % 60,
213          source_p->name, source_p->username, source_p->host,
214          source_p->localClient->send.bytes>>10,
215          source_p->localClient->recv.bytes>>10);
216    }
217 #else
218  {
219    char linebuf[BUFSIZ];
220
221    /*
222     * This conditional makes the logfile active only after
223     * it's been created - thus logging can be turned off by
224     * removing the file.
225     * -Taner
226     */
227    if (IsClient(source_p))
228    {
229      if (user_log_fb == NULL)
230      {
231        if ((ConfigLoggingEntry.userlog[0] != '\0') &&
232           (user_log_fb = fbopen(ConfigLoggingEntry.userlog, "r")) != NULL)
233        {
234          fbclose(user_log_fb);
235          user_log_fb = fbopen(ConfigLoggingEntry.userlog, "a");
236        }
237      }
238
239      if (user_log_fb != NULL)
240      {
241        size_t nbytes = ircsprintf(linebuf,
242                   "%s (%3ld:%02ld:%02ld): %s!%s@%s %llu/%llu\n",
243                   myctime(source_p->firsttime),
244                   (signed long) on_for / 3600,
245                   (signed long) (on_for % 3600)/60,
246                   (signed long) on_for % 60,
247                   source_p->name, source_p->username, source_p->host,
248                   source_p->localClient->send.bytes>>10,
249                   source_p->localClient->recv.bytes>>10);
250        fbputs(linebuf, user_log_fb, nbytes);
251      }
252    }
253  }
254 #endif
255 }
256
257 #ifndef SYSLOG_USERS
258 /* user_log_resync()
259 *
260 * inputs       - NONE
261 * output       - NONE
262 * side effects -
263 */
264 static void
265 user_log_resync(void *notused)
266 {
267  if (user_log_fb != NULL)
268  {
269    fbclose(user_log_fb);
270    user_log_fb = NULL;
271  }
272 }
273 #endif
274
275 /* log_oper_action()
276 *
277 * inputs       - type of oper log entry
278 *              - pointer to oper
279 *              - const char *pattern == format string
280 *              - var args for format string
281 * output       - none
282 * side effects - corresponding log is written to, if its present.
283 *
284 * rewritten sept 5 2005 - Dianora
285 */
286 void
287 log_oper_action(int log_type, const struct Client *source_p,
288                const char *pattern, ...)
289 {
290  va_list args;
291  char linebuf[IRCD_BUFSIZE];
292  FBFILE *log_fb;
293  char *logfile;
294  const char *log_message;
295  size_t nbytes;
296  size_t n_preamble;
297  char *p;
298
299  switch(log_type)
300  {
301  case LOG_OPER_TYPE:
302    logfile = ConfigLoggingEntry.operlog;
303    log_message = "OPER";
304    break;
305  case LOG_FAILED_OPER_TYPE:
306    logfile = ConfigLoggingEntry.failed_operlog;
307    log_message = "FAILED OPER";
308    break;
309  case LOG_KLINE_TYPE:
310    logfile = ConfigLoggingEntry.klinelog;
311    log_message = "KLINE";
312    break;
313  case LOG_RKLINE_TYPE:
314    logfile = ConfigLoggingEntry.klinelog;
315    log_message = "RKLINE";
316    break;
317  case LOG_DLINE_TYPE:
318    logfile = ConfigLoggingEntry.klinelog;
319    log_message = "DLINE";
320    break;
321  case LOG_TEMP_DLINE_TYPE:
322    logfile = ConfigLoggingEntry.klinelog;
323    log_message = "TEMP DLINE";
324    break;
325  case LOG_TEMP_KLINE_TYPE:
326    logfile = ConfigLoggingEntry.klinelog;
327    log_message = "TEMP KLINE";
328    break;
329  case LOG_GLINE_TYPE:
330    logfile = ConfigLoggingEntry.glinelog;
331    log_message = "GLINE";
332    break;
333  case LOG_KILL_TYPE:
334    logfile = ConfigLoggingEntry.killlog;
335    log_message = "KILL";
336    break;
337  case LOG_IOERR_TYPE:
338    logfile = ConfigLoggingEntry.ioerrlog;
339    log_message = "IO ERR";
340    break;
341  default:
342    return;
343  }
344
345  if (*logfile == '\0')
346    return;
347
348  p = linebuf;
349  if (source_p != NULL)
350  {
351    n_preamble = ircsprintf(linebuf, "%s %s by (%s!%s@%s) :",
352                            myctime(CurrentTime), log_message,
353                            source_p->name, source_p->username, source_p->host);
354
355  }
356  else
121    {
122 <    n_preamble = ircsprintf(linebuf, "%s %s :",
359 <                            myctime(CurrentTime), log_message);
360 <  }
361 <
362 <  p += n_preamble;
122 >    write_log(type, buf);
123  
124 <  if ((log_fb = fbopen(logfile, "r")) != NULL)
365 <  {
366 <    fbclose(log_fb);
367 <    log_fb = fbopen(logfile, "a");
368 <    if (log_fb == NULL)
124 >    if (log_exceed_size(type) <= 0)
125        return;
126 <    va_start(args, pattern);
127 <    /* XXX add check for IRCD_BUFSIZE-(n_preamble+1) < 0 ? -db */
128 <    nbytes = vsnprintf(p, IRCD_BUFSIZE-(n_preamble+1), pattern, args);
129 <    nbytes += n_preamble;
130 <    va_end(args);
131 <    fbputs(linebuf, log_fb, nbytes);
132 <    fbclose(log_fb);
126 >
127 >    snprintf(buf, sizeof(buf), "Rotating logfile %s",
128 >             log_type_table[type].path);
129 >    write_log(type, buf);
130 >    fbclose(log_type_table[type].file);
131 >    log_type_table[type].file = NULL;
132 >
133 >    snprintf(buf, sizeof(buf), "%s.old", log_type_table[type].path);
134 >    unlink(buf);
135 >    rename(log_type_table[type].path, buf);
136 >    log_add_file(type, log_type_table[type].size, log_type_table[type].path);
137    }
138   }

Comparing:
ircd-hybrid/src/s_log.c (property svn:keywords), Revision 32 by knight, Sun Oct 2 20:41:23 2005 UTC vs.
ircd-hybrid-8/src/log.c (property svn:keywords), Revision 1309 by michael, Sun Mar 25 11:24:18 2012 UTC

# Line 1 | Line 1
1 < Revision
1 > Id Revision

Diff Legend

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