xref: /csrg-svn/sbin/dmesg/dmesg.c (revision 53677)
148128Sbostic /*-
248966Sbostic  * Copyright (c) 1991 The Regents of the University of California.
348128Sbostic  * All rights reserved.
448128Sbostic  *
548966Sbostic  * %sccs.include.redist.c%
622058Sdist  */
722058Sdist 
822058Sdist #ifndef lint
948128Sbostic char copyright[] =
1048966Sbostic "@(#) Copyright (c) 1991 The Regents of the University of California.\n\
1148128Sbostic  All rights reserved.\n";
1248128Sbostic #endif /* not lint */
1322058Sdist 
1448128Sbostic #ifndef lint
15*53677Sbostic static char sccsid[] = "@(#)dmesg.c	5.14 (Berkeley) 05/26/92";
1648128Sbostic #endif /* not lint */
1748128Sbostic 
1848966Sbostic #include <sys/cdefs.h>
196019Swnj #include <sys/msgbuf.h>
2053665Sbostic #include <fcntl.h>
2153665Sbostic #include <limits.h>
2248966Sbostic #include <time.h>
2337263Sbostic #include <nlist.h>
2448966Sbostic #include <kvm.h>
2548966Sbostic #include <stdlib.h>
2637263Sbostic #include <stdio.h>
2753665Sbostic #include <unistd.h>
2853665Sbostic #include <vis.h>
296019Swnj 
3048966Sbostic struct nlist nl[] = {
3148966Sbostic #define	X_MSGBUF	0
3252479Skarels 	{ "_msgbufp" },
3348966Sbostic 	{ NULL },
346019Swnj };
356019Swnj 
3648966Sbostic void err __P((const char *, ...));
3753665Sbostic void usage __P((void));
3848966Sbostic 
3953665Sbostic #define	KREAD(addr, var) \
40*53677Sbostic 	kvm_read(kd, addr, &var, sizeof(var)) != sizeof(var)
4153665Sbostic 
4253665Sbostic int
436019Swnj main(argc, argv)
4448966Sbostic 	int argc;
4553665Sbostic 	char *argv[];
466019Swnj {
4748966Sbostic 	register int ch, newl, skip;
4848966Sbostic 	register char *p, *ep;
4952479Skarels 	struct msgbuf *bufp, cur;
5052241Sbostic 	char *memf, *nlistf;
5153665Sbostic 	kvm_t *kd;
5253665Sbostic 	char buf[_POSIX2_LINE_MAX];
536019Swnj 
5452241Sbostic 	memf = nlistf = NULL;
5548966Sbostic 	while ((ch = getopt(argc, argv, "M:N:")) != EOF)
5648966Sbostic 		switch(ch) {
5748966Sbostic 		case 'M':
5852241Sbostic 			memf = optarg;
596019Swnj 			break;
6048966Sbostic 		case 'N':
6152241Sbostic 			nlistf = optarg;
6248966Sbostic 			break;
6348966Sbostic 		case '?':
6448966Sbostic 		default:
6548966Sbostic 			usage();
666019Swnj 		}
6748966Sbostic 	argc -= optind;
6848966Sbostic 	argv += optind;
6948966Sbostic 
7052241Sbostic 	/*
7152241Sbostic 	 * Discard setgid privileges if not the running kernel so that bad
7252241Sbostic 	 * guys can't print interesting stuff from kernel memory.
7352241Sbostic 	 */
7452241Sbostic 	if (memf != NULL || nlistf != NULL)
7552241Sbostic 		setgid(getgid());
7652241Sbostic 
7748966Sbostic 	/* Read in kernel message buffer, do sanity checks. */
7853665Sbostic 	buf[0] = 0;
7953665Sbostic 	kd = kvm_open(nlistf, memf, NULL, O_RDONLY, buf);
8053665Sbostic 	if (kd == NULL)
8153665Sbostic 		err("kvm_open: %s", buf);
8253665Sbostic 	if (kvm_nlist(kd, nl) == -1)
8353665Sbostic 		err("kvm_nlist: %s", kvm_geterr(kd));
8448966Sbostic 	if (nl[X_MSGBUF].n_type == 0)
8552545Storek 		err("%s: msgbufp not found", nlistf ? nlistf : "namelist");
8653665Sbostic 	if (KREAD(nl[X_MSGBUF].n_value, bufp) || KREAD((long)bufp, cur))
8753665Sbostic 		err("kvm_read: %s", kvm_geterr(kd));
8853665Sbostic 	kvm_close(kd);
8948966Sbostic 	if (cur.msg_magic != MSG_MAGIC)
9048966Sbostic 		err("magic number incorrect");
9148966Sbostic 	if (cur.msg_bufx >= MSG_BSIZE)
9248966Sbostic 		cur.msg_bufx = 0;
9348966Sbostic 
9448966Sbostic 	/*
9548966Sbostic 	 * The message buffer is circular; start at the read pointer, and
9648966Sbostic 	 * go to the write pointer - 1.
9748966Sbostic 	 */
9848966Sbostic 	p = cur.msg_bufc + cur.msg_bufx;
9948966Sbostic 	ep = cur.msg_bufc + cur.msg_bufx - 1;
10048966Sbostic 	for (newl = skip = 0; p != ep; ++p) {
10148966Sbostic 		if (p == cur.msg_bufc + MSG_BSIZE)
10248966Sbostic 			p = cur.msg_bufc;
10348966Sbostic 		ch = *p;
10448966Sbostic 		/* Skip "\n<.*>" syslog sequences. */
10548966Sbostic 		if (skip) {
10648966Sbostic 			if (ch == '>')
10748966Sbostic 				newl = skip = 0;
10848966Sbostic 			continue;
10948966Sbostic 		}
11048966Sbostic 		if (newl && ch == '<') {
11148966Sbostic 			skip = 1;
11248966Sbostic 			continue;
11348966Sbostic 		}
11448966Sbostic 		if (ch == '\0')
11548966Sbostic 			continue;
11653665Sbostic 		newl = ch == '\n';
11753665Sbostic 		(void) vis(buf, ch, 0, 0);
11853665Sbostic 		if (buf[1] == 0)
11953665Sbostic 			(void) putchar(buf[0]);
12053665Sbostic 		else
12153665Sbostic 			(void) fputs(buf, stdout);
12248966Sbostic 	}
12348966Sbostic 	if (!newl)
12448966Sbostic 		(void)putchar('\n');
12548966Sbostic 	exit(0);
1266019Swnj }
1276019Swnj 
12848966Sbostic #if __STDC__
12948966Sbostic #include <stdarg.h>
13048966Sbostic #else
13148966Sbostic #include <varargs.h>
13248966Sbostic #endif
13348966Sbostic 
13448966Sbostic void
13548966Sbostic #if __STDC__
13648966Sbostic err(const char *fmt, ...)
13748966Sbostic #else
13848966Sbostic err(fmt, va_alist)
13948966Sbostic 	char *fmt;
14048966Sbostic         va_dcl
14148966Sbostic #endif
1426019Swnj {
14348966Sbostic 	va_list ap;
14448966Sbostic #if __STDC__
14548966Sbostic 	va_start(ap, fmt);
14648966Sbostic #else
14748966Sbostic 	va_start(ap);
14848966Sbostic #endif
14948966Sbostic 	(void)fprintf(stderr, "dmesg: ");
15048966Sbostic 	(void)vfprintf(stderr, fmt, ap);
15148966Sbostic 	va_end(ap);
15248966Sbostic 	(void)fprintf(stderr, "\n");
15348966Sbostic 	exit(1);
15448966Sbostic 	/* NOTREACHED */
15548966Sbostic }
1566019Swnj 
15748966Sbostic void
15848966Sbostic usage()
15948966Sbostic {
16048966Sbostic 	(void)fprintf(stderr, "usage: dmesg [-M core] [-N system]\n");
16148966Sbostic 	exit(1);
1626019Swnj }
163