xref: /csrg-svn/sbin/restore/main.c (revision 11308)
110312Smckusick /* Copyright (c) 1983 Regents of the University of California */
24610Smckusick 
36846Smckusick #ifndef lint
4*11308Smckusick static char sccsid[] = "@(#)main.c	3.3	(Berkeley)	83/02/27";
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;
3611302Smckusick time_t	dumpdate;
3711125Smckusick struct	entry **entry;
384610Smckusick 
396846Smckusick main(argc, argv)
404700Smckusic 	int argc;
414700Smckusic 	char *argv[];
424610Smckusick {
434610Smckusick 	register char *cp;
44*11308Smckusick 	ino_t ino;
4510312Smckusick 	char *inputdev = "/dev/rmt8";
46*11308Smckusick 	char *symtbl = "./restoresymtable";
47*11308Smckusick 	char *dirmodefile = "./dirmodes";
484700Smckusic 	int (*signal())();
4910312Smckusick 	extern int onintr();
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);
55*11308Smckusick 	setlinebuf(stderr);
564610Smckusick 	if (argc < 2) {
574610Smckusick usage:
5810312Smckusick 		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;
7110312Smckusick 		case 'd':
7210312Smckusick 			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;
8610312Smckusick 		case 'f':
8710312Smckusick 			inputdev = *argv++;
8810312Smckusick 			argc--;
8910312Smckusick 			break;
9010312Smckusick 		case 's':
9110312Smckusick 			/*
9210312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
9310312Smckusick 			 */
9410312Smckusick 			dumpnum = atoi(*argv++);
9510312Smckusick 			if (dumpnum <= 0) {
9610312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
9710312Smckusick 				done(1);
9810312Smckusick 			}
9910312Smckusick 			argc--;
10010312Smckusick 			break;
1014610Smckusick 		case 't':
10211125Smckusick 			if (command != '\0') {
10311125Smckusick 				fprintf(stderr,
10411125Smckusick 					"t and %c are mutually exclusive\n",
10511125Smckusick 					command);
10611125Smckusick 				goto usage;
10711125Smckusick 			}
10811125Smckusick 			command = 't';
10911302Smckusick 			break;
11010312Smckusick 		case 'R':
11111125Smckusick 			if (command != '\0') {
11211125Smckusick 				fprintf(stderr,
11311125Smckusick 					"R and %c are mutually exclusive\n",
11411125Smckusick 					command);
11511125Smckusick 				goto usage;
11611125Smckusick 			}
11711125Smckusick 			command = 'R';
11811302Smckusick 			break;
11910312Smckusick 		case 'r':
12011125Smckusick 			if (command != '\0') {
12111125Smckusick 				fprintf(stderr,
12211125Smckusick 					"r and %c are mutually exclusive\n",
12311125Smckusick 					command);
12411125Smckusick 				goto usage;
12511125Smckusick 			}
12611125Smckusick 			command = 'r';
12711302Smckusick 			break;
12810312Smckusick 		case 'x':
12910202Smckusick 			if (command != '\0') {
13010312Smckusick 				fprintf(stderr,
13111125Smckusick 					"x and %c are mutually exclusive\n",
13211125Smckusick 					command);
13310202Smckusick 				goto usage;
13410202Smckusick 			}
13511125Smckusick 			command = 'x';
1364610Smckusick 			break;
1374610Smckusick 		default:
1384700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1394610Smckusick 			goto usage;
1404610Smckusick 		}
1414610Smckusick 	}
14210202Smckusick 	if (command == '\0') {
14310312Smckusick 		fprintf(stderr, "must specify t, r, R, or x\n");
14410202Smckusick 		goto usage;
14510202Smckusick 	}
14610312Smckusick 	setinput(inputdev);
14710202Smckusick 	if (argc == 0) {
14810312Smckusick 		argc = 1;
14910202Smckusick 		*--argv = ".";
15010202Smckusick 	}
15110312Smckusick 	switch (command) {
15210312Smckusick 
15310312Smckusick 	case 't':
15410312Smckusick 		setup();
15510312Smckusick 		extractdirs((char *)0);
15610312Smckusick 		while (argc--) {
15711125Smckusick 			if ((ino = psearch(*argv)) == 0 ||
15810312Smckusick 			    BIT(ino, dumpmap) == 0) {
15911125Smckusick 				fprintf(stderr, "%s: not on tape\n", *argv++);
1608505Smckusick 				continue;
16110312Smckusick 			}
16211125Smckusick 			treescan(*argv++, ino, listfile);
1634837Smckusic 		}
16410312Smckusick 		done(0);
1654837Smckusic 
16610312Smckusick 	case 'x':
16710312Smckusick 		setup();
16810312Smckusick 		extractdirs(dirmodefile);
16911125Smckusick 		entry = (struct entry **)
17011125Smckusick 			calloc((int)maxino, sizeof(struct entry *));
17111125Smckusick 		if (entry == (struct entry **)NIL)
17211125Smckusick 			panic("no memory for entry table\n");
17311125Smckusick 		(void)addentry(".", ROOTINO, NODE);
17410312Smckusick 		while (argc--) {
17511125Smckusick 			if ((ino = psearch(*argv)) == 0 ||
17610312Smckusick 			    BIT(ino, dumpmap) == 0) {
17711125Smckusick 				fprintf(stderr, "%s: not on tape\n", *argv++);
1786289Smckusick 				continue;
1796289Smckusick 			}
18010312Smckusick 			if (mflag)
18111125Smckusick 				pathcheck(*argv, NEW);
18210312Smckusick 			if (hflag)
18311125Smckusick 				treescan(*argv++, ino, addfile);
18410312Smckusick 			else
18511125Smckusick 				addfile(*argv++, ino, LEAF);
1865943Smckusic 		}
187*11308Smckusick 		createnodes();
18810312Smckusick 		createfiles();
189*11308Smckusick 		createlinks();
19010312Smckusick 		setdirmodes(dirmodefile);
19110312Smckusick 		if (dflag)
19210312Smckusick 			checkrestore();
19310312Smckusick 		done(0);
1944843Smckusic 
19510312Smckusick 	case 'r':
19610312Smckusick 		setup();
19710312Smckusick 		if (dumptime > 0) {
19810312Smckusick 			initsymtable(symtbl);
19910312Smckusick 		} else {
20011125Smckusick 			entry = (struct entry **)
20111125Smckusick 				calloc((int)maxino, sizeof(struct entry *));
20211125Smckusick 			if (entry == (struct entry **)NIL)
20311125Smckusick 				panic("no memory for entry table\n");
20411125Smckusick 			(void)addentry(".", ROOTINO, NODE);
2054843Smckusic 		}
20611302Smckusick 		extractdirs(dirmodefile);
20711125Smckusick 		markremove();
20811125Smckusick 		if ((ino = psearch(".")) == 0 || BIT(ino, dumpmap) == 0)
20911125Smckusick 			panic("Root directory is not on tape\n");
21011125Smckusick 		vprintf(stdout, "Calculate extraction list.\n");
21111125Smckusick 		treescan(".", ino, markfile);
21211125Smckusick 		findunref();
21311125Smckusick 		removeleaves();
21411125Smckusick 		renamenodes();
21511125Smckusick 		createnodes();
21611125Smckusick 		renameleaves();
21711125Smckusick 		removenodes();
21810312Smckusick 		createleaves(symtbl);
21910312Smckusick 		createlinks();
22010312Smckusick 		setdirmodes(dirmodefile);
22110312Smckusick 		checkrestore();
22210312Smckusick 		if (dflag) {
22310312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
22410312Smckusick 			treescan(".", ROOTINO, verifyfile);
2254610Smckusick 		}
22610312Smckusick 		dumpsymtable(symtbl, (long)1);
22710312Smckusick 		done(0);
2284610Smckusick 
22910312Smckusick 	case 'R':
23010312Smckusick 		initsymtable(symtbl);
23110312Smckusick 		createleaves(symtbl);
23210312Smckusick 		createlinks();
23310312Smckusick 		setdirmodes(dirmodefile);
23410312Smckusick 		checkrestore();
23510312Smckusick 		dumpsymtable(symtbl, (long)1);
23610312Smckusick 		done(0);
2374843Smckusic 	}
2384843Smckusic }
239