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