3 * dumpscan - routines for scanning and manipulating AFS volume dumps
5 * Copyright (c) 1998, 2001, 2003 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 /* dumpscan.h - Public interface */
38 #include <afs/afsint.h>
40 #include <afs/ihandle.h>
41 #include <afs/vnode.h>
43 /* Random useful types */
44 typedef struct tagged_field tagged_field;
45 typedef struct tag_parse_info tag_parse_info;
46 typedef afs_uint32 (*tag_parser)(XFILE *, unsigned char *, tagged_field *,
47 afs_uint32, tag_parse_info *, void *, void *);
48 typedef struct dir_state dir_state;
50 /* Error codes used within dumpscan.
51 * Any of the routines declared below, or callbacks used by them,
52 * may signal a system error by returning the error number, or
53 * some other error by returning a com_err code. Note that
54 * ParseTaggedData does _not_ return DSERR_TAG; instead, it returns
55 * 0, assuming the tag will be handled at a higher level.
57 * In addition, these errors may be reported to the caller of
58 * ParseDumpFile using the error callback. Such reports will be
59 * issued whether or not error recovery is possible or attempted.
61 * NB: These errors are now in dumpscan_errs.h
65 /* Backup system dump header */
66 /* Right now, this looks a lot like an old stage header. Eventually, it
67 * should contain enough fields to fully represent headers from old or
68 * new stage, Transarc, or other backup systems, and the appropriate read
69 * functions should extract as much data as possible from the actual file
77 unsigned char *server;
79 unsigned char *volname;
86 } backup_system_header;
89 /** AFS dump header **/
90 #define F_DUMPHDR_VOLID 0x00000001
91 #define F_DUMPHDR_VOLNAME 0x00000002
92 #define F_DUMPHDR_FROM 0x00000004
93 #define F_DUMPHDR_TO 0x00000008
95 dt_uint64 offset; /* Where in the input stream is it? */
96 afs_uint32 field_mask; /* What fields are present? */
97 afs_uint32 magic; /* Magic number */
98 afs_uint32 version; /* Dump format version */
99 afs_uint32 volid; /* VolID of volume in dump */
100 unsigned char *volname; /* Name of volume in dump */
101 afs_uint32 from_date; /* Reference date */
102 afs_uint32 to_date; /* Date of dump */
106 /** AFS volume header **/
107 #define F_VOLHDR_VOLID 0x00000001
108 #define F_VOLHDR_VOLVERS 0x00000002
109 #define F_VOLHDR_VOLNAME 0x00000004
110 #define F_VOLHDR_INSERV 0x00000008
111 #define F_VOLHDR_BLESSED 0x00000010
112 #define F_VOLHDR_VOLUNIQ 0x00000020
113 #define F_VOLHDR_VOLTYPE 0x00000040
114 #define F_VOLHDR_PARENT 0x00000080
115 #define F_VOLHDR_CLONE 0x00000100
116 #define F_VOLHDR_MAXQ 0x00000200
117 #define F_VOLHDR_MINQ 0x00000400
118 #define F_VOLHDR_DISKUSED 0x00000800
119 #define F_VOLHDR_NFILES 0x00001000
120 #define F_VOLHDR_ACCOUNT 0x00002000
121 #define F_VOLHDR_OWNER 0x00004000
122 #define F_VOLHDR_CREATE_DATE 0x00008000
123 #define F_VOLHDR_ACCESS_DATE 0x00010000
124 #define F_VOLHDR_UPDATE_DATE 0x00020000
125 #define F_VOLHDR_EXPIRE_DATE 0x00040000
126 #define F_VOLHDR_BACKUP_DATE 0x00080000
127 #define F_VOLHDR_OFFLINE_MSG 0x00100000
128 #define F_VOLHDR_MOTD 0x00200000
129 #define F_VOLHDR_WEEKUSE 0x00400000
130 #define F_VOLHDR_DAYUSE 0x00800000
131 #define F_VOLHDR_DAYUSE_DATE 0x01000000
133 dt_uint64 offset; /* Where in the input stream is it? */
134 afs_uint32 field_mask; /* What fields are present? */
135 afs_uint32 volid; /* Volume ID */
136 afs_uint32 volvers; /* ?? */
137 unsigned char *volname; /* Volume Name */
138 int flag_inservice; /* Inservice flag (0 or not) */
139 int flag_blessed; /* Blessed to come online (0 or not) */
140 afs_uint32 voluniq; /* Volume uniquifier */
141 int voltype; /* Volume type */
142 afs_uint32 parent_volid; /* Parent volume ID */
143 afs_uint32 clone_volid; /* Clone volume ID */
144 afs_uint32 maxquota; /* Max quota */
145 afs_uint32 minquota; /* Min quota (obsolete) */
146 afs_uint32 diskused; /* Disk blocks used */
147 afs_uint32 nfiles; /* Number of files in volume */
148 afs_uint32 account_no; /* Account number (unused) */
149 afs_uint32 owner; /* Volume owner */
150 afs_uint32 create_date; /* Creation date of this copy */
151 afs_uint32 access_date; /* Last access */
152 afs_uint32 update_date; /* Last modification */
153 afs_uint32 expire_date; /* Expiration (unused) */
154 afs_uint32 backup_date; /* Last backup clone */
155 unsigned char *offline_msg; /* Offline message */
156 unsigned char *motd_msg; /* Volume MOTD */
157 afs_uint32 weekuse[7]; /* Weekuse data */
158 afs_uint32 dayuse; /* # accesses in last day */
159 afs_uint32 dayuse_date; /* Date for which dayuse is valid */
164 #define F_VNODE_TYPE 0x00000001
165 #define F_VNODE_NLINKS 0x00000002
166 #define F_VNODE_PARENT 0x00000004
167 #define F_VNODE_DVERS 0x00000008
168 #define F_VNODE_AUTHOR 0x00000010
169 #define F_VNODE_OWNER 0x00000020
170 #define F_VNODE_GROUP 0x00000040
171 #define F_VNODE_MODE 0x00000080
172 #define F_VNODE_CDATE 0x00000100
173 #define F_VNODE_SDATE 0x00000200
174 #define F_VNODE_ACL 0x00000400
175 #define F_VNODE_SIZE 0x00000800 /* Set if size is present */
176 #define F_VNODE_DATA 0x00001000 /* Set if size nonzero and data present */
177 #define F_VNODE_PARTIAL 0x00002000 /* Partial vnode continuation (no header) */
178 #define F_VNODE_LINK_TARGET 0x00004000 /* Symlink target present */
180 dt_uint64 offset; /* Where in the input stream is it? */
181 afs_uint32 field_mask; /* What fields are present? */
182 afs_uint32 vnode; /* Vnode number */
183 afs_uint32 vuniq; /* Uniquifier */
184 int type; /* Vnode type */
185 afs_uint16 nlinks; /* Number of links (should be in 1 dir!) */
186 afs_uint32 parent; /* Parent vnode */
187 afs_uint32 datavers; /* Data version */
188 afs_uint32 author; /* Last writer */
189 afs_uint32 owner; /* Owner UID */
190 afs_uint32 group; /* Owning group */
191 afs_uint16 mode; /* UNIX mode bits */
192 afs_uint32 client_date; /* Last modified date from client */
193 afs_uint32 server_date; /* Last modified date on server */
194 afs_uint32 size; /* Size of data */
195 dt_uint64 d_offset; /* Where in the input stream is the data? */
196 char *link_target; /* Target of symbolic link */
197 unsigned char acl[SIZEOF_LARGEDISKVNODE - SIZEOF_SMALLDISKVNODE];
201 /** AFS directory entry **/
203 int slot; /* Directory slot # (info only) */
204 char *name; /* Name of entry */
205 afs_uint32 vnode; /* Vnode number */
206 afs_uint32 uniq; /* Uniquifier */
210 /** Tagged field definitions **/
211 #define DKIND_NOOP 0x00 /* No data */
212 #define DKIND_BYTE 0x10 /* 1 byte - decimal */
213 #define DKIND_HEX8 0x11 /* 1 byte - hex */
214 #define DKIND_CHAR 0x12 /* 1 byte - character */
215 #define DKIND_FLAG 0x13 /* 1 byte - true/false */
216 #define DKIND_INT16 0x20 /* 2 bytes - decimal */
217 #define DKIND_HEX16 0x21 /* 2 bytes - hex */
218 #define DKIND_OCT16 0x28 /* 2 bytes - octal */
219 #define DKIND_INT32 0x30 /* 4 bytes - decimal */
220 #define DKIND_HEX32 0x31 /* 4 bytes - hex */
221 #define DKIND_TIME 0x32 /* 4 bytes - time */
222 #define DKIND_OCT32 0x38 /* 4 bytes - octal */
223 #define DKIND_STRING 0x40 /* ASCIIZ string */
224 #define DKIND_SPECIAL 0x50 /* Custom parser */
225 #define DKIND_MASK (~0x0f)
226 struct tag_parse_info {
228 afs_uint32 (*cb_error)(afs_uint32, int, void *, char *, ...);
230 #define TPFLAG_SKIP 0x0001
231 #define TPFLAG_RSKIP 0x0002
233 dt_uint64 shift_start;
235 struct tagged_field {
236 char tag; /* Tag character */
237 int kind; /* Kind of object */
238 char *label; /* Label to use (for debugging) */
239 tag_parser func; /* Parser function (for DKIND_SPECIAL) */
240 void *refptr; /* Reference pointer (for parser's use) */
241 int refarg; /* Reference argument (for parser's use) */
245 /** Control structure for parsing volume dumps **/
247 /* Callback functions:
248 * Whenever a "complex" object is parsed, we call a callback function.
249 * The callback gets a pointer to the complex object, the file pointer
250 * for the dump we're parsing, and the value of refcon in this structure.
251 * Callbacks should return 0 if all is well, non-0 to abort the dump.
252 * By convention, positive numbers should be errno values, and negative
253 * numbers can be used for other things. It is OK to _try_ to seek anywhere
254 * in the file. Beware, though, that the input is not always seekable.
255 * Also, note that the structures passed to these callbacks are going to
256 * go away after the callback returns. There is no way to prevent this;
257 * make a copy if you want one.
260 afs_uint32 (*cb_bckhdr)(backup_system_header *, XFILE *, void *); /* Backup Header */
261 afs_uint32 (*cb_dumphdr)(afs_dump_header *, XFILE *, void *); /* Dump Header */
262 afs_uint32 (*cb_volhdr)(afs_vol_header *, XFILE *, void *); /* Volume Header */
263 afs_uint32 (*cb_vnode_dir)(afs_vnode *, XFILE *, void *); /* Directory Vnode */
264 afs_uint32 (*cb_vnode_file)(afs_vnode *, XFILE *, void *); /* File Vnode */
265 afs_uint32 (*cb_vnode_link)(afs_vnode *, XFILE *, void *); /* Symlink Vnode */
266 afs_uint32 (*cb_vnode_empty)(afs_vnode *, XFILE *, void *); /* vnode+uniq only */
267 afs_uint32 (*cb_vnode_wierd)(afs_vnode *, XFILE *, void *); /* Unknown type */
268 afs_uint32 (*cb_file_data)(afs_vnode *, XFILE *, void *); /* File Data */
269 afs_uint32 (*cb_dir_data)(afs_vnode *, XFILE *, void *); /* Directory Data */
270 afs_uint32 (*cb_link_data)(afs_vnode *, XFILE *, void *); /* Symlink Data */
272 /* This function is called when there is an error in the dump. */
273 /* (cb_error)(errno, fatal, refcon, msg_fmt, msg_args...) */
274 void *err_refcon; /* If set, use instead of refcon for dir entries */
275 afs_uint32 (*cb_error)(afs_uint32, int, void *, char *, ...);
277 /* This function is called for each directory entry, if set */
278 afs_uint32 (*cb_dirent)(afs_vnode *, afs_dir_entry *, XFILE *, void *);
280 int flags; /* Flags and options */
281 #define DSFLAG_SEEK 0x0001 /* Input file is seekable */
283 int print_flags; /* Flags to control what is printed */
284 #define DSPRINT_BCKHDR 0x0001 /* Print backup system header */
285 #define DSPRINT_DUMPHDR 0x0002 /* Print AFS dump header */
286 #define DSPRINT_VOLHDR 0x0004 /* Print AFS volume header */
287 #define DSPRINT_ITEM 0x0010 /* Print top-level tags */
288 #define DSPRINT_VNODE 0x0020 /* Print vnode attributes */
289 #define DSPRINT_ACL 0x0040 /* Print directory ACL's */
290 #define DSPRINT_DIR 0x0080 /* Print directory contents */
291 #define DSPRINT_DEBUG 0x0100 /* Print debugging info */
292 #define DSPRINT_PATH 0x0200 /* Print vnode paths */
294 int repair_flags; /* Flags to control what is repaired.
295 * Most of these _require_ DSFLAG_SEEK */
296 #define DSFIX_SKIP 0x0001 /* Try to skip null tags */
297 #define DSFIX_RSKIP 0x0002 /* Seek back to fing skipped tags */
298 #define DSFIX_VDSYNC 0x0004 /* Resync location after vnode data */
299 #define DSFIX_VFSYNC 0x0008 /* Try to resync after bad vnode */
301 /** Things below this point for internal use only **/
302 afs_uint32 vol_uniquifier;
306 /** Hash table and control info for pathname manipulation **/
307 typedef struct vhash_ent {
308 struct vhash_ent *next; /* Pointer to next entry */
309 afs_uint32 vnode; /* VNode number */
310 afs_uint32 parent; /* Parent VNode number */
311 dt_uint64 v_offset; /* Offset to start of vnode */
312 dt_uint64 d_offset; /* Offset to data (0 if none) */
313 afs_uint32 d_size; /* Size of data */
316 afs_uint32 n_vnodes; /* Number of vnodes in volume */
317 afs_uint32 n_dirs; /* Number of file vnodes */
318 afs_uint32 n_files; /* Number of directory vnodes */
319 int hash_size; /* Hash table size (bits) */
320 vhash_ent **hash_table; /* Hash table */
321 dump_parser *p; /* Dump parser to use */
325 /** Function prototypes **/
326 /** Only the functions declared below are public interfaces **/
327 /** Maybe someday, I'll write man pages for these **/
329 /* primitive.c - I/O primitives */
330 extern afs_uint32 ReadByte(XFILE *, unsigned char *);
331 extern afs_uint32 ReadInt16(XFILE *, afs_uint16 *);
332 extern afs_uint32 ReadInt32(XFILE *, afs_uint32 *);
333 extern afs_uint32 ReadString(XFILE *, unsigned char **);
334 extern afs_uint32 WriteByte(XFILE *, unsigned char);
335 extern afs_uint32 WriteInt16(XFILE *, afs_uint16);
336 extern afs_uint32 WriteInt32(XFILE *, afs_uint32);
337 extern afs_uint32 WriteString(XFILE *, unsigned char *);
338 extern afs_uint32 WriteTagByte(XFILE *, unsigned char, unsigned char);
339 extern afs_uint32 WriteTagInt16(XFILE *, unsigned char, afs_uint16);
340 extern afs_uint32 WriteTagInt32(XFILE *, unsigned char, afs_uint32);
341 extern afs_uint32 WriteTagInt32Pair(XFILE *, unsigned char, afs_uint32, afs_uint32);
342 extern afs_uint32 WriteTagString(XFILE *, unsigned char, unsigned char *);
344 /* parsetag.c - Parse tagged data */
345 extern afs_uint32 ParseTaggedData(XFILE *, tagged_field *, unsigned char *,
346 tag_parse_info *, void *, void *);
348 /* stagehdr.c - Parse and dump Stage dump headers */
349 extern afs_uint32 ParseStageHdr(XFILE *, unsigned char *, backup_system_header *);
350 extern afs_uint32 ParseStageV20Hdr(XFILE *, unsigned char *, backup_system_header *);
351 extern afs_uint32 DumpStageV20Hdr(XFILE *, backup_system_header *);
353 /* backuphdr.c - Parse and print backup system headers */
354 extern void PrintBackupHdr(backup_system_header *);
356 /* parsedump.c - Parse all or part of a volume dump */
357 extern afs_uint32 ParseDumpFile(XFILE *, dump_parser *);
358 extern afs_uint32 ParseDumpHeader(XFILE *, dump_parser *);
359 extern afs_uint32 ParseVolumeHeader(XFILE *, dump_parser *);
360 extern afs_uint32 ParseVNode(XFILE *, dump_parser *);
363 /* directory.c - Directory parsing, lookup, and generation */
364 extern afs_uint32 ParseDirectory(XFILE *, dump_parser *, afs_uint32, int);
365 extern afs_uint32 DirectoryLookup(XFILE *, dump_parser *, afs_uint32,
366 char **, afs_uint32 *, afs_uint32 *);
367 extern afs_uint32 Dir_Init(dir_state **);
368 extern afs_uint32 Dir_AddEntry(dir_state *, char *, afs_uint32, afs_uint32);
369 extern afs_uint32 Dir_Finalize(dir_state *);
370 extern afs_uint32 Dir_EmitData(dir_state *, XFILE *, int);
371 extern afs_uint32 Dir_Free(dir_state *ds);
374 /* dump.c - Dump parts of a volume dump */
375 extern afs_uint32 DumpDumpHeader(XFILE *, afs_dump_header *);
376 extern afs_uint32 DumpVolumeHeader(XFILE *, afs_vol_header *);
377 extern afs_uint32 DumpVNode(XFILE *, afs_vnode *);
378 extern afs_uint32 DumpVnodeData(XFILE *, char *, afs_uint32);
379 extern afs_uint32 CopyVnodeData(XFILE *, XFILE *, afs_uint32);
380 extern afs_uint32 DumpVNodeData(XFILE *OX, char *buf, afs_uint32 size);
381 extern afs_uint32 DumpDumpEnd(XFILE *OX);
383 /* pathname.c - Follow and construct pathnames */
384 extern afs_uint32 Path_PreScan(XFILE *, path_hashinfo *, int);
385 extern void Path_FreeHashTable(path_hashinfo *);
386 extern afs_uint32 Path_Follow(XFILE *, path_hashinfo *, char *, vhash_ent *);
387 extern afs_uint32 Path_Build(XFILE *, path_hashinfo *, afs_uint32, char **, int);