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