Some doc path fixes from Anders
[pkg-k5-afs_openafs.git] / src / bucoord / dsstub.c
blob01b1c78e7c441290d27f53b3935bd6323e5a380e
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
11 * ALL RIGHTS RESERVED
14 #include <afsconfig.h>
15 #include <afs/param.h>
17 #include <roken.h>
19 #include <afs/cmd.h>
20 #include <afs/afsutil.h>
21 #include <afs/budb.h>
22 #include <afs/bubasics.h>
23 #include <afs/afsint.h>
24 #include <afs/volser.h>
26 #include "bc.h"
28 /* protos */
30 static char * TapeName(char *);
31 static char * DumpName(afs_int32 adumpID);
32 static FILE * OpenDump(afs_int32 , char * );
33 FILE * OpenTape(char * , char * );
34 static afs_int32 ScanForChildren(afs_int32 );
35 static afs_int32 DeleteDump(afs_int32 );
36 char * tailCompPtr(char *);
37 afs_int32 ScanDumpHdr(FILE *, char *, char *, afs_int32 *, afs_int32 *,
38 afs_int32 *, afs_int32 *);
39 afs_int32 ScanTapeVolume(FILE *, char *, afs_int32 *, char *, afs_int32 *, afs_int32 *,
40 afs_int32 *, afs_int32 *);
41 afs_int32 ScanVolClone(FILE *, char *, afs_int32 *);
44 /* basic format of a tape file is a file, whose name is "T<tapename>.db", and
45 * which contains the fields
46 * (afs_int32) dumpID, (afs_int32) tape-sequence-within-dump, (afs_int32) damage_flag
47 * all as space-separated integers.
50 /* The format of a dump file is:
51 * a file whose name is "D<dump#>.db"
52 * and whose contents are a header line:
53 * (string) dumpName, (long) parent-id, (long) incTime, (long) dumpEndTime, (long) level
54 * and a bunch of bcdb_volumeEntries with this format:
55 * (string) volume name, (long) volume ID, (string) tape name, (long) position-on-tape,
56 * (long) sequence-in-volume-dump, (long) is-this-the-last-vol-frag, (long) incTime
57 * again, all space-separated.
58 * Note that dumpEndTime is stored and returned in the dump creation time field.
61 /* return the tape file name corresponding to a particular tape */
63 static char * TapeName(char *atapeName)
65 char *tbuffer;
67 if (asprintf(&tbuffer, "%s/T%s.db", AFSDIR_SERVER_BACKUP_DIRPATH,
68 atapeName) < 0)
69 return NULL;
70 return tbuffer;
73 /* return the dump file name corresponding to a particular dump ID */
75 static char * DumpName(afs_int32 adumpID)
77 char *tbuffer;
79 if (asprintf(&tbuffer, "%s/D%d.db", AFSDIR_SERVER_BACKUP_DIRPATH,
80 adumpID) < 0)
81 return NULL;
82 return tbuffer;
85 static FILE * OpenDump(afs_int32 adumpID, char * awrite)
87 char *tp;
88 FILE *tfile;
90 tp = DumpName(adumpID);
91 if (tp == NULL)
92 return NULL;
93 tfile = fopen(tp, awrite);
94 free(tp);
95 return tfile;
98 /* OpenTape
99 * notes:
100 * non-static for recoverDB
103 FILE * OpenTape(char * atapeName, char * awrite)
105 char *tp;
106 FILE *tfile;
108 tp = TapeName(atapeName);
109 if (tp == NULL)
110 return NULL;
111 tfile = fopen(tp, awrite);
112 free(tp);
113 return tfile;
116 /* scan for, and delete, all dumps whose parent dump ID is aparentID */
118 static afs_int32 ScanForChildren(afs_int32 aparentID)
120 DIR *tdir;
121 struct dirent *tde;
122 afs_int32 dumpID, parent;
123 FILE *tfile;
124 afs_int32 code;
125 afs_int32 j2, j3, j4;
126 char dname[256];
127 char dumpName[1024];
129 tdir = opendir(AFSDIR_SERVER_BACKUP_DIRPATH);
130 if (!tdir)
131 return -1;
133 for (tde = readdir(tdir); tde; tde = readdir(tdir)) {
134 code = sscanf(tde->d_name, "D%ld.db", (long int *) &dumpID);
135 if (code != 1)
136 continue;
138 tfile = OpenDump(dumpID, "r");
139 if (!tfile)
140 continue; /* shouldn't happen, but should continue anyway */
142 code = ScanDumpHdr(tfile, dname, dumpName, &parent, &j2, &j3, &j4);
143 fclose(tfile);
144 if (code) {
145 printf("backup:dsstub: bad dump header for dump %d\n", dumpID);
146 continue;
149 /* if this guy's parent is the ID we're scanning for, delete it */
150 if (aparentID == parent) {
151 code = DeleteDump(dumpID);
152 if (code)
153 printf("backup:dsstub: failed to delete child dump %d\n",
154 dumpID);
157 closedir(tdir);
158 return 0;
161 static afs_int32 DeleteDump(afs_int32 adumpID)
163 char *tp;
164 afs_int32 code;
166 tp = DumpName(adumpID);
167 if (tp == NULL)
168 return ENOMEM;
169 code = unlink(tp);
170 free(tp);
171 if (code)
172 return code;
173 code = ScanForChildren(adumpID);
174 return code;
177 #if 0
178 static afs_int32 DeleteTape(char * atapeName)
180 char *tp;
181 afs_int32 code;
183 tp = TapeName(atapeName);
184 if (tp == NULL)
185 return ENOMEM;
186 code = unlink(tp);
187 free(tp);
188 return code;
190 #endif
192 /* tailCompPtr
193 * name is a pathname style name, determine trailing name and return
194 * pointer to it
197 char *
198 tailCompPtr(char *pathNamePtr)
200 char *ptr;
201 ptr = strrchr(pathNamePtr, '/');
202 if (ptr == 0) {
203 /* this should never happen */
204 printf("tailCompPtr: could not find / in name(%s)\n", pathNamePtr);
205 return (pathNamePtr);
206 } else
207 ptr++; /* skip the / */
208 return (ptr);
211 /* ScanDumpHdr
212 * scan a dump header out of a dump file, leaving the file ptr set after
213 * the header.
214 * entry:
215 * afile - ptr to file, for reading.
216 * various - ptrs for return values
217 * exit:
218 * aname - string of form volume_set.dump_level
219 * dumpName - pathname of dump schedule node
220 * aparent - id of parent
221 * aincTime
222 * acreateTime - time at which dump was created
223 * alevel - level of dump (0 = full, 1+ are incrementals)
225 afs_int32
226 ScanDumpHdr(FILE *afile, char *aname, char *dumpName, afs_int32 *aparent, afs_int32 *aincTime, afs_int32 *acreateTime, afs_int32 *alevel)
228 char tbuffer[256];
229 char *tp;
230 afs_int32 dbmagic, dbversion;
231 afs_int32 code;
233 tp = fgets(tbuffer, sizeof(tbuffer), afile);
234 if (!tp)
235 return -1;
236 code =
237 sscanf(tbuffer, "%d %d %s %s %ld %ld %ld %ld", &dbmagic, &dbversion,
238 aname, dumpName, (long int *) aparent, (long int *) aincTime,
239 (long int *) acreateTime, (long int *) alevel);
240 if (code != 8)
241 return -1;
243 /* now check the magic and version numbers */
244 if ((dbmagic != BC_DUMPDB_MAGIC) || (dbversion != BC_DUMPDB_VERSION))
245 return (-1);
247 return 0;
250 #if 0
251 /* scan a tape header out of a tape file, leaving the file ptr positioned just past the header */
252 static afs_int32 ScanTapeHdr(FILE *afile, afs_int32 *adumpID, afs_int32 *aseq, afs_int32 *adamage)
254 char tbuffer[256];
255 char *tp;
256 afs_int32 code;
258 tp = fgets(tbuffer, sizeof(tbuffer), afile);
259 if (!tp)
260 return -1;
261 code = sscanf(tbuffer, "%ld %ld %ld", (long int *)adumpID,
262 (long int *)aseq, (long int *)adamage);
263 if (code != 3)
264 return -1;
265 return 0;
267 #endif
269 /* ScanTapeVolume
270 * scan a tape volume record from a dump file, leaving the file ptr
271 * positioned past the just-scanned record.
272 * exit:
273 * 0 - success
274 * 1 - EOF
275 * -1 for error
278 afs_int32 ScanTapeVolume(FILE *afile, char *avolName, afs_int32 *avolID, char *atapeName, afs_int32 *apos, afs_int32 *aseq, afs_int32 *alastp, afs_int32 *cloneTime)
280 char tbuffer[256];
281 afs_int32 code;
282 char *tp;
284 tp = fgets(tbuffer, sizeof(tbuffer), afile);
285 if (!tp) { /* something went wrong, or eof hit */
286 if (ferror(afile))
287 return -1; /* error occurred */
288 else
289 return 1; /* eof */
291 code =
292 sscanf(tbuffer, "%s %ld %s %ld %ld %ld %ld", avolName,
293 (long int *) avolID, atapeName, (long int *)apos,
294 (long int *) aseq, (long int *) alastp,
295 (long int *) cloneTime);
296 if (code != 7)
297 return -1; /* bad input line */
298 return 0;
301 /* ScanVolClone
302 * Search the dump for the volume with name volName, and return it's
303 * clone time.
304 * exit:
305 * 0 - clonetime set.
306 * -1 - volume with volName not found
309 afs_int32 ScanVolClone(FILE *tdump, char *volName, afs_int32 *cloneTime)
311 char avolName[256], atapeName[256];
312 afs_int32 retval, avolID, apos, aseq, alastp;
314 retval =
315 ScanTapeVolume(tdump, &avolName[0], &avolID, &atapeName[0], &apos,
316 &aseq, &alastp, cloneTime);
317 while (retval == 0) {
318 if (strcmp(avolName, volName) == 0)
319 return (0);
320 retval =
321 ScanTapeVolume(tdump, &avolName[0], &avolID, &atapeName[0], &apos,
322 &aseq, &alastp, cloneTime);
324 return (-1);
327 #if 0
328 /* seek a dump file (after a header scan has been done) to position apos */
329 static int SeekDump(FILE *afile, afs_int32 apos)
331 afs_int32 i;
332 char *tp;
333 char tbuffer[256];
335 /* now skip to appropriate position */
336 for (i = 0; i < apos; i++) {
337 tp = fgets(tbuffer, sizeof(tbuffer), afile);
338 if (!tp) {
339 fclose(afile);
340 return -1;
343 return 0;
345 #endif