1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1991 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)dmesg.c 5.12 (Berkeley) 02/17/92"; 16 #endif /* not lint */ 17 18 #include <sys/cdefs.h> 19 #include <sys/msgbuf.h> 20 #include <time.h> 21 #include <nlist.h> 22 #include <kvm.h> 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <ctype.h> 26 27 struct nlist nl[] = { 28 #define X_MSGBUF 0 29 { "_msgbufp" }, 30 { NULL }, 31 }; 32 33 void usage(), vputc(); 34 void err __P((const char *, ...)); 35 36 main(argc, argv) 37 int argc; 38 char **argv; 39 { 40 register int ch, newl, skip; 41 register char *p, *ep; 42 struct msgbuf *bufp, cur; 43 char *memf, *nlistf; 44 45 memf = nlistf = NULL; 46 while ((ch = getopt(argc, argv, "M:N:")) != EOF) 47 switch(ch) { 48 case 'M': 49 memf = optarg; 50 break; 51 case 'N': 52 nlistf = optarg; 53 break; 54 case '?': 55 default: 56 usage(); 57 } 58 argc -= optind; 59 argv += optind; 60 61 /* 62 * Discard setgid privileges if not the running kernel so that bad 63 * guys can't print interesting stuff from kernel memory. 64 */ 65 if (memf != NULL || nlistf != NULL) 66 setgid(getgid()); 67 68 /* Read in kernel message buffer, do sanity checks. */ 69 if (kvm_openfiles(nlistf, memf, NULL) == -1) 70 err("kvm_openfiles: %s", kvm_geterr()); 71 if (kvm_nlist(nl) == -1) 72 err("kvm_nlist: %s", kvm_geterr()); 73 if (nl[X_MSGBUF].n_type == 0) 74 err("%s: msgbufp not found", nlistf ? nlistf : "namelist"); 75 76 kvm_read((void *)nl[X_MSGBUF].n_value, (void *)&bufp, sizeof(bufp)); 77 kvm_read((void *)bufp, (void *)&cur, sizeof(cur)); 78 if (cur.msg_magic != MSG_MAGIC) 79 err("magic number incorrect"); 80 if (cur.msg_bufx >= MSG_BSIZE) 81 cur.msg_bufx = 0; 82 83 /* 84 * The message buffer is circular; start at the read pointer, and 85 * go to the write pointer - 1. 86 */ 87 p = cur.msg_bufc + cur.msg_bufx; 88 ep = cur.msg_bufc + cur.msg_bufx - 1; 89 for (newl = skip = 0; p != ep; ++p) { 90 if (p == cur.msg_bufc + MSG_BSIZE) 91 p = cur.msg_bufc; 92 ch = *p; 93 /* Skip "\n<.*>" syslog sequences. */ 94 if (skip) { 95 if (ch == '>') 96 newl = skip = 0; 97 continue; 98 } 99 if (newl && ch == '<') { 100 skip = 1; 101 continue; 102 } 103 if (ch == '\0') 104 continue; 105 newl = (ch = *p) == '\n'; 106 vputc(ch); 107 } 108 if (!newl) 109 (void)putchar('\n'); 110 exit(0); 111 } 112 113 void 114 vputc(ch) 115 register int ch; 116 { 117 int meta; 118 119 if (!isascii(ch)) { 120 (void)putchar('M'); 121 (void)putchar('-'); 122 ch = toascii(ch); 123 meta = 1; 124 } else 125 meta = 0; 126 if (isprint(ch) || !meta && (ch == ' ' || ch == '\t' || ch == '\n')) 127 (void)putchar(ch); 128 else { 129 (void)putchar('^'); 130 (void)putchar(ch == '\177' ? '?' : ch | 0100); 131 } 132 } 133 134 #if __STDC__ 135 #include <stdarg.h> 136 #else 137 #include <varargs.h> 138 #endif 139 140 void 141 #if __STDC__ 142 err(const char *fmt, ...) 143 #else 144 err(fmt, va_alist) 145 char *fmt; 146 va_dcl 147 #endif 148 { 149 va_list ap; 150 #if __STDC__ 151 va_start(ap, fmt); 152 #else 153 va_start(ap); 154 #endif 155 (void)fprintf(stderr, "dmesg: "); 156 (void)vfprintf(stderr, fmt, ap); 157 va_end(ap); 158 (void)fprintf(stderr, "\n"); 159 exit(1); 160 /* NOTREACHED */ 161 } 162 163 void 164 usage() 165 { 166 (void)fprintf(stderr, "usage: dmesg [-M core] [-N system]\n"); 167 exit(1); 168 } 169