/* Parse a dump header, including its tagged attributes, and call the * dump-header callback, if one is defined. */ static afs_uint32 parse_dumphdr(XFILE * X, unsigned char *tag, tagged_field * field, afs_uint32 value, tag_parse_info * pi, void *g_refcon, void *l_refcon) { dump_parser *p = (dump_parser *) g_refcon; afs_dump_header hdr; dt_uint64 where; afs_uint32 r; memset(&hdr, 0, sizeof(hdr)); if ((r = xftell(X, &where))) return r; sub64_32(hdr.offset, where, 1); if ((r = ReadInt32(X, &hdr.magic))) return r; if ((r = ReadInt32(X, &hdr.version))) return r; if (hdr.magic != DUMPBEGINMAGIC) { if (p->cb_error) (p->cb_error) (DSERR_MAGIC, 1, p->err_refcon, "Invalid magic number (0x%08x) in dump header", hdr.magic); return DSERR_MAGIC; } if (hdr.version != DUMPVERSION) { if (p->cb_error) (p->cb_error) (DSERR_MAGIC, 1, p->err_refcon, "Unknown dump format version (%d) in dump header", hdr.version); return DSERR_MAGIC; } if (p->print_flags & DSPRINT_DUMPHDR) printf("%s [%s = 0x%s]\n", field->label, decimate_int64(&hdr.offset, 0), hexify_int64(&hdr.offset, 0)); if (p->print_flags & DSPRINT_DUMPHDR) { printf(" Magic number: 0x%08x\n", hdr.magic); printf(" Version: %d\n", hdr.version); } r = ParseTaggedData(X, dumphdr_fields, tag, pi, g_refcon, (void *)&hdr); if (!r && p->cb_dumphdr) { r = xftell(X, &where); if (!r) r = (p->cb_dumphdr) (&hdr, X, p->refcon); if (p->flags & DSFLAG_SEEK) { if (!r) r = xfseek(X, &where); else xfseek(X, &where); } } if (hdr.field_mask & F_DUMPHDR_VOLNAME) free(hdr.volname); return r; }
afs_uint32 ParseDumpFile(XFILE * X, dump_parser * p) { tag_parse_info pi; unsigned char tag; afs_uint32 r; prep_pi(p, &pi); r = ParseTaggedData(X, top_fields, &tag, &pi, (void *)p, 0); return handle_return(r, X, tag, p); }
/* Parse a volume header, including any tagged attributes, and call the * volume-header callback, if one is defined. */ afs_uint32 parse_volhdr(XFILE * X, unsigned char *tag, tagged_field * field, afs_uint32 value, tag_parse_info * pi, void *g_refcon, void *l_refcon) { dump_parser *p = (dump_parser *) g_refcon; afs_vol_header hdr; u_int64 where; afs_uint32 r; memset(&hdr, 0, sizeof(hdr)); if (r = xftell(X, &where)) return r; sub64_32(hdr.offset, where, 1); if (p->print_flags & DSPRINT_VOLHDR) printf("%s [%s = 0x%s]\n", field->label, decimate_int64(&hdr.offset, 0), hexify_int64(&hdr.offset, 0)); r = ParseTaggedData(X, volhdr_fields, tag, pi, g_refcon, (void *)&hdr); if (!r && p->cb_volhdr) { if (r = xftell(X, &where)) return r; r = (p->cb_volhdr) (&hdr, X, p->refcon); if (p->flags & DSFLAG_SEEK) { if (!r) r = xfseek(X, &where); else xfseek(X, &where); } } if (hdr.field_mask & F_VOLHDR_VOLUNIQ) p->vol_uniquifier = hdr.voluniq; if (hdr.field_mask & F_VOLHDR_VOLNAME) free(hdr.volname); if (hdr.field_mask & F_VOLHDR_OFFLINE_MSG) free(hdr.offline_msg); if (hdr.field_mask & F_VOLHDR_MOTD) free(hdr.motd_msg); return r; }
/* Parse a VNode, including any tagged attributes and data, and call the * appropriate callback, if one is defined. */ afs_uint32 parse_vnode(XFILE * X, unsigned char *tag, tagged_field * field, afs_uint32 value, tag_parse_info * pi, void *g_refcon, void *l_refcon) { dump_parser *p = (dump_parser *) g_refcon; afs_uint32(*cb) (afs_vnode *, XFILE *, void *); dt_uint64 where, offset2k; afs_vnode v; afs_uint32 r; if ((r = xftell(X, &where))) return r; memset(&v, 0, sizeof(v)); sub64_32(v.offset, where, 1); if ((r = ReadInt32(X, &v.vnode))) return r; if ((r = ReadInt32(X, &v.vuniq))) return r; mk64(offset2k, 0, 2048); if (!LastGoodVNode || ((p->flags & DSFLAG_SEEK) && v.vnode == 1 && lt64(v.offset, offset2k))) LastGoodVNode = -1; if (p->print_flags & DSPRINT_ITEM) { printf("%s %d/%d [%s = 0x%s]\n", field->label, v.vnode, v.vuniq, decimate_int64(&where, 0), hexify_int64(&where, 0)); } r = ParseTaggedData(X, vnode_fields, tag, pi, g_refcon, (void *)&v); /* Try to resync, if requested */ if (!r && (p->repair_flags & DSFIX_VFSYNC)) { afs_uint32 drop; dt_uint64 xwhere; if ((r = xftell(X, &where))) return r; sub64_32(xwhere, where, 1); /* Are we at the start of a valid vnode (or dump end)? */ r = match_next_vnode(X, p, &xwhere, v.vnode); if (r && r != DSERR_FMT) return r; if (r) { /* Nope. */ /* Was _this_ a valid vnode? If so, we can keep it and search for * the next one. Otherwise, we throw it out, and start the search * at the starting point of this vnode. */ drop = r = match_next_vnode(X, p, &v.offset, LastGoodVNode); if (r && r != DSERR_FMT) return r; if (!r) { add64_32(where, v.offset, 1); if ((r = xfseek(X, &v.offset))) return r; } else { if ((r = xfseek(X, &xwhere))) return r; } if ((r = resync_vnode(X, p, &v, 0, 1024))) return r; if ((r = ReadByte(X, tag))) return r; if (drop) { if (p->cb_error) (p->cb_error) (DSERR_FMT, 0, p->err_refcon, "Dropping vnode %d", v.vnode); return 0; } } else { if ((r = xfseek(X, &where))) return r; } } LastGoodVNode = v.vnode; if (!r) { if (v.field_mask & F_VNODE_TYPE) switch (v.type) { case vFile: cb = p->cb_vnode_file; break; case vDirectory: cb = p->cb_vnode_dir; break; case vSymlink: cb = p->cb_vnode_link; break; default: cb = p->cb_vnode_wierd; break; } else cb = p->cb_vnode_empty; if (cb) { dt_uint64 where; if ((r = xftell(X, &where))) return r; r = (cb) (&v, X, p->refcon); if (p->flags & DSFLAG_SEEK) { if (!r) r = xfseek(X, &where); else xfseek(X, &where); } } } return r; }