1 /*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char copyright[] =
10 "@(#) Copyright (c) 1991, 1993\n\
11 The Regents of the University of California. All rights reserved.\n";
12 #endif /* not lint */
13
14 #ifndef lint
15 static char sccsid[] = "@(#)dmesg.c 8.1 (Berkeley) 06/05/93";
16 #endif /* not lint */
17
18 #include <sys/cdefs.h>
19 #include <sys/msgbuf.h>
20
21 #include <fcntl.h>
22 #include <kvm.h>
23 #include <limits.h>
24 #include <nlist.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <vis.h>
30
31 struct nlist nl[] = {
32 #define X_MSGBUF 0
33 { "_msgbufp" },
34 { NULL },
35 };
36
37 void usage __P((void));
38
39 #define KREAD(addr, var) \
40 kvm_read(kd, addr, &var, sizeof(var)) != sizeof(var)
41
42 int
main(argc,argv)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[5];
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 if ((kd = kvm_open(nlistf, memf, NULL, O_RDONLY, "dmesg")) == NULL)
79 exit (1);
80 if (kvm_nlist(kd, nl) == -1)
81 errx(1, "kvm_nlist: %s", kvm_geterr(kd));
82 if (nl[X_MSGBUF].n_type == 0)
83 errx(1, "%s: msgbufp not found", nlistf ? nlistf : "namelist");
84 if (KREAD(nl[X_MSGBUF].n_value, bufp) || KREAD((long)bufp, cur))
85 errx(1, "kvm_read: %s", kvm_geterr(kd));
86 kvm_close(kd);
87 if (cur.msg_magic != MSG_MAGIC)
88 errx(1, "magic number incorrect");
89 if (cur.msg_bufx >= MSG_BSIZE)
90 cur.msg_bufx = 0;
91
92 /*
93 * The message buffer is circular; start at the read pointer, and
94 * go to the write pointer - 1.
95 */
96 p = cur.msg_bufc + cur.msg_bufx;
97 ep = cur.msg_bufc + cur.msg_bufx - 1;
98 for (newl = skip = 0; p != ep; ++p) {
99 if (p == cur.msg_bufc + MSG_BSIZE)
100 p = cur.msg_bufc;
101 ch = *p;
102 /* Skip "\n<.*>" syslog sequences. */
103 if (skip) {
104 if (ch == '>')
105 newl = skip = 0;
106 continue;
107 }
108 if (newl && ch == '<') {
109 skip = 1;
110 continue;
111 }
112 if (ch == '\0')
113 continue;
114 newl = ch == '\n';
115 (void)vis(buf, ch, 0, 0);
116 if (buf[1] == 0)
117 (void)putchar(buf[0]);
118 else
119 (void)printf("%s", buf);
120 }
121 if (!newl)
122 (void)putchar('\n');
123 exit(0);
124 }
125
126 void
usage()127 usage()
128 {
129 (void)fprintf(stderr, "usage: dmesg [-M core] [-N system]\n");
130 exit(1);
131 }
132