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