Code "cleanups." I confess that I sometimes went beyond the TODO
[freeradius.git] / src / main / log.c
1 /*
2  * log.c        Logging module.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2000  The FreeRADIUS server project
21  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
22  * Copyright 2000  Alan DeKok <aland@ox.org>
23  * Copyright 2000  Chad Miller <cmiller@surfsouth.com>
24  */
25
26 static const char rcsid[] = "$Id$";
27
28 #include "autoconf.h"
29 #include "libradius.h"
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdarg.h>
34
35 #include "radiusd.h"
36
37 #if HAVE_SYSLOG_H
38 #       include <syslog.h>
39 #endif
40
41 /*
42  *      Log the message to the logfile. Include the severity and
43  *      a time stamp.
44  */
45 static int do_log(int lvl, const char *fmt, va_list ap)
46 {
47         FILE *msgfd = NULL;
48         const char *s = ": ";
49         unsigned char *p;
50         char buffer[8192];
51         time_t timeval;
52         int len;
53 #if HAVE_SYSLOG_H
54         int use_syslog = FALSE;
55 #endif
56         if ((lvl & L_CONS) || radlog_dir == NULL || debug_flag) {
57                 lvl &= ~L_CONS;
58                 if (!debug_flag) 
59                         fprintf(stdout, "%s: ", progname);
60                 vfprintf(stdout, fmt, ap);
61                 fprintf(stdout, "\n");
62         }
63         if (radlog_dir == NULL || debug_flag) 
64                 return 0;
65
66         if (strcmp(radlog_dir, "stdout") == 0) {
67                 msgfd = stdout;
68
69 #if HAVE_SYSLOG_H
70         } else if (strcmp(radlog_dir, "syslog") == 0) {
71                 use_syslog = TRUE;
72 #endif
73         } else {
74                 sprintf(buffer, "%.1000s/%.1000s", radlog_dir, RADIUS_LOG);
75                 if ((msgfd = fopen(buffer, "a")) == NULL) {
76                         fprintf(stderr, "%s: Couldn't open %s for logging: %s\n",
77                                         progname, buffer, strerror(errno));
78                         return -1;
79                 }
80         }
81
82         timeval = time(NULL);
83 #if HAVE_SYSLOG_H
84         if (use_syslog)
85                 *buffer = '\0';
86         else {
87                 strcpy(buffer, ctime(&timeval));
88
89                 switch(lvl) {
90                         case L_DBG:
91                                 s = ": Debug: ";
92                                 break;
93                         case L_AUTH:
94                                 s = ": Auth: ";
95                                 break;
96                         case L_PROXY:
97                                 s = ": Proxy: ";
98                                 break;
99                         case L_INFO:
100                                 s = ": Info: ";
101                                 break;
102                         case L_ERR:
103                                 s = ": Error: ";
104                                 break;
105                 }
106                 strcat(buffer, s);
107         }
108 #endif
109         len = strlen(buffer);
110
111 #ifdef HAVE_VSNPRINTF
112         vsnprintf(buffer + len, sizeof(buffer) - len -1, fmt, ap);
113 #else
114         vsprintf(buffer + len, fmt, ap);
115         if (strlen(buffer) >= sizeof(buffer) - 1)
116                 /* What can we do? */
117                 _exit(42);
118 #endif
119
120         /*
121          *      Filter out characters not in Latin-1.
122          */
123         for (p = (unsigned char *)buffer; *p != '\0'; p++) {
124                 if (*p == '\r' || *p == '\n')
125                         *p = ' ';
126                 else if (*p < 32 || (*p >= 128 && *p <= 160))
127                         *p = '?';
128         }
129         strcat(buffer, "\n");
130
131 #if HAVE_SYSLOG_H
132         if (!use_syslog) {
133                 fputs(buffer, msgfd);
134 #endif
135                 if (msgfd != stdout)
136                         fclose(msgfd);
137                 else
138                         fflush(stdout);
139 #if HAVE_SYSLOG_H
140         } else {
141                 switch(lvl) {
142                         case L_DBG:
143                                 lvl = LOG_DEBUG;
144                                 break;
145                         case L_AUTH:
146                                 lvl = LOG_NOTICE;
147                                 break;
148                         case L_PROXY:
149                                 lvl = LOG_NOTICE;
150                                 break;
151                         case L_INFO:
152                                 lvl = LOG_INFO;
153                                 break;
154                         case L_ERR:
155                                 lvl = LOG_ERR;
156                                 break;
157                 }
158                 syslog(lvl, "%s", buffer);
159         }
160 #endif
161
162         return 0;
163 }
164
165 int log_debug(const char *msg, ...)
166 {
167         va_list ap;
168         int r;
169
170         va_start(ap, msg);
171         r = do_log(L_DBG, msg, ap);
172         va_end(ap);
173
174         return r;
175 }
176
177 int radlog(int lvl, const char *msg, ...)
178 {
179         va_list ap;
180         int r;
181
182         va_start(ap, msg);
183         r = do_log(lvl, msg, ap);
184         va_end(ap);
185
186         return r;
187 }
188