Merge branch 'vendor/AWK'
[dragonfly.git] / sys / kern / subr_prf.c
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  * $FreeBSD: src/sys/kern/subr_prf.c,v 1.61.2.5 2002/08/31 18:22:08 dwmalone Exp $
36  */
37
38 #include "opt_ddb.h"
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/msgbuf.h>
44 #include <sys/malloc.h>
45 #include <sys/proc.h>
46 #include <sys/priv.h>
47 #include <sys/tty.h>
48 #include <sys/tprintf.h>
49 #include <sys/stdint.h>
50 #include <sys/syslog.h>
51 #include <sys/cons.h>
52 #include <sys/uio.h>
53 #include <sys/sysctl.h>
54 #include <sys/lock.h>
55 #include <sys/ctype.h>
56 #include <sys/eventhandler.h>
57 #include <sys/kthread.h>
58
59 #include <sys/thread2.h>
60 #include <sys/spinlock2.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.  We use the __ machine version to stay
69  * within the kernel header file set.
70  */
71 #include <machine/stdarg.h>
72
73 #define TOCONS          0x01
74 #define TOTTY           0x02
75 #define TOLOG           0x04
76 #define TOWAKEUP        0x08
77
78 /* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
79 #define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
80
81 struct putchar_arg {
82         int     flags;
83         int     pri;
84         struct  tty *tty;
85 };
86
87 struct snprintf_arg {
88         char    *str;
89         size_t  remain;
90 };
91
92 extern  int log_open;
93
94 struct  tty *constty;                   /* pointer to console "window" tty */
95
96 static void  msglogchar(int c, int pri);
97 static void  msgaddchar(int c, void *dummy);
98 static void  kputchar (int ch, void *arg);
99 static char *ksprintn (char *nbuf, uintmax_t num, int base, int *lenp,
100                        int upper);
101 static void  snprintf_func (int ch, void *arg);
102
103 static int consintr = 1;                /* Ok to handle console interrupts? */
104 static int msgbufmapped;                /* Set when safe to use msgbuf */
105 static struct spinlock cons_spin = SPINLOCK_INITIALIZER(cons_spin);
106 static thread_t constty_td = NULL;
107
108 int msgbuftrigger;
109
110 static int      log_console_output = 1;
111 TUNABLE_INT("kern.log_console_output", &log_console_output);
112 SYSCTL_INT(_kern, OID_AUTO, log_console_output, CTLFLAG_RW,
113     &log_console_output, 0, "");
114
115 static int unprivileged_read_msgbuf = 1;
116 SYSCTL_INT(_security, OID_AUTO, unprivileged_read_msgbuf, CTLFLAG_RW,
117     &unprivileged_read_msgbuf, 0,
118     "Unprivileged processes may read the kernel message buffer");
119
120 /*
121  * Warn that a system table is full.
122  */
123 void
124 tablefull(const char *tab)
125 {
126
127         log(LOG_ERR, "%s: table is full\n", tab);
128 }
129
130 /*
131  * Uprintf prints to the controlling terminal for the current process.
132  */
133 int
134 uprintf(const char *fmt, ...)
135 {
136         struct proc *p = curproc;
137         __va_list ap;
138         struct putchar_arg pca;
139         int retval = 0;
140
141         if (p && (p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) {
142                 __va_start(ap, fmt);
143                 pca.tty = p->p_session->s_ttyp;
144                 pca.flags = TOTTY;
145
146                 retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
147                 __va_end(ap);
148         }
149         return (retval);
150 }
151
152 tpr_t
153 tprintf_open(struct proc *p)
154 {
155         if ((p->p_flags & P_CONTROLT) && p->p_session->s_ttyvp) {
156                 sess_hold(p->p_session);
157                 return ((tpr_t) p->p_session);
158         }
159         return (NULL);
160 }
161
162 void
163 tprintf_close(tpr_t sess)
164 {
165         if (sess)
166                 sess_rele((struct session *) sess);
167 }
168
169 /*
170  * tprintf prints on the controlling terminal associated
171  * with the given session.
172  */
173 int
174 tprintf(tpr_t tpr, const char *fmt, ...)
175 {
176         struct session *sess = (struct session *)tpr;
177         struct tty *tp = NULL;
178         int flags = TOLOG;
179         __va_list ap;
180         struct putchar_arg pca;
181         int retval;
182
183         if (sess && sess->s_ttyvp && ttycheckoutq(sess->s_ttyp, 0)) {
184                 flags |= TOTTY;
185                 tp = sess->s_ttyp;
186         }
187         __va_start(ap, fmt);
188         pca.tty = tp;
189         pca.flags = flags;
190         pca.pri = LOG_INFO;
191         retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
192         __va_end(ap);
193         msgbuftrigger = 1;
194         return (retval);
195 }
196
197 /*
198  * Ttyprintf displays a message on a tty; it should be used only by
199  * the tty driver, or anything that knows the underlying tty will not
200  * be revoke(2)'d away.  Other callers should use tprintf.
201  */
202 int
203 ttyprintf(struct tty *tp, const char *fmt, ...)
204 {
205         __va_list ap;
206         struct putchar_arg pca;
207         int retval;
208
209         __va_start(ap, fmt);
210         pca.tty = tp;
211         pca.flags = TOTTY;
212         retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
213         __va_end(ap);
214         return (retval);
215 }
216
217 /*
218  * Log writes to the log buffer, and guarantees not to sleep (so can be
219  * called by interrupt routines).  If there is no process reading the
220  * log yet, it writes to the console also.
221  */
222 int
223 log(int level, const char *fmt, ...)
224 {
225         __va_list ap;
226         int retval;
227         struct putchar_arg pca;
228
229         pca.tty = NULL;
230         pca.pri = level;
231         pca.flags = log_open ? TOLOG : TOCONS;
232
233         __va_start(ap, fmt);
234         retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
235         __va_end(ap);
236
237         msgbuftrigger = 1;
238         return (retval);
239 }
240
241 #define CONSCHUNK 128
242
243 void
244 log_console(struct uio *uio)
245 {
246         int c, i, error, iovlen, nl;
247         struct uio muio;
248         struct iovec *miov = NULL;
249         char *consbuffer;
250         int pri;
251
252         if (!log_console_output)
253                 return;
254
255         pri = LOG_INFO | LOG_CONSOLE;
256         muio = *uio;
257         iovlen = uio->uio_iovcnt * sizeof (struct iovec);
258         miov = kmalloc(iovlen, M_TEMP, M_WAITOK);
259         consbuffer = kmalloc(CONSCHUNK, M_TEMP, M_WAITOK);
260         bcopy((caddr_t)muio.uio_iov, (caddr_t)miov, iovlen);
261         muio.uio_iov = miov;
262         uio = &muio;
263
264         nl = 0;
265         while (uio->uio_resid > 0) {
266                 c = (int)szmin(uio->uio_resid, CONSCHUNK);
267                 error = uiomove(consbuffer, (size_t)c, uio);
268                 if (error != 0)
269                         break;
270                 for (i = 0; i < c; i++) {
271                         msglogchar(consbuffer[i], pri);
272                         if (consbuffer[i] == '\n')
273                                 nl = 1;
274                         else
275                                 nl = 0;
276                 }
277         }
278         if (!nl)
279                 msglogchar('\n', pri);
280         msgbuftrigger = 1;
281         kfree(miov, M_TEMP);
282         kfree(consbuffer, M_TEMP);
283         return;
284 }
285
286 /*
287  * Output to the console.
288  */
289 int
290 kprintf(const char *fmt, ...)
291 {
292         __va_list ap;
293         int savintr;
294         struct putchar_arg pca;
295         int retval;
296
297         savintr = consintr;             /* disable interrupts */
298         consintr = 0;
299         __va_start(ap, fmt);
300         pca.tty = NULL;
301         pca.flags = TOCONS | TOLOG;
302         pca.pri = -1;
303         retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
304         __va_end(ap);
305         if (!panicstr)
306                 msgbuftrigger = 1;
307         consintr = savintr;             /* reenable interrupts */
308         return (retval);
309 }
310
311 int
312 kvprintf(const char *fmt, __va_list ap)
313 {
314         int savintr;
315         struct putchar_arg pca;
316         int retval;
317
318         savintr = consintr;             /* disable interrupts */
319         consintr = 0;
320         pca.tty = NULL;
321         pca.flags = TOCONS | TOLOG;
322         pca.pri = -1;
323         retval = kvcprintf(fmt, kputchar, &pca, 10, ap);
324         if (!panicstr)
325                 msgbuftrigger = 1;
326         consintr = savintr;             /* reenable interrupts */
327         return (retval);
328 }
329
330 /*
331  * Limited rate kprintf.  The passed rate structure must be initialized
332  * with the desired reporting frequency.  A frequency of 0 will result in
333  * no output.
334  *
335  * count may be initialized to a negative number to allow an initial
336  * burst.
337  */
338 void
339 krateprintf(struct krate *rate, const char *fmt, ...)
340 {
341         __va_list ap;
342
343         if (rate->ticks != (int)time_second) {
344                 rate->ticks = (int)time_second;
345                 if (rate->count > 0)
346                         rate->count = 0;
347         }
348         if (rate->count < rate->freq) {
349                 ++rate->count;
350                 __va_start(ap, fmt);
351                 kvprintf(fmt, ap);
352                 __va_end(ap);
353         }
354 }
355
356 /*
357  * Print a character to the dmesg log, the console, and/or the user's
358  * terminal.
359  *
360  * NOTE: TOTTY does not require nonblocking operation, but TOCONS
361  *       and TOLOG do.  When we have a constty we still output to
362  *       the real console but we have a monitoring thread which
363  *       we wakeup which tracks the log.
364  */
365 static void
366 kputchar(int c, void *arg)
367 {
368         struct putchar_arg *ap = (struct putchar_arg*) arg;
369         int flags = ap->flags;
370         struct tty *tp = ap->tty;
371
372         if (panicstr)
373                 constty = NULL;
374         if ((flags & TOCONS) && tp == NULL && constty)
375                 flags |= TOLOG | TOWAKEUP;
376         if ((flags & TOTTY) && tputchar(c, tp) < 0)
377                 ap->flags &= ~TOTTY;
378         if ((flags & TOLOG))
379                 msglogchar(c, ap->pri);
380         if ((flags & TOCONS) && c)
381                 cnputc(c);
382         if (flags & TOWAKEUP)
383                 wakeup(constty_td);
384 }
385
386 /*
387  * Scaled down version of sprintf(3).
388  */
389 int
390 ksprintf(char *buf, const char *cfmt, ...)
391 {
392         int retval;
393         __va_list ap;
394
395         __va_start(ap, cfmt);
396         retval = kvcprintf(cfmt, NULL, buf, 10, ap);
397         buf[retval] = '\0';
398         __va_end(ap);
399         return (retval);
400 }
401
402 /*
403  * Scaled down version of vsprintf(3).
404  */
405 int
406 kvsprintf(char *buf, const char *cfmt, __va_list ap)
407 {
408         int retval;
409
410         retval = kvcprintf(cfmt, NULL, buf, 10, ap);
411         buf[retval] = '\0';
412         return (retval);
413 }
414
415 /*
416  * Scaled down version of snprintf(3).
417  */
418 int
419 ksnprintf(char *str, size_t size, const char *format, ...)
420 {
421         int retval;
422         __va_list ap;
423
424         __va_start(ap, format);
425         retval = kvsnprintf(str, size, format, ap);
426         __va_end(ap);
427         return(retval);
428 }
429
430 /*
431  * Scaled down version of vsnprintf(3).
432  */
433 int
434 kvsnprintf(char *str, size_t size, const char *format, __va_list ap)
435 {
436         struct snprintf_arg info;
437         int retval;
438
439         info.str = str;
440         info.remain = size;
441         retval = kvcprintf(format, snprintf_func, &info, 10, ap);
442         if (info.remain >= 1)
443                 *info.str++ = '\0';
444         return (retval);
445 }
446
447 int
448 ksnrprintf(char *str, size_t size, int radix, const char *format, ...)
449 {
450         int retval;
451         __va_list ap;
452
453         __va_start(ap, format);
454         retval = kvsnrprintf(str, size, radix, format, ap);
455         __va_end(ap);
456         return(retval);
457 }
458
459 int
460 kvsnrprintf(char *str, size_t size, int radix, const char *format, __va_list ap)
461 {
462         struct snprintf_arg info;
463         int retval;
464
465         info.str = str;
466         info.remain = size;
467         retval = kvcprintf(format, snprintf_func, &info, radix, ap);
468         if (info.remain >= 1)
469                 *info.str++ = '\0';
470         return (retval);
471 }
472
473 int
474 kvasnrprintf(char **strp, size_t size, int radix,
475              const char *format, __va_list ap)
476 {
477         struct snprintf_arg info;
478         int retval;
479
480         *strp = kmalloc(size, M_TEMP, M_WAITOK);
481         info.str = *strp;
482         info.remain = size;
483         retval = kvcprintf(format, snprintf_func, &info, radix, ap);
484         if (info.remain >= 1)
485                 *info.str++ = '\0';
486         return (retval);
487 }
488
489 void
490 kvasfree(char **strp)
491 {
492         if (*strp) {
493                 kfree(*strp, M_TEMP);
494                 *strp = NULL;
495         }
496 }
497
498 static void
499 snprintf_func(int ch, void *arg)
500 {
501         struct snprintf_arg *const info = arg;
502
503         if (info->remain >= 2) {
504                 *info->str++ = ch;
505                 info->remain--;
506         }
507 }
508
509 /*
510  * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
511  * order; return an optional length and a pointer to the last character
512  * written in the buffer (i.e., the first character of the string).
513  * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
514  */
515 static char *
516 ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
517 {
518         char *p, c;
519
520         p = nbuf;
521         *p = '\0';
522         do {
523                 c = hex2ascii(num % base);
524                 *++p = upper ? toupper(c) : c;
525         } while (num /= base);
526         if (lenp)
527                 *lenp = p - nbuf;
528         return (p);
529 }
530
531 /*
532  * Scaled down version of printf(3).
533  *
534  * Two additional formats:
535  *
536  * The format %b is supported to decode error registers.
537  * Its usage is:
538  *
539  *      kprintf("reg=%b\n", regval, "<base><arg>*");
540  *
541  * where <base> is the output base expressed as a control character, e.g.
542  * \10 gives octal; \20 gives hex.  Each arg is a sequence of characters,
543  * the first of which gives the bit number to be inspected (origin 1), and
544  * the next characters (up to a control character, i.e. a character <= 32),
545  * give the name of the register.  Thus:
546  *
547  *      kvcprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
548  *
549  * would produce output:
550  *
551  *      reg=3<BITTWO,BITONE>
552  */
553
554 #define PCHAR(c) {int cc=(c); if(func) (*func)(cc,arg); else *d++=cc; retval++;}
555
556 int
557 kvcprintf(char const *fmt, void (*func)(int, void*), void *arg,
558           int radix, __va_list ap)
559 {
560         char nbuf[MAXNBUF];
561         char *d;
562         const char *p, *percent, *q;
563         int ch, n;
564         uintmax_t num;
565         int base, tmp, width, ladjust, sharpflag, neg, sign, dot;
566         int cflag, hflag, jflag, lflag, qflag, tflag, zflag;
567         int dwidth, upper;
568         char padc;
569         int retval = 0, stop = 0;
570         int usespin;
571
572         /*
573          * Make a supreme effort to avoid reentrant panics or deadlocks.
574          *
575          * NOTE!  Do nothing that would access mycpu/gd/fs unless the
576          *        function is the normal kputchar(), which allows us to
577          *        use this function for very early debugging with a special
578          *        function.
579          */
580         if (func == kputchar) {
581                 if (mycpu->gd_flags & GDF_KPRINTF)
582                         return(0);
583                 atomic_set_long(&mycpu->gd_flags, GDF_KPRINTF);
584         }
585
586         num = 0;
587         if (!func)
588                 d = (char *) arg;
589         else
590                 d = NULL;
591
592         if (fmt == NULL)
593                 fmt = "(fmt null)\n";
594
595         if (radix < 2 || radix > 36)
596                 radix = 10;
597
598         usespin = (func == kputchar &&
599                    panic_cpu_gd != mycpu &&
600                    (((struct putchar_arg *)arg)->flags & TOTTY) == 0);
601         if (usespin) {
602                 crit_enter_hard();
603                 spin_lock(&cons_spin);
604         }
605
606         for (;;) {
607                 padc = ' ';
608                 width = 0;
609                 while ((ch = (u_char)*fmt++) != '%' || stop) {
610                         if (ch == '\0')
611                                 goto done;
612                         PCHAR(ch);
613                 }
614                 percent = fmt - 1;
615                 dot = dwidth = ladjust = neg = sharpflag = sign = upper = 0;
616                 cflag = hflag = jflag = lflag = qflag = tflag = zflag = 0;
617
618 reswitch:
619                 switch (ch = (u_char)*fmt++) {
620                 case '.':
621                         dot = 1;
622                         goto reswitch;
623                 case '#':
624                         sharpflag = 1;
625                         goto reswitch;
626                 case '+':
627                         sign = 1;
628                         goto reswitch;
629                 case '-':
630                         ladjust = 1;
631                         goto reswitch;
632                 case '%':
633                         PCHAR(ch);
634                         break;
635                 case '*':
636                         if (!dot) {
637                                 width = __va_arg(ap, int);
638                                 if (width < 0) {
639                                         ladjust = !ladjust;
640                                         width = -width;
641                                 }
642                         } else {
643                                 dwidth = __va_arg(ap, int);
644                         }
645                         goto reswitch;
646                 case '0':
647                         if (!dot) {
648                                 padc = '0';
649                                 goto reswitch;
650                         }
651                 case '1': case '2': case '3': case '4':
652                 case '5': case '6': case '7': case '8': case '9':
653                                 for (n = 0;; ++fmt) {
654                                         n = n * 10 + ch - '0';
655                                         ch = *fmt;
656                                         if (ch < '0' || ch > '9')
657                                                 break;
658                                 }
659                         if (dot)
660                                 dwidth = n;
661                         else
662                                 width = n;
663                         goto reswitch;
664                 case 'b':
665                         num = (u_int)__va_arg(ap, int);
666                         p = __va_arg(ap, char *);
667                         for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
668                                 PCHAR(*q--);
669
670                         if (num == 0)
671                                 break;
672
673                         for (tmp = 0; *p;) {
674                                 n = *p++;
675                                 if (num & (1 << (n - 1))) {
676                                         PCHAR(tmp ? ',' : '<');
677                                         for (; (n = *p) > ' '; ++p)
678                                                 PCHAR(n);
679                                         tmp = 1;
680                                 } else
681                                         for (; *p > ' '; ++p)
682                                                 continue;
683                         }
684                         if (tmp)
685                                 PCHAR('>');
686                         break;
687                 case 'c':
688                         PCHAR(__va_arg(ap, int));
689                         break;
690                 case 'd':
691                 case 'i':
692                         base = 10;
693                         sign = 1;
694                         goto handle_sign;
695                 case 'h':
696                         if (hflag) {
697                                 hflag = 0;
698                                 cflag = 1;
699                         } else
700                                 hflag = 1;
701                         goto reswitch;
702                 case 'j':
703                         jflag = 1;
704                         goto reswitch;
705                 case 'l':
706                         if (lflag) {
707                                 lflag = 0;
708                                 qflag = 1;
709                         } else
710                                 lflag = 1;
711                         goto reswitch;
712                 case 'n':
713                         if (cflag)
714                                 *(__va_arg(ap, char *)) = retval;
715                         else if (hflag)
716                                 *(__va_arg(ap, short *)) = retval;
717                         else if (jflag)
718                                 *(__va_arg(ap, intmax_t *)) = retval;
719                         else if (lflag)
720                                 *(__va_arg(ap, long *)) = retval;
721                         else if (qflag)
722                                 *(__va_arg(ap, quad_t *)) = retval;
723                         else
724                                 *(__va_arg(ap, int *)) = retval;
725                         break;
726                 case 'o':
727                         base = 8;
728                         goto handle_nosign;
729                 case 'p':
730                         base = 16;
731                         sharpflag = (width == 0);
732                         sign = 0;
733                         num = (uintptr_t)__va_arg(ap, void *);
734                         goto number;
735                 case 'q':
736                         qflag = 1;
737                         goto reswitch;
738                 case 'r':
739                         base = radix;
740                         if (sign)
741                                 goto handle_sign;
742                         goto handle_nosign;
743                 case 's':
744                         p = __va_arg(ap, char *);
745                         if (p == NULL)
746                                 p = "(null)";
747                         if (!dot)
748                                 n = strlen (p);
749                         else
750                                 for (n = 0; n < dwidth && p[n]; n++)
751                                         continue;
752
753                         width -= n;
754
755                         if (!ladjust && width > 0)
756                                 while (width--)
757                                         PCHAR(padc);
758                         while (n--)
759                                 PCHAR(*p++);
760                         if (ladjust && width > 0)
761                                 while (width--)
762                                         PCHAR(padc);
763                         break;
764                 case 't':
765                         tflag = 1;
766                         goto reswitch;
767                 case 'u':
768                         base = 10;
769                         goto handle_nosign;
770                 case 'X':
771                         upper = 1;
772                         /* FALLTHROUGH */
773                 case 'x':
774                         base = 16;
775                         goto handle_nosign;
776                 case 'z':
777                         zflag = 1;
778                         goto reswitch;
779 handle_nosign:
780                         sign = 0;
781                         if (cflag)
782                                 num = (u_char)__va_arg(ap, int);
783                         else if (hflag)
784                                 num = (u_short)__va_arg(ap, int);
785                         else if (jflag)
786                                 num = __va_arg(ap, uintmax_t);
787                         else if (lflag)
788                                 num = __va_arg(ap, u_long);
789                         else if (qflag)
790                                 num = __va_arg(ap, u_quad_t);
791                         else if (tflag)
792                                 num = __va_arg(ap, ptrdiff_t);
793                         else if (zflag)
794                                 num = __va_arg(ap, size_t);
795                         else
796                                 num = __va_arg(ap, u_int);
797                         goto number;
798 handle_sign:
799                         if (cflag)
800                                 num = (char)__va_arg(ap, int);
801                         else if (hflag)
802                                 num = (short)__va_arg(ap, int);
803                         else if (jflag)
804                                 num = __va_arg(ap, intmax_t);
805                         else if (lflag)
806                                 num = __va_arg(ap, long);
807                         else if (qflag)
808                                 num = __va_arg(ap, quad_t);
809                         else if (tflag)
810                                 num = __va_arg(ap, ptrdiff_t);
811                         else if (zflag)
812                                 num = __va_arg(ap, ssize_t);
813                         else
814                                 num = __va_arg(ap, int);
815 number:
816                         if (sign && (intmax_t)num < 0) {
817                                 neg = 1;
818                                 num = -(intmax_t)num;
819                         }
820                         p = ksprintn(nbuf, num, base, &n, upper);
821                         tmp = 0;
822                         if (sharpflag && num != 0) {
823                                 if (base == 8)
824                                         tmp++;
825                                 else if (base == 16)
826                                         tmp += 2;
827                         }
828                         if (neg)
829                                 tmp++;
830
831                         if (!ladjust && padc == '0')
832                                 dwidth = width - tmp;
833                         width -= tmp + imax(dwidth, n);
834                         dwidth -= n;
835                         if (!ladjust)
836                                 while (width-- > 0)
837                                         PCHAR(' ');
838                         if (neg)
839                                 PCHAR('-');
840                         if (sharpflag && num != 0) {
841                                 if (base == 8) {
842                                         PCHAR('0');
843                                 } else if (base == 16) {
844                                         PCHAR('0');
845                                         PCHAR('x');
846                                 }
847                         }
848                         while (dwidth-- > 0)
849                                 PCHAR('0');
850
851                         while (*p)
852                                 PCHAR(*p--);
853
854                         if (ladjust)
855                                 while (width-- > 0)
856                                         PCHAR(' ');
857
858                         break;
859                 default:
860                         while (percent < fmt)
861                                 PCHAR(*percent++);
862                         /*
863                          * Since we ignore an formatting argument it is no 
864                          * longer safe to obey the remaining formatting
865                          * arguments as the arguments will no longer match
866                          * the format specs.
867                          */
868                         stop = 1;
869                         break;
870                 }
871         }
872 done:
873         /*
874          * Cleanup reentrancy issues.
875          */
876         if (func == kputchar)
877                 atomic_clear_long(&mycpu->gd_flags, GDF_KPRINTF);
878         if (usespin) {
879                 spin_unlock(&cons_spin);
880                 crit_exit_hard();
881         }
882         return (retval);
883 }
884
885 #undef PCHAR
886
887 /*
888  * Called from the panic code to try to get the console working
889  * again in case we paniced inside a kprintf().
890  */
891 void
892 kvcreinitspin(void)
893 {
894         spin_init(&cons_spin);
895         atomic_clear_long(&mycpu->gd_flags, GDF_KPRINTF);
896 }
897
898 /*
899  * Console support thread for constty intercepts.  This is needed because
900  * console tty intercepts can block.  Instead of having kputchar() attempt
901  * to directly write to the console intercept we just force it to log
902  * and wakeup this baby to track and dump the log to constty.
903  */
904 static void
905 constty_daemon(void)
906 {
907         int rindex = -1;
908         int windex = -1;
909         struct msgbuf *mbp;
910         struct tty *tp;
911
912         EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc,
913                               constty_td, SHUTDOWN_PRI_FIRST);
914         constty_td->td_flags |= TDF_SYSTHREAD;
915
916         for (;;) {
917                 kproc_suspend_loop();
918
919                 crit_enter();
920                 mbp = msgbufp;
921                 if (mbp == NULL || msgbufmapped == 0 ||
922                     windex == mbp->msg_bufx) {
923                         tsleep(constty_td, 0, "waiting", hz*60);
924                         crit_exit();
925                         continue;
926                 }
927                 windex = mbp->msg_bufx;
928                 crit_exit();
929
930                 /*
931                  * Get message buf FIFO indices.  rindex is tracking.
932                  */
933                 if ((tp = constty) == NULL) {
934                         rindex = mbp->msg_bufx;
935                         continue;
936                 }
937
938                 /*
939                  * Don't blow up if the message buffer is broken
940                  */
941                 if (windex < 0 || windex >= mbp->msg_size)
942                         continue;
943                 if (rindex < 0 || rindex >= mbp->msg_size)
944                         rindex = windex;
945
946                 /*
947                  * And dump it.  If constty gets stuck will give up.
948                  */
949                 while (rindex != windex) {
950                         if (tputchar((uint8_t)mbp->msg_ptr[rindex], tp) < 0) {
951                                 constty = NULL;
952                                 rindex = mbp->msg_bufx;
953                                 break;
954                         }
955                         if (++rindex >= mbp->msg_size)
956                                 rindex = 0;
957                         if (tp->t_outq.c_cc >= tp->t_ohiwat) {
958                                 tsleep(constty_daemon, 0, "blocked", hz / 10);
959                                 if (tp->t_outq.c_cc >= tp->t_ohiwat) {
960                                         rindex = windex;
961                                         break;
962                                 }
963                         }
964                 }
965         }
966 }
967
968 static struct kproc_desc constty_kp = {
969         "consttyd",
970         constty_daemon,
971         &constty_td
972 };
973 SYSINIT(bufdaemon, SI_SUB_KTHREAD_UPDATE, SI_ORDER_ANY,
974         kproc_start, &constty_kp)
975
976 /*
977  * Put character in log buffer with a particular priority.
978  *
979  * MPSAFE
980  */
981 static void
982 msglogchar(int c, int pri)
983 {
984         static int lastpri = -1;
985         static int dangling;
986         char nbuf[MAXNBUF];
987         char *p;
988
989         if (!msgbufmapped)
990                 return;
991         if (c == '\0' || c == '\r')
992                 return;
993         if (pri != -1 && pri != lastpri) {
994                 if (dangling) {
995                         msgaddchar('\n', NULL);
996                         dangling = 0;
997                 }
998                 msgaddchar('<', NULL);
999                 for (p = ksprintn(nbuf, (uintmax_t)pri, 10, NULL, 0); *p;)
1000                         msgaddchar(*p--, NULL);
1001                 msgaddchar('>', NULL);
1002                 lastpri = pri;
1003         }
1004         msgaddchar(c, NULL);
1005         if (c == '\n') {
1006                 dangling = 0;
1007                 lastpri = -1;
1008         } else {
1009                 dangling = 1;
1010         }
1011 }
1012
1013 /*
1014  * Put char in log buffer.   Make sure nothing blows up beyond repair if
1015  * we have an MP race.
1016  *
1017  * MPSAFE.
1018  */
1019 static void
1020 msgaddchar(int c, void *dummy)
1021 {
1022         struct msgbuf *mbp;
1023         int rindex;
1024         int windex;
1025
1026         if (!msgbufmapped)
1027                 return;
1028         mbp = msgbufp;
1029         windex = mbp->msg_bufx;
1030         mbp->msg_ptr[windex] = c;
1031         if (++windex >= mbp->msg_size)
1032                 windex = 0;
1033         rindex = mbp->msg_bufr;
1034         if (windex == rindex) {
1035                 rindex += 32;
1036                 if (rindex >= mbp->msg_size)
1037                         rindex -= mbp->msg_size;
1038                 mbp->msg_bufr = rindex;
1039         }
1040         mbp->msg_bufx = windex;
1041 }
1042
1043 static void
1044 msgbufcopy(struct msgbuf *oldp)
1045 {
1046         int pos;
1047
1048         pos = oldp->msg_bufr;
1049         while (pos != oldp->msg_bufx) {
1050                 msglogchar(oldp->msg_ptr[pos], -1);
1051                 if (++pos >= oldp->msg_size)
1052                         pos = 0;
1053         }
1054 }
1055
1056 void
1057 msgbufinit(void *ptr, size_t size)
1058 {
1059         char *cp;
1060         static struct msgbuf *oldp = NULL;
1061
1062         size -= sizeof(*msgbufp);
1063         cp = (char *)ptr;
1064         msgbufp = (struct msgbuf *) (cp + size);
1065         if (msgbufp->msg_magic != MSG_MAGIC || msgbufp->msg_size != size ||
1066             msgbufp->msg_bufx >= size || msgbufp->msg_bufr >= size) {
1067                 bzero(cp, size);
1068                 bzero(msgbufp, sizeof(*msgbufp));
1069                 msgbufp->msg_magic = MSG_MAGIC;
1070                 msgbufp->msg_size = (char *)msgbufp - cp;
1071         }
1072         msgbufp->msg_ptr = cp;
1073         if (msgbufmapped && oldp != msgbufp)
1074                 msgbufcopy(oldp);
1075         msgbufmapped = 1;
1076         oldp = msgbufp;
1077 }
1078
1079 /* Sysctls for accessing/clearing the msgbuf */
1080
1081 static int
1082 sysctl_kern_msgbuf(SYSCTL_HANDLER_ARGS)
1083 {
1084         struct ucred *cred;
1085         int error;
1086
1087         /*
1088          * Only wheel or root can access the message log.
1089          */
1090         if (unprivileged_read_msgbuf == 0) {
1091                 KKASSERT(req->td->td_proc);
1092                 cred = req->td->td_proc->p_ucred;
1093
1094                 if ((cred->cr_prison || groupmember(0, cred) == 0) &&
1095                     priv_check(req->td, PRIV_ROOT) != 0
1096                 ) {
1097                         return (EPERM);
1098                 }
1099         }
1100
1101         /*
1102          * Unwind the buffer, so that it's linear (possibly starting with
1103          * some initial nulls).
1104          */
1105         error = sysctl_handle_opaque(oidp, msgbufp->msg_ptr + msgbufp->msg_bufx,
1106             msgbufp->msg_size - msgbufp->msg_bufx, req);
1107         if (error)
1108                 return (error);
1109         if (msgbufp->msg_bufx > 0) {
1110                 error = sysctl_handle_opaque(oidp, msgbufp->msg_ptr,
1111                     msgbufp->msg_bufx, req);
1112         }
1113         return (error);
1114 }
1115
1116 SYSCTL_PROC(_kern, OID_AUTO, msgbuf, CTLTYPE_STRING | CTLFLAG_RD,
1117     0, 0, sysctl_kern_msgbuf, "A", "Contents of kernel message buffer");
1118
1119 static int msgbuf_clear;
1120
1121 static int
1122 sysctl_kern_msgbuf_clear(SYSCTL_HANDLER_ARGS)
1123 {
1124         int error;
1125         error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
1126         if (!error && req->newptr) {
1127                 /* Clear the buffer and reset write pointer */
1128                 bzero(msgbufp->msg_ptr, msgbufp->msg_size);
1129                 msgbufp->msg_bufr = msgbufp->msg_bufx = 0;
1130                 msgbuf_clear = 0;
1131         }
1132         return (error);
1133 }
1134
1135 SYSCTL_PROC(_kern, OID_AUTO, msgbuf_clear,
1136     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE, &msgbuf_clear, 0,
1137     sysctl_kern_msgbuf_clear, "I", "Clear kernel message buffer");
1138
1139 #ifdef DDB
1140
1141 DB_SHOW_COMMAND(msgbuf, db_show_msgbuf)
1142 {
1143         int i, j;
1144
1145         if (!msgbufmapped) {
1146                 db_printf("msgbuf not mapped yet\n");
1147                 return;
1148         }
1149         db_printf("msgbufp = %p\n", msgbufp);
1150         db_printf("magic = %x, size = %d, r= %d, w = %d, ptr = %p\n",
1151             msgbufp->msg_magic, msgbufp->msg_size, msgbufp->msg_bufr,
1152             msgbufp->msg_bufx, msgbufp->msg_ptr);
1153         for (i = 0; i < msgbufp->msg_size; i++) {
1154                 j = (i + msgbufp->msg_bufr) % msgbufp->msg_size;
1155                 db_printf("%c", msgbufp->msg_ptr[j]);
1156         }
1157         db_printf("\n");
1158 }
1159
1160 #endif /* DDB */
1161
1162
1163 void
1164 hexdump(const void *ptr, int length, const char *hdr, int flags)
1165 {
1166         int i, j, k;
1167         int cols;
1168         const unsigned char *cp;
1169         char delim;
1170
1171         if ((flags & HD_DELIM_MASK) != 0)
1172                 delim = (flags & HD_DELIM_MASK) >> 8;
1173         else
1174                 delim = ' ';
1175
1176         if ((flags & HD_COLUMN_MASK) != 0)
1177                 cols = flags & HD_COLUMN_MASK;
1178         else
1179                 cols = 16;
1180
1181         cp = ptr;
1182         for (i = 0; i < length; i+= cols) {
1183                 if (hdr != NULL)
1184                         kprintf("%s", hdr);
1185
1186                 if ((flags & HD_OMIT_COUNT) == 0)
1187                         kprintf("%04x  ", i);
1188
1189                 if ((flags & HD_OMIT_HEX) == 0) {
1190                         for (j = 0; j < cols; j++) {
1191                                 k = i + j;
1192                                 if (k < length)
1193                                         kprintf("%c%02x", delim, cp[k]);
1194                                 else
1195                                         kprintf("   ");
1196                         }
1197                 }
1198
1199                 if ((flags & HD_OMIT_CHARS) == 0) {
1200                         kprintf("  |");
1201                         for (j = 0; j < cols; j++) {
1202                                 k = i + j;
1203                                 if (k >= length)
1204                                         kprintf(" ");
1205                                 else if (cp[k] >= ' ' && cp[k] <= '~')
1206                                         kprintf("%c", cp[k]);
1207                                 else
1208                                         kprintf(".");
1209                         }
1210                         kprintf("|");
1211                 }
1212                 kprintf("\n");
1213         }
1214 }