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