/* * CMUCS AFStools * dumpscan - routines for scanning and manipulating AFS volume dumps * * Copyright (c) 1998 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ /* util.c - Useful utilities */ #include #include "xf_errs.h" #include "dumpscan.h" #include "dumpscan_errs.h" #include "dumpfmt.h" /* Take care of errno, ERROR_XFILE_EOF, and ENOMEM return codes. * Call whatever callbacks are necessary, and return the code to * actually use. If you don't want '0' to result in a DSERR_TAG, * then you must translate it to DSERR_DONE before calling this. */ /*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/ int handle_return(int r, XFILE * X, unsigned char tag, dump_parser * p) { dt_uint64 where, xwhere; switch (r) { case 0: if (p->cb_error) { xftell(X, &where); sub64_32(xwhere, where, 1); (p->cb_error) (DSERR_TAG, 1, p->err_refcon, (tag > 0x20 && tag < 0x7f) ? "Unexpected tag '%c' at %s = 0x%s" : "Unexpected tag 0x%02x at %s = 0x%s", tag, decimate_int64(&xwhere, 0), hexify_int64(&xwhere, 0)); } return DSERR_TAG; case ERROR_XFILE_EOF: if (p->cb_error) { xftell(X, &where); (p->cb_error) (ERROR_XFILE_EOF, 1, p->err_refcon, "Unexpected EOF at %s = 0x%s", decimate_int64(&where, 0), hexify_int64(&where, 0)); } return ERROR_XFILE_EOF; case ENOMEM: if (p->cb_error) { xftell(X, &where); (p->cb_error) (ENOMEM, 1, p->err_refcon, "Out of memory at %s = 0x%s", decimate_int64(&where, 0), hexify_int64(&where, 0)); } return ENOMEM; case DSERR_DONE: return 0; default: /* For other negative valuees, the callback was already done */ if (r > 0 && p->cb_error) (p->cb_error) (r, 1, p->err_refcon, "System error %d reading dump file", r); return r; } } /* Prepare a tag_parse_info for use by the dump parser. */ /* ** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ** */ void prep_pi(dump_parser * p, tag_parse_info * pi) { memset(pi, 0, sizeof(tag_parse_info)); pi->err_refcon = p->err_refcon; pi->cb_error = p->cb_error; if (p->repair_flags & DSFIX_SKIP) pi->flags |= TPFLAG_SKIP; if ((p->flags & DSFLAG_SEEK) && (p->repair_flags & DSFIX_RSKIP)) pi->flags |= TPFLAG_RSKIP; } /* Does the designated location match a vnode? * Returns 0 if yes, DSERR_FMT if no, something else on error */ /*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/ int match_next_vnode(XFILE * X, dump_parser * p, dt_uint64 * where, afs_uint32 vnode) { afs_uint32 r, x, y, z; unsigned char tag; if ((r = xfseek(X, where))) return r; if ((r = ReadByte(X, &tag))) return r; switch (tag) { case 3: /* A vnode? */ if ((r = ReadInt32(X, &x))) return r; if ((r = ReadInt32(X, &y))) return r; if ((r = ReadByte(X, &tag))) return r; if (!((vnode & 1) && !(x & 1) && x < vnode) && !((vnode & 1) == (x & 1) && x > vnode)) return DSERR_FMT; if (x > vnode && x - vnode > 10000) return DSERR_FMT; if (y < 0 || y > p->vol_uniquifier) return DSERR_FMT; /* Now, what follows the vnode/uniquifier? */ switch (tag) { case 3: /* Another vnode? - Only if this is a non-directory */ if (x & 1) return DSERR_FMT; if ((r = ReadInt32(X, &z))) return r; if (!((x & 1) && !(z & 1) && z < x) && !((x & 1) == (z & 1) && z > x)) return DSERR_FMT; return 0; case 4: /* Dump end - Only if this is a non-directory */ if (x & 1) return DSERR_FMT; if ((r = ReadInt32(X, &z))) return r; if (z != DUMPENDMAGIC) return DSERR_FMT; return 0; case 't': /* Vnode type byte */ if ((r = ReadByte(X, &tag))) return r; if ((tag == vFile || tag == vSymlink) && !(x & 1)) return 0; if (tag == vDirectory && (x & 1)) return 0; return DSERR_FMT; default: return DSERR_FMT; } case 4: /* A dump end? */ if ((r = ReadInt32(X, &x))) return r; if (x != DUMPENDMAGIC) return DSERR_FMT; return 0; default: return DSERR_FMT; } }