Commit | Line | Data |
---|---|---|
984263bc MD |
1 | /*- |
2 | * Copyright (c) 1991, 1993 | |
3 | * The Regents of the University of California. All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
dc71b7ab | 13 | * 3. Neither the name of the University nor the names of its contributors |
984263bc MD |
14 | * may be used to endorse or promote products derived from this software |
15 | * without specific prior written permission. | |
16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | |
1de703da MD |
28 | * |
29 | * @(#) Copyright (c) 1991, 1993 The Regents of the University of California. All rights reserved. | |
30 | * @(#)dmesg.c 8.1 (Berkeley) 6/5/93 | |
31 | * $FreeBSD: src/sbin/dmesg/dmesg.c,v 1.11.2.3 2001/08/08 22:32:15 obrien Exp $ | |
984263bc MD |
32 | */ |
33 | ||
984263bc MD |
34 | #include <sys/types.h> |
35 | #include <sys/msgbuf.h> | |
36 | #include <sys/sysctl.h> | |
37 | ||
38 | #include <err.h> | |
39 | #include <fcntl.h> | |
40 | #include <kvm.h> | |
41 | #include <locale.h> | |
42 | #include <stdio.h> | |
43 | #include <stdlib.h> | |
44 | #include <unistd.h> | |
45 | #include <vis.h> | |
46 | #include <sys/syslog.h> | |
47 | ||
48 | struct nlist nl[] = { | |
49 | #define X_MSGBUF 0 | |
f44d99cd CP |
50 | { "_msgbufp", 0, 0, 0, 0 }, |
51 | { NULL, 0, 0, 0, 0 }, | |
984263bc MD |
52 | }; |
53 | ||
d08d23b2 MD |
54 | static void dumpbuf(char *bp, size_t bufpos, size_t buflen, |
55 | int *newl, int *skip, int *pri); | |
9a76cd75 | 56 | void usage(void); |
984263bc MD |
57 | |
58 | #define KREAD(addr, var) \ | |
59 | kvm_read(kd, addr, &var, sizeof(var)) != sizeof(var) | |
60 | ||
d08d23b2 MD |
61 | #define INCRBUFSIZE 65536 |
62 | ||
63 | int all_opt; | |
64 | ||
984263bc | 65 | int |
b5744197 | 66 | main(int argc, char **argv) |
984263bc | 67 | { |
d08d23b2 | 68 | int newl, skip; |
984263bc MD |
69 | struct msgbuf *bufp, cur; |
70 | char *bp, *memf, *nlistf; | |
71 | kvm_t *kd; | |
d08d23b2 | 72 | int ch; |
f5c1f6e0 | 73 | int clear = 0; |
8af0d623 | 74 | int pri = 0; |
d08d23b2 | 75 | int tailmode = 0; |
a53014fb | 76 | int kno; |
f44d99cd | 77 | size_t buflen, bufpos; |
984263bc | 78 | |
7cee7052 | 79 | setlocale(LC_CTYPE, ""); |
984263bc | 80 | memf = nlistf = NULL; |
a53014fb | 81 | while ((ch = getopt(argc, argv, "acfM:N:n:")) != -1) { |
984263bc MD |
82 | switch(ch) { |
83 | case 'a': | |
d08d23b2 | 84 | all_opt++; |
984263bc | 85 | break; |
f5c1f6e0 EA |
86 | case 'c': |
87 | clear = 1; | |
88 | break; | |
d08d23b2 | 89 | case 'f': |
595fda35 | 90 | ++tailmode; |
d08d23b2 | 91 | break; |
984263bc MD |
92 | case 'M': |
93 | memf = optarg; | |
94 | break; | |
95 | case 'N': | |
96 | nlistf = optarg; | |
97 | break; | |
a53014fb MD |
98 | case 'n': |
99 | kno = strtol(optarg, NULL, 0); | |
100 | asprintf(&memf, "/var/crash/vmcore.%d", kno); | |
101 | asprintf(&nlistf, "/var/crash/kern.%d", kno); | |
102 | break; | |
984263bc MD |
103 | case '?': |
104 | default: | |
105 | usage(); | |
106 | } | |
d08d23b2 | 107 | } |
984263bc MD |
108 | argc -= optind; |
109 | argv += optind; | |
110 | ||
79ff9003 | 111 | newl = 1; |
d08d23b2 MD |
112 | skip = 0; |
113 | pri = 0; | |
114 | ||
115 | if (memf == NULL && nlistf == NULL && tailmode == 0) { | |
984263bc | 116 | /* Running kernel. Use sysctl. */ |
5608ef17 | 117 | buflen = 0; |
984263bc MD |
118 | if (sysctlbyname("kern.msgbuf", NULL, &buflen, NULL, 0) == -1) |
119 | err(1, "sysctl kern.msgbuf"); | |
9e900855 MD |
120 | if (buflen == 0) /* can happen if msgbuf was cleared */ |
121 | buflen = 1; | |
122 | ||
984263bc MD |
123 | if ((bp = malloc(buflen)) == NULL) |
124 | errx(1, "malloc failed"); | |
125 | if (sysctlbyname("kern.msgbuf", bp, &buflen, NULL, 0) == -1) | |
126 | err(1, "sysctl kern.msgbuf"); | |
127 | /* We get a dewrapped buffer using sysctl. */ | |
128 | bufpos = 0; | |
d08d23b2 | 129 | dumpbuf(bp, bufpos, buflen, &newl, &skip, &pri); |
984263bc | 130 | } else { |
5608ef17 MD |
131 | u_int rindex; |
132 | u_int xindex; | |
133 | u_int ri; | |
134 | u_int xi; | |
135 | u_int n; | |
136 | ||
984263bc MD |
137 | /* Read in kernel message buffer, do sanity checks. */ |
138 | kd = kvm_open(nlistf, memf, NULL, O_RDONLY, "dmesg"); | |
139 | if (kd == NULL) | |
140 | exit (1); | |
141 | if (kvm_nlist(kd, nl) == -1) | |
142 | errx(1, "kvm_nlist: %s", kvm_geterr(kd)); | |
143 | if (nl[X_MSGBUF].n_type == 0) | |
144 | errx(1, "%s: msgbufp not found", | |
145 | nlistf ? nlistf : "namelist"); | |
d08d23b2 MD |
146 | bp = malloc(INCRBUFSIZE); |
147 | if (!bp) | |
148 | errx(1, "malloc failed"); | |
149 | if (KREAD(nl[X_MSGBUF].n_value, bufp)) | |
150 | errx(1, "kvm_read: %s", kvm_geterr(kd)); | |
151 | if (KREAD((long)bufp, cur)) | |
984263bc | 152 | errx(1, "kvm_read: %s", kvm_geterr(kd)); |
5608ef17 | 153 | if (cur.msg_magic != MSG_MAGIC && cur.msg_magic != MSG_OMAGIC) |
984263bc MD |
154 | errx(1, "kernel message buffer has different magic " |
155 | "number"); | |
d08d23b2 MD |
156 | |
157 | /* | |
5608ef17 MD |
158 | * NOTE: current algorithm is compatible with both old and |
159 | * new msgbuf structures. The new structure doesn't | |
160 | * modulo the indexes (so we do), and adds a separate | |
161 | * log index which we don't access here. | |
d08d23b2 | 162 | */ |
5608ef17 | 163 | |
d08d23b2 | 164 | rindex = cur.msg_bufr; |
d08d23b2 MD |
165 | |
166 | for (;;) { | |
5608ef17 MD |
167 | /* |
168 | * Calculate index for dump and do sanity clipping. | |
169 | */ | |
170 | xindex = cur.msg_bufx; | |
171 | n = xindex - rindex; | |
172 | if (n > cur.msg_size - 1024) { | |
173 | rindex = xindex - cur.msg_size + 2048; | |
174 | n = xindex - rindex; | |
175 | } | |
176 | ri = rindex % cur.msg_size; | |
177 | xi = xindex % cur.msg_size; | |
178 | ||
179 | if (ri < xi) | |
180 | buflen = xi - ri; | |
d08d23b2 | 181 | else |
5608ef17 MD |
182 | buflen = cur.msg_size - ri; |
183 | if (buflen > n) | |
184 | buflen = n; | |
d08d23b2 MD |
185 | if (buflen > INCRBUFSIZE) |
186 | buflen = INCRBUFSIZE; | |
5608ef17 MD |
187 | |
188 | if (kvm_read(kd, (long)cur.msg_ptr + ri, | |
d08d23b2 MD |
189 | bp, buflen) != (ssize_t)buflen) { |
190 | errx(1, "kvm_read: %s", kvm_geterr(kd)); | |
191 | } | |
192 | if (buflen) | |
193 | dumpbuf(bp, 0, buflen, &newl, &skip, &pri); | |
5608ef17 MD |
194 | ri = (ri + buflen) % cur.msg_size; |
195 | n = n - buflen; | |
d08d23b2 | 196 | rindex += buflen; |
5608ef17 | 197 | if ((int)n <= 0) { |
d08d23b2 MD |
198 | if (tailmode == 0) |
199 | break; | |
80f63443 | 200 | fflush(stdout); |
595fda35 MD |
201 | if (tailmode == 1) |
202 | sleep(1); | |
d08d23b2 MD |
203 | } |
204 | if (KREAD((long)bufp, cur)) | |
205 | errx(1, "kvm_read: %s", kvm_geterr(kd)); | |
206 | } | |
984263bc | 207 | kvm_close(kd); |
984263bc | 208 | } |
d08d23b2 MD |
209 | if (!newl) |
210 | putchar('\n'); | |
211 | if (clear) { | |
212 | if (sysctlbyname("kern.msgbuf_clear", NULL, NULL, | |
213 | &clear, sizeof(int)) != 0) { | |
214 | err(1, "sysctl kern.msgbuf_clear"); | |
215 | } | |
216 | } | |
217 | return(0); | |
218 | } | |
219 | ||
220 | static | |
221 | void | |
222 | dumpbuf(char *bp, size_t bufpos, size_t buflen, | |
223 | int *newl, int *skip, int *pri) | |
224 | { | |
225 | int ch; | |
226 | char *p, *ep; | |
227 | char buf[5]; | |
984263bc MD |
228 | |
229 | /* | |
230 | * The message buffer is circular. If the buffer has wrapped, the | |
231 | * write pointer points to the oldest data. Otherwise, the write | |
232 | * pointer points to \0's following the data. Read the entire | |
233 | * buffer starting at the write pointer and ignore nulls so that | |
234 | * we effectively start at the oldest data. | |
235 | */ | |
236 | p = bp + bufpos; | |
237 | ep = (bufpos == 0 ? bp + buflen : p); | |
984263bc MD |
238 | do { |
239 | if (p == bp + buflen) | |
240 | p = bp; | |
241 | ch = *p; | |
242 | /* Skip "\n<.*>" syslog sequences. */ | |
d08d23b2 | 243 | if (*skip) { |
984263bc | 244 | if (ch == '\n') { |
d08d23b2 MD |
245 | *skip = 0; |
246 | *newl = 1; | |
984263bc | 247 | } if (ch == '>') { |
5608ef17 | 248 | if (LOG_FAC(*pri) == LOG_KERN) |
d08d23b2 | 249 | *newl = *skip = 0; |
984263bc | 250 | } else if (ch >= '0' && ch <= '9') { |
d08d23b2 MD |
251 | *pri *= 10; |
252 | *pri += ch - '0'; | |
984263bc MD |
253 | } |
254 | continue; | |
255 | } | |
5608ef17 | 256 | if (*newl && ch == '<' && all_opt == 0) { |
d08d23b2 MD |
257 | *pri = 0; |
258 | *skip = 1; | |
984263bc MD |
259 | continue; |
260 | } | |
261 | if (ch == '\0') | |
262 | continue; | |
5608ef17 | 263 | *newl = (ch == '\n'); |
7cee7052 | 264 | vis(buf, ch, 0, 0); |
984263bc | 265 | if (buf[1] == 0) |
7cee7052 | 266 | putchar(buf[0]); |
984263bc | 267 | else |
7cee7052 | 268 | printf("%s", buf); |
984263bc | 269 | } while (++p != ep); |
984263bc MD |
270 | } |
271 | ||
272 | void | |
b5744197 | 273 | usage(void) |
984263bc | 274 | { |
f5c1f6e0 | 275 | fprintf(stderr, "usage: dmesg [-ac] [-M core] [-N system]\n"); |
984263bc MD |
276 | exit(1); |
277 | } |