]> git.sommitrealweird.co.uk Git - onak.git/blob - log.c
0.3.5 release.
[onak.git] / log.c
1 /*
2  * log.c - Simple logging framework.
3  *
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2003 Project Purple
7  */
8
9 #include <stdarg.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14 #include <unistd.h>
15
16 #include "log.h"
17
18 /*
19  *      logthres - holds the minimum log level we'll output
20  *
21  *      This variable keeps track of the threshold we've set for outputting
22  *      logs - if we're asked to log something below this level we won't output
23  *      it.
24  */
25 static loglevels logthres = LOGTHING_NOTICE;
26
27 /*
28  *      logappname - the name of the application using us.
29  *
30  *      This holds information about the name of the application we're being
31  *      called by. It's set when we're initialized.
32  */
33 static char *logappname = NULL;
34
35 /*
36  *      logfilename - the file to log to.
37  *
38  *      The full name and path of the file we should log to.
39  */
40 static char *logfilename = NULL;
41
42 /*
43  *      initlogthing - initialize the logging module
44  *      @appname: The application name to use in the log.
45  *      @filename: The filename to log to. NULL means stderr.
46  *
47  *      This function sets up the logging module ready to log. The appname is
48  *      written as part of every log entry and the filename is the file we
49  *      should log to. If the appname is NULL then none is written. If the
50  *      filename is NULL all output is sent to stderr.
51  */
52 int initlogthing(const char *appname, const char *filename)
53 {
54         if (appname != NULL) {
55                 logappname = strdup(appname);
56         }
57
58         if (filename != NULL) {
59                 logfilename = strdup(filename);
60         }
61
62         return 0;
63 }
64
65 /*
66  *      cleanuplogthing - clean up the logging module
67  *
68  *      This function cleans up the logging module after use.
69  */
70 void cleanuplogthing(void)
71 {
72         if (logappname != NULL) {
73                 free(logappname);
74                 logappname = NULL;
75         }
76
77         if (logfilename != NULL) {
78                 free(logfilename);
79                 logfilename = NULL;
80         }
81
82         return;
83 }
84
85 /*
86  *      setlogthreshold - set the threshold for log output
87  *      @loglevel: The minimum log level we should output
88  *
89  *      Sets the threshold for log output; anything logged with a log level
90  *      lower than this will be silently dropped. Returns the old log threshold
91  *      value.
92  */
93 loglevels setlogthreshold(loglevels loglevel)
94 {
95         loglevels oldlevel;
96
97         oldlevel = logthres;
98         logthres = loglevel;
99
100         return oldlevel;
101 }
102
103 /*
104  *      vflog - write a log entry to an already opened log file.
105  *      @logfile: The FILE * handle of the open log file.
106  *      @format: A format string.
107  *      @ap: The va_list of the parmeters for the format string.
108  *
109  *      This function outputs a log entry to an opened file. A leading
110  *      time/date stamp and a trailing newline are automatically added. The
111  *      format parameter is of the same nature as that used in vprintf.
112  */
113 static void vflog(FILE *logfile, const char *format, va_list ap)
114 {
115         struct tm *timestamp = NULL;
116         time_t     timer = 0;
117
118         timer = time(NULL);
119         timestamp = localtime(&timer);
120
121         fprintf(logfile, "[%02d/%02d/%4d %02d:%02d:%02d] %s[%d]: ",
122                         timestamp->tm_mday,
123                         timestamp->tm_mon + 1,
124                         timestamp->tm_year + 1900,
125                         timestamp->tm_hour,
126                         timestamp->tm_min,
127                         timestamp->tm_sec,
128                         (logappname == NULL) ? "" : logappname,
129                         getpid());
130         vfprintf(logfile, format, ap);
131         fprintf(logfile, "\n");
132
133         return;
134 }
135
136 /*
137  *      flog - write a log entry to an already opened log file.
138  *      @logfile: The FILE * handle of the open log file.
139  *      @format: A format string.
140  *
141  *      This function outputs a log entry to an opened file. A leading
142  *      time/date stamp and a trailing newline are automatically added. The
143  *      format parameter is of the same nature as that used in printf.
144  */
145 static void flog(FILE *logfile, const char *format, ...)
146 {
147         va_list ap;
148
149         va_start(ap, format);
150         vflog(logfile, format, ap);
151         va_end(ap);
152 }
153
154 /*
155  *      logthing - output a log entry
156  *      @loglevel: The level of the log.
157  *      @format: A format string, followed by any parameters required.
158  *
159  *      This function outputs a log entry. A leading time/date stamp and a
160  *      trailing newline are automatically added. The loglevel is compared to
161  *      the current log threshold and if equal or above the log entry is
162  *      output. The format parameter is of the same nature as that used in
163  *      printf.
164  */
165 int logthing(loglevels loglevel, const char *format, ...)
166 {
167         FILE      *logfile = NULL;
168         va_list    ap;
169
170         if (loglevel >= logthres) {
171                 if (logfilename != NULL) {
172                         logfile = fopen(logfilename, "a");
173                         if (logfile != NULL) {
174                                 flockfile(logfile);
175                         } else {
176                                 logfile = stderr;
177                                 flog(logfile, "Couldn't open logfile: %s",
178                                                 logfilename);
179                         }
180                 } else {
181                         logfile = stderr;
182                 }
183         
184                 va_start(ap, format);
185                 vflog(logfile, format, ap);
186                 va_end(ap);
187
188                 if (logfile != stderr) {
189                         funlockfile(logfile);
190                         fclose(logfile);
191                         logfile = NULL;
192                 }
193         }
194
195         return 0;
196 }