9b95368e315f549baad8d11814985ecd57eef041
[openafs.git] / src / tools / 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     u_int64 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 }