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