Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tools / dumpscan / stagehdr.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 /* stagehdr.c - Parse and dump stage backup headers */
30
31 #include <sys/types.h>
32 #include <netinet/in.h>
33 #include <stdlib.h>
34 #include <errno.h>
35
36 #include "dumpscan.h"
37 #include "dumpscan_errs.h"
38 #include "xf_errs.h"
39 #include "stagehdr.h"
40
41 static afs_uint32
42 hdr_checksum(char *buf, int size)
43 {
44 afs_uint32 sum = 0, n = size / sizeof(afs_uint32), *words =
45 (afs_uint32 *) buf;
46
47 while (--n)
48 sum += ntohl(*words++);
49 return sum;
50 }
51
52
53 /* Parse a stage backup header.
54 * If tag is non-NULL, *tag should contain the first byte (already read),
55 * and will be filled in with the first byte after the header, if one exists.
56 * On success, returns 0 and leaves us positioned after the header
57 * On failure, returns an error and position is undefined
58 * Iff there is no header, returns DSERR_MAGIC and leaves us
59 * positioned where we started.
60 */
61 afs_uint32
62 ParseStageHdr(XFILE * X, unsigned char *tag, backup_system_header * hdr)
63 {
64 char buf[STAGE_HDRLEN];
65 struct stage_header *bckhdr = (struct stage_header *)buf;
66 dt_uint64 where;
67 afs_int32 r;
68
69 if ((r = xftell(X, &where)))
70 return r;
71 if (hdr)
72 memset(hdr, 0, sizeof(*hdr));
73 if (tag) {
74 if (*tag != STAGE_VERSMIN)
75 return DSERR_MAGIC;
76 buf[0] = *tag;
77 r = xfread(X, buf + 1, STAGE_HDRLEN - 1);
78 } else {
79 r = xfread(X, buf, STAGE_HDRLEN);
80 }
81
82 if (r == ERROR_XFILE_EOF) {
83 r = xfseek(X, &where);
84 return r ? r : DSERR_MAGIC;
85 } else if (r)
86 return r;
87
88 if (bckhdr->c_vers < STAGE_VERSMIN
89 || ntohl(bckhdr->c_magic) != STAGE_MAGIC
90 || hdr_checksum(buf, STAGE_HDRLEN) != STAGE_CHECKSUM) {
91 r = xfseek(X, &where);
92 return r ? r : DSERR_MAGIC;
93 }
94
95 if (hdr) {
96 hdr->version = bckhdr->c_vers;
97 hdr->from_date = ntohl(bckhdr->c_fdate);
98 hdr->to_date = ntohl(bckhdr->c_tdate);
99 hdr->dump_date = ntohl(bckhdr->c_time);
100 hdr->filenum = ntohl(bckhdr->c_filenum);
101 hdr->volid = ntohl(bckhdr->c_id);
102 #ifdef NATIVE_UINT64
103 hdr->dumplen = ntohl(bckhdr->c_length);
104 #else
105 hdr->dumplen.hi = 0;
106 hdr->dumplen.lo = ntohl(bckhdr->c_length);
107 #endif
108 hdr->level = ntohl(bckhdr->c_level);
109 hdr->magic = ntohl(bckhdr->c_magic);
110 hdr->cksum = ntohl(bckhdr->c_checksum);
111 hdr->flags = ntohl(bckhdr->c_flags);
112 hdr->server = (unsigned char *) strdup(bckhdr->c_host);
113 hdr->part = (unsigned char *) strdup(bckhdr->c_disk);
114 hdr->volname = (unsigned char *) strdup(bckhdr->c_name);
115
116 if (!hdr->server || !hdr->part || !hdr->volname) {
117 if (hdr->server)
118 free(hdr->server);
119 if (hdr->part)
120 free(hdr->part);
121 if (hdr->volname)
122 free(hdr->volname);
123 return ENOMEM;
124 }
125 }
126
127 if (tag)
128 return ReadByte(X, tag);
129 else
130 return 0;
131 }
132
133
134 /* Dump a stage backup header */
135 afs_uint32
136 DumpStageHdr(XFILE * OX, backup_system_header * hdr)
137 {
138 char buf[STAGE_HDRLEN];
139 struct stage_header *bckhdr = (struct stage_header *)buf;
140 afs_uint32 checksum;
141 afs_uint32 r;
142
143 memset(buf, 0, STAGE_HDRLEN);
144 bckhdr->c_vers = hdr->version;
145 bckhdr->c_fdate = htonl(hdr->from_date);
146 bckhdr->c_tdate = htonl(hdr->to_date);
147 bckhdr->c_filenum = htonl(hdr->filenum);
148 bckhdr->c_time = htonl(hdr->dump_date);
149 bckhdr->c_id = htonl(hdr->volid);
150 #ifdef NATIVE_UINT64
151 bckhdr->c_length = htonl((afs_uint32) hdr->dumplen);
152 #else
153 bckhdr->c_length = htonl(hdr->dumplen.lo);
154 #endif
155 bckhdr->c_level = htonl(hdr->level);
156 bckhdr->c_magic = htonl(STAGE_MAGIC);
157 bckhdr->c_flags = htonl(hdr->flags);
158
159 strcpy(bckhdr->c_host, (char *)hdr->server);
160 strcpy(bckhdr->c_disk, (char *)hdr->part);
161 strcpy(bckhdr->c_name, (char *)hdr->volname);
162
163 /* Now, compute the checksum */
164 checksum = hdr_checksum(buf, STAGE_HDRLEN);
165 bckhdr->c_checksum = htonl(STAGE_CHECKSUM - checksum);
166
167 if ((r = xfwrite(OX, buf, STAGE_HDRLEN)))
168 return r;
169 return 0;
170 }