xref: /csrg-svn/sbin/restore/main.c (revision 18496)
16846Smckusick #ifndef lint
2*18496Smckusick static char sccsid[] = "@(#)main.c	3.16	(Berkeley)	85/03/24";
36846Smckusick #endif
44610Smckusick 
514564Ssam /* Copyright (c) 1983 Regents of the University of California */
614564Ssam 
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  *
2011993Smckusick  *	Full incremental restore running entirely in user code and
2111993Smckusick  *	interactive tape browser.
2210312Smckusick  *	1/19/83		by Kirk McKusick
234610Smckusick  */
244610Smckusick 
2510312Smckusick #include "restore.h"
2617707Smckusick #include <dumprestor.h>
274610Smckusick #include <signal.h>
284610Smckusick 
29*18496Smckusick int	bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
3010312Smckusick int	hflag = 1, mflag = 1;
3110312Smckusick char	command = '\0';
3210312Smckusick long	dumpnum = 1;
3311438Smckusick long	volno = 0;
34*18496Smckusick long	ntrec;
355327Smckusic char	*dumpmap;
365327Smckusic char	*clrimap;
3710312Smckusick ino_t	maxino;
3810312Smckusick time_t	dumptime;
3911302Smckusick time_t	dumpdate;
4011993Smckusick FILE 	*terminal;
414610Smckusick 
426846Smckusick main(argc, argv)
434700Smckusic 	int argc;
444700Smckusic 	char *argv[];
454610Smckusick {
464610Smckusick 	register char *cp;
4711308Smckusick 	ino_t ino;
4810312Smckusick 	char *inputdev = "/dev/rmt8";
4911308Smckusick 	char *symtbl = "./restoresymtable";
5011993Smckusick 	char name[MAXPATHLEN];
514700Smckusic 	int (*signal())();
5210312Smckusick 	extern int onintr();
534610Smckusick 
5410312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
5511438Smckusick 		(void) signal(SIGINT, SIG_IGN);
5610312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
5711438Smckusick 		(void) signal(SIGTERM, SIG_IGN);
5811308Smckusick 	setlinebuf(stderr);
594610Smckusick 	if (argc < 2) {
604610Smckusick usage:
6111993Smckusick 		fprintf(stderr, "Usage:\n%s%s%s%s%s",
6211993Smckusick 			"\trestore tfhsvy [file file ...]\n",
6311993Smckusick 			"\trestore xfhmsvy [file file ...]\n",
6411993Smckusick 			"\trestore ifhmsvy\n",
6511993Smckusick 			"\trestore rfsvy\n",
6611993Smckusick 			"\trestore Rfsvy\n");
674700Smckusic 		done(1);
684610Smckusick 	}
694610Smckusick 	argv++;
704610Smckusick 	argc -= 2;
7110202Smckusick 	command = '\0';
724610Smckusick 	for (cp = *argv++; *cp; cp++) {
734610Smckusick 		switch (*cp) {
744610Smckusick 		case '-':
754610Smckusick 			break;
768302Smckusick 		case 'c':
778302Smckusick 			cvtflag++;
788302Smckusick 			break;
7910312Smckusick 		case 'd':
8010312Smckusick 			dflag++;
814610Smckusick 			break;
824610Smckusick 		case 'h':
8310202Smckusick 			hflag = 0;
844610Smckusick 			break;
854610Smckusick 		case 'm':
8610202Smckusick 			mflag = 0;
874610Smckusick 			break;
888374Smckusick 		case 'v':
898374Smckusick 			vflag++;
908374Smckusick 			break;
918374Smckusick 		case 'y':
928374Smckusick 			yflag++;
938374Smckusick 			break;
9410312Smckusick 		case 'f':
9511400Smckusick 			if (argc < 1) {
9611400Smckusick 				fprintf(stderr, "missing device specifier\n");
9711400Smckusick 				done(1);
9811400Smckusick 			}
9910312Smckusick 			inputdev = *argv++;
10010312Smckusick 			argc--;
10110312Smckusick 			break;
10217707Smckusick 		case 'b':
10317707Smckusick 			/*
10417707Smckusick 			 * change default tape blocksize
10517707Smckusick 			 */
106*18496Smckusick 			bflag++;
10717707Smckusick 			if (argc < 1) {
10817707Smckusick 				fprintf(stderr, "missing block size\n");
10917707Smckusick 				done(1);
11017707Smckusick 			}
11117707Smckusick 			ntrec = atoi(*argv++);
11217707Smckusick 			if (ntrec <= 0) {
11317707Smckusick 				fprintf(stderr, "Block size must be a positive integer\n");
11417707Smckusick 				done(1);
11517707Smckusick 			}
11617707Smckusick 			argc--;
11717707Smckusick 			break;
11810312Smckusick 		case 's':
11910312Smckusick 			/*
12010312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
12110312Smckusick 			 */
12211400Smckusick 			if (argc < 1) {
12311400Smckusick 				fprintf(stderr, "missing dump number\n");
12411400Smckusick 				done(1);
12511400Smckusick 			}
12610312Smckusick 			dumpnum = atoi(*argv++);
12710312Smckusick 			if (dumpnum <= 0) {
12810312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
12910312Smckusick 				done(1);
13010312Smckusick 			}
13110312Smckusick 			argc--;
13210312Smckusick 			break;
1334610Smckusick 		case 't':
13410312Smckusick 		case 'R':
13510312Smckusick 		case 'r':
13610312Smckusick 		case 'x':
13711993Smckusick 		case 'i':
13810202Smckusick 			if (command != '\0') {
13910312Smckusick 				fprintf(stderr,
14011400Smckusick 					"%c and %c are mutually exclusive\n",
14111400Smckusick 					*cp, command);
14210202Smckusick 				goto usage;
14310202Smckusick 			}
14411400Smckusick 			command = *cp;
1454610Smckusick 			break;
1464610Smckusick 		default:
1474700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1484610Smckusick 			goto usage;
1494610Smckusick 		}
1504610Smckusick 	}
15110202Smckusick 	if (command == '\0') {
15211993Smckusick 		fprintf(stderr, "must specify i, t, r, R, or x\n");
15310202Smckusick 		goto usage;
15410202Smckusick 	}
15510312Smckusick 	setinput(inputdev);
15610202Smckusick 	if (argc == 0) {
15710312Smckusick 		argc = 1;
15810202Smckusick 		*--argv = ".";
15910202Smckusick 	}
16010312Smckusick 	switch (command) {
16111993Smckusick 	/*
16211993Smckusick 	 * Interactive mode.
16311993Smckusick 	 */
16411993Smckusick 	case 'i':
16510312Smckusick 		setup();
16611993Smckusick 		extractdirs(1);
16711438Smckusick 		initsymtable((char *)0);
16811993Smckusick 		runcmdshell();
16910312Smckusick 		done(0);
17011993Smckusick 	/*
17111993Smckusick 	 * Incremental restoration of a file system.
17211993Smckusick 	 */
17310312Smckusick 	case 'r':
17410312Smckusick 		setup();
17510312Smckusick 		if (dumptime > 0) {
17611438Smckusick 			/*
17711438Smckusick 			 * This is an incremental dump tape.
17811438Smckusick 			 */
17911438Smckusick 			vprintf(stdout, "Begin incremental restore\n");
18010312Smckusick 			initsymtable(symtbl);
18111993Smckusick 			extractdirs(1);
18211438Smckusick 			removeoldleaves();
18311438Smckusick 			vprintf(stdout, "Calculate node updates.\n");
18411438Smckusick 			treescan(".", ROOTINO, nodeupdates);
18511438Smckusick 			findunreflinks();
18611438Smckusick 			removeoldnodes();
18710312Smckusick 		} else {
18811438Smckusick 			/*
18911438Smckusick 			 * This is a level zero dump tape.
19011438Smckusick 			 */
19111438Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
19211438Smckusick 			initsymtable((char *)0);
19311993Smckusick 			extractdirs(1);
19411438Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
19511438Smckusick 			treescan(".", ROOTINO, nodeupdates);
1964843Smckusic 		}
19710312Smckusick 		createleaves(symtbl);
19810312Smckusick 		createlinks();
19911993Smckusick 		setdirmodes();
20010312Smckusick 		checkrestore();
20110312Smckusick 		if (dflag) {
20210312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
20310312Smckusick 			treescan(".", ROOTINO, verifyfile);
2044610Smckusick 		}
20510312Smckusick 		dumpsymtable(symtbl, (long)1);
20610312Smckusick 		done(0);
20711993Smckusick 	/*
20811993Smckusick 	 * Resume an incremental file system restoration.
20911993Smckusick 	 */
21010312Smckusick 	case 'R':
21110312Smckusick 		initsymtable(symtbl);
21211320Smckusick 		skipmaps();
21311320Smckusick 		skipdirs();
21410312Smckusick 		createleaves(symtbl);
21510312Smckusick 		createlinks();
21611993Smckusick 		setdirmodes();
21710312Smckusick 		checkrestore();
21810312Smckusick 		dumpsymtable(symtbl, (long)1);
21910312Smckusick 		done(0);
22011993Smckusick 	/*
22111993Smckusick 	 * List contents of tape.
22211993Smckusick 	 */
22311993Smckusick 	case 't':
22411993Smckusick 		setup();
22511993Smckusick 		extractdirs(0);
22611993Smckusick 		while (argc--) {
22711993Smckusick 			canon(*argv++, name);
22811993Smckusick 			ino = dirlookup(name);
22911993Smckusick 			if (ino == 0)
23011993Smckusick 				continue;
23111993Smckusick 			treescan(name, ino, listfile);
23211993Smckusick 		}
23311993Smckusick 		done(0);
23411993Smckusick 	/*
23511993Smckusick 	 * Batch extraction of tape contents.
23611993Smckusick 	 */
23711993Smckusick 	case 'x':
23811993Smckusick 		setup();
23911993Smckusick 		extractdirs(1);
24011993Smckusick 		initsymtable((char *)0);
24111993Smckusick 		while (argc--) {
24211993Smckusick 			canon(*argv++, name);
24311993Smckusick 			ino = dirlookup(name);
24411993Smckusick 			if (ino == 0)
24511993Smckusick 				continue;
24611993Smckusick 			if (mflag)
24711993Smckusick 				pathcheck(name);
24811993Smckusick 			treescan(name, ino, addfile);
24911993Smckusick 		}
25011993Smckusick 		createfiles();
25111993Smckusick 		createlinks();
25211993Smckusick 		setdirmodes();
25311993Smckusick 		if (dflag)
25411993Smckusick 			checkrestore();
25511993Smckusick 		done(0);
2564843Smckusic 	}
2574843Smckusic }
258