Update the GPL boilerplate with the new address of the FSF.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2001  The FreeRADIUS server project
21  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
22  * Copyright 2000  Alan DeKok <aland@ox.org>
23  * Copyright 2001  Chad Miller <cmiller@surfsouth.com>
24  */
25
26 static const char rcsid[] = "$Id$";
27
28 #include <freeradius-devel/autoconf.h>
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdarg.h>
33 #include <unistd.h>
34 #include <sys/types.h>
35 #include <errno.h>
36
37 #include <freeradius-devel/radiusd.h>
38
39 #ifdef HAVE_SYSLOG_H
40 #       include <syslog.h>
41 /* keep track of whether we've run openlog() */
42 static int openlog_run = 0;
43 #endif
44
45  /*
46  * Logging facility names
47  */
48 static const LRAD_NAME_NUMBER levels[] = {
49         { ": Debug: ",          L_DBG   },
50         { ": Auth: ",           L_AUTH  },
51         { ": Proxy: ",          L_PROXY },
52         { ": Info: ",           L_INFO  },
53         { ": Error: ",          L_ERR   },
54         { NULL, 0 }
55 };
56
57 /*
58  *      Log the message to the logfile. Include the severity and
59  *      a time stamp.
60  */
61 int vradlog(int lvl, const char *fmt, va_list ap)
62 {
63         FILE *fp = NULL;
64         unsigned char *p;
65         char buffer[8192];
66         int len;
67
68         /*
69          *      NOT debugging, and trying to log debug messages.
70          *
71          *      Throw the message away.
72          */
73         if (!debug_flag && (lvl == L_DBG)) {
74                 return 0;
75         }
76
77         /*
78          *      If we don't want any messages, then
79          *      throw them away.
80          */
81         if (mainconfig.radlog_dest == RADLOG_NULL) {
82                 return 0;
83         }
84         
85         *buffer = '\0';
86         len = 0;
87         if (mainconfig.radlog_fd != -1) {
88                 /*
89                  *      Do nothing, but allow it.
90                  */
91
92 #ifdef HAVE_SYSLOG_H
93         } else if (mainconfig.radlog_dest == RADLOG_SYSLOG) {
94                 /*
95                  *      Open run openlog() on the first log message
96                  */
97                 if(!openlog_run) {
98                         openlog(progname, LOG_PID, mainconfig.syslog_facility);
99                         openlog_run = 1;
100                 }
101 #endif
102
103         } else if (!mainconfig.log_file) {
104                 /*
105                  *      No log file set.  Discard it.
106                  */
107                 return 0;
108
109         } else if ((fp = fopen(mainconfig.log_file, "a")) == NULL) {
110                 fprintf(stderr, "%s: Couldn't open %s for logging: %s\n",
111                         progname, mainconfig.log_file, strerror(errno));
112                 
113                 fprintf(stderr, "  (");
114                 vfprintf(stderr, fmt, ap);  /* the message that caused the log */
115                 fprintf(stderr, ")\n");
116                 return -1;
117         }
118
119         /*
120          *      Don't print timestamps to syslog, it does that for us.
121          *      Don't print timestamps for low levels of debugging.
122          *
123          *      Print timestamps for non-debugging, and for high levels
124          *      of debugging.
125          */
126         if ((mainconfig.radlog_dest != RADLOG_SYSLOG) &&
127             (debug_flag != 1) && (debug_flag != 2)) {
128                 const char *s;
129                 time_t timeval;
130
131                 timeval = time(NULL);
132                 CTIME_R(&timeval, buffer, 8192);
133
134                 s = lrad_int2str(levels, (lvl & ~L_CONS), ": ");
135
136                 strcat(buffer, s);
137                 len = strlen(buffer);
138         }
139
140         vsnprintf(buffer + len, sizeof(buffer) - len - 1, fmt, ap);
141
142         /*
143          *      Filter out characters not in Latin-1.
144          */
145         for (p = (unsigned char *)buffer; *p != '\0'; p++) {
146                 if (*p == '\r' || *p == '\n')
147                         *p = ' ';
148                 else if (*p == '\t') continue;
149                 else if (*p < 32 || (*p >= 128 && *p <= 160))
150                         *p = '?';
151         }
152         strcat(buffer, "\n");
153
154 #ifdef HAVE_SYSLOG_H
155         if (mainconfig.radlog_dest == RADLOG_SYSLOG) {
156                 switch(lvl & ~L_CONS) {
157                         case L_DBG:
158                                 lvl = LOG_DEBUG;
159                                 break;
160                         case L_AUTH:
161                                 lvl = LOG_NOTICE;
162                                 break;
163                         case L_PROXY:
164                                 lvl = LOG_NOTICE;
165                                 break;
166                         case L_INFO:
167                                 lvl = LOG_INFO;
168                                 break;
169                         case L_ERR:
170                                 lvl = LOG_ERR;
171                                 break;
172                 }
173                 syslog(lvl, "%s", buffer);
174         } else
175 #endif
176         if (fp != NULL) {
177                 fputs(buffer, fp);
178                 fflush(fp);
179                 fclose(fp);
180         } else {
181                 write(mainconfig.radlog_fd, buffer, strlen(buffer));
182         }
183
184         return 0;
185 }
186
187 int log_debug(const char *msg, ...)
188 {
189         va_list ap;
190         int r;
191
192         va_start(ap, msg);
193         r = vradlog(L_DBG, msg, ap);
194         va_end(ap);
195
196         return r;
197 }
198
199 int radlog(int lvl, const char *msg, ...)
200 {
201         va_list ap;
202         int r;
203
204         va_start(ap, msg);
205         r = vradlog(lvl, msg, ap);
206         va_end(ap);
207
208         return r;
209 }
210
211
212 /*
213  *      Dump a whole list of attributes to DEBUG2
214  */
215 void vp_listdebug(VALUE_PAIR *vp)
216 {
217         char tmpPair[70];
218         for (; vp; vp = vp->next) {
219                 vp_prints(tmpPair, sizeof(tmpPair), vp);
220                 DEBUG2("     %s", tmpPair);
221         }
222 }
223
224
225
226