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