GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/npppd/npppd/../common/debugutil.c Lines: 0 103 0.0 %
Date: 2017-11-07 Branches: 0 68 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: debugutil.c,v 1.6 2017/05/30 17:22:00 yasuoka Exp $ */
2
/*-
3
 * Copyright (c) 2009 Internet Initiative Japan Inc.
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 * 1. Redistributions of source code must retain the above copyright
10
 *    notice, this list of conditions and the following disclaimer.
11
 * 2. Redistributions in binary form must reproduce the above copyright
12
 *    notice, this list of conditions and the following disclaimer in the
13
 *    documentation and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
 * SUCH DAMAGE.
26
 */
27
#include <sys/types.h>
28
#include <stdio.h>
29
#include <errno.h>
30
#include <string.h>
31
#include <syslog.h>
32
#include <stdarg.h>
33
#include <stdlib.h>
34
#include <time.h>
35
36
#include "debugutil.h"
37
38
#define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
39
#define MAXIMUM(a, b)	(((a) > (b)) ? (a) : (b))
40
41
int debuglevel = 0;
42
FILE *debugfp = NULL;
43
static int prio_idx_inititialized = 0;
44
45
static void  set_prio_idx_init(void);
46
47
#ifndef countof
48
#define countof(x)	(sizeof((x)) / sizeof((x)[0]))
49
#endif
50
#define VAL_NAME(x)	{ (x), #x}
51
52
#ifndef LOG_PRI
53
#define LOG_PRI(p)	((p) & LOG_PRIMASK)
54
#endif
55
56
static int use_syslog = 1;
57
static int no_debuglog = 0;
58
static int syslog_level_adjust = 0;
59
60
static struct {
61
	int prio;
62
	const char *name;
63
} prio_name[] = {
64
	VAL_NAME(LOG_EMERG),
65
	VAL_NAME(LOG_ALERT),
66
	VAL_NAME(LOG_CRIT),
67
	VAL_NAME(LOG_ERR),
68
	VAL_NAME(LOG_WARNING),
69
	VAL_NAME(LOG_NOTICE),
70
	VAL_NAME(LOG_INFO),
71
	VAL_NAME(LOG_DEBUG)
72
};
73
74
static const char *prio_name_idx[16];
75
76
static void
77
set_prio_idx_init()
78
{
79
	int i;
80
81
	if (prio_idx_inititialized)
82
		return;
83
	for (i = 0; i < (int)countof(prio_name); i++) {
84
		ASSERT(prio_name[i].prio < countof(prio_name_idx));
85
		if (prio_name[i].prio >= (int)countof(prio_name_idx))
86
		    continue;
87
		prio_name_idx[prio_name[i].prio] = &prio_name[i].name[4];
88
	}
89
	prio_idx_inititialized = 1;
90
}
91
92
void
93
debug_set_debugfp(fp)
94
	FILE *fp;
95
{
96
	debugfp = fp;
97
}
98
99
void
100
debug_use_syslog(b)
101
	int b;
