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