xref: /csrg-svn/sbin/restore/main.c (revision 56428)
121167Sdist /*
236105Sbostic  * Copyright (c) 1983 The Regents of the University of California.
336105Sbostic  * All rights reserved.
436105Sbostic  *
542708Sbostic  * %sccs.include.redist.c%
621167Sdist  */
721167Sdist 
86846Smckusick #ifndef lint
921167Sdist char copyright[] =
1036105Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
1121167Sdist  All rights reserved.\n";
1236105Sbostic #endif /* not lint */
134610Smckusick 
1421167Sdist #ifndef lint
15*56428Smckusick static char sccsid[] = "@(#)main.c	5.10 (Berkeley) 10/05/92";
1636105Sbostic #endif /* not lint */
1714564Ssam 
1810312Smckusick /*
1910312Smckusick  *	Modified to recursively extract all files within a subtree
2010312Smckusick  *	(supressed by the h option) and recreate the heirarchical
2110312Smckusick  *	structure of that subtree and move extracted files to their
2210312Smckusick  *	proper homes (supressed by the m option).
2310312Smckusick  *	Includes the s (skip files) option for use with multiple
2410312Smckusick  *	dumps on a single tape.
254610Smckusick  *	8/29/80		by Mike Litzkow
264610Smckusick  *
2710312Smckusick  *	Modified to work on the new file system and to recover from
2810312Smckusick  *	tape read errors.
296846Smckusick  *	1/19/82		by Kirk McKusick
306846Smckusick  *
3111993Smckusick  *	Full incremental restore running entirely in user code and
3211993Smckusick  *	interactive tape browser.
3310312Smckusick  *	1/19/83		by Kirk McKusick
344610Smckusick  */
354610Smckusick 
3610312Smckusick #include "restore.h"
3723547Smckusick #include <protocols/dumprestore.h>
3837952Sbostic #include <sys/signal.h>
3937952Sbostic #include "pathnames.h"
404610Smckusick 
4118496Smckusick int	bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
4234269Smckusick int	hflag = 1, mflag = 1, Nflag = 0;
4310312Smckusick char	command = '\0';
4410312Smckusick long	dumpnum = 1;
4511438Smckusick long	volno = 0;
4618496Smckusick long	ntrec;
475327Smckusic char	*dumpmap;
485327Smckusic char	*clrimap;
4910312Smckusick ino_t	maxino;
5010312Smckusick time_t	dumptime;
5111302Smckusick time_t	dumpdate;
5211993Smckusick FILE 	*terminal;
534610Smckusick 
54*56428Smckusick int
556846Smckusick main(argc, argv)
564700Smckusic 	int argc;
574700Smckusic 	char *argv[];
584610Smckusick {
594610Smckusick 	register char *cp;
6011308Smckusick 	ino_t ino;
6137952Sbostic 	char *inputdev = _PATH_DEFTAPE;
6211308Smckusick 	char *symtbl = "./restoresymtable";
6311993Smckusick 	char name[MAXPATHLEN];
6439944Sbostic 	void onintr();
654610Smckusick 
6610312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
6711438Smckusick 		(void) signal(SIGINT, SIG_IGN);
6810312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
6911438Smckusick 		(void) signal(SIGTERM, SIG_IGN);
7011308Smckusick 	setlinebuf(stderr);
71*56428Smckusick 	if (argc < 2)
72*56428Smckusick 		usage();
734610Smckusick 	argv++;
744610Smckusick 	argc -= 2;
7510202Smckusick 	command = '\0';
764610Smckusick 	for (cp = *argv++; *cp; cp++) {
774610Smckusick 		switch (*cp) {
784610Smckusick 		case '-':
794610Smckusick 			break;
808302Smckusick 		case 'c':
818302Smckusick 			cvtflag++;
828302Smckusick 			break;
8310312Smckusick 		case 'd':
8410312Smckusick 			dflag++;
854610Smckusick 			break;
864610Smckusick 		case 'h':
8710202Smckusick 			hflag = 0;
884610Smckusick 			break;
894610Smckusick 		case 'm':
9010202Smckusick 			mflag = 0;
914610Smckusick 			break;
9234269Smckusick 		case 'N':
9334269Smckusick 			Nflag++;
9434269Smckusick 			break;
958374Smckusick 		case 'v':
968374Smckusick 			vflag++;
978374Smckusick 			break;
988374Smckusick 		case 'y':
998374Smckusick 			yflag++;
1008374Smckusick 			break;
10110312Smckusick 		case 'f':
10211400Smckusick 			if (argc < 1) {
10311400Smckusick 				fprintf(stderr, "missing device specifier\n");
10411400Smckusick 				done(1);
10511400Smckusick 			}
10610312Smckusick 			inputdev = *argv++;
10710312Smckusick 			argc--;
10810312Smckusick 			break;
10917707Smckusick 		case 'b':
11017707Smckusick 			/*
11117707Smckusick 			 * change default tape blocksize
11217707Smckusick 			 */
11318496Smckusick 			bflag++;
11417707Smckusick 			if (argc < 1) {
11517707Smckusick 				fprintf(stderr, "missing block size\n");
11617707Smckusick 				done(1);
11717707Smckusick 			}
11817707Smckusick 			ntrec = atoi(*argv++);
11917707Smckusick 			if (ntrec <= 0) {
12017707Smckusick 				fprintf(stderr, "Block size must be a positive integer\n");
12117707Smckusick 				done(1);
12217707Smckusick 			}
12317707Smckusick 			argc--;
12417707Smckusick 			break;
12510312Smckusick 		case 's':
12610312Smckusick 			/*
12710312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
12810312Smckusick 			 */
12911400Smckusick 			if (argc < 1) {
13011400Smckusick 				fprintf(stderr, "missing dump number\n");
13111400Smckusick 				done(1);
13211400Smckusick 			}
13310312Smckusick 			dumpnum = atoi(*argv++);
13410312Smckusick 			if (dumpnum <= 0) {
13510312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
13610312Smckusick 				done(1);
13710312Smckusick 			}
13810312Smckusick 			argc--;
13910312Smckusick 			break;
1404610Smckusick 		case 't':
14110312Smckusick 		case 'R':
14210312Smckusick 		case 'r':
14310312Smckusick 		case 'x':
14411993Smckusick 		case 'i':
14510202Smckusick 			if (command != '\0') {
14610312Smckusick 				fprintf(stderr,
14711400Smckusick 					"%c and %c are mutually exclusive\n",
14811400Smckusick 					*cp, command);
149*56428Smckusick 				usage();
15010202Smckusick 			}
15111400Smckusick 			command = *cp;
1524610Smckusick 			break;
1534610Smckusick 		default:
1544700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
155*56428Smckusick 			usage();
1564610Smckusick 		}
1574610Smckusick 	}
15810202Smckusick 	if (command == '\0') {
15911993Smckusick 		fprintf(stderr, "must specify i, t, r, R, or x\n");
160*56428Smckusick 		usage();
16110202Smckusick 	}
16210312Smckusick 	setinput(inputdev);
16310202Smckusick 	if (argc == 0) {
16410312Smckusick 		argc = 1;
16510202Smckusick 		*--argv = ".";
16610202Smckusick 	}
16710312Smckusick 	switch (command) {
16811993Smckusick 	/*
16911993Smckusick 	 * Interactive mode.
17011993Smckusick 	 */
17111993Smckusick 	case 'i':
17210312Smckusick 		setup();
17311993Smckusick 		extractdirs(1);
17411438Smckusick 		initsymtable((char *)0);
17511993Smckusick 		runcmdshell();
17610312Smckusick 		done(0);
17711993Smckusick 	/*
17811993Smckusick 	 * Incremental restoration of a file system.
17911993Smckusick 	 */
18010312Smckusick 	case 'r':
18110312Smckusick 		setup();
18210312Smckusick 		if (dumptime > 0) {
18311438Smckusick 			/*
18411438Smckusick 			 * This is an incremental dump tape.
18511438Smckusick 			 */
18611438Smckusick 			vprintf(stdout, "Begin incremental restore\n");
18710312Smckusick 			initsymtable(symtbl);
18811993Smckusick 			extractdirs(1);
18911438Smckusick 			removeoldleaves();
19011438Smckusick 			vprintf(stdout, "Calculate node updates.\n");
19111438Smckusick 			treescan(".", ROOTINO, nodeupdates);
19211438Smckusick 			findunreflinks();
19311438Smckusick 			removeoldnodes();
19410312Smckusick 		} else {
19511438Smckusick 			/*
19611438Smckusick 			 * This is a level zero dump tape.
19711438Smckusick 			 */
19811438Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
19911438Smckusick 			initsymtable((char *)0);
20011993Smckusick 			extractdirs(1);
20111438Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
20211438Smckusick 			treescan(".", ROOTINO, nodeupdates);
2034843Smckusic 		}
20410312Smckusick 		createleaves(symtbl);
20510312Smckusick 		createlinks();
20655880Smckusick 		setdirmodes(FORCE);
20710312Smckusick 		checkrestore();
20810312Smckusick 		if (dflag) {
20910312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
21010312Smckusick 			treescan(".", ROOTINO, verifyfile);
2114610Smckusick 		}
21210312Smckusick 		dumpsymtable(symtbl, (long)1);
21310312Smckusick 		done(0);
21411993Smckusick 	/*
21511993Smckusick 	 * Resume an incremental file system restoration.
21611993Smckusick 	 */
21710312Smckusick 	case 'R':
21810312Smckusick 		initsymtable(symtbl);
21911320Smckusick 		skipmaps();
22011320Smckusick 		skipdirs();
22110312Smckusick 		createleaves(symtbl);
22210312Smckusick 		createlinks();
22355880Smckusick 		setdirmodes(FORCE);
22410312Smckusick 		checkrestore();
22510312Smckusick 		dumpsymtable(symtbl, (long)1);
22610312Smckusick 		done(0);
22711993Smckusick 	/*
22811993Smckusick 	 * List contents of tape.
22911993Smckusick 	 */
23011993Smckusick 	case 't':
23111993Smckusick 		setup();
23211993Smckusick 		extractdirs(0);
23327264Smckusick 		initsymtable((char *)0);
23411993Smckusick 		while (argc--) {
23511993Smckusick 			canon(*argv++, name);
23611993Smckusick 			ino = dirlookup(name);
23711993Smckusick 			if (ino == 0)
23811993Smckusick 				continue;
23911993Smckusick 			treescan(name, ino, listfile);
24011993Smckusick 		}
24111993Smckusick 		done(0);
24211993Smckusick 	/*
24311993Smckusick 	 * Batch extraction of tape contents.
24411993Smckusick 	 */
24511993Smckusick 	case 'x':
24611993Smckusick 		setup();
24711993Smckusick 		extractdirs(1);
24811993Smckusick 		initsymtable((char *)0);
24911993Smckusick 		while (argc--) {
25011993Smckusick 			canon(*argv++, name);
25111993Smckusick 			ino = dirlookup(name);
25211993Smckusick 			if (ino == 0)
25311993Smckusick 				continue;
25411993Smckusick 			if (mflag)
25511993Smckusick 				pathcheck(name);
25611993Smckusick 			treescan(name, ino, addfile);
25711993Smckusick 		}
25811993Smckusick 		createfiles();
25911993Smckusick 		createlinks();
26055880Smckusick 		setdirmodes(0);
26111993Smckusick 		if (dflag)
26211993Smckusick 			checkrestore();
26311993Smckusick 		done(0);
2644843Smckusic 	}
2654843Smckusic }
266*56428Smckusick 
267*56428Smckusick usage()
268*56428Smckusick {
269*56428Smckusick 	(void)fprintf(stderr, "usage:\n%s%s%s%s%s",
270*56428Smckusick 	    "\trestore tfhsvy [file file ...]\n",
271*56428Smckusick 	    "\trestore xfhmsvy [file file ...]\n",
272*56428Smckusick 	    "\trestore ifhmsvy\n",
273*56428Smckusick 	    "\trestore rfsvy\n",
274*56428Smckusick 	    "\trestore Rfsvy\n");
275*56428Smckusick 	done(1);
276*56428Smckusick }
277