Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tools / dumpscan / parsevol.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 /* parsevol.c - Parse a volume header */
30
31 #include "dumpscan.h"
32 #include "dumpscan_errs.h"
33 #include "dumpfmt.h"
34
35 static afs_uint32 store_volhdr(XFILE *, unsigned char *, tagged_field *,
36 afs_uint32, tag_parse_info *, void *, void *);
37 static afs_uint32 parse_weekuse(XFILE *, unsigned char *, tagged_field *,
38 afs_uint32, tag_parse_info *, void *, void *);
39
40 /** Field list for volume headers **/
41 static tagged_field volhdr_fields[] = {
42 {VHTAG_VOLID, DKIND_INT32, " Volume ID: ", store_volhdr, 0, 0},
43 {VHTAG_VERS, DKIND_INT32, " Version: ", store_volhdr, 0, 0},
44 {VHTAG_VOLNAME, DKIND_STRING, " Volume name: ", store_volhdr, 0, 0},
45 {VHTAG_INSERV, DKIND_FLAG, " In service? ", store_volhdr, 0, 0},
46 {VHTAG_BLESSED, DKIND_FLAG, " Blessed? ", store_volhdr, 0, 0},
47 {VHTAG_VUNIQ, DKIND_INT32, " Uniquifier: ", store_volhdr, 0, 0},
48 {VHTAG_TYPE, DKIND_BYTE, " Type: ", store_volhdr, 0, 0},
49 {VHTAG_PARENT, DKIND_INT32, " Parent ID: ", store_volhdr, 0, 0},
50 {VHTAG_CLONE, DKIND_INT32, " Clone ID: ", store_volhdr, 0, 0},
51 {VHTAG_MAXQUOTA, DKIND_INT32, " Max quota: ", store_volhdr, 0, 0},
52 {VHTAG_MINQUOTA, DKIND_INT32, " Min quota: ", store_volhdr, 0, 0},
53 {VHTAG_DISKUSED, DKIND_INT32, " Disk used: ", store_volhdr, 0, 0},
54 {VHTAG_FILECNT, DKIND_INT32, " File count: ", store_volhdr, 0, 0},
55 {VHTAG_ACCOUNT, DKIND_INT32, " Account: ", store_volhdr, 0, 0},
56 {VHTAG_OWNER, DKIND_INT32, " Owner: ", store_volhdr, 0, 0},
57 {VHTAG_CREAT, DKIND_TIME, " Created: ", store_volhdr, 0, 0},
58 {VHTAG_ACCESS, DKIND_TIME, " Accessed: ", store_volhdr, 0, 0},
59 {VHTAG_UPDATE, DKIND_TIME, " Updated: ", store_volhdr, 0, 0},
60 {VHTAG_EXPIRE, DKIND_TIME, " Expires: ", store_volhdr, 0, 0},
61 {VHTAG_BACKUP, DKIND_TIME, " Backed up: ", store_volhdr, 0, 0},
62 {VHTAG_OFFLINE, DKIND_STRING, " Offine Msg: ", store_volhdr, 0, 0},
63 {VHTAG_MOTD, DKIND_STRING, " MOTD: ", store_volhdr, 0, 0},
64 {VHTAG_WEEKUSE, DKIND_SPECIAL, " Weekuse: ", parse_weekuse, 0, 0},
65 {VHTAG_DUDATE, DKIND_TIME, " Dayuse Date: ", store_volhdr, 0, 0},
66 {VHTAG_DAYUSE, DKIND_INT32, " Daily usage: ", store_volhdr, 0, 0},
67 {0, 0, 0, 0, 0, 0}
68 };
69
70
71 /* Parse a volume header, including any tagged attributes, and call the
72 * volume-header callback, if one is defined.
73 */
74 afs_uint32
75 parse_volhdr(XFILE * X, unsigned char *tag, tagged_field * field,
76 afs_uint32 value, tag_parse_info * pi, void *g_refcon,
77 void *l_refcon)
78 {
79 dump_parser *p = (dump_parser *) g_refcon;
80 afs_vol_header hdr;
81 dt_uint64 where;
82 afs_uint32 r;
83
84 memset(&hdr, 0, sizeof(hdr));
85 if ((r = xftell(X, &where)))
86 return r;
87 sub64_32(hdr.offset, where, 1);
88 if (p->print_flags & DSPRINT_VOLHDR)
89 printf("%s [%s = 0x%s]\n", field->label,
90 decimate_int64(&hdr.offset, 0), hexify_int64(&hdr.offset, 0));
91
92 r = ParseTaggedData(X, volhdr_fields, tag, pi, g_refcon, (void *)&hdr);
93
94 if (!r && p->cb_volhdr) {
95 if ((r = xftell(X, &where)))
96 return r;
97 r = (p->cb_volhdr) (&hdr, X, p->refcon);
98 if (p->flags & DSFLAG_SEEK) {
99 if (!r)
100 r = xfseek(X, &where);
101 else
102 xfseek(X, &where);
103 }
104 }
105 if (hdr.field_mask & F_VOLHDR_VOLUNIQ)
106 p->vol_uniquifier = hdr.voluniq;
107 if (hdr.field_mask & F_VOLHDR_VOLNAME)
108 free(hdr.volname);
109 if (hdr.field_mask & F_VOLHDR_OFFLINE_MSG)
110 free(hdr.offline_msg);
111 if (hdr.field_mask & F_VOLHDR_MOTD)
112 free(hdr.motd_msg);
113 return r;
114 }
115
116
117 /* Store data in a volume header */
118 static afs_uint32
119 store_volhdr(XFILE * X, unsigned char *tag, tagged_field * field,
120 afs_uint32 value, tag_parse_info * pi, void *g_refcon,
121 void *l_refcon)
122 {
123 dump_parser *p = (dump_parser *) g_refcon;
124 afs_vol_header *hdr = (afs_vol_header *) l_refcon;
125 time_t when;
126 afs_uint32 r = 0;
127
128 switch (field->tag) {
129 case VHTAG_VOLID:
130 hdr->field_mask |= F_VOLHDR_VOLID;
131 hdr->volid = value;
132 break;
133
134 case VHTAG_VERS:
135 hdr->field_mask |= F_VOLHDR_VOLVERS;
136 hdr->volvers = value;
137 break;
138
139 case VHTAG_VOLNAME:
140 if (tag && tag[0]) {
141 hdr->field_mask |= F_VOLHDR_VOLNAME;
142 hdr->volname = tag;
143 r = DSERR_KEEP;
144 }
145 break;
146
147 case VHTAG_INSERV:
148 hdr->field_mask |= F_VOLHDR_INSERV;
149 hdr->flag_inservice = value;
150 break;
151
152 case VHTAG_BLESSED:
153 hdr->field_mask |= F_VOLHDR_BLESSED;
154 hdr->flag_blessed = value;
155 break;
156
157 case VHTAG_VUNIQ:
158 hdr->field_mask |= F_VOLHDR_VOLUNIQ;
159 hdr->voluniq = value;
160 break;
161
162 case VHTAG_TYPE:
163 hdr->field_mask |= F_VOLHDR_VOLTYPE;
164 hdr->voltype = value;
165 break;
166
167 case VHTAG_PARENT:
168 hdr->field_mask |= F_VOLHDR_PARENT;
169 hdr->parent_volid = value;
170 break;
171
172 case VHTAG_CLONE:
173 hdr->field_mask |= F_VOLHDR_CLONE;
174 hdr->clone_volid = value;
175 break;
176
177 case VHTAG_MAXQUOTA:
178 hdr->field_mask |= F_VOLHDR_MAXQ;
179 hdr->maxquota = value;
180 break;
181
182 case VHTAG_MINQUOTA:
183 hdr->field_mask |= F_VOLHDR_MINQ;
184 hdr->minquota = value;
185 break;
186
187 case VHTAG_DISKUSED:
188 hdr->field_mask |= F_VOLHDR_DISKUSED;
189 hdr->diskused = value;
190 break;
191
192 case VHTAG_FILECNT:
193 hdr->field_mask |= F_VOLHDR_NFILES;
194 hdr->nfiles = value;
195 break;
196
197 case VHTAG_ACCOUNT:
198 hdr->field_mask |= F_VOLHDR_ACCOUNT;
199 hdr->account_no = value;
200 break;
201
202 case VHTAG_OWNER:
203 hdr->field_mask |= F_VOLHDR_OWNER;
204 hdr->owner = value;
205 break;
206
207 case VHTAG_CREAT:
208 hdr->field_mask |= F_VOLHDR_CREATE_DATE;
209 hdr->create_date = value;
210 break;
211
212 case VHTAG_ACCESS:
213 hdr->field_mask |= F_VOLHDR_ACCESS_DATE;
214 hdr->access_date = value;
215 break;
216
217 case VHTAG_UPDATE:
218 hdr->field_mask |= F_VOLHDR_UPDATE_DATE;
219 hdr->update_date = value;
220 break;
221
222 case VHTAG_EXPIRE:
223 hdr->field_mask |= F_VOLHDR_EXPIRE_DATE;
224 hdr->expire_date = value;
225 break;
226
227 case VHTAG_BACKUP:
228 hdr->field_mask |= F_VOLHDR_BACKUP_DATE;
229 hdr->backup_date = value;
230 break;
231
232 case VHTAG_OFFLINE:
233 if (tag && tag[0]) {
234 hdr->field_mask |= F_VOLHDR_OFFLINE_MSG;
235 hdr->offline_msg = tag;
236 r = DSERR_KEEP;
237 }
238 break;
239
240 case VHTAG_MOTD:
241 if (tag && tag[0]) {
242 hdr->field_mask |= F_VOLHDR_MOTD;
243 hdr->motd_msg = tag;
244 r = DSERR_KEEP;
245 }
246 break;
247
248 case VHTAG_DUDATE:
249 hdr->field_mask |= F_VOLHDR_DAYUSE_DATE;
250 hdr->dayuse_date = value;
251 break;
252
253 case VHTAG_DAYUSE:
254 hdr->field_mask |= F_VOLHDR_DAYUSE;
255 hdr->dayuse = value;
256 break;
257 }
258
259 if (p->print_flags & DSPRINT_VOLHDR)
260 switch (field->kind) {
261 case DKIND_BYTE:
262 case DKIND_INT16:
263 case DKIND_INT32:
264 printf("%s%d\n", field->label, value);
265 break;
266 case DKIND_HEX8:
267 printf("%s0x%02x\n", field->label, value);
268 break;
269 case DKIND_HEX16:
270 printf("%s0x%04x\n", field->label, value);
271 break;
272 case DKIND_HEX32:
273 printf("%s0x%08x\n", field->label, value);
274 break;
275 case DKIND_CHAR:
276 printf("%s%c\n", field->label, value);
277 break;
278 case DKIND_STRING:
279 printf("%s%s\n", field->label, tag);
280 break;
281 case DKIND_FLAG:
282 printf("%s%s\n", field->label, value ? "true" : "false");
283 break;
284 case DKIND_TIME:
285 when = value;
286 printf("%s%s", field->label, ctime(&when));
287 break;
288 }
289 return r;
290 }
291
292
293 /* Parse and store the week use data from a volume header */
294 static afs_uint32
295 parse_weekuse(XFILE * X, unsigned char *tag, tagged_field * field,
296 afs_uint32 value, tag_parse_info * pi, void *g_refcon,
297 void *l_refcon)
298 {
299 dump_parser *p = (dump_parser *) g_refcon;
300 afs_vol_header *hdr = (afs_vol_header *) l_refcon;
301 afs_uint16 count;
302 afs_uint32 r;
303 unsigned int i;
304
305 if ((r = ReadInt16(X, &count)))
306 return r;
307 if (count != 7) {
308 if (p->cb_error)
309 (p->cb_error) (DSERR_FMT, 1, p->err_refcon,
310 "Incorrect array count (%d) in weekuse data",
311 count);
312 return DSERR_FMT;
313 }
314 for (i = 0; i < count; i++)
315 if ((r = ReadInt32(X, hdr->weekuse + i)))
316 return r;
317 hdr->field_mask |= F_VOLHDR_WEEKUSE;
318 if (p->print_flags & DSPRINT_VOLHDR) {
319 printf("%s%10d %10d %10d %10d\n", field->label, hdr->weekuse[0],
320 hdr->weekuse[1], hdr->weekuse[2], hdr->weekuse[3]);
321 printf("%s%10d %10d %10d\n", field->label, hdr->weekuse[4],
322 hdr->weekuse[5], hdr->weekuse[6]);
323 }
324 return ReadByte(X, tag);
325 }