a0ebe39d343f8e162d91d11255cae9cd08d2c410
[openafs.git] / src / tools / dumpscan.h
1 /*
2  * CMUCS AFStools
3  * dumpscan - routines for scanning and manipulating AFS volume dumps
4  *
5  * Copyright (c) 1998, 2001, 2003 Carnegie Mellon University
6  * All Rights Reserved.
7  *
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.
13  *
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.
17  *
18  * Carnegie Mellon requests users of this software to return to
19  *
20  *  Software Distribution Coordinator  or  Software_Distribution@CS.CMU.EDU
21  *  School of Computer Science
22  *  Carnegie Mellon University
23  *  Pittsburgh PA 15213-3890
24  *
25  * any improvements or extensions that they make and grant Carnegie Mellon
26  * the rights to redistribute these changes.
27  */
28
29 /* dumpscan.h - Public interface */
30
31 #ifndef _DUMPSCAN_H_
32 #define _DUMPSCAN_H_
33
34 #include "intNN.h"
35 #include "xfiles.h"
36
37 #include <lock.h>
38 #include <afs/afsint.h>
39 #include <afs/nfs.h>
40 #include <afs/ihandle.h>
41 #include <afs/vnode.h>
42
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;
49
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.
56  *
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.
60  *
61  * NB: These errors are now in dumpscan_errs.h
62  */
63
64
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
70  * to fill this in. */
71 typedef struct {
72   afs_uint32 version;
73   afs_uint32 from_date;
74   afs_uint32 to_date;
75   afs_uint32 dump_date;
76   afs_uint32 filenum;
77   unsigned char *server;
78   unsigned char *part;
79   unsigned char *volname;
80   afs_uint32 volid;
81   u_int64 dumplen;
82   afs_uint32 level;
83   afs_uint32 magic;
84   afs_uint32 cksum;
85   afs_uint32 flags;
86 } backup_system_header;
87
88
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
94 typedef struct {
95   u_int64 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 */
103 } afs_dump_header;
104
105
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
132 typedef struct {
133   u_int64 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 */
160 } afs_vol_header;
161
162
163 /** AFS vnode **/
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 */
179 typedef struct {
180   u_int64 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   u_int64 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];
198 } afs_vnode;
199
200
201 /** AFS directory entry **/
202 typedef struct {
203   int  slot;                /* Directory slot # (info only) */
204   char *name;               /* Name of entry */
205   afs_uint32 vnode;            /* Vnode number */
206   afs_uint32 uniq;             /* Uniquifier */
207 } afs_dir_entry;
208
209
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 {
227   void *err_refcon;
228   afs_uint32 (*cb_error)(afs_uint32, int, void *, char *, ...);
229   afs_uint32 flags;
230 #define TPFLAG_SKIP   0x0001
231 #define TPFLAG_RSKIP  0x0002
232   int shift_offset;
233   u_int64 shift_start;
234 };
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) */
242 };
243
244
245 /** Control structure for parsing volume dumps **/
246 typedef struct {
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.
258    */
259   void *refcon;
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    */
271
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 *, ...);
276
277   /* This function is called for each directory entry, if set */
278   afs_uint32 (*cb_dirent)(afs_vnode *, afs_dir_entry *, XFILE *, void *);
279
280   int flags;            /* Flags and options */
281 #define DSFLAG_SEEK     0x0001  /* Input file is seekable */
282
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 */
293
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 */
300
301   /** Things below this point for internal use only **/
302   afs_uint32 vol_uniquifier;
303 } dump_parser;
304
305
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   u_int64 v_offset;          /* Offset to start of vnode */
312   u_int64 d_offset;          /* Offset to data (0 if none) */
313   afs_uint32 d_size;            /* Size of data */
314 } vhash_ent;
315 typedef struct {
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 */
322 } path_hashinfo;
323
324
325 /** Function prototypes **/
326 /** Only the functions declared below are public interfaces **/
327 /** Maybe someday, I'll write man pages for these **/
328
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 *);
343
344 /* parsetag.c - Parse tagged data */
345 extern afs_uint32 ParseTaggedData(XFILE *, tagged_field *, unsigned char *,
346                            tag_parse_info *, void *, void *);
347
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 *);
352
353 /* backuphdr.c - Parse and print backup system headers */
354 extern void PrintBackupHdr(backup_system_header *);
355
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 *);
361
362
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);
372
373
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);
382
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);
388
389 #endif