3 * dumpscan - routines for scanning and manipulating AFS volume dumps
5 * Copyright (c) 1998 Carnegie Mellon University
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18 * Carnegie Mellon requests users of this software to return to
20 * Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
29 /* parsedump.c - Parse a volume dump file */
32 #include "dumpscan_errs.h"
37 static afs_uint32 parse_dumphdr(XFILE *, unsigned char *, tagged_field *,
38 afs_uint32, tag_parse_info *, void *, void *);
39 static afs_uint32 parse_dumpend(XFILE *, unsigned char *, tagged_field *,
40 afs_uint32, tag_parse_info *, void *, void *);
41 static afs_uint32 store_dumphdr(XFILE *, unsigned char *, tagged_field *,
42 afs_uint32, tag_parse_info *, void *, void *);
43 static afs_uint32 parse_dumptimes(XFILE *, unsigned char *, tagged_field *,
44 afs_uint32, tag_parse_info *, void *,
47 /** Field list for top-level objects **/
48 static tagged_field top_fields[] = {
49 {TAG_DUMPHEADER, DKIND_SPECIAL, "* DUMP HEADER", parse_dumphdr, 0, 0},
50 {TAG_VOLHEADER, DKIND_SPECIAL, "* VOLUME HEADER", parse_volhdr, 0, 0},
51 {TAG_VNODE, DKIND_SPECIAL, "* VNODE ", parse_vnode, 0, 0},
52 {TAG_DUMPEND, DKIND_INT32, "* DUMP END", parse_dumpend, 0, 0},
53 {STAGE_VERSMIN, DKIND_SPECIAL, "* STAGE HEADER", try_backuphdr, 0, 0},
58 /** Field list for dump headers **/
59 static tagged_field dumphdr_fields[] = {
60 {DHTAG_VOLNAME, DKIND_STRING, " Volume name: ", store_dumphdr, 0, 0},
61 {DHTAG_VOLID, DKIND_INT32, " Volume ID: ", store_dumphdr, 0, 0},
62 {DHTAG_DUMPTIMES, DKIND_SPECIAL, " Dump Range: ", parse_dumptimes, 0,
68 /* Parse a dump header, including its tagged attributes, and call the
69 * dump-header callback, if one is defined.
72 parse_dumphdr(XFILE * X, unsigned char *tag, tagged_field * field,
73 afs_uint32 value, tag_parse_info * pi, void *g_refcon,
76 dump_parser *p = (dump_parser *) g_refcon;
81 memset(&hdr, 0, sizeof(hdr));
82 if ((r = xftell(X, &where)))
84 sub64_32(hdr.offset, where, 1);
86 if ((r = ReadInt32(X, &hdr.magic)))
88 if ((r = ReadInt32(X, &hdr.version)))
91 if (hdr.magic != DUMPBEGINMAGIC) {
93 (p->cb_error) (DSERR_MAGIC, 1, p->err_refcon,
94 "Invalid magic number (0x%08x) in dump header",
98 if (hdr.version != DUMPVERSION) {
100 (p->cb_error) (DSERR_MAGIC, 1, p->err_refcon,
101 "Unknown dump format version (%d) in dump header",
106 if (p->print_flags & DSPRINT_DUMPHDR)
107 printf("%s [%s = 0x%s]\n", field->label,
108 decimate_int64(&hdr.offset, 0), hexify_int64(&hdr.offset, 0));
109 if (p->print_flags & DSPRINT_DUMPHDR) {
110 printf(" Magic number: 0x%08x\n", hdr.magic);
111 printf(" Version: %d\n", hdr.version);
113 r = ParseTaggedData(X, dumphdr_fields, tag, pi, g_refcon, (void *)&hdr);
115 if (!r && p->cb_dumphdr) {
116 r = xftell(X, &where);
118 r = (p->cb_dumphdr) (&hdr, X, p->refcon);
119 if (p->flags & DSFLAG_SEEK) {
121 r = xfseek(X, &where);
126 if (hdr.field_mask & F_DUMPHDR_VOLNAME)
132 /* Store tagged attributes into a dump header */
134 store_dumphdr(XFILE * X, unsigned char *tag, tagged_field * field,
135 afs_uint32 value, tag_parse_info * pi, void *g_refcon,
138 dump_parser *p = (dump_parser *) g_refcon;
139 afs_dump_header *hdr = (afs_dump_header *) l_refcon;
141 switch (field->tag) {
143 hdr->field_mask |= F_DUMPHDR_VOLID;
145 if (p->print_flags & DSPRINT_DUMPHDR)
146 printf("%s%d\n", field->label, hdr->volid);
151 hdr->field_mask |= F_DUMPHDR_VOLNAME;
153 if (p->print_flags & DSPRINT_DUMPHDR)
154 printf("%s%s\n", field->label, hdr->volname);
160 if (p->print_flags & DSPRINT_DUMPHDR)
161 printf("%s<<< UNKNOWN FIELD >>>\n", field->label);
167 /* Parse and store the dump time range from a dump header */
169 parse_dumptimes(XFILE * X, unsigned char *tag, tagged_field * field,
170 afs_uint32 value, tag_parse_info * pi, void *g_refcon,
173 dump_parser *p = (dump_parser *) g_refcon;
174 afs_dump_header *hdr = (afs_dump_header *) l_refcon;
178 if ((r = ReadInt16(X, &count)))
182 (p->cb_error) (DSERR_FMT, 1, p->err_refcon,
183 "Incorrect array count (%d) in dump times", count);
186 if ((r = ReadInt32(X, &hdr->from_date)))
188 if ((r = ReadInt32(X, &hdr->to_date)))
190 hdr->field_mask |= (F_DUMPHDR_FROM | F_DUMPHDR_TO);
191 if (p->print_flags & DSPRINT_DUMPHDR)
192 printf("%s%d => %d\n", field->label, hdr->from_date, hdr->to_date);
194 return ReadByte(X, tag);
198 /* Parse a dump_end record */
200 parse_dumpend(XFILE * X, unsigned char *tag, tagged_field * field,
201 afs_uint32 value, tag_parse_info * pi, void *g_refcon,
204 dump_parser *p = (dump_parser *) g_refcon;
206 if (value != DUMPENDMAGIC) {
208 (p->cb_error) (DSERR_MAGIC, 1, p->err_refcon,
209 "Invalid magic number (0x%08x) in dump trailer",
213 if (p->print_flags & (DSPRINT_DUMPHDR | DSPRINT_ITEM))
214 printf("%s\n", field->label);
221 ParseDumpFile(XFILE * X, dump_parser * p)
228 r = ParseTaggedData(X, top_fields, &tag, &pi, (void *)p, 0);
229 return handle_return(r, X, tag, p);
234 ParseDumpHeader(XFILE * X, dump_parser * p)
241 if ((r = ReadByte(X, &tag)))
242 return handle_return(r, X, tag, p);
243 if (tag != TAG_DUMPHEADER)
244 return handle_return(0, X, tag, p);
245 r = parse_dumphdr(X, &tag, &top_fields[0], 0, &pi, (void *)p, 0);
246 if (!r && tag >= 1 && tag <= 4)
248 return handle_return(r, X, tag, p);
253 ParseVolumeHeader(XFILE * X, dump_parser * p)
260 if ((r = ReadByte(X, &tag)))
261 return handle_return(r, X, tag, p);
262 if (tag != TAG_VOLHEADER)
263 return handle_return(0, X, tag, p);
264 r = parse_volhdr(X, &tag, &top_fields[1], 0, &pi, (void *)p, 0);
265 if (!r && tag >= 1 && tag <= 4)
267 return handle_return(r, X, tag, p);
272 ParseVNode(XFILE * X, dump_parser * p)
279 if ((r = ReadByte(X, &tag)))
280 return handle_return(r, X, tag, p);
281 if (tag != TAG_VNODE)
282 return handle_return(0, X, tag, p);
283 r = parse_vnode(X, &tag, &top_fields[2], 0, &pi, (void *)p, 0);
284 if (!r && tag >= 1 && tag <= 4)
286 return handle_return(r, X, tag, p);