Don't include libradius.h right after autoconf.h, it's already
[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 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 "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 "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 #ifdef HAVE_VSNPRINTF
141         vsnprintf(buffer + len, sizeof(buffer) - len -1, fmt, ap);
142 #else
143         vsprintf(buffer + len, fmt, ap);
144         if (strlen(buffer) >= sizeof(buffer) - 1)
145                 /* What can we do? */
146                 _exit(42);
147 #endif
148
149         /*
150          *      Filter out characters not in Latin-1.
151          */
152         for (p = (unsigned char *)buffer; *p != '\0'; p++) {
153                 if (*p == '\r' || *p == '\n')
154                         *p = ' ';
155                 else if (*p < 32 || (*p >= 128 && *p <= 160))
156                         *p = '?';
157         }
158         strcat(buffer, "\n");
159
160 #ifdef HAVE_SYSLOG_H
161         if (mainconfig.radlog_dest == RADLOG_SYSLOG) {
162                 switch(lvl & ~L_CONS) {
163                         case L_DBG:
164                                 lvl = LOG_DEBUG;
165                                 break;
166                         case L_AUTH:
167                                 lvl = LOG_NOTICE;
168                                 break;
169                         case L_PROXY:
170                                 lvl = LOG_NOTICE;
171                                 break;
172                         case L_INFO:
173                                 lvl = LOG_INFO;
174                                 break;
175                         case L_ERR:
176                                 lvl = LOG_ERR;
177                                 break;
178                 }
179                 syslog(lvl, "%s", buffer);
180         } else
181 #endif
182         if (fp != NULL) {
183                 fputs(buffer, fp);
184                 fflush(fp);
185                 fclose(fp);
186         } else {
187                 write(mainconfig.radlog_fd, buffer, strlen(buffer));
188         }
189
190         return 0;
191 }
192
193 int log_debug(const char *msg, ...)
194 {
195         va_list ap;
196         int r;
197
198         va_start(ap, msg);
199         r = vradlog(L_DBG, msg, ap);
200         va_end(ap);
201
202         return r;
203 }
204
205 int radlog(int lvl, const char *msg, ...)
206 {
207         va_list ap;
208         int r;
209
210         va_start(ap, msg);
211         r = vradlog(lvl, msg, ap);
212         va_end(ap);
213
214         return r;
215 }
216
217
218 /*
219  *      Dump a whole list of attributes to DEBUG2
220  */
221 void vp_listdebug(VALUE_PAIR *vp)
222 {
223         char tmpPair[70];
224         for (; vp; vp = vp->next) {
225                 vp_prints(tmpPair, sizeof(tmpPair), vp);
226                 DEBUG2("     %s", tmpPair);
227         }
228 }
229
230
231
232