]> git.decadent.org.uk Git - nfs-utils.git/blob - support/nfs/xlog.c
nfsdcltrack: rename the nfsdcld directory and options to nfsdcltrack
[nfs-utils.git] / support / nfs / xlog.c
1 /*
2  * support/nfs/xlog.c
3  *
4  * This module handles the logging of requests.
5  *
6  * TODO:        Merge the two "XXX_log() calls.
7  *
8  * Authors:     Donald J. Becker, <becker@super.org>
9  *              Rick Sladkey, <jrs@world.std.com>
10  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
11  *              Olaf Kirch, <okir@monad.swb.de>
12  *
13  *              This software maybe be used for any purpose provided
14  *              the above copyright notice is retained.  It is supplied
15  *              as is, with no warranty expressed or implied.
16  */
17
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21
22 #include <unistd.h>
23 #include <signal.h>
24 #include <time.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <syslog.h>
30 #include "nfslib.h"
31
32 #undef  VERBOSE_PRINTF
33
34 static int  log_stderr = 1;
35 static int  log_syslog = 1;
36 static int  logging = 0;                /* enable/disable DEBUG logs    */
37 static int  logmask = 0;                /* What will be logged          */
38 static char log_name[256];              /* name of this program         */
39 static int  log_pid = -1;               /* PID of this program          */
40
41 static void     xlog_toggle(int sig);
42 static struct xlog_debugfac     debugnames[] = {
43         { "general",    D_GENERAL, },
44         { "call",       D_CALL, },
45         { "auth",       D_AUTH, },
46         { "parse",      D_PARSE, },
47         { "all",        D_ALL, },
48         { NULL,         0, },
49 };
50
51 void
52 xlog_open(char *progname)
53 {
54         openlog(progname, LOG_PID, LOG_DAEMON);
55
56         strncpy(log_name, progname, sizeof (log_name) - 1);
57         log_name [sizeof (log_name) - 1] = '\0';
58         log_pid = getpid();
59
60         signal(SIGUSR1, xlog_toggle);
61         signal(SIGUSR2, xlog_toggle);
62 }
63
64 void
65 xlog_stderr(int on)
66 {
67         log_stderr = on;
68 }
69
70 void
71 xlog_syslog(int on)
72 {
73         log_syslog = on;
74 }
75
76 static void
77 xlog_toggle(int sig)
78 {
79         unsigned int    tmp, i;
80
81         if (sig == SIGUSR1) {
82                 if ((logmask & D_ALL) && !logging) {
83                         xlog(D_GENERAL, "turned on logging");
84                         logging = 1;
85                         return;
86                 }
87                 tmp = ~logmask;
88                 logmask |= ((logmask & D_ALL) << 1) | D_GENERAL;
89                 for (i = -1, tmp &= logmask; tmp; tmp >>= 1, i++)
90                         if (tmp & 1)
91                                 xlog(D_GENERAL,
92                                         "turned on logging level %d", i);
93         } else {
94                 xlog(D_GENERAL, "turned off logging");
95                 logging = 0;
96         }
97         signal(sig, xlog_toggle);
98 }
99
100 void
101 xlog_config(int fac, int on)
102 {
103         if (on)
104                 logmask |= fac;
105         else
106                 logmask &= ~fac;
107         if (on)
108                 logging = 1;
109 }
110
111 void
112 xlog_sconfig(char *kind, int on)
113 {
114         struct xlog_debugfac    *tbl = debugnames;
115
116         while (tbl->df_name != NULL && strcasecmp(tbl->df_name, kind)) 
117                 tbl++;
118         if (!tbl->df_name) {
119                 xlog (L_WARNING, "Invalid debug facility: %s\n", kind);
120                 return;
121         }
122         xlog_config(tbl->df_fac, on);
123 }
124
125 int
126 xlog_enabled(int fac)
127 {
128         return (logging && (fac & logmask));
129 }
130
131
132 /* Write something to the system logfile and/or stderr */
133 void
134 xlog_backend(int kind, const char *fmt, va_list args)
135 {
136         va_list args2;
137
138         if (!(kind & (L_ALL)) && !(logging && (kind & logmask)))
139                 return;
140
141         if (log_stderr)
142                 va_copy(args2, args);
143
144         if (log_syslog) {
145                 switch (kind) {
146                 case L_FATAL:
147                         vsyslog(LOG_ERR, fmt, args);
148                         break;
149                 case L_ERROR:
150                         vsyslog(LOG_ERR, fmt, args);
151                         break;
152                 case L_WARNING:
153                         vsyslog(LOG_WARNING, fmt, args);
154                         break;
155                 case L_NOTICE:
156                         vsyslog(LOG_NOTICE, fmt, args);
157                         break;
158                 default:
159                         if (!log_stderr)
160                                 vsyslog(LOG_INFO, fmt, args);
161                         break;
162                 }
163         }
164
165         if (log_stderr) {
166 #ifdef VERBOSE_PRINTF
167                 time_t          now;
168                 struct tm       *tm;
169
170                 time(&now);
171                 tm = localtime(&now);
172                 fprintf(stderr, "%s[%d] %04d-%02d-%02d %02d:%02d:%02d ",
173                                 log_name, log_pid,
174                                 tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday,
175                                 tm->tm_hour, tm->tm_min, tm->tm_sec);
176 #else
177                 fprintf(stderr, "%s: ", log_name);
178 #endif
179                 vfprintf(stderr, fmt, args2);
180                 fprintf(stderr, "\n");
181                 va_end(args2);
182         }
183
184         if (kind == L_FATAL)
185                 exit(1);
186 }
187
188 void
189 xlog(int kind, const char* fmt, ...)
190 {
191         va_list args;
192
193         va_start(args, fmt);
194         xlog_backend(kind, fmt, args);
195         va_end(args);
196 }
197
198 void
199 xlog_warn(const char* fmt, ...)
200 {
201         va_list args;
202
203         va_start(args, fmt);
204         xlog_backend(L_WARNING, fmt, args);
205         va_end(args);
206 }
207
208
209 void
210 xlog_err(const char* fmt, ...)
211 {
212         va_list args;
213
214         va_start(args, fmt);
215         xlog_backend(L_FATAL, fmt, args);
216         va_end(args);
217 }