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