xref: /csrg-svn/sbin/restore/main.c (revision 11320)
110312Smckusick /* Copyright (c) 1983 Regents of the University of California */
24610Smckusick 
36846Smckusick #ifndef lint
4*11320Smckusick static char sccsid[] = "@(#)main.c	3.4	(Berkeley)	83/02/28";
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;
4411308Smckusick 	ino_t ino;
4510312Smckusick 	char *inputdev = "/dev/rmt8";
4611308Smckusick 	char *symtbl = "./restoresymtable";
4711308Smckusick 	char *dirmodefile = "./dirmodes";
48*11320Smckusick 	char name[BUFSIZ];
494700Smckusic 	int (*signal())();
5010312Smckusick 	extern int onintr();
514610Smckusick 
5210312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
5311125Smckusick 		signal(SIGINT, SIG_IGN);
5410312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
5511125Smckusick 		signal(SIGTERM, SIG_IGN);
5611308Smckusick 	setlinebuf(stderr);
574610Smckusick 	if (argc < 2) {
584610Smckusick usage:
5910312Smckusick 		fprintf(stderr, "Usage: restor xtfhmsvy file file... or restor rRfsvy\n");
604700Smckusic 		done(1);
614610Smckusick 	}
624610Smckusick 	argv++;
634610Smckusick 	argc -= 2;
6410202Smckusick 	command = '\0';
654610Smckusick 	for (cp = *argv++; *cp; cp++) {
664610Smckusick 		switch (*cp) {
674610Smckusick 		case '-':
684610Smckusick 			break;
698302Smckusick 		case 'c':
708302Smckusick 			cvtflag++;
718302Smckusick 			break;
7210312Smckusick 		case 'd':
7310312Smckusick 			dflag++;
744610Smckusick 			break;
754610Smckusick 		case 'h':
7610202Smckusick 			hflag = 0;
774610Smckusick 			break;
784610Smckusick 		case 'm':
7910202Smckusick 			mflag = 0;
804610Smckusick 			break;
818374Smckusick 		case 'v':
828374Smckusick 			vflag++;
838374Smckusick 			break;
848374Smckusick 		case 'y':
858374Smckusick 			yflag++;
868374Smckusick 			break;
8710312Smckusick 		case 'f':
8810312Smckusick 			inputdev = *argv++;
8910312Smckusick 			argc--;
9010312Smckusick 			break;
9110312Smckusick 		case 's':
9210312Smckusick 			/*
9310312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
9410312Smckusick 			 */
9510312Smckusick 			dumpnum = atoi(*argv++);
9610312Smckusick 			if (dumpnum <= 0) {
9710312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
9810312Smckusick 				done(1);
9910312Smckusick 			}
10010312Smckusick 			argc--;
10110312Smckusick 			break;
1024610Smckusick 		case 't':
10311125Smckusick 			if (command != '\0') {
10411125Smckusick 				fprintf(stderr,
10511125Smckusick 					"t and %c are mutually exclusive\n",
10611125Smckusick 					command);
10711125Smckusick 				goto usage;
10811125Smckusick 			}
10911125Smckusick 			command = 't';
11011302Smckusick 			break;
11110312Smckusick 		case 'R':
11211125Smckusick 			if (command != '\0') {
11311125Smckusick 				fprintf(stderr,
11411125Smckusick 					"R and %c are mutually exclusive\n",
11511125Smckusick 					command);
11611125Smckusick 				goto usage;
11711125Smckusick 			}
11811125Smckusick 			command = 'R';
11911302Smckusick 			break;
12010312Smckusick 		case 'r':
12111125Smckusick 			if (command != '\0') {
12211125Smckusick 				fprintf(stderr,
12311125Smckusick 					"r and %c are mutually exclusive\n",
12411125Smckusick 					command);
12511125Smckusick 				goto usage;
12611125Smckusick 			}
12711125Smckusick 			command = 'r';
12811302Smckusick 			break;
12910312Smckusick 		case 'x':
13010202Smckusick 			if (command != '\0') {
13110312Smckusick 				fprintf(stderr,
13211125Smckusick 					"x and %c are mutually exclusive\n",
13311125Smckusick 					command);
13410202Smckusick 				goto usage;
13510202Smckusick 			}
13611125Smckusick 			command = 'x';
1374610Smckusick 			break;
1384610Smckusick 		default:
1394700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1404610Smckusick 			goto usage;
1414610Smckusick 		}
1424610Smckusick 	}
14310202Smckusick 	if (command == '\0') {
14410312Smckusick 		fprintf(stderr, "must specify t, r, R, or x\n");
14510202Smckusick 		goto usage;
14610202Smckusick 	}
14710312Smckusick 	setinput(inputdev);
14810202Smckusick 	if (argc == 0) {
14910312Smckusick 		argc = 1;
15010202Smckusick 		*--argv = ".";
15110202Smckusick 	}
15210312Smckusick 	switch (command) {
15310312Smckusick 
15410312Smckusick 	case 't':
15510312Smckusick 		setup();
15610312Smckusick 		extractdirs((char *)0);
15710312Smckusick 		while (argc--) {
158*11320Smckusick 			canon(*argv++, name);
159*11320Smckusick 			if ((ino = psearch(name)) == 0 ||
16010312Smckusick 			    BIT(ino, dumpmap) == 0) {
161*11320Smckusick 				fprintf(stderr, "%s: not on tape\n", name);
1628505Smckusick 				continue;
16310312Smckusick 			}
164*11320Smckusick 			treescan(name, ino, listfile);
1654837Smckusic 		}
16610312Smckusick 		done(0);
1674837Smckusic 
16810312Smckusick 	case 'x':
16910312Smckusick 		setup();
17010312Smckusick 		extractdirs(dirmodefile);
17111125Smckusick 		entry = (struct entry **)
17211125Smckusick 			calloc((int)maxino, sizeof(struct entry *));
17311125Smckusick 		if (entry == (struct entry **)NIL)
17411125Smckusick 			panic("no memory for entry table\n");
17511125Smckusick 		(void)addentry(".", ROOTINO, NODE);
17610312Smckusick 		while (argc--) {
177*11320Smckusick 			canon(*argv++, name);
178*11320Smckusick 			if ((ino = psearch(name)) == 0 ||
17910312Smckusick 			    BIT(ino, dumpmap) == 0) {
180*11320Smckusick 				fprintf(stderr, "%s: not on tape\n", name);
1816289Smckusick 				continue;
1826289Smckusick 			}
18310312Smckusick 			if (mflag)
184*11320Smckusick 				pathcheck(name, NULL);
18510312Smckusick 			if (hflag)
186*11320Smckusick 				treescan(name, ino, addfile);
18710312Smckusick 			else
188*11320Smckusick 				addfile(name, ino, inodetype(ino));
1895943Smckusic 		}
19010312Smckusick 		createfiles();
19111308Smckusick 		createlinks();
19210312Smckusick 		setdirmodes(dirmodefile);
19310312Smckusick 		if (dflag)
19410312Smckusick 			checkrestore();
19510312Smckusick 		done(0);
1964843Smckusic 
19710312Smckusick 	case 'r':
19810312Smckusick 		setup();
19910312Smckusick 		if (dumptime > 0) {
20010312Smckusick 			initsymtable(symtbl);
20110312Smckusick 		} else {
20211125Smckusick 			entry = (struct entry **)
20311125Smckusick 				calloc((int)maxino, sizeof(struct entry *));
20411125Smckusick 			if (entry == (struct entry **)NIL)
20511125Smckusick 				panic("no memory for entry table\n");
20611125Smckusick 			(void)addentry(".", ROOTINO, NODE);
2074843Smckusic 		}
20811302Smckusick 		extractdirs(dirmodefile);
20911125Smckusick 		markremove();
21011125Smckusick 		if ((ino = psearch(".")) == 0 || BIT(ino, dumpmap) == 0)
21111125Smckusick 			panic("Root directory is not on tape\n");
21211125Smckusick 		vprintf(stdout, "Calculate extraction list.\n");
21311125Smckusick 		treescan(".", ino, markfile);
21411125Smckusick 		findunref();
21511125Smckusick 		removeleaves();
21611125Smckusick 		renamenodes();
21711125Smckusick 		createnodes();
21811125Smckusick 		renameleaves();
21911125Smckusick 		removenodes();
22010312Smckusick 		createleaves(symtbl);
22110312Smckusick 		createlinks();
22210312Smckusick 		setdirmodes(dirmodefile);
22310312Smckusick 		checkrestore();
22410312Smckusick 		if (dflag) {
22510312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
22610312Smckusick 			treescan(".", ROOTINO, verifyfile);
2274610Smckusick 		}
22810312Smckusick 		dumpsymtable(symtbl, (long)1);
22910312Smckusick 		done(0);
2304610Smckusick 
23110312Smckusick 	case 'R':
23210312Smckusick 		initsymtable(symtbl);
233*11320Smckusick 		skipmaps();
234*11320Smckusick 		skipdirs();
23510312Smckusick 		createleaves(symtbl);
23610312Smckusick 		createlinks();
23710312Smckusick 		setdirmodes(dirmodefile);
23810312Smckusick 		checkrestore();
23910312Smckusick 		dumpsymtable(symtbl, (long)1);
24010312Smckusick 		done(0);
2414843Smckusic 	}
2424843Smckusic }
243