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