File: logging.c

package info (click to toggle)
netstd 3.07-7slink.3
  • links: PTS
  • area: main
  • in suites: slink
  • size: 6,312 kB
  • ctags: 9,027
  • sloc: ansic: 72,107; cpp: 6,144; makefile: 1,650; yacc: 1,614; sh: 1,164; perl: 308; awk: 46
file content (184 lines) | stat: -rw-r--r-- 4,342 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * logging	This module handles the logging of requests.
 *
 * TODO:	Merge the two "XXX_log() calls.
 *
 * Authors:	Donald J. Becker, <becker@super.org>
 *		Rick Sladkey, <jrs@world.std.com>
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Olaf Kirch, <okir@monad.swb.de>
 *
 *		This software maybe be used for any purpose provided
 *		the above copyright notice is retained.  It is supplied
 *		as is, with no warranty expressed or implied.
 */

#include "nfsd.h"

#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#else
#define LOG_FILE	"/var/tmp/%s.log"
#endif

static int  logging = 0;		/* enable/disable DEBUG logs	*/
static int  dbg_mask = D_GENERAL;	/* What will be logged		*/
static char log_name[256];		/* name of this program		*/
static FILE *log_fp = (FILE *)NULL;	/* fp for the log file		*/

void
log_open(char *progname, int foreground)
{
#ifdef HAVE_SYSLOG_H
	openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON );
	if (foreground)
		log_fp = stderr;
#else
	if (foreground) {
		log_fp = stderr;
	} else {
		char path[1024];

		sprintf(path, LOG_FILE, progname);
		logfile = path;
		if ((log_fp = fopen(path, "a")) == NULL)
			return;
	}
#endif
	if (log_fp != NULL)
		setbuf(log_fp, (char *) NULL);

	sprintf(log_name, "%s[%d]", progname, getpid());
}

void
background_logging(void)
{
	if (log_fp == stderr)
		log_fp = NULL;
}

void
toggle_logging(int sig)
{
	(void) signal(sig, toggle_logging);
	Dprintf(D_GENERAL, "turned off logging\n");
	logging = 1 - logging;
	Dprintf(D_GENERAL, "turned on logging\n");
}

void
enable_logging(char *kind)
{
	if ('a' == *kind && !strcmp(kind, "auth"))
		dbg_mask |= D_AUTH;
	else if ('a' == *kind && !strcmp(kind, "all"))
		dbg_mask |= D_ALL;
	else if ('c' == *kind && !strcmp(kind, "call"))
		dbg_mask |= D_CALL;
	else if ('f' == *kind && !strcmp(kind, "fhcache"))
		dbg_mask |= D_FHCACHE;
	else if ('f' == *kind && !strcmp(kind, "fhtrace"))
		dbg_mask |= D_FHTRACE;
	else if ('r' == *kind && !strcmp(kind, "rmtab"))
		dbg_mask |= D_RMTAB;
	else if ('s' == *kind && !strcmp(kind, "stale"))
		dbg_mask |= D_AUTH | D_CALL | D_FHCACHE | D_FHTRACE;
	else if ('u' == *kind && !strcmp(kind, "ugid"))
		dbg_mask |= D_UGID;
	else
		fprintf (stderr, "Invalid debug facility: %s\n", kind);
	logging = 1;
}

int
logging_enabled(int level)
{
	return (logging && (level & dbg_mask));
}


/* Write something to the system logfile. */
void
Dprintf(int kind, const char *fmt, ...)
{
	char buff[1024];
	va_list args;
	time_t now;
	struct tm *tm;

	if (!(kind & (L_FATAL | L_ERROR | L_WARNING | L_NOTICE))
	 && !(logging && (kind & dbg_mask)))
		return;

	va_start(args, fmt);
#ifdef HAVE_VPRINTF
	vsprintf(buff, fmt, args);
#else
	/* Figure out how to use _doprnt here. */
#endif
	va_end(args);

#ifdef HAVE_SYSLOG_H
	if (kind & (L_FATAL | L_ERROR)) {
		(void) syslog(LOG_ERR, "%s", buff);
	} else if (kind & L_WARNING) {
		(void) syslog(LOG_WARNING, "%s", buff);
	} else if (kind & L_NOTICE) {
		(void) syslog(LOG_NOTICE, "%s", buff);
	} else if (log_fp == NULL) {
		(void) syslog(LOG_DEBUG, "%s", buff);
	}
#endif
	if (log_fp != (FILE *) NULL) {
		(void) time(&now);
		tm = localtime(&now);
		fprintf(log_fp, "%s %02d/%02d/%02d %02d:%02d %s",
		      log_name, tm->tm_mon + 1, tm->tm_mday, tm->tm_year,
			tm->tm_hour, tm->tm_min, buff);
	}

	if (kind & L_FATAL)
		exit(1);
}

/* Log an incoming call. */
void
log_call(struct svc_req *rqstp, char *xname, char *arg)
{
	char buff[1024];
	register char *sp;
	int i;

	if (!logging || !(dbg_mask & D_CALL))
		return;

	sp = buff;
	sprintf(sp, "%s [%d ", xname, rqstp->rq_cred.oa_flavor);
	sp += strlen(sp);
	if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
		struct authunix_parms *unix_cred;
		struct tm *tm;

		unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
		tm = localtime(&unix_cred->aup_time);
		sprintf(sp, "%d/%d/%d %02d:%02d:%02d %s %d.%d",
			tm->tm_year, tm->tm_mon + 1, tm->tm_mday,
			tm->tm_hour, tm->tm_min, tm->tm_sec,
			unix_cred->aup_machname,
			unix_cred->aup_uid,
			unix_cred->aup_gid);
		sp += strlen(sp);
		if ((int) unix_cred->aup_len > 0) {
			sprintf(sp, "+%d", unix_cred->aup_gids[0]);
			sp += strlen(sp);
			for (i = 1; i < unix_cred->aup_len; i++) {
				sprintf(sp, ",%d", unix_cred->aup_gids[i]);
				sp += strlen(sp);
			}
		}
	}
	Dprintf(D_CALL, "%s]\n", buff);
	if (arg && *arg)
		Dprintf(D_CALL, "\t%s\n", arg);
}