xref: /original-bsd/sbin/dmesg/dmesg.c (revision 10042f30)
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