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