Esempio n. 1
0
/*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/
int
handle_return(int r, XFILE * X, unsigned char tag, dump_parser * p)
{
    u_int64 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;
    }
}
Esempio n. 2
0
/* 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;
}
Esempio n. 3
0
static afs_uint32
resync_vnode(XFILE * X, dump_parser * p, afs_vnode * v, int start, int limit)
{
    dt_uint64 where, expected_where;
    afs_uint32 r;
    int i;

    if ((r = xftell(X, &expected_where)))
	return r;
    cp64(where, expected_where);

    r = match_next_vnode(X, p, &where, v->vnode);
    if (r && r != DSERR_FMT)
	return r;
    if (r)
	for (i = -start; i < limit; i++) {
	    add64_32(where, expected_where, i);
	    r = match_next_vnode(X, p, &where, v->vnode);
	    if (!r)
		break;
	    if (r != DSERR_FMT)
		return r;
	}
    if (r) {
	if (p->cb_error)
	    (p->cb_error) (r, 1, p->err_refcon,
			   "Unable to resync after vnode %d [%s = 0x%s]",
			   v->vnode, decimate_int64(&expected_where, 0),
			   hexify_int64(&expected_where, 0));
	return r;
    }
    if (ne64(where, expected_where) && p->cb_error) {
	(p->cb_error) (DSERR_FMT, 0, p->err_refcon,
		       "Vnode after %d not in expected location", v->vnode);
	(p->cb_error) (DSERR_FMT, 0, p->err_refcon,
		       "Expected location: %s = 0x%s",
		       decimate_int64(&expected_where, 0),
		       hexify_int64(&expected_where, 0));
	(p->cb_error) (DSERR_FMT, 0, p->err_refcon,
		       "Actual location: %s = 0x%s", decimate_int64(&where,
								    0),
		       hexify_int64(&where, 0));
    }
    return xfseek(X, &where);
}
Esempio n. 4
0
/* do_seek for profiled xfiles */
static afs_uint32
xf_PROFILE_do_seek(XFILE * X, u_int64 * offset)
{
    PFILE *PF = X->refcon;
    afs_uint32 err;

    err = xfseek(&PF->content, offset);
    xfprintf(&PF->profile, "SEEK %s =%ld\n", hexify_int64(offset, 0),
	     (long)err);
    return err;
}
Esempio n. 5
0
/* do_tell for profiled xfiles */
static afs_uint32
xf_PROFILE_do_tell(XFILE * X, u_int64 * offset)
{
    PFILE *PF = X->refcon;
    afs_uint32 err;

    err = xftell(&PF->content, offset);
    if (err)
	xfprintf(&PF->profile, "TELL ERR =%ld\n", (long)err);
    else
	xfprintf(&PF->profile, "TELL %s =0\n", hexify_int64(offset, 0));
    return err;
}
Esempio n. 6
0
/* 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;
}
Esempio n. 7
0
/* Parse or skip over the vnode data */
static afs_uint32
parse_vdata(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_vnode *v = (afs_vnode *) l_refcon;
    static char *symlink_buf = 0;
    static int symlink_size = 0;
    afs_uint32 r;

    if ((r = ReadInt32(X, &v->size)))
	return r;
    v->field_mask |= F_VNODE_SIZE;

    if (v->size) {
	v->field_mask |= F_VNODE_DATA;
	if ((r = xftell(X, &v->d_offset)))
	    return r;
	if (p->print_flags & DSPRINT_VNODE)
	    printf("%s%d (0x%08x) bytes at %s (0x%s)\n", field->label,
		   v->size, v->size, decimate_int64(&v->d_offset, 0),
		   hexify_int64(&v->d_offset, 0));

	switch (v->type) {
	case vSymlink:
	    if (v->size > symlink_size) {
		if (symlink_buf)
		    symlink_buf = realloc(symlink_buf, v->size + 1);
		else
		    symlink_buf = (char *)malloc(v->size + 1);
		symlink_size = symlink_buf ? v->size : 0;
	    }
	    if (symlink_buf) {
		if ((r = xfread(X, symlink_buf, v->size)))
		    return r;
		symlink_buf[v->size] = 0;
		if (p->print_flags & DSPRINT_VNODE)
		    printf(" Target:       %s\n", symlink_buf);
	    } else {
		/* Call the callback here, because it's non-fatal */
		if (p->cb_error)
		    (p->cb_error) (ENOMEM, 0, p->err_refcon,
				   "Out of memory reading symlink");
		if ((r = xfskip(X, v->size)))
		    return r;
	    }
	    break;

	case vDirectory:
	    if (p->cb_dirent || (p->print_flags & DSPRINT_DIR)) {
		if ((r = parse_directory(X, p, v, v->size, 0)))
		    return r;
		break;
	    }

	default:
	    if ((r = xfskip(X, v->size)))
		return r;
	}
    } else if (p->print_flags & DSPRINT_VNODE) {
	printf("%sEmpty\n", field->label);
    }
    if (p->repair_flags & DSFIX_VDSYNC) {
	r = resync_vnode(X, p, v, 10, 15);
	if (r)
	    return r;
    }
    return ReadByte(X, tag);
}
Esempio n. 8
0
/* 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;
}