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.2 2005/03/07 05:05:04 dillon Exp $ 35 */ 36 37 #include "jscan.h" 38 39 static void dump_debug_stream(struct jstream *js); 40 static int dump_subrecord(struct jstream *js, off_t off, int recsize, int level); 41 static int dump_payload(int16_t rectype, struct jstream *js, off_t off, 42 int recsize, int level); 43 44 void 45 dump_debug(struct jfile *jf) 46 { 47 struct jstream *js; 48 49 while ((js = jscan_stream(jf)) != NULL) { 50 dump_debug_stream(js); 51 jscan_dispose(js); 52 } 53 } 54 55 static void 56 dump_debug_stream(struct jstream *js) 57 { 58 struct journal_rawrecbeg head; 59 int16_t sid; 60 61 jsread(js, 0, &head, sizeof(head)); 62 63 sid = head.streamid & JREC_STREAMID_MASK; 64 printf("STREAM %04x {\n", (int)(u_int16_t)head.streamid); 65 if (sid >= JREC_STREAMID_JMIN && sid < JREC_STREAMID_JMAX) { 66 dump_subrecord(js, sizeof(head), 67 head.recsize - sizeof(struct journal_rawrecbeg) - 68 sizeof(struct journal_rawrecend), 69 1); 70 } else { 71 switch(head.streamid & JREC_STREAMID_MASK) { 72 case JREC_STREAMID_SYNCPT & JREC_STREAMID_MASK: 73 printf(" SYNCPT\n"); 74 break; 75 case JREC_STREAMID_PAD & JREC_STREAMID_MASK: 76 printf(" PAD\n"); 77 break; 78 case JREC_STREAMID_DISCONT & JREC_STREAMID_MASK: 79 printf(" DISCONT\n"); 80 break; 81 case JREC_STREAMID_ANNOTATE & JREC_STREAMID_MASK: 82 printf(" ANNOTATION\n"); 83 break; 84 default: 85 printf(" UNKNOWN\n"); 86 break; 87 } 88 } 89 printf("}\n"); 90 } 91 92 static int 93 dump_subrecord(struct jstream *js, off_t off, int recsize, int level) 94 { 95 struct journal_subrecord sub; 96 int payload; 97 int subsize; 98 int error; 99 int i; 100 101 error = 0; 102 while (recsize > 0) { 103 if ((error = jsread(js, off, &sub, sizeof(sub))) != 0) 104 break; 105 printf("%*.*s", level * 4, level * 4, ""); 106 printf("@%lld ", off); 107 printf("RECORD %s [%04x/%d]", type_to_name(sub.rectype), 108 (int)(u_int16_t)sub.rectype, sub.recsize); 109 payload = sub.recsize - sizeof(sub); 110 subsize = (sub.recsize + 7) & ~7; 111 if (sub.rectype & JMASK_NESTED) { 112 printf(" {\n"); 113 if (payload) 114 error = dump_subrecord(js, off + sizeof(sub), payload, level + 1); 115 printf("%*.*s}\n", level * 4, level * 4, ""); 116 } else if (sub.rectype & JMASK_SUBRECORD) { 117 printf(" DATA (%d)", payload); 118 error = dump_payload(sub.rectype, js, off + sizeof(sub), payload, level); 119 printf("\n"); 120 if (error) 121 break; 122 } else { 123 printf("[unknown content]\n", sub.recsize); 124 } 125 if (subsize == 0) 126 subsize = sizeof(sub); 127 recsize -= subsize; 128 off += subsize; 129 } 130 return(error); 131 } 132 133 static int 134 dump_payload(int16_t rectype, struct jstream *js, off_t off, 135 int recsize, int level) 136 { 137 enum { DT_NONE, DT_STRING, DT_DEC, DT_HEX, DT_OCT, 138 DT_DATA, DT_TIMESTAMP } dt = DT_DATA; 139 const char *buf; 140 int didalloc; 141 int error; 142 int i; 143 int j; 144 145 error = jsreadp(js, off, (const void **)&buf, recsize); 146 if (error) 147 return (error); 148 149 switch(rectype & ~JMASK_LAST) { 150 case JLEAF_PAD: 151 case JLEAF_ABORT: 152 break; 153 case JLEAF_FILEDATA: 154 break; 155 case JLEAF_PATH1: 156 case JLEAF_PATH2: 157 case JLEAF_PATH3: 158 case JLEAF_PATH4: 159 dt = DT_STRING; 160 break; 161 case JLEAF_UID: 162 case JLEAF_GID: 163 dt = DT_DEC; 164 break; 165 case JLEAF_MODES: 166 dt = DT_OCT; 167 break; 168 case JLEAF_FFLAGS: 169 dt = DT_HEX; 170 break; 171 case JLEAF_PID: 172 case JLEAF_PPID: 173 dt = DT_DEC; 174 break; 175 case JLEAF_COMM: 176 dt = DT_STRING; 177 break; 178 case JLEAF_ATTRNAME: 179 dt = DT_STRING; 180 break; 181 case JLEAF_PATH_REF: 182 dt = DT_STRING; 183 break; 184 case JLEAF_RESERVED_0F: 185 break; 186 case JLEAF_SYMLINKDATA: 187 dt = DT_STRING; 188 break; 189 case JLEAF_SEEKPOS: 190 dt = DT_HEX; 191 break; 192 case JLEAF_INUM: 193 dt = DT_HEX; 194 break; 195 case JLEAF_NLINK: 196 dt = DT_DEC; 197 break; 198 case JLEAF_FSID: 199 dt = DT_HEX; 200 break; 201 case JLEAF_SIZE: 202 dt = DT_HEX; 203 break; 204 case JLEAF_ATIME: 205 case JLEAF_MTIME: 206 case JLEAF_CTIME: 207 dt = DT_TIMESTAMP; 208 break; 209 case JLEAF_GEN: 210 dt = DT_HEX; 211 break; 212 case JLEAF_FLAGS: 213 dt = DT_HEX; 214 break; 215 case JLEAF_UDEV: 216 dt = DT_HEX; 217 break; 218 case JLEAF_FILEREV: 219 dt = DT_HEX; 220 break; 221 default: 222 break; 223 } 224 switch(dt) { 225 case DT_NONE: 226 break; 227 case DT_STRING: 228 printf(" \""); 229 for (i = 0; i < recsize; ++i) 230 stringout(stdout, buf[i], 1); 231 printf("\""); 232 break; 233 case DT_DEC: 234 switch(recsize) { 235 case 1: 236 printf(" %d", (int)*(u_int8_t *)buf); 237 break; 238 case 2: 239 printf(" %d", (int)*(u_int16_t *)buf); 240 break; 241 case 4: 242 printf(" %d", (int)*(u_int32_t *)buf); 243 break; 244 case 8: 245 printf(" %d", (int64_t)*(u_int64_t *)buf); 246 break; 247 default: 248 printf(" ?"); 249 break; 250 } 251 break; 252 case DT_HEX: 253 switch(recsize) { 254 case 1: 255 printf(" 0x%02x", (int)*(u_int8_t *)buf); 256 break; 257 case 2: 258 printf(" 0x%04x", (int)*(u_int16_t *)buf); 259 break; 260 case 4: 261 printf(" 0x%08x", (int)*(u_int32_t *)buf); 262 break; 263 case 8: 264 printf(" 0x%016llx", (int64_t)*(u_int64_t *)buf); 265 break; 266 default: 267 printf(" ?"); 268 break; 269 } 270 break; 271 case DT_OCT: 272 switch(recsize) { 273 case 1: 274 printf(" %03o", (int)*(u_int8_t *)buf); 275 break; 276 case 2: 277 printf(" %06o", (int)*(u_int16_t *)buf); 278 break; 279 case 4: 280 printf(" %011o", (int)*(u_int32_t *)buf); 281 break; 282 case 8: 283 printf(" %022llo", (int64_t)*(u_int64_t *)buf); 284 break; 285 default: 286 printf(" ?"); 287 break; 288 } 289 break; 290 case DT_TIMESTAMP: 291 { 292 struct tm *tp; 293 time_t t = ((struct timespec *)buf)->tv_sec; 294 char outbuf[64]; 295 296 tp = localtime(&t); 297 strftime(outbuf, sizeof(outbuf), " <%d-%b-%Y %H:%M:%S>", tp); 298 printf("%s", outbuf); 299 } 300 break; 301 case DT_DATA: 302 default: 303 if (recsize < 16) { 304 for (i = 0; i < recsize; ++i) 305 printf(" %02x", (int)(unsigned char)buf[i]); 306 printf(" \""); 307 for (i = 0; i < recsize; ++i) 308 stringout(stdout, buf[i], 0); 309 printf("\""); 310 } else { 311 printf(" {\n"); 312 for (i = 0; i < recsize; i += 16) { 313 printf("%*.*s", level * 4 + 4, level * 4 + 4, ""); 314 for (j = i; j < i + 16 && j < recsize; ++j) 315 printf(" %02x", (int)(unsigned char)buf[j]); 316 for (; j < i + 16; ++j) 317 printf(" "); 318 printf(" \""); 319 for (j = i; j < i + 16 && j < recsize; ++j) 320 stringout(stdout, buf[j], 0); 321 printf("\"\n"); 322 } 323 printf("%*.*s}", level * 4, level * 4, ""); 324 } 325 break; 326 } 327 return (0); 328 } 329 330