102
{
103
	if (b)
104
		use_syslog = 1;
105
	else
106
		use_syslog = 0;
107
}
108
109
void
110
debug_set_no_debuglog(int no_debuglog0)
111
{
112
	if (no_debuglog0)
113
		no_debuglog = 1;
114
	else
115
		no_debuglog = 0;
116
}
117
118
FILE *
119
debug_get_debugfp()
120
{
121
	return debugfp;
122
}
123
124
#define	DL(p)		((p) >> 24 & 0xff)
125
int
126
vlog_printf(uint32_t prio, const char *format, va_list ap)
127
{
128
	int status = 0, i, fmtoff = 0, state = 0, fmtlen, saved_errno, level;
129
	char fmt[8192];
130
	struct tm *lt;
131
	time_t now;
132
133
	ASSERT(format != NULL);
134
	ASSERT(format[0] != '\0');
135
	if (DL(prio) > 0 && debuglevel < (int)DL(prio))
136
		return -1;
137
	if (no_debuglog &&  LOG_PRI(prio) >= LOG_DEBUG)
138
		return -1;
139
140
	if (!prio_idx_inititialized)
141
		set_prio_idx_init();
142
	if (use_syslog && DL(prio) == 0) {
143
		level = LOG_PRI(prio) + syslog_level_adjust;
144
		if (!no_debuglog || level < LOG_DEBUG) {
145
			level = MINIMUM(LOG_DEBUG, level);
146
			level = MAXIMUM(LOG_EMERG, level);
147
			level |= (prio & LOG_FACMASK);
148
			vsyslog(level, format, ap);
149
		}
150
	}
151
152
	if (debugfp == NULL)
153
		return -1;
154
155
	time(&now);
156
	lt = localtime(&now);
157
158
	fmtlen = strlen(format);
159
	for (i = 0; i < fmtlen; i++) {
160
		/* 2 chars in this block and 2 chars after this block */
161
		if (sizeof(fmt) - fmtoff < 4)
162
			break;
163
		switch(state) {
164
		case 0:
165
			switch(format[i]) {
166
			case '%':
167
				state = 1;
168
				goto copy_loop;
169
			case '\n':
170
				fmt[fmtoff++] = '\n';
171
				fmt[fmtoff++] = '\t';
172
				goto copy_loop;
173
			}
174
			break;
175
		case 1:
176
			switch(format[i]) {
177
			default:
178
			case '%':
179
				fmt[fmtoff++] = '%';
180
				state = 0;
181
				break;
182
			case 'm':
183
				fmt[fmtoff] = '\0';
184
				saved_errno = errno;
185
				/* -1 is to reserve for '\n' */
186
				strlcat(fmt, strerror(errno), sizeof(fmt) - 1);
187
				errno = saved_errno;
188
				fmtoff = strlen(fmt);
189
				state = 0;
190
				goto copy_loop;
191
			}
192
		}
193
		fmt[fmtoff++] = format[i];
194
copy_loop:
195
		continue;
196
	}
197
	/* remove trailing TAB */
198
	if (fmtoff > 0 && fmt[fmtoff - 1] == '\t')
199
		fmtoff--;
200
	/* append new line char */
201
	if (fmtoff == 0 || fmt[fmtoff-1] != '\n')
202
		fmt[fmtoff++] = '\n';
203
204
	fmt[fmtoff] = '\0';
205
206
	ASSERT(0 <= LOG_PRI(prio)
207
	    && LOG_PRI(prio) < countof(prio_name_idx)
208
	    && prio_name_idx[LOG_PRI(prio)] != NULL);
209
	ftell(debugfp);
210
	fprintf(debugfp,
211
	    "%04d-%02d-%02d %02d:%02d:%02d:%s: "
212
	    , lt->tm_year + 1900
213
	    , lt->tm_mon + 1
214
	    , lt->tm_mday
215
	    , lt->tm_hour
216
	    , lt->tm_min
217
	    , lt->tm_sec
218
	    , (prio & 0xff000000) ? "DEBUG" : prio_name_idx[LOG_PRI(prio)]
219
	);
220
	status = vfprintf(debugfp, fmt, ap);
221
	fflush(debugfp);
222
223
	return status;
224
}
225
226
int
227
log_printf(int prio, const char *fmt, ...)
228
{
229
	int status;
230
	va_list ap;
231
232
	va_start(ap, fmt);
233
	status = vlog_printf((uint32_t)prio, fmt, ap);
234
	va_end(ap);
235
236
	return status;
237
}
238
239
void
240
debug_set_syslog_level_adjust(int adjust)
241
{
242
	syslog_level_adjust = adjust;
243
}
244
245
int
246
debug_get_syslog_level_adjust(void)
247
{
248
	return syslog_level_adjust;
249
}
250
251
252
/*
253
 * show_hd -
254
 *	print hexadecimal/ascii dump for debug
255
 *
256
 * usage:
257
 *  show_hd(stderr, buf, sizeof(buf));
258
 */
259
void
260
show_hd(FILE *file, const u_char *buf, int len)
261
{
262
	int i, o = 0;
263
	int hd_cnt = 0;
264
	char linebuf[80];
265
	char asciibuf[17];
266
267
	memset(asciibuf, ' ', sizeof(asciibuf));
268
	asciibuf[sizeof(asciibuf)-1] = '\0';
269
270
	for (i = 0; i < len; i++) {
271
		if (0x20 <= *(buf+i)  && *(buf+i) <= 0x7e)
272
			asciibuf[hd_cnt % 16] = *(buf+i);
273
		else
274
			asciibuf[hd_cnt % 16] = '.';
275
276
		switch (hd_cnt % 16) {
277
		case 0:
278
			o += snprintf(linebuf + o, sizeof(linebuf) - o,
279
			    "%04x  %02x", hd_cnt,
280
			    (unsigned char)*(buf+i));
281
			break;
282
		case 15:
283
			o += snprintf(linebuf + o, sizeof(linebuf) - o,
284
			    "%02x", (unsigned char)*(buf+i));
285
			if (file)
286
				fprintf(file, "\t%-47s  |%s|\n", linebuf,
287
				    asciibuf);
288
			else
289
				syslog(LOG_ERR, "%-47s  |%s|\n", linebuf,
290
				    asciibuf);
291
			memset(asciibuf, ' ', sizeof(asciibuf));
292
			asciibuf[sizeof(asciibuf)-1] = '\0';
293
			o = 0;
294
			break;
295
		case 8:
296
			o += snprintf(linebuf + o, sizeof(linebuf) - o,
297
			    "- %02x", (unsigned char)*(buf+i));
298
			break;
299
		default:
300
			if (hd_cnt % 2 == 1)
301
				o += snprintf(linebuf + o, sizeof(linebuf) - o,
302
				    "%02x ", (unsigned char)*(buf+i));
303
			else
304
				o += snprintf(linebuf + o, sizeof(linebuf) - o,
305
				    "%02x", (unsigned char)*(buf+i));
306
			break;
307
		}
308
		hd_cnt++;
309
	}
310
	if (hd_cnt > 0 && (hd_cnt % 16) != 0) {
311
		if (file)
312
			fprintf(file, "\t%-47s  |%s|\n", linebuf, asciibuf);
313
		else
314
			syslog(LOG_ERR, "%-47s  |%s|\n", linebuf, asciibuf);
315
	}
316
	if (file)
317
		fflush(file);
318
}