xref: /csrg-svn/sbin/restore/main.c (revision 11438)
110312Smckusick /* Copyright (c) 1983 Regents of the University of California */
24610Smckusick 
36846Smckusick #ifndef lint
4*11438Smckusick static char sccsid[] = "@(#)main.c	3.7	(Berkeley)	83/03/08";
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;
31*11438Smckusick long	volno = 0;
325327Smckusic char	*dumpmap;
335327Smckusic char	*clrimap;
3410312Smckusick ino_t	maxino;
3510312Smckusick time_t	dumptime;
3611302Smckusick time_t	dumpdate;
374610Smckusick 
386846Smckusick main(argc, argv)
394700Smckusic 	int argc;
404700Smckusic 	char *argv[];
414610Smckusick {
424610Smckusick 	register char *cp;
4311308Smckusick 	ino_t ino;
4410312Smckusick 	char *inputdev = "/dev/rmt8";
4511308Smckusick 	char *symtbl = "./restoresymtable";
4611308Smckusick 	char *dirmodefile = "./dirmodes";
4711320Smckusick 	char name[BUFSIZ];
484700Smckusic 	int (*signal())();
4910312Smckusick 	extern int onintr();
504610Smckusick 
5110312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
52*11438Smckusick 		(void) signal(SIGINT, SIG_IGN);
5310312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
54*11438Smckusick 		(void) signal(SIGTERM, SIG_IGN);
5511308Smckusick 	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':
8711400Smckusick 			if (argc < 1) {
8811400Smckusick 				fprintf(stderr, "missing device specifier\n");
8911400Smckusick 				done(1);
9011400Smckusick 			}
9110312Smckusick 			inputdev = *argv++;
9210312Smckusick 			argc--;
9310312Smckusick 			break;
9410312Smckusick 		case 's':
9510312Smckusick 			/*
9610312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
9710312Smckusick 			 */
9811400Smckusick 			if (argc < 1) {
9911400Smckusick 				fprintf(stderr, "missing dump number\n");
10011400Smckusick 				done(1);
10111400Smckusick 			}
10210312Smckusick 			dumpnum = atoi(*argv++);
10310312Smckusick 			if (dumpnum <= 0) {
10410312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
10510312Smckusick 				done(1);
10610312Smckusick 			}
10710312Smckusick 			argc--;
10810312Smckusick 			break;
1094610Smckusick 		case 't':
11010312Smckusick 		case 'R':
11110312Smckusick 		case 'r':
11210312Smckusick 		case 'x':
11310202Smckusick 			if (command != '\0') {
11410312Smckusick 				fprintf(stderr,
11511400Smckusick 					"%c and %c are mutually exclusive\n",
11611400Smckusick 					*cp, command);
11710202Smckusick 				goto usage;
11810202Smckusick 			}
11911400Smckusick 			command = *cp;
1204610Smckusick 			break;
1214610Smckusick 		default:
1224700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1234610Smckusick 			goto usage;
1244610Smckusick 		}
1254610Smckusick 	}
12610202Smckusick 	if (command == '\0') {
12710312Smckusick 		fprintf(stderr, "must specify t, r, R, or x\n");
12810202Smckusick 		goto usage;
12910202Smckusick 	}
13010312Smckusick 	setinput(inputdev);
13110202Smckusick 	if (argc == 0) {
13210312Smckusick 		argc = 1;
13310202Smckusick 		*--argv = ".";
13410202Smckusick 	}
13510312Smckusick 	switch (command) {
13610312Smckusick 
13710312Smckusick 	case 't':
13810312Smckusick 		setup();
13910312Smckusick 		extractdirs((char *)0);
14010312Smckusick 		while (argc--) {
14111320Smckusick 			canon(*argv++, name);
14211320Smckusick 			if ((ino = psearch(name)) == 0 ||
14310312Smckusick 			    BIT(ino, dumpmap) == 0) {
14411320Smckusick 				fprintf(stderr, "%s: not on tape\n", name);
1458505Smckusick 				continue;
14610312Smckusick 			}
14711400Smckusick 			if (hflag)
14811400Smckusick 				treescan(name, ino, listfile);
14911400Smckusick 			else
15011400Smckusick 				listfile(name, ino, inodetype(ino));
1514837Smckusic 		}
15210312Smckusick 		done(0);
1534837Smckusic 
15410312Smckusick 	case 'x':
15510312Smckusick 		setup();
15610312Smckusick 		extractdirs(dirmodefile);
157*11438Smckusick 		initsymtable((char *)0);
15810312Smckusick 		while (argc--) {
15911320Smckusick 			canon(*argv++, name);
16011320Smckusick 			if ((ino = psearch(name)) == 0 ||
16110312Smckusick 			    BIT(ino, dumpmap) == 0) {
16211320Smckusick 				fprintf(stderr, "%s: not on tape\n", name);
1636289Smckusick 				continue;
1646289Smckusick 			}
16510312Smckusick 			if (mflag)
166*11438Smckusick 				pathcheck(name);
16710312Smckusick 			if (hflag)
16811320Smckusick 				treescan(name, ino, addfile);
16910312Smckusick 			else
17011320Smckusick 				addfile(name, ino, inodetype(ino));
1715943Smckusic 		}
17210312Smckusick 		createfiles();
17311308Smckusick 		createlinks();
17410312Smckusick 		setdirmodes(dirmodefile);
17510312Smckusick 		if (dflag)
17610312Smckusick 			checkrestore();
17710312Smckusick 		done(0);
1784843Smckusic 
17910312Smckusick 	case 'r':
18010312Smckusick 		setup();
18110312Smckusick 		if (dumptime > 0) {
182*11438Smckusick 			/*
183*11438Smckusick 			 * This is an incremental dump tape.
184*11438Smckusick 			 */
185*11438Smckusick 			vprintf(stdout, "Begin incremental restore\n");
18610312Smckusick 			initsymtable(symtbl);
187*11438Smckusick 			extractdirs(dirmodefile);
188*11438Smckusick 			removeoldleaves();
189*11438Smckusick 			vprintf(stdout, "Calculate node updates.\n");
190*11438Smckusick 			treescan(".", ROOTINO, nodeupdates);
191*11438Smckusick 			findunreflinks();
192*11438Smckusick 			removeoldnodes();
19310312Smckusick 		} else {
194*11438Smckusick 			/*
195*11438Smckusick 			 * This is a level zero dump tape.
196*11438Smckusick 			 */
197*11438Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
198*11438Smckusick 			initsymtable((char *)0);
199*11438Smckusick 			extractdirs(dirmodefile);
200*11438Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
201*11438Smckusick 			treescan(".", ROOTINO, nodeupdates);
2024843Smckusic 		}
20310312Smckusick 		createleaves(symtbl);
20410312Smckusick 		createlinks();
20510312Smckusick 		setdirmodes(dirmodefile);
20610312Smckusick 		checkrestore();
20710312Smckusick 		if (dflag) {
20810312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
20910312Smckusick 			treescan(".", ROOTINO, verifyfile);
2104610Smckusick 		}
21110312Smckusick 		dumpsymtable(symtbl, (long)1);
21210312Smckusick 		done(0);
2134610Smckusick 
21410312Smckusick 	case 'R':
21510312Smckusick 		initsymtable(symtbl);
21611320Smckusick 		skipmaps();
21711320Smckusick 		skipdirs();
21810312Smckusick 		createleaves(symtbl);
21910312Smckusick 		createlinks();
22010312Smckusick 		setdirmodes(dirmodefile);
22110312Smckusick 		checkrestore();
22210312Smckusick 		dumpsymtable(symtbl, (long)1);
22310312Smckusick 		done(0);
2244843Smckusic 	}
2254843Smckusic }
226