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