AMD64 - AUDIT RUN - Fix format strings, size_t, and other issues
[dragonfly.git] / sbin / jscan / dump_debug.c
1 /*
2  * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/sbin/jscan/dump_debug.c,v 1.7 2005/09/07 19:10:09 dillon Exp $
35  */
36
37 #include "jscan.h"
38
39 static void dump_debug_stream(struct jstream *js);
40 static int dump_debug_subrecord(struct jstream *js, off_t *off, 
41                                 off_t recsize, int level);
42 static int dump_debug_payload(int16_t rectype, struct jstream *js, off_t off, 
43                                  int recsize, int level);
44
45 void
46 dump_debug(struct jsession *ss, struct jdata *jd)
47 {
48     struct jstream *js;
49
50     if ((js = jaddrecord(ss, jd)) != NULL) {
51         dump_debug_stream(js);
52         jscan_dispose(js);
53     }
54     jsession_update_transid(ss, jd->jd_transid);
55 }
56
57 static void
58 dump_debug_stream(struct jstream *js)
59 {
60         struct journal_rawrecbeg head;
61         int16_t sid;
62
63         jsread(js, 0, &head, sizeof(head));
64
65         sid = head.streamid & JREC_STREAMID_MASK;
66         printf("STREAM %04x %016jx {\n",
67                (int)(u_int16_t)head.streamid,
68                (uintmax_t)head.transid);
69         if (sid >= JREC_STREAMID_JMIN && sid < JREC_STREAMID_JMAX) {
70             off_t off = sizeof(head);
71
72             dump_debug_subrecord(js, &off,
73                         js->js_normalized_total - sizeof(head),
74                         1);
75         } else {
76             switch(head.streamid & JREC_STREAMID_MASK) {
77             case JREC_STREAMID_SYNCPT & JREC_STREAMID_MASK:
78                 printf("    SYNCPT\n");
79                 break;
80             case JREC_STREAMID_PAD & JREC_STREAMID_MASK:
81                 printf("    PAD\n");
82                 break;
83             case JREC_STREAMID_DISCONT & JREC_STREAMID_MASK:
84                 printf("    DISCONT\n");
85                 break;
86             case JREC_STREAMID_ANNOTATE & JREC_STREAMID_MASK:
87                 printf("    ANNOTATION\n");
88                 break;
89             default:
90                 printf("    UNKNOWN\n");
91                 break;
92             }
93         }
94         printf("}\n");
95 }
96
97 static int
98 dump_debug_subrecord(struct jstream *js, off_t *off, off_t recsize, int level)
99 {
100     struct journal_subrecord sub;
101     int payload;
102     int subsize;
103     int error;
104     off_t base = *off;
105
106     error = 0;
107     while (recsize > 0) {
108         if ((error = jsread(js, base, &sub, sizeof(sub))) != 0) {
109             break;
110         }
111         printf("%*.*s", level * 4, level * 4, "");
112         printf("@%jd ", (intmax_t)base);
113         printf("RECORD %s [%04x/%d]", type_to_name(sub.rectype), 
114                                 (int)(u_int16_t)sub.rectype, sub.recsize);
115         if (sub.recsize == -1) {
116             if ((sub.rectype & JMASK_NESTED) == 0) {
117                 printf("Record size of -1 only works for nested records\n");
118                 error = -1;
119                 break;
120             }
121             payload = 0x7FFFFFFF;
122             subsize = 0x7FFFFFFF;
123         } else {
124             payload = sub.recsize - sizeof(sub);
125             subsize = (sub.recsize + 7) & ~7;
126         }
127         if (sub.rectype & JMASK_NESTED) {
128             printf(" {\n");
129             if (payload) {
130                 *off = base + sizeof(sub);
131                 error = dump_debug_subrecord(js, off, payload, level + 1);
132             }
133             printf("%*.*s}\n", level * 4, level * 4, "");
134         } else if (sub.rectype & JMASK_SUBRECORD) {
135             printf(" DATA (%d)", payload);
136             error = dump_debug_payload(sub.rectype, js, base + sizeof(sub), payload, level);
137             *off = base + sizeof(sub) + payload;
138             printf("\n");
139         } else {
140             printf("[%d bytes of unknown content]\n", sub.recsize);
141         }
142         if (error)
143             break;
144         if (sub.recsize == -1) {
145             recsize -= ((*off + 7) & ~7) - base;
146             base = (*off + 7) & ~7;
147         } else {
148             if (subsize == 0)
149                 subsize = sizeof(sub);
150             recsize -= subsize;
151             base += subsize;
152         }
153         if (sub.rectype & JMASK_LAST)
154                 break;
155     }
156     *off = base;
157     return(error);
158 }
159
160 static int
161 dump_debug_payload(int16_t rectype, struct jstream *js, off_t off, 
162              int recsize, int level)
163 {
164     enum { DT_NONE, DT_STRING, DT_DEC, DT_HEX, DT_OCT,
165            DT_DATA, DT_TIMESTAMP } dt = DT_DATA;
166     const char *buf;
167     int error;
168     int i;
169     int j;
170
171     error = jsreadp(js, off, (const void **)&buf, recsize);
172     if (error)
173         return (error);
174
175     switch(rectype & ~JMASK_LAST) {
176     case JLEAF_PAD:
177     case JLEAF_ABORT:
178         break;
179     case JLEAF_FILEDATA:
180         break;
181     case JLEAF_PATH1:
182     case JLEAF_PATH2:
183     case JLEAF_PATH3:
184     case JLEAF_PATH4:
185         dt = DT_STRING;
186         break;
187     case JLEAF_UID:
188     case JLEAF_GID:
189     case JLEAF_VTYPE:
190         dt = DT_DEC;
191         break;
192     case JLEAF_MODES:
193         dt = DT_OCT;
194         break;
195     case JLEAF_FFLAGS:
196         dt = DT_HEX;
197         break;
198     case JLEAF_PID:
199     case JLEAF_PPID:
200         dt = DT_DEC;
201         break;
202     case JLEAF_COMM:
203         dt = DT_STRING;
204         break;
205     case JLEAF_ATTRNAME:
206         dt = DT_STRING;
207         break;
208     case JLEAF_PATH_REF:
209         dt = DT_STRING;
210         break;
211     case JLEAF_RESERVED_0F:
212         break;
213     case JLEAF_SYMLINKDATA:
214         dt = DT_STRING;
215         break;
216     case JLEAF_SEEKPOS:
217         dt = DT_HEX;
218         break;
219     case JLEAF_INUM:
220         dt = DT_HEX;
221         break;
222     case JLEAF_NLINK:
223         dt = DT_DEC;
224         break;
225     case JLEAF_FSID:
226         dt = DT_HEX;
227         break;
228     case JLEAF_SIZE:
229         dt = DT_HEX;
230         break;
231     case JLEAF_ATIME:
232     case JLEAF_MTIME:
233     case JLEAF_CTIME:
234         dt = DT_TIMESTAMP;
235         break;
236     case JLEAF_GEN:
237         dt = DT_HEX;
238         break;
239     case JLEAF_FLAGS:
240         dt = DT_HEX;
241         break;
242     case JLEAF_UDEV:
243         dt = DT_HEX;
244         break;
245     case JLEAF_FILEREV:
246         dt = DT_HEX;
247         break;
248     default:
249         break;
250     }
251     switch(dt) {
252     case DT_NONE:
253         break;
254     case DT_STRING:
255         printf(" \"");
256         for (i = 0; i < recsize; ++i)
257             stringout(stdout, buf[i], 1);
258         printf("\"");
259         break;
260     case DT_DEC:
261         switch(recsize) {
262         case 1:
263             printf(" %d", (int)*(const u_int8_t *)buf);
264             break;
265         case 2:
266             printf(" %d", (int)*(const u_int16_t *)buf);
267             break;
268         case 4:
269             printf(" %d", (int)*(const u_int32_t *)buf);
270             break;
271         case 8:
272             printf(" %jd", (intmax_t)*(const int64_t *)buf);
273             break;
274         default:
275             printf(" ?");
276             break;
277         }
278         break;
279     case DT_HEX:
280         switch(recsize) {
281         case 1:
282             printf(" 0x%02x", (int)*(const u_int8_t *)buf);
283             break;
284         case 2:
285             printf(" 0x%04x", (int)*(const u_int16_t *)buf);
286             break;
287         case 4:
288             printf(" 0x%08x", (int)*(const u_int32_t *)buf);
289             break;
290         case 8:
291             printf(" 0x%016jx", (uintmax_t)*(const u_int64_t *)buf);
292             break;
293         default:
294             printf(" ?");
295             break;
296         }
297         break;
298     case DT_OCT:
299         switch(recsize) {
300         case 1:
301             printf(" %03o", (int)*(const u_int8_t *)buf);
302             break;
303         case 2:
304             printf(" %06o", (int)*(const u_int16_t *)buf);
305             break;
306         case 4:
307             printf(" %011o", (int)*(const u_int32_t *)buf);
308             break;
309         case 8:
310             printf(" %022jo", (intmax_t)*(const int64_t *)buf);
311             break;
312         default:
313             printf(" ?");
314             break;
315         }
316         break;
317     case DT_TIMESTAMP:
318         {
319             struct tm *tp;
320             time_t t = ((const struct timespec *)buf)->tv_sec;
321             char outbuf[64];
322
323             tp = localtime(&t);
324             strftime(outbuf, sizeof(outbuf), " <%d-%b-%Y %H:%M:%S>", tp);
325             printf("%s", outbuf);
326         }
327         break;
328     case DT_DATA:
329     default:
330         if (recsize < 16) {
331             for (i = 0; i < recsize; ++i)
332                 printf(" %02x", (int)(unsigned char)buf[i]);
333             printf(" \"");
334             for (i = 0; i < recsize; ++i)
335                 stringout(stdout, buf[i], 0);
336             printf("\"");
337         } else {
338             printf(" {\n");
339             for (i = 0; i < recsize; i += 16) {
340                 printf("%*.*s", level * 4 + 4, level * 4 + 4, "");
341                 for (j = i; j < i + 16 && j < recsize; ++j)
342                     printf(" %02x", (int)(unsigned char)buf[j]);
343                 for (; j < i + 16; ++j)
344                     printf("   ");
345                 printf(" \"");
346                 for (j = i; j < i + 16 && j < recsize; ++j)
347                     stringout(stdout, buf[j], 0);
348                 printf("\"\n");
349             }
350             printf("%*.*s}", level * 4, level * 4, "");
351         }
352         break;
353     }
354     return (0);
355 }
356