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