subr_prf.c revision 331722
1/*-
2 * Copyright (c) 1986, 1988, 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 4. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 *	@(#)subr_prf.c	8.3 (Berkeley) 1/21/94
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: stable/11/sys/kern/subr_prf.c 331722 2018-03-29 02:50:57Z eadler $");
39
40#ifdef _KERNEL
41#include "opt_ddb.h"
42#include "opt_printf.h"
43#endif  /* _KERNEL */
44
45#include <sys/param.h>
46#ifdef _KERNEL
47#include <sys/systm.h>
48#include <sys/lock.h>
49#include <sys/kdb.h>
50#include <sys/mutex.h>
51#include <sys/sx.h>
52#include <sys/kernel.h>
53#include <sys/msgbuf.h>
54#include <sys/malloc.h>
55#include <sys/priv.h>
56#include <sys/proc.h>
57#include <sys/stddef.h>
58#include <sys/sysctl.h>
59#include <sys/tty.h>
60#include <sys/syslog.h>
61#include <sys/cons.h>
62#include <sys/uio.h>
63#endif
64#include <sys/ctype.h>
65#include <sys/sbuf.h>
66
67#ifdef DDB
68#include <ddb/ddb.h>
69#endif
70
71/*
72 * Note that stdarg.h and the ANSI style va_start macro is used for both
73 * ANSI and traditional C compilers.
74 */
75#ifdef _KERNEL
76#include <machine/stdarg.h>
77#else
78#include <stdarg.h>
79#endif
80
81/*
82 * This is needed for sbuf_putbuf() when compiled into userland.  Due to the
83 * shared nature of this file, it's the only place to put it.
84 */
85#ifndef _KERNEL
86#include <stdio.h>
87#endif
88
89#ifdef _KERNEL
90
91#define TOCONS	0x01
92#define TOTTY	0x02
93#define TOLOG	0x04
94
95/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
96#define MAXNBUF	(sizeof(intmax_t) * NBBY + 1)
97
98struct putchar_arg {
99	int	flags;
100	int	pri;
101	struct	tty *tty;
102	char	*p_bufr;
103	size_t	n_bufr;
104	char	*p_next;
105	size_t	remain;
106};
107
108struct snprintf_arg {
109	char	*str;
110	size_t	remain;
111};
112
113extern	int log_open;
114
115static void  msglogchar(int c, int pri);
116static void  msglogstr(char *str, int pri, int filter_cr);
117static void  putchar(int ch, void *arg);
118static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper);
119static void  snprintf_func(int ch, void *arg);
120
121static int msgbufmapped;		/* Set when safe to use msgbuf */
122int msgbuftrigger;
123
124static int log_console_output = 1;
125SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RWTUN,
126    &log_console_output, 0, "Duplicate console output to the syslog");
127
128/*
129 * See the comment in log_console() below for more explanation of this.
130 */
131static int log_console_add_linefeed;
132SYSCTL_INT(_kern, OID_AUTO, log_console_add_linefeed, CTLFLAG_RWTUN,
133    &log_console_add_linefeed, 0, "log_console() adds extra newlines");
134
135static int always_console_output;
136SYSCTL_INT(_kern, OID_AUTO, always_console_output, CTLFLAG_RWTUN,
137    &always_console_output, 0, "Always output to console despite TIOCCONS");
138
139/*
140 * Warn that a system table is full.
141 */
142void
143tablefull(const char *tab)
144{
145
146	log(LOG_ERR, "%s: table is full\n", tab);
147}
148
149/*
150 * Uprintf prints to the controlling terminal for the current process.
151 */
152int
153uprintf(const char *fmt, ...)
154{
155	va_list ap;
156	struct putchar_arg pca;
157	struct proc *p;
158	struct thread *td;
159	int retval;
160
161	td = curthread;
162	if (TD_IS_IDLETHREAD(td))
163		return (0);
164
165	sx_slock(&proctree_lock);
166	p = td->td_proc;
167	PROC_LOCK(p);
168	if ((p->p_flag & P_CONTROLT) == 0) {
169		PROC_UNLOCK(p);
170		sx_sunlock(&proctree_lock);
171		return (0);
172	}
173	SESS_LOCK(p->p_session);
174	pca.tty = p->p_session->s_ttyp;
175	SESS_UNLOCK(p->p_session);
176	PROC_UNLOCK(p);
177	if (pca.tty == NULL) {
178		sx_sunlock(&proctree_lock);
179		return (0);
180	}
181	pca.flags = TOTTY;
182	pca.p_bufr = NULL;
183	va_start(ap, fmt);
184	tty_lock(pca.tty);
185	sx_sunlock(&proctree_lock);
186	retval = kvprintf(fmt, putchar, &pca, 10, ap);
187	tty_unlock(pca.tty);
188	va_end(ap);
189	return (retval);
190}
191
192/*
193 * tprintf and vtprintf print on the controlling terminal associated with the
194 * given session, possibly to the log as well.
195 */
196void
197tprintf(struct proc *p, int pri, const char *fmt, ...)
198{
199	va_list ap;
200
201	va_start(ap, fmt);
202	vtprintf(p, pri, fmt, ap);
203	va_end(ap);
204}
205
206void
207vtprintf(struct proc *p, int pri, const char *fmt, va_list ap)
208{
209	struct tty *tp = NULL;
210	int flags = 0;
211	struct putchar_arg pca;
212	struct session *sess = NULL;
213
214	sx_slock(&proctree_lock);
215	if (pri != -1)
216		flags |= TOLOG;
217	if (p != NULL) {
218		PROC_LOCK(p);
219		if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) {
220			sess = p->p_session;
221			sess_hold(sess);
222			PROC_UNLOCK(p);
223			tp = sess->s_ttyp;
224			if (tp != NULL && tty_checkoutq(tp))
225				flags |= TOTTY;
226			else
227				tp = NULL;
228		} else
229			PROC_UNLOCK(p);
230	}
231	pca.pri = pri;
232	pca.tty = tp;
233	pca.flags = flags;
234	pca.p_bufr = NULL;
235	if (pca.tty != NULL)
236		tty_lock(pca.tty);
237	sx_sunlock(&proctree_lock);
238	kvprintf(fmt, putchar, &pca, 10, ap);
239	if (pca.tty != NULL)
240		tty_unlock(pca.tty);
241	if (sess != NULL)
242		sess_release(sess);
243	msgbuftrigger = 1;
244}
245
246/*
247 * Ttyprintf displays a message on a tty; it should be used only by
248 * the tty driver, or anything that knows the underlying tty will not
249 * be revoke(2)'d away.  Other callers should use tprintf.
250 */
251int
252ttyprintf(struct tty *tp, const char *fmt, ...)
253{
254	va_list ap;
255	struct putchar_arg pca;
256	int retval;
257
258	va_start(ap, fmt);
259	pca.tty = tp;
260	pca.flags = TOTTY;
261	pca.p_bufr = NULL;
262	retval = kvprintf(fmt, putchar, &pca, 10, ap);
263	va_end(ap);
264	return (retval);
265}
266
267static int
268_vprintf(int level, int flags, const char *fmt, va_list ap)
269{
270	struct putchar_arg pca;
271	int retval;
272#ifdef PRINTF_BUFR_SIZE
273	char bufr[PRINTF_BUFR_SIZE];
274#endif
275
276	pca.tty = NULL;
277	pca.pri = level;
278	pca.flags = flags;
279#ifdef PRINTF_BUFR_SIZE
280	pca.p_bufr = bufr;
281	pca.p_next = pca.p_bufr;
282	pca.n_bufr = sizeof(bufr);
283	pca.remain = sizeof(bufr);
284	*pca.p_next = '\0';
285#else
286	/* Don't buffer console output. */
287	pca.p_bufr = NULL;
288#endif
289
290	retval = kvprintf(fmt, putchar, &pca, 10, ap);
291
292#ifdef PRINTF_BUFR_SIZE
293	/* Write any buffered console/log output: */
294	if (*pca.p_bufr != '\0') {
295		if (pca.flags & TOLOG)
296			msglogstr(pca.p_bufr, level, /*filter_cr*/1);
297
298		if (pca.flags & TOCONS)
299			cnputs(pca.p_bufr);
300	}
301#endif
302
303	return (retval);
304}
305
306/*
307 * Log writes to the log buffer, and guarantees not to sleep (so can be
308 * called by interrupt routines).  If there is no process reading the
309 * log yet, it writes to the console also.
310 */
311void
312log(int level, const char *fmt, ...)
313{
314	va_list ap;
315
316	va_start(ap, fmt);
317	vlog(level, fmt, ap);
318	va_end(ap);
319}
320
321void
322vlog(int level, const char *fmt, va_list ap)
323{
324
325	(void)_vprintf(level, log_open ? TOLOG : TOCONS | TOLOG, fmt, ap);
326	msgbuftrigger = 1;
327}
328
329#define CONSCHUNK 128
330
331void
332log_console(struct uio *uio)
333{
334	int c, error, nl;
335	char *consbuffer;
336	int pri;
337
338	if (!log_console_output)
339		return;
340
341	pri = LOG_INFO | LOG_CONSOLE;
342	uio = cloneuio(uio);
343	consbuffer = malloc(CONSCHUNK, M_TEMP, M_WAITOK);
344
345	nl = 0;
346	while (uio->uio_resid > 0) {
347		c = imin(uio->uio_resid, CONSCHUNK - 1);
348		error = uiomove(consbuffer, c, uio);
349		if (error != 0)
350			break;
351		/* Make sure we're NUL-terminated */
352		consbuffer[c] = '\0';
353		if (consbuffer[c - 1] == '\n')
354			nl = 1;
355		else
356			nl = 0;
357		msglogstr(consbuffer, pri, /*filter_cr*/ 1);
358	}
359	/*
360	 * The previous behavior in log_console() is preserved when
361	 * log_console_add_linefeed is non-zero.  For that behavior, if an
362	 * individual console write came in that was not terminated with a
363	 * line feed, it would add a line feed.
364	 *
365	 * This results in different data in the message buffer than
366	 * appears on the system console (which doesn't add extra line feed
367	 * characters).
368	 *
369	 * A number of programs and rc scripts write a line feed, or a period
370	 * and a line feed when they have completed their operation.  On
371	 * the console, this looks seamless, but when displayed with
372	 * 'dmesg -a', you wind up with output that looks like this:
373	 *
374	 * Updating motd:
375	 * .
376	 *
377	 * On the console, it looks like this:
378	 * Updating motd:.
379	 *
380	 * We could add logic to detect that situation, or just not insert
381	 * the extra newlines.  Set the kern.log_console_add_linefeed
382	 * sysctl/tunable variable to get the old behavior.
383	 */
384	if (!nl && log_console_add_linefeed) {
385		consbuffer[0] = '\n';
386		consbuffer[1] = '\0';
387		msglogstr(consbuffer, pri, /*filter_cr*/ 1);
388	}
389	msgbuftrigger = 1;
390	free(uio, M_IOV);
391	free(consbuffer, M_TEMP);
392}
393
394int
395printf(const char *fmt, ...)
396{
397	va_list ap;
398	int retval;
399
400	va_start(ap, fmt);
401	retval = vprintf(fmt, ap);
402	va_end(ap);
403
404	return (retval);
405}
406
407int
408vprintf(const char *fmt, va_list ap)
409{
410	int retval;
411
412	retval = _vprintf(-1, TOCONS | TOLOG, fmt, ap);
413
414	if (!panicstr)
415		msgbuftrigger = 1;
416
417	return (retval);
418}
419
420static void
421prf_putbuf(char *bufr, int flags, int pri)
422{
423
424	if (flags & TOLOG)
425		msglogstr(bufr, pri, /*filter_cr*/1);
426
427	if (flags & TOCONS) {
428		if ((panicstr == NULL) && (constty != NULL))
429			msgbuf_addstr(&consmsgbuf, -1,
430			    bufr, /*filter_cr*/ 0);
431
432		if ((constty == NULL) ||(always_console_output))
433			cnputs(bufr);
434	}
435}
436
437static void
438putbuf(int c, struct putchar_arg *ap)
439{
440	/* Check if no console output buffer was provided. */
441	if (ap->p_bufr == NULL) {
442		/* Output direct to the console. */
443		if (ap->flags & TOCONS)
444			cnputc(c);
445
446		if (ap->flags & TOLOG)
447			msglogchar(c, ap->pri);
448	} else {
449		/* Buffer the character: */
450		*ap->p_next++ = c;
451		ap->remain--;
452
453		/* Always leave the buffer zero terminated. */
454		*ap->p_next = '\0';
455
456		/* Check if the buffer needs to be flushed. */
457		if (ap->remain == 2 || c == '\n') {
458			prf_putbuf(ap->p_bufr, ap->flags, ap->pri);
459
460			ap->p_next = ap->p_bufr;
461			ap->remain = ap->n_bufr;
462			*ap->p_next = '\0';
463		}
464
465		/*
466		 * Since we fill the buffer up one character at a time,
467		 * this should not happen.  We should always catch it when
468		 * ap->remain == 2 (if not sooner due to a newline), flush
469		 * the buffer and move on.  One way this could happen is
470		 * if someone sets PRINTF_BUFR_SIZE to 1 or something
471		 * similarly silly.
472		 */
473		KASSERT(ap->remain > 2, ("Bad buffer logic, remain = %zd",
474		    ap->remain));
475	}
476}
477
478/*
479 * Print a character on console or users terminal.  If destination is
480 * the console then the last bunch of characters are saved in msgbuf for
481 * inspection later.
482 */
483static void
484putchar(int c, void *arg)
485{
486	struct putchar_arg *ap = (struct putchar_arg*) arg;
487	struct tty *tp = ap->tty;
488	int flags = ap->flags;
489
490	/* Don't use the tty code after a panic or while in ddb. */
491	if (kdb_active) {
492		if (c != '\0')
493			cnputc(c);
494		return;
495	}
496
497	if ((flags & TOTTY) && tp != NULL && panicstr == NULL)
498		tty_putchar(tp, c);
499
500	if ((flags & (TOCONS | TOLOG)) && c != '\0')
501		putbuf(c, ap);
502}
503
504/*
505 * Scaled down version of sprintf(3).
506 */
507int
508sprintf(char *buf, const char *cfmt, ...)
509{
510	int retval;
511	va_list ap;
512
513	va_start(ap, cfmt);
514	retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
515	buf[retval] = '\0';
516	va_end(ap);
517	return (retval);
518}
519
520/*
521 * Scaled down version of vsprintf(3).
522 */
523int
524vsprintf(char *buf, const char *cfmt, va_list ap)
525{
526	int retval;
527
528	retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
529	buf[retval] = '\0';
530	return (retval);
531}
532
533/*
534 * Scaled down version of snprintf(3).
535 */
536int
537snprintf(char *str, size_t size, const char *format, ...)
538{
539	int retval;
540	va_list ap;
541
542	va_start(ap, format);
543	retval = vsnprintf(str, size, format, ap);
544	va_end(ap);
545	return(retval);
546}
547
548/*
549 * Scaled down version of vsnprintf(3).
550 */
551int
552vsnprintf(char *str, size_t size, const char *format, va_list ap)
553{
554	struct snprintf_arg info;
555	int retval;
556
557	info.str = str;
558	info.remain = size;
559	retval = kvprintf(format, snprintf_func, &info, 10, ap);
560	if (info.remain >= 1)
561		*info.str++ = '\0';
562	return (retval);
563}
564
565/*
566 * Kernel version which takes radix argument vsnprintf(3).
567 */
568int
569vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap)
570{
571	struct snprintf_arg info;
572	int retval;
573
574	info.str = str;
575	info.remain = size;
576	retval = kvprintf(format, snprintf_func, &info, radix, ap);
577	if (info.remain >= 1)
578		*info.str++ = '\0';
579	return (retval);
580}
581
582static void
583snprintf_func(int ch, void *arg)
584{
585	struct snprintf_arg *const info = arg;
586
587	if (info->remain >= 2) {
588		*info->str++ = ch;
589		info->remain--;
590	}
591}
592
593/*
594 * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
595 * order; return an optional length and a pointer to the last character
596 * written in the buffer (i.e., the first character of the string).
597 * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
598 */
599static char *
600ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
601{
602	char *p, c;
603
604	p = nbuf;
605	*p = '\0';
606	do {
607		c = hex2ascii(num % base);
608		*++p = upper ? toupper(c) : c;
609	} while (num /= base);
610	if (lenp)
611		*lenp = p - nbuf;
612	return (p);
613}
614
615/*
616 * Scaled down version of printf(3).
617 *
618 * Two additional formats:
619 *
620 * The format %b is supported to decode error registers.
621 * Its usage is:
622 *
623 *	printf("reg=%b\n", regval, "<base><arg>*");
624 *
625 * where <base> is the output base expressed as a control character, e.g.
626 * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
627 * the first of which gives the bit number to be inspected (origin 1), and
628 * the next characters (up to a control character, i.e. a character <= 32),
629 * give the name of the register.  Thus:
630 *
631 *	kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE");
632 *
633 * would produce output:
634 *
635 *	reg=3<BITTWO,BITONE>
636 *
637 * XXX:  %D  -- Hexdump, takes pointer and separator string:
638 *		("%6D", ptr, ":")   -> XX:XX:XX:XX:XX:XX
639 *		("%*D", len, ptr, " " -> XX XX XX XX ...
640 */
641int
642kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
643{
644#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
645	char nbuf[MAXNBUF];
646	char *d;
647	const char *p, *percent, *q;
648	u_char *up;
649	int ch, n;
650	uintmax_t num;
651	int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
652	int cflag, hflag, jflag, tflag, zflag;
653	int dwidth, upper;
654	char padc;
655	int stop = 0, retval = 0;
656
657	num = 0;
658	if (!func)
659		d = (char *) arg;
660	else
661		d = NULL;
662
663	if (fmt == NULL)
664		fmt = "(fmt null)\n";
665
666	if (radix < 2 || radix > 36)
667		radix = 10;
668
669	for (;;) {
670		padc = ' ';
671		width = 0;
672		while ((ch = (u_char)*fmt++) != '%' || stop) {
673			if (ch == '\0')
674				return (retval);
675			PCHAR(ch);
676		}
677		percent = fmt - 1;
678		qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
679		sign = 0; dot = 0; dwidth = 0; upper = 0;
680		cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
681reswitch:	switch (ch = (u_char)*fmt++) {
682		case '.':
683			dot = 1;
684			goto reswitch;
685		case '#':
686			sharpflag = 1;
687			goto reswitch;
688		case '+':
689			sign = 1;
690			goto reswitch;
691		case '-':
692			ladjust = 1;
693			goto reswitch;
694		case '%':
695			PCHAR(ch);
696			break;
697		case '*':
698			if (!dot) {
699				width = va_arg(ap, int);
700				if (width < 0) {
701					ladjust = !ladjust;
702					width = -width;
703				}
704			} else {
705				dwidth = va_arg(ap, int);
706			}
707			goto reswitch;
708		case '0':
709			if (!dot) {
710				padc = '0';
711				goto reswitch;
712			}
713		case '1': case '2': case '3': case '4':
714		case '5': case '6': case '7': case '8': case '9':
715				for (n = 0;; ++fmt) {
716					n = n * 10 + ch - '0';
717					ch = *fmt;
718					if (ch < '0' || ch > '9')
719						break;
720				}
721			if (dot)
722				dwidth = n;
723			else
724				width = n;
725			goto reswitch;
726		case 'b':
727			num = (u_int)va_arg(ap, int);
728			p = va_arg(ap, char *);
729			for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
730				PCHAR(*q--);
731
732			if (num == 0)
733				break;
734
735			for (tmp = 0; *p;) {
736				n = *p++;
737				if (num & (1 << (n - 1))) {
738					PCHAR(tmp ? ',' : '<');
739					for (; (n = *p) > ' '; ++p)
740						PCHAR(n);
741					tmp = 1;
742				} else
743					for (; *p > ' '; ++p)
744						continue;
745			}
746			if (tmp)
747				PCHAR('>');
748			break;
749		case 'c':
750			width -= 1;
751
752			if (!ladjust && width > 0)
753				while (width--)
754					PCHAR(padc);
755			PCHAR(va_arg(ap, int));
756			if (ladjust && width > 0)
757				while (width--)
758					PCHAR(padc);
759			break;
760		case 'D':
761			up = va_arg(ap, u_char *);
762			p = va_arg(ap, char *);
763			if (!width)
764				width = 16;
765			while(width--) {
766				PCHAR(hex2ascii(*up >> 4));
767				PCHAR(hex2ascii(*up & 0x0f));
768				up++;
769				if (width)
770					for (q=p;*q;q++)
771						PCHAR(*q);
772			}
773			break;
774		case 'd':
775		case 'i':
776			base = 10;
777			sign = 1;
778			goto handle_sign;
779		case 'h':
780			if (hflag) {
781				hflag = 0;
782				cflag = 1;
783			} else
784				hflag = 1;
785			goto reswitch;
786		case 'j':
787			jflag = 1;
788			goto reswitch;
789		case 'l':
790			if (lflag) {
791				lflag = 0;
792				qflag = 1;
793			} else
794				lflag = 1;
795			goto reswitch;
796		case 'n':
797			if (jflag)
798				*(va_arg(ap, intmax_t *)) = retval;
799			else if (qflag)
800				*(va_arg(ap, quad_t *)) = retval;
801			else if (lflag)
802				*(va_arg(ap, long *)) = retval;
803			else if (zflag)
804				*(va_arg(ap, size_t *)) = retval;
805			else if (hflag)
806				*(va_arg(ap, short *)) = retval;
807			else if (cflag)
808				*(va_arg(ap, char *)) = retval;
809			else
810				*(va_arg(ap, int *)) = retval;
811			break;
812		case 'o':
813			base = 8;
814			goto handle_nosign;
815		case 'p':
816			base = 16;
817			sharpflag = (width == 0);
818			sign = 0;
819			num = (uintptr_t)va_arg(ap, void *);
820			goto number;
821		case 'q':
822			qflag = 1;
823			goto reswitch;
824		case 'r':
825			base = radix;
826			if (sign)
827				goto handle_sign;
828			goto handle_nosign;
829		case 's':
830			p = va_arg(ap, char *);
831			if (p == NULL)
832				p = "(null)";
833			if (!dot)
834				n = strlen (p);
835			else
836				for (n = 0; n < dwidth && p[n]; n++)
837					continue;
838
839			width -= n;
840
841			if (!ladjust && width > 0)
842				while (width--)
843					PCHAR(padc);
844			while (n--)
845				PCHAR(*p++);
846			if (ladjust && width > 0)
847				while (width--)
848					PCHAR(padc);
849			break;
850		case 't':
851			tflag = 1;
852			goto reswitch;
853		case 'u':
854			base = 10;
855			goto handle_nosign;
856		case 'X':
857			upper = 1;
858		case 'x':
859			base = 16;
860			goto handle_nosign;
861		case 'y':
862			base = 16;
863			sign = 1;
864			goto handle_sign;
865		case 'z':
866			zflag = 1;
867			goto reswitch;
868handle_nosign:
869			sign = 0;
870			if (jflag)
871				num = va_arg(ap, uintmax_t);
872			else if (qflag)
873				num = va_arg(ap, u_quad_t);
874			else if (tflag)
875				num = va_arg(ap, ptrdiff_t);
876			else if (lflag)
877				num = va_arg(ap, u_long);
878			else if (zflag)
879				num = va_arg(ap, size_t);
880			else if (hflag)
881				num = (u_short)va_arg(ap, int);
882			else if (cflag)
883				num = (u_char)va_arg(ap, int);
884			else
885				num = va_arg(ap, u_int);
886			goto number;
887handle_sign:
888			if (jflag)
889				num = va_arg(ap, intmax_t);
890			else if (qflag)
891				num = va_arg(ap, quad_t);
892			else if (tflag)
893				num = va_arg(ap, ptrdiff_t);
894			else if (lflag)
895				num = va_arg(ap, long);
896			else if (zflag)
897				num = va_arg(ap, ssize_t);
898			else if (hflag)
899				num = (short)va_arg(ap, int);
900			else if (cflag)
901				num = (char)va_arg(ap, int);
902			else
903				num = va_arg(ap, int);
904number:
905			if (sign && (intmax_t)num < 0) {
906				neg = 1;
907				num = -(intmax_t)num;
908			}
909			p = ksprintn(nbuf, num, base, &n, upper);
910			tmp = 0;
911			if (sharpflag && num != 0) {
912				if (base == 8)
913					tmp++;
914				else if (base == 16)
915					tmp += 2;
916			}
917			if (neg)
918				tmp++;
919
920			if (!ladjust && padc == '0')
921				dwidth = width - tmp;
922			width -= tmp + imax(dwidth, n);
923			dwidth -= n;
924			if (!ladjust)
925				while (width-- > 0)
926					PCHAR(' ');
927			if (neg)
928				PCHAR('-');
929			if (sharpflag && num != 0) {
930				if (base == 8) {
931					PCHAR('0');
932				} else if (base == 16) {
933					PCHAR('0');
934					PCHAR('x');
935				}
936			}
937			while (dwidth-- > 0)
938				PCHAR('0');
939
940			while (*p)
941				PCHAR(*p--);
942
943			if (ladjust)
944				while (width-- > 0)
945					PCHAR(' ');
946
947			break;
948		default:
949			while (percent < fmt)
950				PCHAR(*percent++);
951			/*
952			 * Since we ignore a formatting argument it is no
953			 * longer safe to obey the remaining formatting
954			 * arguments as the arguments will no longer match
955			 * the format specs.
956			 */
957			stop = 1;
958			break;
959		}
960	}
961#undef PCHAR
962}
963
964/*
965 * Put character in log buffer with a particular priority.
966 */
967static void
968msglogchar(int c, int pri)
969{
970	static int lastpri = -1;
971	static int dangling;
972	char nbuf[MAXNBUF];
973	char *p;
974
975	if (!msgbufmapped)
976		return;
977	if (c == '\0' || c == '\r')
978		return;
979	if (pri != -1 && pri != lastpri) {
980		if (dangling) {
981			msgbuf_addchar(msgbufp, '\n');
982			dangling = 0;
983		}
984		msgbuf_addchar(msgbufp, '<');
985		for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;)
986			msgbuf_addchar(msgbufp, *p--);
987		msgbuf_addchar(msgbufp, '>');
988		lastpri = pri;
989	}
990	msgbuf_addchar(msgbufp, c);
991	if (c == '\n') {
992		dangling = 0;
993		lastpri = -1;
994	} else {
995		dangling = 1;
996	}
997}
998
999static void
1000msglogstr(char *str, int pri, int filter_cr)
1001{
1002	if (!msgbufmapped)
1003		return;
1004
1005	msgbuf_addstr(msgbufp, pri, str, filter_cr);
1006}
1007
1008void
1009msgbufinit(void *ptr, int size)
1010{
1011	char *cp;
1012	static struct msgbuf *oldp = NULL;
1013
1014	size -= sizeof(*msgbufp);
1015	cp = (char *)ptr;
1016	msgbufp = (struct msgbuf *)(cp + size);
1017	msgbuf_reinit(msgbufp, cp, size);
1018	if (msgbufmapped && oldp != msgbufp)
1019		msgbuf_copy(oldp, msgbufp);
1020	msgbufmapped = 1;
1021	oldp = msgbufp;
1022}
1023
1024static int unprivileged_read_msgbuf = 1;
1025SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_read_msgbuf,
1026    CTLFLAG_RW, &unprivileged_read_msgbuf, 0,
1027    "Unprivileged processes may read the kernel message buffer");
1028
1029/* Sysctls for accessing/clearing the msgbuf */
1030static int
1031sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
1032{
1033	char buf[128];
1034	u_int seq;
1035	int error, len;
1036
1037	if (!unprivileged_read_msgbuf) {
1038		error = priv_check(req->td, PRIV_MSGBUF);
1039		if (error)
1040			return (error);
1041	}
1042
1043	/* Read the whole buffer, one chunk at a time. */
1044	mtx_lock(&msgbuf_lock);
1045	msgbuf_peekbytes(msgbufp, NULL, 0, &seq);
1046	for (;;) {
1047		len = msgbuf_peekbytes(msgbufp, buf, sizeof(buf), &seq);
1048		mtx_unlock(&msgbuf_lock);
1049		if (len == 0)
1050			return (SYSCTL_OUT(req, "", 1)); /* add nulterm */
1051
1052		error = sysctl_handle_opaque(oidp, buf, len, req);
1053		if (error)
1054			return (error);
1055
1056		mtx_lock(&msgbuf_lock);
1057	}
1058}
1059
1060SYSCTL_PROC(_kern, OID_AUTO, msgbuf,
1061    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
1062    NULL, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
1063
1064static int msgbuf_clearflag;
1065
1066static int
1067sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)
1068{
1069	int error;
1070	error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
1071	if (!error && req->newptr) {
1072		mtx_lock(&msgbuf_lock);
1073		msgbuf_clear(msgbufp);
1074		mtx_unlock(&msgbuf_lock);
1075		msgbuf_clearflag = 0;
1076	}
1077	return (error);
1078}
1079
1080SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear,
1081    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE | CTLFLAG_MPSAFE,
1082    &msgbuf_clearflag, 0, sysctl_kern_msgbuf_clear, "I",
1083    "Clear kernel message buffer");
1084
1085#ifdef DDB
1086
1087DB_SHOW_COMMAND(msgbuf, db_show_msgbuf)
1088{
1089	int i, j;
1090
1091	if (!msgbufmapped) {
1092		db_printf("msgbuf not mapped yet\n");
1093		return;
1094	}
1095	db_printf("msgbufp = %p\n", msgbufp);
1096	db_printf("magic = %x, size = %d, r= %u, w = %u, ptr = %p, cksum= %u\n",
1097	    msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_rseq,
1098	    msgbufp->msg_wseq, msgbufp->msg_ptr, msgbufp->msg_cksum);
1099	for (i = 0; i < msgbufp->msg_size && !db_pager_quit; i++) {
1100		j = MSGBUF_SEQ_TO_POS(msgbufp, i + msgbufp->msg_rseq);
1101		db_printf("%c", msgbufp->msg_ptr[j]);
1102	}
1103	db_printf("\n");
1104}
1105
1106#endif /* DDB */
1107
1108void
1109hexdump(const void *ptr, int length, const char *hdr, int flags)
1110{
1111	int i, j, k;
1112	int cols;
1113	const unsigned char *cp;
1114	char delim;
1115
1116	if ((flags & HD_DELIM_MASK) != 0)
1117		delim = (flags & HD_DELIM_MASK) >> 8;
1118	else
1119		delim = ' ';
1120
1121	if ((flags & HD_COLUMN_MASK) != 0)
1122		cols = flags & HD_COLUMN_MASK;
1123	else
1124		cols = 16;
1125
1126	cp = ptr;
1127	for (i = 0; i < length; i+= cols) {
1128		if (hdr != NULL)
1129			printf("%s", hdr);
1130
1131		if ((flags & HD_OMIT_COUNT) == 0)
1132			printf("%04x  ", i);
1133
1134		if ((flags & HD_OMIT_HEX) == 0) {
1135			for (j = 0; j < cols; j++) {
1136				k = i + j;
1137				if (k < length)
1138					printf("%c%02x", delim, cp[k]);
1139				else
1140					printf("   ");
1141			}
1142		}
1143
1144		if ((flags & HD_OMIT_CHARS) == 0) {
1145			printf("  |");
1146			for (j = 0; j < cols; j++) {
1147				k = i + j;
1148				if (k >= length)
1149					printf(" ");
1150				else if (cp[k] >= ' ' && cp[k] <= '~')
1151					printf("%c", cp[k]);
1152				else
1153					printf(".");
1154			}
1155			printf("|");
1156		}
1157		printf("\n");
1158	}
1159}
1160#endif /* _KERNEL */
1161
1162void
1163sbuf_hexdump(struct sbuf *sb, const void *ptr, int length, const char *hdr,
1164	     int flags)
1165{
1166	int i, j, k;
1167	int cols;
1168	const unsigned char *cp;
1169	char delim;
1170
1171	if ((flags & HD_DELIM_MASK) != 0)
1172		delim = (flags & HD_DELIM_MASK) >> 8;
1173	else
1174		delim = ' ';
1175
1176	if ((flags & HD_COLUMN_MASK) != 0)
1177		cols = flags & HD_COLUMN_MASK;
1178	else
1179		cols = 16;
1180
1181	cp = ptr;
1182	for (i = 0; i < length; i+= cols) {
1183		if (hdr != NULL)
1184			sbuf_printf(sb, "%s", hdr);
1185
1186		if ((flags & HD_OMIT_COUNT) == 0)
1187			sbuf_printf(sb, "%04x  ", i);
1188
1189		if ((flags & HD_OMIT_HEX) == 0) {
1190			for (j = 0; j < cols; j++) {
1191				k = i + j;
1192				if (k < length)
1193					sbuf_printf(sb, "%c%02x", delim, cp[k]);
1194				else
1195					sbuf_printf(sb, "   ");
1196			}
1197		}
1198
1199		if ((flags & HD_OMIT_CHARS) == 0) {
1200			sbuf_printf(sb, "  |");
1201			for (j = 0; j < cols; j++) {
1202				k = i + j;
1203				if (k >= length)
1204					sbuf_printf(sb, " ");
1205				else if (cp[k] >= ' ' && cp[k] <= '~')
1206					sbuf_printf(sb, "%c", cp[k]);
1207				else
1208					sbuf_printf(sb, ".");
1209			}
1210			sbuf_printf(sb, "|");
1211		}
1212		sbuf_printf(sb, "\n");
1213	}
1214}
1215
1216#ifdef _KERNEL
1217void
1218counted_warning(unsigned *counter, const char *msg)
1219{
1220	struct thread *td;
1221	unsigned c;
1222
1223	for (;;) {
1224		c = *counter;
1225		if (c == 0)
1226			break;
1227		if (atomic_cmpset_int(counter, c, c - 1)) {
1228			td = curthread;
1229			log(LOG_INFO, "pid %d (%s) %s%s\n",
1230			    td->td_proc->p_pid, td->td_name, msg,
1231			    c > 1 ? "" : " - not logging anymore");
1232			break;
1233		}
1234	}
1235}
1236#endif
1237
1238#ifdef _KERNEL
1239void
1240sbuf_putbuf(struct sbuf *sb)
1241{
1242
1243	prf_putbuf(sbuf_data(sb), TOLOG | TOCONS, -1);
1244}
1245#else
1246void
1247sbuf_putbuf(struct sbuf *sb)
1248{
1249
1250	printf("%s", sbuf_data(sb));
1251}
1252#endif
1253