xref: /original-bsd/sbin/restore/main.c (revision c47935e1)
1 /*
2  * Copyright (c) 1983 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)main.c	5.6 (Berkeley) 05/11/89";
26 #endif /* not lint */
27 
28 /*
29  *	Modified to recursively extract all files within a subtree
30  *	(supressed by the h option) and recreate the heirarchical
31  *	structure of that subtree and move extracted files to their
32  *	proper homes (supressed by the m option).
33  *	Includes the s (skip files) option for use with multiple
34  *	dumps on a single tape.
35  *	8/29/80		by Mike Litzkow
36  *
37  *	Modified to work on the new file system and to recover from
38  *	tape read errors.
39  *	1/19/82		by Kirk McKusick
40  *
41  *	Full incremental restore running entirely in user code and
42  *	interactive tape browser.
43  *	1/19/83		by Kirk McKusick
44  */
45 
46 #include "restore.h"
47 #include <protocols/dumprestore.h>
48 #include <sys/signal.h>
49 #include "pathnames.h"
50 
51 int	bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
52 int	hflag = 1, mflag = 1, Nflag = 0;
53 char	command = '\0';
54 long	dumpnum = 1;
55 long	volno = 0;
56 long	ntrec;
57 char	*dumpmap;
58 char	*clrimap;
59 ino_t	maxino;
60 time_t	dumptime;
61 time_t	dumpdate;
62 FILE 	*terminal;
63 
64 main(argc, argv)
65 	int argc;
66 	char *argv[];
67 {
68 	register char *cp;
69 	ino_t ino;
70 	char *inputdev = _PATH_DEFTAPE;
71 	char *symtbl = "./restoresymtable";
72 	char name[MAXPATHLEN];
73 	int (*signal())();
74 	extern int onintr();
75 
76 	if (signal(SIGINT, onintr) == SIG_IGN)
77 		(void) signal(SIGINT, SIG_IGN);
78 	if (signal(SIGTERM, onintr) == SIG_IGN)
79 		(void) signal(SIGTERM, SIG_IGN);
80 	setlinebuf(stderr);
81 	if (argc < 2) {
82 usage:
83 		fprintf(stderr, "Usage:\n%s%s%s%s%s",
84 			"\trestore tfhsvy [file file ...]\n",
85 			"\trestore xfhmsvy [file file ...]\n",
86 			"\trestore ifhmsvy\n",
87 			"\trestore rfsvy\n",
88 			"\trestore Rfsvy\n");
89 		done(1);
90 	}
91 	argv++;
92 	argc -= 2;
93 	command = '\0';
94 	for (cp = *argv++; *cp; cp++) {
95 		switch (*cp) {
96 		case '-':
97 			break;
98 		case 'c':
99 			cvtflag++;
100 			break;
101 		case 'd':
102 			dflag++;
103 			break;
104 		case 'h':
105 			hflag = 0;
106 			break;
107 		case 'm':
108 			mflag = 0;
109 			break;
110 		case 'N':
111 			Nflag++;
112 			break;
113 		case 'v':
114 			vflag++;
115 			break;
116 		case 'y':
117 			yflag++;
118 			break;
119 		case 'f':
120 			if (argc < 1) {
121 				fprintf(stderr, "missing device specifier\n");
122 				done(1);
123 			}
124 			inputdev = *argv++;
125 			argc--;
126 			break;
127 		case 'b':
128 			/*
129 			 * change default tape blocksize
130 			 */
131 			bflag++;
132 			if (argc < 1) {
133 				fprintf(stderr, "missing block size\n");
134 				done(1);
135 			}
136 			ntrec = atoi(*argv++);
137 			if (ntrec <= 0) {
138 				fprintf(stderr, "Block size must be a positive integer\n");
139 				done(1);
140 			}
141 			argc--;
142 			break;
143 		case 's':
144 			/*
145 			 * dumpnum (skip to) for multifile dump tapes
146 			 */
147 			if (argc < 1) {
148 				fprintf(stderr, "missing dump number\n");
149 				done(1);
150 			}
151 			dumpnum = atoi(*argv++);
152 			if (dumpnum <= 0) {
153 				fprintf(stderr, "Dump number must be a positive integer\n");
154 				done(1);
155 			}
156 			argc--;
157 			break;
158 		case 't':
159 		case 'R':
160 		case 'r':
161 		case 'x':
162 		case 'i':
163 			if (command != '\0') {
164 				fprintf(stderr,
165 					"%c and %c are mutually exclusive\n",
166 					*cp, command);
167 				goto usage;
168 			}
169 			command = *cp;
170 			break;
171 		default:
172 			fprintf(stderr, "Bad key character %c\n", *cp);
173 			goto usage;
174 		}
175 	}
176 	if (command == '\0') {
177 		fprintf(stderr, "must specify i, t, r, R, or x\n");
178 		goto usage;
179 	}
180 	setinput(inputdev);
181 	if (argc == 0) {
182 		argc = 1;
183 		*--argv = ".";
184 	}
185 	switch (command) {
186 	/*
187 	 * Interactive mode.
188 	 */
189 	case 'i':
190 		setup();
191 		extractdirs(1);
192 		initsymtable((char *)0);
193 		runcmdshell();
194 		done(0);
195 	/*
196 	 * Incremental restoration of a file system.
197 	 */
198 	case 'r':
199 		setup();
200 		if (dumptime > 0) {
201 			/*
202 			 * This is an incremental dump tape.
203 			 */
204 			vprintf(stdout, "Begin incremental restore\n");
205 			initsymtable(symtbl);
206 			extractdirs(1);
207 			removeoldleaves();
208 			vprintf(stdout, "Calculate node updates.\n");
209 			treescan(".", ROOTINO, nodeupdates);
210 			findunreflinks();
211 			removeoldnodes();
212 		} else {
213 			/*
214 			 * This is a level zero dump tape.
215 			 */
216 			vprintf(stdout, "Begin level 0 restore\n");
217 			initsymtable((char *)0);
218 			extractdirs(1);
219 			vprintf(stdout, "Calculate extraction list.\n");
220 			treescan(".", ROOTINO, nodeupdates);
221 		}
222 		createleaves(symtbl);
223 		createlinks();
224 		setdirmodes();
225 		checkrestore();
226 		if (dflag) {
227 			vprintf(stdout, "Verify the directory structure\n");
228 			treescan(".", ROOTINO, verifyfile);
229 		}
230 		dumpsymtable(symtbl, (long)1);
231 		done(0);
232 	/*
233 	 * Resume an incremental file system restoration.
234 	 */
235 	case 'R':
236 		initsymtable(symtbl);
237 		skipmaps();
238 		skipdirs();
239 		createleaves(symtbl);
240 		createlinks();
241 		setdirmodes();
242 		checkrestore();
243 		dumpsymtable(symtbl, (long)1);
244 		done(0);
245 	/*
246 	 * List contents of tape.
247 	 */
248 	case 't':
249 		setup();
250 		extractdirs(0);
251 		initsymtable((char *)0);
252 		while (argc--) {
253 			canon(*argv++, name);
254 			ino = dirlookup(name);
255 			if (ino == 0)
256 				continue;
257 			treescan(name, ino, listfile);
258 		}
259 		done(0);
260 	/*
261 	 * Batch extraction of tape contents.
262 	 */
263 	case 'x':
264 		setup();
265 		extractdirs(1);
266 		initsymtable((char *)0);
267 		while (argc--) {
268 			canon(*argv++, name);
269 			ino = dirlookup(name);
270 			if (ino == 0)
271 				continue;
272 			if (mflag)
273 				pathcheck(name);
274 			treescan(name, ino, addfile);
275 		}
276 		createfiles();
277 		createlinks();
278 		setdirmodes();
279 		if (dflag)
280 			checkrestore();
281 		done(0);
282 	}
283 }
284