Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tools / dumpscan / util.c
1 /*
2 * CMUCS AFStools
3 * dumpscan - routines for scanning and manipulating AFS volume dumps
4 *
5 * Copyright (c) 1998 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 /* util.c - Useful utilities */
30
31 #include <errno.h>
32
33 #include "xf_errs.h"
34 #include "dumpscan.h"
35 #include "dumpscan_errs.h"
36 #include "dumpfmt.h"
37
38
39 /* Take care of errno, ERROR_XFILE_EOF, and ENOMEM return codes.
40 * Call whatever callbacks are necessary, and return the code to
41 * actually use. If you don't want '0' to result in a DSERR_TAG,
42 * then you must translate it to DSERR_DONE before calling this.
43 */
44 /*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/
45 int
46 handle_return(int r, XFILE * X, unsigned char tag, dump_parser * p)
47 {
48 dt_uint64 where, xwhere;
49
50 switch (r) {
51 case 0:
52 if (p->cb_error) {
53 xftell(X, &where);
54 sub64_32(xwhere, where, 1);
55 (p->cb_error) (DSERR_TAG, 1, p->err_refcon,
56 (tag > 0x20 && tag < 0x7f)
57 ? "Unexpected tag '%c' at %s = 0x%s" :
58 "Unexpected tag 0x%02x at %s = 0x%s", tag,
59 decimate_int64(&xwhere, 0), hexify_int64(&xwhere,
60 0));
61 }
62 return DSERR_TAG;
63
64 case ERROR_XFILE_EOF:
65 if (p->cb_error) {
66 xftell(X, &where);
67 (p->cb_error) (ERROR_XFILE_EOF, 1, p->err_refcon,
68 "Unexpected EOF at %s = 0x%s",
69 decimate_int64(&where, 0), hexify_int64(&where,
70 0));
71 }
72 return ERROR_XFILE_EOF;
73
74 case ENOMEM:
75 if (p->cb_error) {
76 xftell(X, &where);
77 (p->cb_error) (ENOMEM, 1, p->err_refcon,
78 "Out of memory at %s = 0x%s",
79 decimate_int64(&where, 0), hexify_int64(&where,
80 0));
81 }
82 return ENOMEM;
83
84 case DSERR_DONE:
85 return 0;
86
87 default:
88 /* For other negative valuees, the callback was already done */
89 if (r > 0 && p->cb_error)
90 (p->cb_error) (r, 1, p->err_refcon,
91 "System error %d reading dump file", r);
92 return r;
93 }
94 }
95
96
97 /* Prepare a tag_parse_info for use by the dump parser. */
98 /* ** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ** */
99 void
100 prep_pi(dump_parser * p, tag_parse_info * pi)
101 {
102 memset(pi, 0, sizeof(tag_parse_info));
103 pi->err_refcon = p->err_refcon;
104 pi->cb_error = p->cb_error;
105
106 if (p->repair_flags & DSFIX_SKIP)
107 pi->flags |= TPFLAG_SKIP;
108 if ((p->flags & DSFLAG_SEEK) && (p->repair_flags & DSFIX_RSKIP))
109 pi->flags |= TPFLAG_RSKIP;
110 }
111
112
113 /* Does the designated location match a vnode?
114 * Returns 0 if yes, DSERR_FMT if no, something else on error
115 */
116 /*** THIS FUNCTION INTENDED FOR INTERNAL USE ONLY ***/
117 int
118 match_next_vnode(XFILE * X, dump_parser * p, dt_uint64 * where,
119 afs_uint32 vnode)
120 {
121 afs_uint32 r, x, y, z;
122 unsigned char tag;
123
124 if ((r = xfseek(X, where)))
125 return r;
126 if ((r = ReadByte(X, &tag)))
127 return r;
128 switch (tag) {
129 case 3: /* A vnode? */
130 if ((r = ReadInt32(X, &x)))
131 return r;
132 if ((r = ReadInt32(X, &y)))
133 return r;
134 if ((r = ReadByte(X, &tag)))
135 return r;
136 if (!((vnode & 1) && !(x & 1) && x < vnode)
137 && !((vnode & 1) == (x & 1) && x > vnode))
138 return DSERR_FMT;
139 if (x > vnode && x - vnode > 10000)
140 return DSERR_FMT;
141 if (y > p->vol_uniquifier)
142 return DSERR_FMT;
143
144 /* Now, what follows the vnode/uniquifier? */
145 switch (tag) {
146 case 3: /* Another vnode? - Only if this is a non-directory */
147 if (x & 1)
148 return DSERR_FMT;
149 if ((r = ReadInt32(X, &z)))
150 return r;
151 if (!((x & 1) && !(z & 1) && z < x)
152 && !((x & 1) == (z & 1) && z > x))
153 return DSERR_FMT;
154 return 0;
155
156 case 4: /* Dump end - Only if this is a non-directory */
157 if (x & 1)
158 return DSERR_FMT;
159 if ((r = ReadInt32(X, &z)))
160 return r;
161 if (z != DUMPENDMAGIC)
162 return DSERR_FMT;
163 return 0;
164
165 case 't': /* Vnode type byte */
166 if ((r = ReadByte(X, &tag)))
167 return r;
168 if ((tag == vFile || tag == vSymlink) && !(x & 1))
169 return 0;
170 if (tag == vDirectory && (x & 1))
171 return 0;
172 return DSERR_FMT;
173
174 default:
175 return DSERR_FMT;
176 }
177
178 case 4: /* A dump end? */
179 if ((r = ReadInt32(X, &x)))
180 return r;
181 if (x != DUMPENDMAGIC)
182 return DSERR_FMT;
183 return 0;
184
185 default:
186 return DSERR_FMT;
187 }
188 }