]> git.decadent.org.uk Git - nfs-utils.git/blob - support/nfs/xlog.c
Assorted changes from Steve Dickson
[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 #include "config.h"
19
20 #include <unistd.h>
21 #include <signal.h>
22 #include <time.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <syslog.h>
28 #include "nfslib.h"
29
30 #undef  VERBOSE_PRINTF
31
32 static int  log_stderr = 1;
33 static int  log_syslog = 1;
34 static int  logging = 0;                /* enable/disable DEBUG logs    */
35 static int  logmask = 0;                /* What will be logged          */
36 static char log_name[256];              /* name of this program         */
37 static int  log_pid = -1;               /* PID of this program          */
38
39 static void     xlog_toggle(int sig);
40 static struct xlog_debugfac     debugnames[] = {
41         { "general",    D_GENERAL, },
42         { "call",       D_CALL, },
43         { "auth",       D_AUTH, },
44         { "parse",      D_PARSE, },
45         { "all",        D_ALL, },
46         { NULL,         0, },
47 };
48
49 void
50 xlog_open(char *progname)
51 {
52         openlog(progname, LOG_PID, LOG_DAEMON);
53
54         strncpy(log_name, progname, sizeof (log_name) - 1);
55         log_name [sizeof (log_name) - 1] = '\0';
56         log_pid = getpid();
57
58         signal(SIGUSR1, xlog_toggle);
59         signal(SIGUSR2, xlog_toggle);
60 }
61
62 void
63 xlog_stderr(int on)
64 {
65         log_stderr = on;
66 }
67
68 void
69 xlog_syslog(int on)
70 {
71         log_syslog = on;
72 }
73
74 static void
75 xlog_toggle(int sig)
76 {
77         unsigned int    tmp, i;
78
79         if (sig == SIGUSR1) {
80                 if ((logmask & D_ALL) && !logging) {
81                         xlog(D_GENERAL, "turned on logging");
82                         logging = 1;
83                         return;
84                 }
85                 tmp = ~logmask;
86                 logmask |= ((logmask & D_ALL) << 1) | D_GENERAL;
87                 for (i = -1, tmp &= logmask; tmp; tmp >>= 1, i++)
88                         if (tmp & 1)
89                                 xlog(D_GENERAL,
90                                         "turned on logging level %d", i);
91         } else {
92                 xlog(D_GENERAL, "turned off logging");
93                 logging = 0;
94         }
95         signal(sig, xlog_toggle);
96 }
97
98 void
99 xlog_config(int fac, int on)
100 {
101         if (on)
102                 logmask |= fac;
103         else
104                 logmask &= ~fac;
105         if (on)
106                 logging = 1;
107 }
108
109 void
110 xlog_sconfig(char *kind, int on)
111 {
112         struct xlog_debugfac    *tbl = debugnames;
113
114         while (tbl->df_name != NULL && strcasecmp(tbl->df_name, kind)) 
115                 tbl++;
116         if (!tbl->df_name) {
117                 xlog (L_WARNING, "Invalid debug facility: %s\n", kind);
118                 return;
119         }
120         xlog_config(tbl->df_fac, on);
121 }
122
123 int
124 xlog_enabled(int fac)
125 {
126         return (logging && (fac & logmask));
127 }
128
129
130 /* Write something to the system logfile and/or stderr */
131 void
132 xlog(int kind, const char *fmt, ...)
133 {
134         char            buff[1024];
135         va_list         args;
136         int             n;
137
138         if (!(kind & (L_ALL)) && !(logging && (kind & logmask)))
139                 return;
140
141         va_start(args, fmt);
142         vsnprintf(buff, sizeof (buff), fmt, args);
143         va_end(args);
144
145         if ((n = strlen(buff)) > 0 && buff[n-1] == '\n')
146                 buff[--n] = '\0';
147
148         if (log_syslog) {
149                 switch (kind) {
150                 case L_FATAL:
151                         syslog(LOG_ERR, "%s", buff);
152                         break;
153                 case L_ERROR:
154                         syslog(LOG_ERR, "%s", buff);
155                         break;
156                 case L_WARNING:
157                         syslog(LOG_WARNING, "%s", buff);
158                         break;
159                 case L_NOTICE:
160                         syslog(LOG_NOTICE, "%s", buff);
161                         break;
162                 default:
163                         if (!log_stderr)
164                                 syslog(LOG_INFO, "%s", buff);
165                         break;
166                 }
167         }
168
169         if (log_stderr) {
170 #ifdef VERBOSE_PRINTF
171                 time_t          now;
172                 struct tm       *tm;
173
174                 time(&now);
175                 tm = localtime(&now);
176                 fprintf(stderr, "%s[%d] %04d-%02d-%02d %02d:%02d:%02d %s\n",
177                                 log_name, log_pid,
178                                 tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday,
179                                 tm->tm_hour, tm->tm_min, tm->tm_sec,
180                                 buff);
181 #else
182                 fprintf(stderr, "%s: %s\n", log_name, buff);
183 #endif
184         }
185
186         if (kind == L_FATAL)
187                 exit(1);
188 }