xref: /csrg-svn/sbin/restore/main.c (revision 55880)
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*55880Smckusick static char sccsid[] = "@(#)main.c	5.9 (Berkeley) 08/09/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 
546846Smckusick main(argc, argv)
554700Smckusic 	int argc;
564700Smckusic 	char *argv[];
574610Smckusick {
584610Smckusick 	register char *cp;
5911308Smckusick 	ino_t ino;
6037952Sbostic 	char *inputdev = _PATH_DEFTAPE;
6111308Smckusick 	char *symtbl = "./restoresymtable";
6211993Smckusick 	char name[MAXPATHLEN];
6339944Sbostic 	void onintr();
644610Smckusick 
6510312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
6611438Smckusick 		(void) signal(SIGINT, SIG_IGN);
6710312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
6811438Smckusick 		(void) signal(SIGTERM, SIG_IGN);
6911308Smckusick 	setlinebuf(stderr);
704610Smckusick 	if (argc < 2) {
714610Smckusick usage:
7211993Smckusick 		fprintf(stderr, "Usage:\n%s%s%s%s%s",
7311993Smckusick 			"\trestore tfhsvy [file file ...]\n",
7411993Smckusick 			"\trestore xfhmsvy [file file ...]\n",
7511993Smckusick 			"\trestore ifhmsvy\n",
7611993Smckusick 			"\trestore rfsvy\n",
7711993Smckusick 			"\trestore Rfsvy\n");
784700Smckusic 		done(1);
794610Smckusick 	}
804610Smckusick 	argv++;
814610Smckusick 	argc -= 2;
8210202Smckusick 	command = '\0';
834610Smckusick 	for (cp = *argv++; *cp; cp++) {
844610Smckusick 		switch (*cp) {
854610Smckusick 		case '-':
864610Smckusick 			break;
878302Smckusick 		case 'c':
888302Smckusick 			cvtflag++;
898302Smckusick 			break;
9010312Smckusick 		case 'd':
9110312Smckusick 			dflag++;
924610Smckusick 			break;
934610Smckusick 		case 'h':
9410202Smckusick 			hflag = 0;
954610Smckusick 			break;
964610Smckusick 		case 'm':
9710202Smckusick 			mflag = 0;
984610Smckusick 			break;
9934269Smckusick 		case 'N':
10034269Smckusick 			Nflag++;
10134269Smckusick 			break;
1028374Smckusick 		case 'v':
1038374Smckusick 			vflag++;
1048374Smckusick 			break;
1058374Smckusick 		case 'y':
1068374Smckusick 			yflag++;
1078374Smckusick 			break;
10810312Smckusick 		case 'f':
10911400Smckusick 			if (argc < 1) {
11011400Smckusick 				fprintf(stderr, "missing device specifier\n");
11111400Smckusick 				done(1);
11211400Smckusick 			}
11310312Smckusick 			inputdev = *argv++;
11410312Smckusick 			argc--;
11510312Smckusick 			break;
11617707Smckusick 		case 'b':
11717707Smckusick 			/*
11817707Smckusick 			 * change default tape blocksize
11917707Smckusick 			 */
12018496Smckusick 			bflag++;
12117707Smckusick 			if (argc < 1) {
12217707Smckusick 				fprintf(stderr, "missing block size\n");
12317707Smckusick 				done(1);
12417707Smckusick 			}
12517707Smckusick 			ntrec = atoi(*argv++);
12617707Smckusick 			if (ntrec <= 0) {
12717707Smckusick 				fprintf(stderr, "Block size must be a positive integer\n");
12817707Smckusick 				done(1);
12917707Smckusick 			}
13017707Smckusick 			argc--;
13117707Smckusick 			break;
13210312Smckusick 		case 's':
13310312Smckusick 			/*
13410312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
13510312Smckusick 			 */
13611400Smckusick 			if (argc < 1) {
13711400Smckusick 				fprintf(stderr, "missing dump number\n");
13811400Smckusick 				done(1);
13911400Smckusick 			}
14010312Smckusick 			dumpnum = atoi(*argv++);
14110312Smckusick 			if (dumpnum <= 0) {
14210312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
14310312Smckusick 				done(1);
14410312Smckusick 			}
14510312Smckusick 			argc--;
14610312Smckusick 			break;
1474610Smckusick 		case 't':
14810312Smckusick 		case 'R':
14910312Smckusick 		case 'r':
15010312Smckusick 		case 'x':
15111993Smckusick 		case 'i':
15210202Smckusick 			if (command != '\0') {
15310312Smckusick 				fprintf(stderr,
15411400Smckusick 					"%c and %c are mutually exclusive\n",
15511400Smckusick 					*cp, command);
15610202Smckusick 				goto usage;
15710202Smckusick 			}
15811400Smckusick 			command = *cp;
1594610Smckusick 			break;
1604610Smckusick 		default:
1614700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1624610Smckusick 			goto usage;
1634610Smckusick 		}
1644610Smckusick 	}
16510202Smckusick 	if (command == '\0') {
16611993Smckusick 		fprintf(stderr, "must specify i, t, r, R, or x\n");
16710202Smckusick 		goto usage;
16810202Smckusick 	}
16910312Smckusick 	setinput(inputdev);
17010202Smckusick 	if (argc == 0) {
17110312Smckusick 		argc = 1;
17210202Smckusick 		*--argv = ".";
17310202Smckusick 	}
17410312Smckusick 	switch (command) {
17511993Smckusick 	/*
17611993Smckusick 	 * Interactive mode.
17711993Smckusick 	 */
17811993Smckusick 	case 'i':
17910312Smckusick 		setup();
18011993Smckusick 		extractdirs(1);
18111438Smckusick 		initsymtable((char *)0);
18211993Smckusick 		runcmdshell();
18310312Smckusick 		done(0);
18411993Smckusick 	/*
18511993Smckusick 	 * Incremental restoration of a file system.
18611993Smckusick 	 */
18710312Smckusick 	case 'r':
18810312Smckusick 		setup();
18910312Smckusick 		if (dumptime > 0) {
19011438Smckusick 			/*
19111438Smckusick 			 * This is an incremental dump tape.
19211438Smckusick 			 */
19311438Smckusick 			vprintf(stdout, "Begin incremental restore\n");
19410312Smckusick 			initsymtable(symtbl);
19511993Smckusick 			extractdirs(1);
19611438Smckusick 			removeoldleaves();
19711438Smckusick 			vprintf(stdout, "Calculate node updates.\n");
19811438Smckusick 			treescan(".", ROOTINO, nodeupdates);
19911438Smckusick 			findunreflinks();
20011438Smckusick 			removeoldnodes();
20110312Smckusick 		} else {
20211438Smckusick 			/*
20311438Smckusick 			 * This is a level zero dump tape.
20411438Smckusick 			 */
20511438Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
20611438Smckusick 			initsymtable((char *)0);
20711993Smckusick 			extractdirs(1);
20811438Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
20911438Smckusick 			treescan(".", ROOTINO, nodeupdates);
2104843Smckusic 		}
21110312Smckusick 		createleaves(symtbl);
21210312Smckusick 		createlinks();
213*55880Smckusick 		setdirmodes(FORCE);
21410312Smckusick 		checkrestore();
21510312Smckusick 		if (dflag) {
21610312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
21710312Smckusick 			treescan(".", ROOTINO, verifyfile);
2184610Smckusick 		}
21910312Smckusick 		dumpsymtable(symtbl, (long)1);
22010312Smckusick 		done(0);
22111993Smckusick 	/*
22211993Smckusick 	 * Resume an incremental file system restoration.
22311993Smckusick 	 */
22410312Smckusick 	case 'R':
22510312Smckusick 		initsymtable(symtbl);
22611320Smckusick 		skipmaps();
22711320Smckusick 		skipdirs();
22810312Smckusick 		createleaves(symtbl);
22910312Smckusick 		createlinks();
230*55880Smckusick 		setdirmodes(FORCE);
23110312Smckusick 		checkrestore();
23210312Smckusick 		dumpsymtable(symtbl, (long)1);
23310312Smckusick 		done(0);
23411993Smckusick 	/*
23511993Smckusick 	 * List contents of tape.
23611993Smckusick 	 */
23711993Smckusick 	case 't':
23811993Smckusick 		setup();
23911993Smckusick 		extractdirs(0);
24027264Smckusick 		initsymtable((char *)0);
24111993Smckusick 		while (argc--) {
24211993Smckusick 			canon(*argv++, name);
24311993Smckusick 			ino = dirlookup(name);
24411993Smckusick 			if (ino == 0)
24511993Smckusick 				continue;
24611993Smckusick 			treescan(name, ino, listfile);
24711993Smckusick 		}
24811993Smckusick 		done(0);
24911993Smckusick 	/*
25011993Smckusick 	 * Batch extraction of tape contents.
25111993Smckusick 	 */
25211993Smckusick 	case 'x':
25311993Smckusick 		setup();
25411993Smckusick 		extractdirs(1);
25511993Smckusick 		initsymtable((char *)0);
25611993Smckusick 		while (argc--) {
25711993Smckusick 			canon(*argv++, name);
25811993Smckusick 			ino = dirlookup(name);
25911993Smckusick 			if (ino == 0)
26011993Smckusick 				continue;
26111993Smckusick 			if (mflag)
26211993Smckusick 				pathcheck(name);
26311993Smckusick 			treescan(name, ino, addfile);
26411993Smckusick 		}
26511993Smckusick 		createfiles();
26611993Smckusick 		createlinks();
267*55880Smckusick 		setdirmodes(0);
26811993Smckusick 		if (dflag)
26911993Smckusick 			checkrestore();
27011993Smckusick 		done(0);
2714843Smckusic 	}
2724843Smckusic }
273