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
);