]> git.wh0rd.org - dump.git/blame - restore/main.c
Initial revision
[dump.git] / restore / main.c
CommitLineData
1227625a
SP
1/*
2 * Ported to Linux's Second Extended File System as part of the
3 * dump and restore backup suit
4 * Remy Card <card@Linux.EU.Org>, 1994, 1995, 1996
5 *
6 */
7
8/*
9 * Copyright (c) 1983, 1993
10 * The Regents of the University of California. All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 */
40
41#ifndef lint
42static char copyright[] =
43"@(#) Copyright (c) 1983, 1993\n\
44 The Regents of the University of California. All rights reserved.\n";
45#endif /* not lint */
46
47#ifndef lint
48static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/4/95";
49#endif /* not lint */
50
51#include <sys/param.h>
52#include <sys/time.h>
53#include <sys/stat.h>
54
55#ifdef __linux__
56#include <linux/ext2_fs.h>
57#include <bsdcompat.h>
58#else /* __linux__ */
59#include <ufs/ufs/dinode.h>
60#include <ufs/ffs/fs.h>
61#endif /* __linux__ */
62#include <protocols/dumprestore.h>
63
64#include <err.h>
65#include <errno.h>
66#include <signal.h>
67#include <stdio.h>
68#include <stdlib.h>
69#include <string.h>
70#include <unistd.h>
71
72#ifdef __linux__
73#include <ext2fs/ext2fs.h>
74#include <getopt.h>
75#endif
76
77#include "pathnames.h"
78#include "restore.h"
79#include "extern.h"
80
81int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
82int hflag = 1, mflag = 1, Nflag = 0;
83char command = '\0';
84long dumpnum = 1;
85long volno = 0;
86long ntrec;
87char *dumpmap;
88char *usedinomap;
89ino_t maxino;
90time_t dumptime;
91time_t dumpdate;
92FILE *terminal;
93int compare_ignore_not_found;
94char *filesys = NULL;
95char *tmpdir = _PATH_TMP;
96
97#ifdef __linux__
98char *__progname;
99#endif
100
101static void obsolete __P((int *, char **[]));
102static void usage __P((void));
103
104int
105main(argc, argv)
106 int argc;
107 char *argv[];
108{
109 int ch;
110 ino_t ino;
111 char *inputdev = _PATH_DEFTAPE;
112 char *symtbl = "./restoresymtable";
113 char *p, name[MAXPATHLEN];
114
115 if (argc < 2)
116 usage();
117
118#ifdef __linux__
119 __progname = argv[0];
120#endif
121
122 obsolete(&argc, &argv);
123 while ((ch = getopt(argc, argv, "b:CcdD:f:himNRrs:tT:vxy")) != EOF)
124 switch(ch) {
125 case 'b':
126 /* Change default tape blocksize. */
127 bflag = 1;
128 ntrec = strtol(optarg, &p, 10);
129 if (*p)
130 errx(1, "illegal blocksize -- %s", optarg);
131 if (ntrec <= 0)
132 errx(1, "block size must be greater than 0");
133 break;
134 case 'c':
135 cvtflag = 1;
136 break;
137 case 'D':
138 filesys = optarg;
139 break;
140 case 'T':
141 tmpdir = optarg;
142 break;
143 case 'd':
144 dflag = 1;
145 break;
146 case 'f':
147 inputdev = optarg;
148 break;
149 case 'h':
150 hflag = 0;
151 break;
152 case 'C':
153 case 'i':
154 case 'R':
155 case 'r':
156 case 't':
157 case 'x':
158 if (command != '\0')
159 errx(1,
160 "%c and %c options are mutually exclusive",
161 ch, command);
162 command = ch;
163 break;
164 case 'm':
165 mflag = 0;
166 break;
167 case 'N':
168 Nflag = 1;
169 break;
170 case 's':
171 /* Dumpnum (skip to) for multifile dump tapes. */
172 dumpnum = strtol(optarg, &p, 10);
173 if (*p)
174 errx(1, "illegal dump number -- %s", optarg);
175 if (dumpnum <= 0)
176 errx(1, "dump number must be greater than 0");
177 break;
178 case 'v':
179 vflag = 1;
180 break;
181 case 'y':
182 yflag = 1;
183 break;
184 default:
185 usage();
186 }
187 argc -= optind;
188 argv += optind;
189
190 if (command == '\0')
191 errx(1, "none of C, i, R, r, t or x options specified");
192
193 if (signal(SIGINT, onintr) == SIG_IGN)
194 (void) signal(SIGINT, SIG_IGN);
195 if (signal(SIGTERM, onintr) == SIG_IGN)
196 (void) signal(SIGTERM, SIG_IGN);
197 setlinebuf(stderr);
198
199 setinput(inputdev);
200
201 if (argc == 0) {
202 argc = 1;
203 *--argv = ".";
204 }
205
206 switch (command) {
207 /*
208 * Compare contents of tape.
209 */
210 case 'C': {
211 struct stat stbuf;
212
213 vprintf(stdout, "Begin compare restore\n");
214 compare_ignore_not_found = 0;
215 setup();
216 printf("filesys = %s\n", filesys);
217 if (stat(filesys, &stbuf) < 0) {
218 fprintf(stderr, "cannot stat directory %s: %s\n",
219 filesys, strerror(errno));
220 exit(1);
221 } else {
222 if (chdir(filesys) < 0) {
223 fprintf(stderr, "cannot cd to %s: %s\n",
224 filesys, strerror(errno));
225 exit(1);
226 }
227 }
228 compare_ignore_not_found = dumptime > 0;
229 initsymtable((char *)0);
230 extractdirs(0);
231 treescan(".", ROOTINO, nodeupdates);
232 compareleaves();
233 checkrestore();
234 break;
235 }
236
237 /*
238 * Interactive mode.
239 */
240 case 'i':
241 setup();
242 extractdirs(1);
243 initsymtable(NULL);
244 runcmdshell();
245 break;
246 /*
247 * Incremental restoration of a file system.
248 */
249 case 'r':
250 setup();
251 if (dumptime > 0) {
252 /*
253 * This is an incremental dump tape.
254 */
255 vprintf(stdout, "Begin incremental restore\n");
256 initsymtable(symtbl);
257 extractdirs(1);
258 removeoldleaves();
259 vprintf(stdout, "Calculate node updates.\n");
260 treescan(".", ROOTINO, nodeupdates);
261 findunreflinks();
262 removeoldnodes();
263 } else {
264 /*
265 * This is a level zero dump tape.
266 */
267 vprintf(stdout, "Begin level 0 restore\n");
268 initsymtable((char *)0);
269 extractdirs(1);
270 vprintf(stdout, "Calculate extraction list.\n");
271 treescan(".", ROOTINO, nodeupdates);
272 }
273 createleaves(symtbl);
274 createlinks();
275 setdirmodes(FORCE);
276 checkrestore();
277 if (dflag) {
278 vprintf(stdout, "Verify the directory structure\n");
279 treescan(".", ROOTINO, verifyfile);
280 }
281 dumpsymtable(symtbl, (long)1);
282 break;
283 /*
284 * Resume an incremental file system restoration.
285 */
286 case 'R':
287 initsymtable(symtbl);
288 skipmaps();
289 skipdirs();
290 createleaves(symtbl);
291 createlinks();
292 setdirmodes(FORCE);
293 checkrestore();
294 dumpsymtable(symtbl, (long)1);
295 break;
296 /*
297 * List contents of tape.
298 */
299 case 't':
300 setup();
301 extractdirs(0);
302 initsymtable((char *)0);
303 while (argc--) {
304 canon(*argv++, name);
305 ino = dirlookup(name);
306 if (ino == 0)
307 continue;
308 treescan(name, ino, listfile);
309 }
310 break;
311 /*
312 * Batch extraction of tape contents.
313 */
314 case 'x':
315 setup();
316 extractdirs(1);
317 initsymtable((char *)0);
318 while (argc--) {
319 canon(*argv++, name);
320 ino = dirlookup(name);
321 if (ino == 0)
322 continue;
323 if (mflag)
324 pathcheck(name);
325 treescan(name, ino, addfile);
326 }
327 createfiles();
328 createlinks();
329 setdirmodes(0);
330 if (dflag)
331 checkrestore();
332 break;
333 }
334 done(0);
335 /* NOTREACHED */
336}
337
338static void
339usage()
340{
341 (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n",
342 "restore -i [-chmvy] [-b blocksize] [-f file] [-s fileno]",
343 "restore -r [-cvy] [-b blocksize] [-f file] [-s fileno]",
344 "restore -R [-cvy] [-b blocksize] [-f file] [-s fileno]",
345 "restore -x [-chmvy] [-b blocksize] [-f file] [-s fileno] [file ...]", "restore -t [-chvy] [-b blocksize] [-f file] [-s fileno] [file ...]");
346 done(1);
347}
348
349/*
350 * obsolete --
351 * Change set of key letters and ordered arguments into something
352 * getopt(3) will like.
353 */
354static void
355obsolete(argcp, argvp)
356 int *argcp;
357 char **argvp[];
358{
359 int argc, flags;
360 char *ap, **argv, *flagsp, **nargv, *p;
361
362 /* Setup. */
363 argv = *argvp;
364 argc = *argcp;
365
366 /* Return if no arguments or first argument has leading dash. */
367 ap = argv[1];
368 if (argc == 1 || *ap == '-')
369 return;
370
371 /* Allocate space for new arguments. */
372 if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL ||
373 (p = flagsp = malloc(strlen(ap) + 2)) == NULL)
374 err(1, NULL);
375
376 *nargv++ = *argv;
377 argv += 2;
378
379 for (flags = 0; *ap; ++ap) {
380 switch (*ap) {
381 case 'b':
382 case 'f':
383 case 's':
384 if (*argv == NULL) {
385 warnx("option requires an argument -- %c", *ap);
386 usage();
387 }
388 if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL)
389 err(1, NULL);
390 nargv[0][0] = '-';
391 nargv[0][1] = *ap;
392 (void)strcpy(&nargv[0][2], *argv);
393 ++argv;
394 ++nargv;
395 break;
396 default:
397 if (!flags) {
398 *p++ = '-';
399 flags = 1;
400 }
401 *p++ = *ap;
402 break;
403 }
404 }
405
406 /* Terminate flags. */
407 if (flags) {
408 *p = '\0';
409 *nargv++ = flagsp;
410 }
411
412 /* Copy remaining arguments. */
413 while (*nargv++ = *argv++);
414
415 /* Update argument count. */
416 *argcp = nargv - *argvp - 1;
417}