xref: /csrg-svn/sbin/restore/main.c (revision 10312)
1*10312Smckusick /* Copyright (c) 1983 Regents of the University of California */
24610Smckusick 
36846Smckusick #ifndef lint
4*10312Smckusick static char sccsid[] = "@(#)main.c	3.6	(Berkeley)	83/01/16";
56846Smckusick #endif
64610Smckusick 
7*10312Smckusick /*
8*10312Smckusick  *	Modified to recursively extract all files within a subtree
9*10312Smckusick  *	(supressed by the h option) and recreate the heirarchical
10*10312Smckusick  *	structure of that subtree and move extracted files to their
11*10312Smckusick  *	proper homes (supressed by the m option).
12*10312Smckusick  *	Includes the s (skip files) option for use with multiple
13*10312Smckusick  *	dumps on a single tape.
144610Smckusick  *	8/29/80		by Mike Litzkow
154610Smckusick  *
16*10312Smckusick  *	Modified to work on the new file system and to recover from
17*10312Smckusick  *	tape read errors.
186846Smckusick  *	1/19/82		by Kirk McKusick
196846Smckusick  *
20*10312Smckusick  *	Full incremental restore running entirely in user code.
21*10312Smckusick  *	1/19/83		by Kirk McKusick
224610Smckusick  */
234610Smckusick 
24*10312Smckusick #include "restore.h"
254610Smckusick #include <signal.h>
264610Smckusick 
27*10312Smckusick int	cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
28*10312Smckusick int	hflag = 1, mflag = 1;
29*10312Smckusick char	command = '\0';
30*10312Smckusick long	dumpnum = 1;
31*10312Smckusick long	volno = 1;
325327Smckusic char	*dumpmap;
335327Smckusic char	*clrimap;
34*10312Smckusick ino_t	maxino;
35*10312Smckusick time_t	dumptime;
36*10312Smckusick time_t	dumpdate;
374610Smckusick 
386846Smckusick main(argc, argv)
394700Smckusic 	int argc;
404700Smckusic 	char *argv[];
414610Smckusick {
424610Smckusick 	register char *cp;
43*10312Smckusick 	ino_t ino;
44*10312Smckusick 	char *inputdev = "/dev/rmt8";
45*10312Smckusick 	char *symtbl = "./restoresymtable";
46*10312Smckusick 	char *dirmodefile = "./dirmodes";
47*10312Smckusick 	char name[BUFSIZ];
484700Smckusic 	int (*signal())();
49*10312Smckusick 	extern int onintr();
504610Smckusick 
51*10312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
52*10312Smckusick 		(void) signal(SIGINT, SIG_IGN);
53*10312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
54*10312Smckusick 		(void) signal(SIGTERM, SIG_IGN);
55*10312Smckusick 	setlinebuf(stderr);
564610Smckusick 	if (argc < 2) {
574610Smckusick usage:
58*10312Smckusick 		fprintf(stderr, "Usage: restor xtfhmsvy file file... or restor rRfsvy\n");
594700Smckusic 		done(1);
604610Smckusick 	}
614610Smckusick 	argv++;
624610Smckusick 	argc -= 2;
6310202Smckusick 	command = '\0';
644610Smckusick 	for (cp = *argv++; *cp; cp++) {
654610Smckusick 		switch (*cp) {
664610Smckusick 		case '-':
674610Smckusick 			break;
688302Smckusick 		case 'c':
698302Smckusick 			cvtflag++;
708302Smckusick 			break;
71*10312Smckusick 		case 'd':
72*10312Smckusick 			dflag++;
734610Smckusick 			break;
744610Smckusick 		case 'h':
7510202Smckusick 			hflag = 0;
764610Smckusick 			break;
774610Smckusick 		case 'm':
7810202Smckusick 			mflag = 0;
794610Smckusick 			break;
808374Smckusick 		case 'v':
818374Smckusick 			vflag++;
828374Smckusick 			break;
838374Smckusick 		case 'y':
848374Smckusick 			yflag++;
858374Smckusick 			break;
86*10312Smckusick 		case 'f':
87*10312Smckusick 			if (argc < 1) {
88*10312Smckusick 				fprintf(stderr, "missing device specifier\n");
89*10312Smckusick 				done(1);
90*10312Smckusick 			}
91*10312Smckusick 			inputdev = *argv++;
92*10312Smckusick 			argc--;
93*10312Smckusick 			break;
94*10312Smckusick 		case 's':
95*10312Smckusick 			/*
96*10312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
97*10312Smckusick 			 */
98*10312Smckusick 			if (argc < 1) {
99*10312Smckusick 				fprintf(stderr, "missing dump number\n");
100*10312Smckusick 				done(1);
101*10312Smckusick 			}
102*10312Smckusick 			dumpnum = atoi(*argv++);
103*10312Smckusick 			if (dumpnum <= 0) {
104*10312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
105*10312Smckusick 				done(1);
106*10312Smckusick 			}
107*10312Smckusick 			argc--;
108*10312Smckusick 			break;
1094610Smckusick 		case 't':
110*10312Smckusick 		case 'R':
111*10312Smckusick 		case 'r':
112*10312Smckusick 		case 'x':
11310202Smckusick 			if (command != '\0') {
114*10312Smckusick 				fprintf(stderr,
115*10312Smckusick 					"%c and %c are mutually exclusive\n",
116*10312Smckusick 					*cp, command);
11710202Smckusick 				goto usage;
11810202Smckusick 			}
119*10312Smckusick 			command = *cp;
1204610Smckusick 			break;
1214610Smckusick 		default:
1224700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1234610Smckusick 			goto usage;
1244610Smckusick 		}
1254610Smckusick 	}
12610202Smckusick 	if (command == '\0') {
127*10312Smckusick 		fprintf(stderr, "must specify t, r, R, or x\n");
12810202Smckusick 		goto usage;
12910202Smckusick 	}
130*10312Smckusick 	setinput(inputdev);
13110202Smckusick 	if (argc == 0) {
132*10312Smckusick 		argc = 1;
13310202Smckusick 		*--argv = ".";
13410202Smckusick 	}
135*10312Smckusick 	switch (command) {
136*10312Smckusick 
137*10312Smckusick 	case 't':
138*10312Smckusick 		setup();
139*10312Smckusick 		extractdirs((char *)0);
140*10312Smckusick 		while (argc--) {
141*10312Smckusick 			canon(*argv++, name);
142*10312Smckusick 			if ((ino = psearch(name)) == 0 ||
143*10312Smckusick 			    BIT(ino, dumpmap) == 0) {
144*10312Smckusick 				fprintf(stderr, "%s: not on tape\n", name);
1458505Smckusick 				continue;
146*10312Smckusick 			}
147*10312Smckusick 			if (hflag)
148*10312Smckusick 				treescan(name, ino, listfile);
1494837Smckusic 			else
150*10312Smckusick 				listfile(name, ino, inodetype(ino));
1514837Smckusic 		}
152*10312Smckusick 		done(0);
1534837Smckusic 
154*10312Smckusick 	case 'x':
155*10312Smckusick 		setup();
156*10312Smckusick 		extractdirs(dirmodefile);
157*10312Smckusick 		initsymtable((char *)0);
158*10312Smckusick 		while (argc--) {
159*10312Smckusick 			canon(*argv++, name);
160*10312Smckusick 			if ((ino = psearch(name)) == 0 ||
161*10312Smckusick 			    BIT(ino, dumpmap) == 0) {
162*10312Smckusick 				fprintf(stderr, "%s: not on tape\n", name);
1636289Smckusick 				continue;
1646289Smckusick 			}
165*10312Smckusick 			if (mflag)
166*10312Smckusick 				pathcheck(name);
167*10312Smckusick 			if (hflag)
168*10312Smckusick 				treescan(name, ino, addfile);
169*10312Smckusick 			else
170*10312Smckusick 				addfile(name, ino, inodetype(ino));
1715943Smckusic 		}
172*10312Smckusick 		createfiles();
173*10312Smckusick 		createlinks();
174*10312Smckusick 		setdirmodes(dirmodefile);
175*10312Smckusick 		if (dflag)
176*10312Smckusick 			checkrestore();
177*10312Smckusick 		done(0);
1784843Smckusic 
179*10312Smckusick 	case 'r':
180*10312Smckusick 		setup();
181*10312Smckusick 		if (dumptime > 0) {
182*10312Smckusick 			/*
183*10312Smckusick 			 * This is an incremental dump tape.
184*10312Smckusick 			 */
185*10312Smckusick 			vprintf(stdout, "Begin incremental restore\n");
186*10312Smckusick 			initsymtable(symtbl);
187*10312Smckusick 			extractdirs(dirmodefile);
188*10312Smckusick 			removeoldleaves();
189*10312Smckusick 			vprintf(stdout, "Calculate node updates.\n");
190*10312Smckusick 			treescan(".", ROOTINO, nodeupdates);
191*10312Smckusick 			findunreflinks();
192*10312Smckusick 			removeoldnodes();
193*10312Smckusick 		} else {
194*10312Smckusick 			/*
195*10312Smckusick 			 * This is a level zero dump tape.
196*10312Smckusick 			 */
197*10312Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
198*10312Smckusick 			initsymtable((char *)0);
199*10312Smckusick 			extractdirs(dirmodefile);
200*10312Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
201*10312Smckusick 			treescan(".", ROOTINO, nodeupdates);
2024843Smckusic 		}
203*10312Smckusick 		createleaves(symtbl);
204*10312Smckusick 		createlinks();
205*10312Smckusick 		setdirmodes(dirmodefile);
206*10312Smckusick 		checkrestore();
207*10312Smckusick 		if (dflag) {
208*10312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
209*10312Smckusick 			treescan(".", ROOTINO, verifyfile);
2104610Smckusick 		}
211*10312Smckusick 		dumpsymtable(symtbl, (long)1);
212*10312Smckusick 		done(0);
2134610Smckusick 
214*10312Smckusick 	case 'R':
215*10312Smckusick 		initsymtable(symtbl);
216*10312Smckusick 		skipmaps();
217*10312Smckusick 		skipdirs();
218*10312Smckusick 		createleaves(symtbl);
219*10312Smckusick 		createlinks();
220*10312Smckusick 		setdirmodes(dirmodefile);
221*10312Smckusick 		checkrestore();
222*10312Smckusick 		dumpsymtable(symtbl, (long)1);
223*10312Smckusick 		done(0);
2244843Smckusic 	}
2254843Smckusic }
226