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