1 /* $NetBSD: dmesg.c,v 1.20 2000/06/20 01:49:20 simonb Exp $ */ 2 /*- 3 * Copyright (c) 1991, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 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 35 #include <sys/cdefs.h> 36 #ifndef lint 37 __COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\ 38 The Regents of the University of California. All rights reserved.\n"); 39 #endif /* not lint */ 40 41 #ifndef lint 42 #if 0 43 static char sccsid[] = "@(#)dmesg.c 8.1 (Berkeley) 6/5/93"; 44 #else 45 __RCSID("$NetBSD: dmesg.c,v 1.20 2000/06/20 01:49:20 simonb Exp $"); 46 #endif 47 #endif /* not lint */ 48 49 #include <sys/param.h> 50 #include <sys/msgbuf.h> 51 #include <sys/sysctl.h> 52 53 #include <err.h> 54 #include <fcntl.h> 55 #include <kvm.h> 56 #include <nlist.h> 57 #include <stdio.h> 58 #include <stddef.h> 59 #include <stdlib.h> 60 #include <unistd.h> 61 #include <vis.h> 62 63 #ifndef SMALL 64 struct nlist nl[] = { 65 #define X_MSGBUF 0 66 { "_msgbufp" }, 67 { NULL }, 68 }; 69 #endif 70 71 int main(int, char *[]); 72 void usage(void); 73 74 #define KREAD(addr, var) \ 75 kvm_read(kd, addr, &var, sizeof(var)) != sizeof(var) 76 77 int 78 main(int argc, char *argv[]) 79 { 80 struct kern_msgbuf cur; 81 int ch, newl, skip, i; 82 char *p, *bufdata; 83 #ifndef SMALL 84 char *memf, *nlistf; 85 #endif 86 char buf[5]; 87 88 #ifndef SMALL 89 memf = nlistf = NULL; 90 while ((ch = getopt(argc, argv, "M:N:")) != -1) 91 switch(ch) { 92 case 'M': 93 memf = optarg; 94 break; 95 case 'N': 96 nlistf = optarg; 97 break; 98 case '?': 99 default: 100 usage(); 101 } 102 argc -= optind; 103 argv += optind; 104 105 if (memf == NULL) { 106 #endif 107 size_t size; 108 int mib[2]; 109 110 mib[0] = CTL_KERN; 111 mib[1] = KERN_MSGBUF; 112 113 if (sysctl(mib, 2, NULL, &size, NULL, 0) == -1) 114 errx(1, "can't get size of msgbuf"); 115 116 if ((bufdata = malloc(size)) == NULL) 117 err(1, "couldn't allocate space for buffer data"); 118 119 if (sysctl(mib, 2, bufdata, &size, NULL, 0) == -1) 120 err(1, "can't get msgbuf"); 121 122 /* make a dummy struct msgbuf for the display logic */ 123 cur.msg_bufx = cur.msg_bufs = size; 124 #ifndef SMALL 125 } else { 126 kvm_t *kd; 127 struct kern_msgbuf *bufp; 128 129 /* 130 * Read in message buffer header and data, and do sanity 131 * checks. 132 */ 133 kd = kvm_open(nlistf, memf, NULL, O_RDONLY, "dmesg"); 134 if (kd == NULL) 135 exit (1); 136 if (kvm_nlist(kd, nl) == -1) 137 errx(1, "kvm_nlist: %s", kvm_geterr(kd)); 138 if (nl[X_MSGBUF].n_type == 0) 139 errx(1, "%s: msgbufp not found", nlistf ? nlistf : 140 "namelist"); 141 if (KREAD(nl[X_MSGBUF].n_value, bufp)) 142 errx(1, "kvm_read: %s (0x%lx)", kvm_geterr(kd), 143 nl[X_MSGBUF].n_value); 144 if (kvm_read(kd, (long)bufp, &cur, 145 offsetof(struct kern_msgbuf, msg_bufc)) != 146 offsetof(struct kern_msgbuf, msg_bufc)) 147 errx(1, "kvm_read: %s (0x%lx)", kvm_geterr(kd), 148 (unsigned long)bufp); 149 if (cur.msg_magic != MSG_MAGIC) 150 errx(1, "magic number incorrect"); 151 bufdata = malloc(cur.msg_bufs); 152 if (bufdata == NULL) 153 errx(1, "couldn't allocate space for buffer data"); 154 if (kvm_read(kd, (long)&bufp->msg_bufc, bufdata, 155 cur.msg_bufs) != cur.msg_bufs) 156 errx(1, "kvm_read: %s", kvm_geterr(kd)); 157 kvm_close(kd); 158 if (cur.msg_bufx >= cur.msg_bufs) 159 cur.msg_bufx = 0; 160 } 161 #endif 162 163 /* 164 * The message buffer is circular; start at the write pointer 165 * (which points the oldest character), and go to the write 166 * pointer - 1 (which points the newest character). I.e, loop 167 * over cur.msg_bufs times. Unused area is skipped since it 168 * contains nul. 169 */ 170 for (newl = skip = i = 0, p = bufdata + cur.msg_bufx; 171 i < cur.msg_bufs; i++, p++) { 172 if (p == bufdata + cur.msg_bufs) 173 p = bufdata; 174 ch = *p; 175 /* Skip "\n<.*>" syslog sequences. */ 176 if (skip) { 177 if (ch == '>') 178 newl = skip = 0; 179 continue; 180 } 181 if (newl && ch == '<') { 182 skip = 1; 183 continue; 184 } 185 if (ch == '\0') 186 continue; 187 newl = ch == '\n'; 188 (void)vis(buf, ch, 0, 0); 189 if (buf[1] == 0) 190 (void)putchar(buf[0]); 191 else 192 (void)printf("%s", buf); 193 } 194 if (!newl) 195 (void)putchar('\n'); 196 exit(0); 197 } 198 199 void 200 usage(void) 201 { 202 203 #ifdef SMALL 204 (void)fprintf(stderr, "usage: dmesg\n"); 205 #else 206 (void)fprintf(stderr, "usage: dmesg [-M core] [-N system]\n"); 207 #endif 208 exit(1); 209 } 210