xref: /csrg-svn/sbin/restore/main.c (revision 11302)
110312Smckusick /* Copyright (c) 1983 Regents of the University of California */
24610Smckusick 
36846Smckusick #ifndef lint
4*11302Smckusick static char sccsid[] = "@(#)main.c	3.2	(Berkeley)	83/02/26";
56846Smckusick #endif
64610Smckusick 
710312Smckusick /*
810312Smckusick  *	Modified to recursively extract all files within a subtree
910312Smckusick  *	(supressed by the h option) and recreate the heirarchical
1010312Smckusick  *	structure of that subtree and move extracted files to their
1110312Smckusick  *	proper homes (supressed by the m option).
1210312Smckusick  *	Includes the s (skip files) option for use with multiple
1310312Smckusick  *	dumps on a single tape.
144610Smckusick  *	8/29/80		by Mike Litzkow
154610Smckusick  *
1610312Smckusick  *	Modified to work on the new file system and to recover from
1710312Smckusick  *	tape read errors.
186846Smckusick  *	1/19/82		by Kirk McKusick
196846Smckusick  *
2010312Smckusick  *	Full incremental restore running entirely in user code.
2110312Smckusick  *	1/19/83		by Kirk McKusick
224610Smckusick  */
234610Smckusick 
2410312Smckusick #include "restore.h"
254610Smckusick #include <signal.h>
264610Smckusick 
2710312Smckusick int	cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
2810312Smckusick int	hflag = 1, mflag = 1;
2910312Smckusick char	command = '\0';
3010312Smckusick long	dumpnum = 1;
3110312Smckusick long	volno = 1;
325327Smckusic char	*dumpmap;
335327Smckusic char	*clrimap;
3410312Smckusick ino_t	maxino;
3510312Smckusick time_t	dumptime;
36*11302Smckusick time_t	dumpdate;
3711125Smckusick struct	entry **entry;
384610Smckusick 
396846Smckusick main(argc, argv)
404700Smckusic 	int argc;
414700Smckusic 	char *argv[];
424610Smckusick {
434610Smckusick 	register char *cp;
4410312Smckusick 	char *inputdev = "/dev/rmt8";
4511125Smckusick 	char *symtbl = "./lost+found/restoresymtable";
4611125Smckusick 	char *dirmodefile = "./lost+found/dirmodes";
474700Smckusic 	int (*signal())();
4810312Smckusick 	extern int onintr();
4911125Smckusick 	ino_t ino;
504610Smckusick 
5110312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
5211125Smckusick 		signal(SIGINT, SIG_IGN);
5310312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
5411125Smckusick 		signal(SIGTERM, SIG_IGN);
554610Smckusick 	if (argc < 2) {
564610Smckusick usage:
5710312Smckusick 		fprintf(stderr, "Usage: restor xtfhmsvy file file... or restor rRfsvy\n");
584700Smckusic 		done(1);
594610Smckusick 	}
604610Smckusick 	argv++;
614610Smckusick 	argc -= 2;
6210202Smckusick 	command = '\0';
634610Smckusick 	for (cp = *argv++; *cp; cp++) {
644610Smckusick 		switch (*cp) {
654610Smckusick 		case '-':
664610Smckusick 			break;
678302Smckusick 		case 'c':
688302Smckusick 			cvtflag++;
698302Smckusick 			break;
7010312Smckusick 		case 'd':
7110312Smckusick 			dflag++;
724610Smckusick 			break;
734610Smckusick 		case 'h':
7410202Smckusick 			hflag = 0;
754610Smckusick 			break;
764610Smckusick 		case 'm':
7710202Smckusick 			mflag = 0;
784610Smckusick 			break;
798374Smckusick 		case 'v':
808374Smckusick 			vflag++;
818374Smckusick 			break;
828374Smckusick 		case 'y':
838374Smckusick 			yflag++;
848374Smckusick 			break;
8510312Smckusick 		case 'f':
8610312Smckusick 			inputdev = *argv++;
8710312Smckusick 			argc--;
8810312Smckusick 			break;
8910312Smckusick 		case 's':
9010312Smckusick 			/*
9110312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
9210312Smckusick 			 */
9310312Smckusick 			dumpnum = atoi(*argv++);
9410312Smckusick 			if (dumpnum <= 0) {
9510312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
9610312Smckusick 				done(1);
9710312Smckusick 			}
9810312Smckusick 			argc--;
9910312Smckusick 			break;
1004610Smckusick 		case 't':
10111125Smckusick 			if (command != '\0') {
10211125Smckusick 				fprintf(stderr,
10311125Smckusick 					"t and %c are mutually exclusive\n",
10411125Smckusick 					command);
10511125Smckusick 				goto usage;
10611125Smckusick 			}
10711125Smckusick 			command = 't';
108*11302Smckusick 			break;
10910312Smckusick 		case 'R':
11011125Smckusick 			if (command != '\0') {
11111125Smckusick 				fprintf(stderr,
11211125Smckusick 					"R and %c are mutually exclusive\n",
11311125Smckusick 					command);
11411125Smckusick 				goto usage;
11511125Smckusick 			}
11611125Smckusick 			command = 'R';
117*11302Smckusick 			break;
11810312Smckusick 		case 'r':
11911125Smckusick 			if (command != '\0') {
12011125Smckusick 				fprintf(stderr,
12111125Smckusick 					"r and %c are mutually exclusive\n",
12211125Smckusick 					command);
12311125Smckusick 				goto usage;
12411125Smckusick 			}
12511125Smckusick 			command = 'r';
126*11302Smckusick 			break;
12710312Smckusick 		case 'x':
12810202Smckusick 			if (command != '\0') {
12910312Smckusick 				fprintf(stderr,
13011125Smckusick 					"x and %c are mutually exclusive\n",
13111125Smckusick 					command);
13210202Smckusick 				goto usage;
13310202Smckusick 			}
13411125Smckusick 			command = 'x';
1354610Smckusick 			break;
1364610Smckusick 		default:
1374700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1384610Smckusick 			goto usage;
1394610Smckusick 		}
1404610Smckusick 	}
14110202Smckusick 	if (command == '\0') {
14210312Smckusick 		fprintf(stderr, "must specify t, r, R, or x\n");
14310202Smckusick 		goto usage;
14410202Smckusick 	}
14510312Smckusick 	setinput(inputdev);
14610202Smckusick 	if (argc == 0) {
14710312Smckusick 		argc = 1;
14810202Smckusick 		*--argv = ".";
14910202Smckusick 	}
15010312Smckusick 	switch (command) {
15110312Smckusick 
15210312Smckusick 	case 't':
15310312Smckusick 		setup();
15410312Smckusick 		extractdirs((char *)0);
15510312Smckusick 		while (argc--) {
15611125Smckusick 			if ((ino = psearch(*argv)) == 0 ||
15710312Smckusick 			    BIT(ino, dumpmap) == 0) {
15811125Smckusick 				fprintf(stderr, "%s: not on tape\n", *argv++);
1598505Smckusick 				continue;
16010312Smckusick 			}
16111125Smckusick 			treescan(*argv++, ino, listfile);
1624837Smckusic 		}
16310312Smckusick 		done(0);
1644837Smckusic 
16510312Smckusick 	case 'x':
16610312Smckusick 		setup();
16710312Smckusick 		extractdirs(dirmodefile);
16811125Smckusick 		entry = (struct entry **)
16911125Smckusick 			calloc((int)maxino, sizeof(struct entry *));
17011125Smckusick 		if (entry == (struct entry **)NIL)
17111125Smckusick 			panic("no memory for entry table\n");
17211125Smckusick 		(void)addentry(".", ROOTINO, NODE);
17310312Smckusick 		while (argc--) {
17411125Smckusick 			if ((ino = psearch(*argv)) == 0 ||
17510312Smckusick 			    BIT(ino, dumpmap) == 0) {
17611125Smckusick 				fprintf(stderr, "%s: not on tape\n", *argv++);
1776289Smckusick 				continue;
1786289Smckusick 			}
17910312Smckusick 			if (mflag)
18011125Smckusick 				pathcheck(*argv, NEW);
18110312Smckusick 			if (hflag)
18211125Smckusick 				treescan(*argv++, ino, addfile);
18310312Smckusick 			else
18411125Smckusick 				addfile(*argv++, ino, LEAF);
1855943Smckusic 		}
18610312Smckusick 		createfiles();
18710312Smckusick 		setdirmodes(dirmodefile);
18810312Smckusick 		if (dflag)
18910312Smckusick 			checkrestore();
19010312Smckusick 		done(0);
1914843Smckusic 
19210312Smckusick 	case 'r':
19310312Smckusick 		setup();
19410312Smckusick 		if (dumptime > 0) {
19510312Smckusick 			initsymtable(symtbl);
19610312Smckusick 		} else {
19711125Smckusick 			entry = (struct entry **)
19811125Smckusick 				calloc((int)maxino, sizeof(struct entry *));
19911125Smckusick 			if (entry == (struct entry **)NIL)
20011125Smckusick 				panic("no memory for entry table\n");
20111125Smckusick 			(void)addentry(".", ROOTINO, NODE);
2024843Smckusic 		}
203*11302Smckusick 		extractdirs(dirmodefile);
20411125Smckusick 		markremove();
20511125Smckusick 		if ((ino = psearch(".")) == 0 || BIT(ino, dumpmap) == 0)
20611125Smckusick 			panic("Root directory is not on tape\n");
20711125Smckusick 		vprintf(stdout, "Calculate extraction list.\n");
20811125Smckusick 		treescan(".", ino, markfile);
20911125Smckusick 		findunref();
21011125Smckusick 		removeleaves();
21111125Smckusick 		renamenodes();
21211125Smckusick 		createnodes();
21311125Smckusick 		renameleaves();
21411125Smckusick 		removenodes();
21510312Smckusick 		createleaves(symtbl);
21610312Smckusick 		createlinks();
21710312Smckusick 		setdirmodes(dirmodefile);
21810312Smckusick 		checkrestore();
21910312Smckusick 		if (dflag) {
22010312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
22110312Smckusick 			treescan(".", ROOTINO, verifyfile);
2224610Smckusick 		}
22310312Smckusick 		dumpsymtable(symtbl, (long)1);
22410312Smckusick 		done(0);
2254610Smckusick 
22610312Smckusick 	case 'R':
22710312Smckusick 		initsymtable(symtbl);
22810312Smckusick 		createleaves(symtbl);
22910312Smckusick 		createlinks();
23010312Smckusick 		setdirmodes(dirmodefile);
23110312Smckusick 		checkrestore();
23210312Smckusick 		dumpsymtable(symtbl, (long)1);
23310312Smckusick 		done(0);
2344843Smckusic 	}
2354843Smckusic }
236