xref: /csrg-svn/sbin/restore/main.c (revision 34269)
121167Sdist /*
221167Sdist  * Copyright (c) 1983 Regents of the University of California.
321167Sdist  * All rights reserved.  The Berkeley software License Agreement
421167Sdist  * specifies the terms and conditions for redistribution.
521167Sdist  */
621167Sdist 
76846Smckusick #ifndef lint
821167Sdist char copyright[] =
921167Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1021167Sdist  All rights reserved.\n";
1121167Sdist #endif not lint
124610Smckusick 
1321167Sdist #ifndef lint
14*34269Smckusick static char sccsid[] = "@(#)main.c	5.4 (Berkeley) 05/13/88";
1521167Sdist #endif not lint
1614564Ssam 
1710312Smckusick /*
1810312Smckusick  *	Modified to recursively extract all files within a subtree
1910312Smckusick  *	(supressed by the h option) and recreate the heirarchical
2010312Smckusick  *	structure of that subtree and move extracted files to their
2110312Smckusick  *	proper homes (supressed by the m option).
2210312Smckusick  *	Includes the s (skip files) option for use with multiple
2310312Smckusick  *	dumps on a single tape.
244610Smckusick  *	8/29/80		by Mike Litzkow
254610Smckusick  *
2610312Smckusick  *	Modified to work on the new file system and to recover from
2710312Smckusick  *	tape read errors.
286846Smckusick  *	1/19/82		by Kirk McKusick
296846Smckusick  *
3011993Smckusick  *	Full incremental restore running entirely in user code and
3111993Smckusick  *	interactive tape browser.
3210312Smckusick  *	1/19/83		by Kirk McKusick
334610Smckusick  */
344610Smckusick 
3510312Smckusick #include "restore.h"
3623547Smckusick #include <protocols/dumprestore.h>
374610Smckusick #include <signal.h>
384610Smckusick 
3918496Smckusick int	bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
40*34269Smckusick int	hflag = 1, mflag = 1, Nflag = 0;
4110312Smckusick char	command = '\0';
4210312Smckusick long	dumpnum = 1;
4311438Smckusick long	volno = 0;
4418496Smckusick long	ntrec;
455327Smckusic char	*dumpmap;
465327Smckusic char	*clrimap;
4710312Smckusick ino_t	maxino;
4810312Smckusick time_t	dumptime;
4911302Smckusick time_t	dumpdate;
5011993Smckusick FILE 	*terminal;
514610Smckusick 
526846Smckusick main(argc, argv)
534700Smckusic 	int argc;
544700Smckusic 	char *argv[];
554610Smckusick {
564610Smckusick 	register char *cp;
5711308Smckusick 	ino_t ino;
5810312Smckusick 	char *inputdev = "/dev/rmt8";
5911308Smckusick 	char *symtbl = "./restoresymtable";
6011993Smckusick 	char name[MAXPATHLEN];
614700Smckusic 	int (*signal())();
6210312Smckusick 	extern int onintr();
634610Smckusick 
6410312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
6511438Smckusick 		(void) signal(SIGINT, SIG_IGN);
6610312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
6711438Smckusick 		(void) signal(SIGTERM, SIG_IGN);
6811308Smckusick 	setlinebuf(stderr);
694610Smckusick 	if (argc < 2) {
704610Smckusick usage:
7111993Smckusick 		fprintf(stderr, "Usage:\n%s%s%s%s%s",
7211993Smckusick 			"\trestore tfhsvy [file file ...]\n",
7311993Smckusick 			"\trestore xfhmsvy [file file ...]\n",
7411993Smckusick 			"\trestore ifhmsvy\n",
7511993Smckusick 			"\trestore rfsvy\n",
7611993Smckusick 			"\trestore Rfsvy\n");
774700Smckusic 		done(1);
784610Smckusick 	}
794610Smckusick 	argv++;
804610Smckusick 	argc -= 2;
8110202Smckusick 	command = '\0';
824610Smckusick 	for (cp = *argv++; *cp; cp++) {
834610Smckusick 		switch (*cp) {
844610Smckusick 		case '-':
854610Smckusick 			break;
868302Smckusick 		case 'c':
878302Smckusick 			cvtflag++;
888302Smckusick 			break;
8910312Smckusick 		case 'd':
9010312Smckusick 			dflag++;
914610Smckusick 			break;
924610Smckusick 		case 'h':
9310202Smckusick 			hflag = 0;
944610Smckusick 			break;
954610Smckusick 		case 'm':
9610202Smckusick 			mflag = 0;
974610Smckusick 			break;
98*34269Smckusick 		case 'N':
99*34269Smckusick 			Nflag++;
100*34269Smckusick 			break;
1018374Smckusick 		case 'v':
1028374Smckusick 			vflag++;
1038374Smckusick 			break;
1048374Smckusick 		case 'y':
1058374Smckusick 			yflag++;
1068374Smckusick 			break;
10710312Smckusick 		case 'f':
10811400Smckusick 			if (argc < 1) {
10911400Smckusick 				fprintf(stderr, "missing device specifier\n");
11011400Smckusick 				done(1);
11111400Smckusick 			}
11210312Smckusick 			inputdev = *argv++;
11310312Smckusick 			argc--;
11410312Smckusick 			break;
11517707Smckusick 		case 'b':
11617707Smckusick 			/*
11717707Smckusick 			 * change default tape blocksize
11817707Smckusick 			 */
11918496Smckusick 			bflag++;
12017707Smckusick 			if (argc < 1) {
12117707Smckusick 				fprintf(stderr, "missing block size\n");
12217707Smckusick 				done(1);
12317707Smckusick 			}
12417707Smckusick 			ntrec = atoi(*argv++);
12517707Smckusick 			if (ntrec <= 0) {
12617707Smckusick 				fprintf(stderr, "Block size must be a positive integer\n");
12717707Smckusick 				done(1);
12817707Smckusick 			}
12917707Smckusick 			argc--;
13017707Smckusick 			break;
13110312Smckusick 		case 's':
13210312Smckusick 			/*
13310312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
13410312Smckusick 			 */
13511400Smckusick 			if (argc < 1) {
13611400Smckusick 				fprintf(stderr, "missing dump number\n");
13711400Smckusick 				done(1);
13811400Smckusick 			}
13910312Smckusick 			dumpnum = atoi(*argv++);
14010312Smckusick 			if (dumpnum <= 0) {
14110312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
14210312Smckusick 				done(1);
14310312Smckusick 			}
14410312Smckusick 			argc--;
14510312Smckusick 			break;
1464610Smckusick 		case 't':
14710312Smckusick 		case 'R':
14810312Smckusick 		case 'r':
14910312Smckusick 		case 'x':
15011993Smckusick 		case 'i':
15110202Smckusick 			if (command != '\0') {
15210312Smckusick 				fprintf(stderr,
15311400Smckusick 					"%c and %c are mutually exclusive\n",
15411400Smckusick 					*cp, command);
15510202Smckusick 				goto usage;
15610202Smckusick 			}
15711400Smckusick 			command = *cp;
1584610Smckusick 			break;
1594610Smckusick 		default:
1604700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1614610Smckusick 			goto usage;
1624610Smckusick 		}
1634610Smckusick 	}
16410202Smckusick 	if (command == '\0') {
16511993Smckusick 		fprintf(stderr, "must specify i, t, r, R, or x\n");
16610202Smckusick 		goto usage;
16710202Smckusick 	}
16810312Smckusick 	setinput(inputdev);
16910202Smckusick 	if (argc == 0) {
17010312Smckusick 		argc = 1;
17110202Smckusick 		*--argv = ".";
17210202Smckusick 	}
17310312Smckusick 	switch (command) {
17411993Smckusick 	/*
17511993Smckusick 	 * Interactive mode.
17611993Smckusick 	 */
17711993Smckusick 	case 'i':
17810312Smckusick 		setup();
17911993Smckusick 		extractdirs(1);
18011438Smckusick 		initsymtable((char *)0);
18111993Smckusick 		runcmdshell();
18210312Smckusick 		done(0);
18311993Smckusick 	/*
18411993Smckusick 	 * Incremental restoration of a file system.
18511993Smckusick 	 */
18610312Smckusick 	case 'r':
18710312Smckusick 		setup();
18810312Smckusick 		if (dumptime > 0) {
18911438Smckusick 			/*
19011438Smckusick 			 * This is an incremental dump tape.
19111438Smckusick 			 */
19211438Smckusick 			vprintf(stdout, "Begin incremental restore\n");
19310312Smckusick 			initsymtable(symtbl);
19411993Smckusick 			extractdirs(1);
19511438Smckusick 			removeoldleaves();
19611438Smckusick 			vprintf(stdout, "Calculate node updates.\n");
19711438Smckusick 			treescan(".", ROOTINO, nodeupdates);
19811438Smckusick 			findunreflinks();
19911438Smckusick 			removeoldnodes();
20010312Smckusick 		} else {
20111438Smckusick 			/*
20211438Smckusick 			 * This is a level zero dump tape.
20311438Smckusick 			 */
20411438Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
20511438Smckusick 			initsymtable((char *)0);
20611993Smckusick 			extractdirs(1);
20711438Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
20811438Smckusick 			treescan(".", ROOTINO, nodeupdates);
2094843Smckusic 		}
21010312Smckusick 		createleaves(symtbl);
21110312Smckusick 		createlinks();
21211993Smckusick 		setdirmodes();
21310312Smckusick 		checkrestore();
21410312Smckusick 		if (dflag) {
21510312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
21610312Smckusick 			treescan(".", ROOTINO, verifyfile);
2174610Smckusick 		}
21810312Smckusick 		dumpsymtable(symtbl, (long)1);
21910312Smckusick 		done(0);
22011993Smckusick 	/*
22111993Smckusick 	 * Resume an incremental file system restoration.
22211993Smckusick 	 */
22310312Smckusick 	case 'R':
22410312Smckusick 		initsymtable(symtbl);
22511320Smckusick 		skipmaps();
22611320Smckusick 		skipdirs();
22710312Smckusick 		createleaves(symtbl);
22810312Smckusick 		createlinks();
22911993Smckusick 		setdirmodes();
23010312Smckusick 		checkrestore();
23110312Smckusick 		dumpsymtable(symtbl, (long)1);
23210312Smckusick 		done(0);
23311993Smckusick 	/*
23411993Smckusick 	 * List contents of tape.
23511993Smckusick 	 */
23611993Smckusick 	case 't':
23711993Smckusick 		setup();
23811993Smckusick 		extractdirs(0);
23927264Smckusick 		initsymtable((char *)0);
24011993Smckusick 		while (argc--) {
24111993Smckusick 			canon(*argv++, name);
24211993Smckusick 			ino = dirlookup(name);
24311993Smckusick 			if (ino == 0)
24411993Smckusick 				continue;
24511993Smckusick 			treescan(name, ino, listfile);
24611993Smckusick 		}
24711993Smckusick 		done(0);
24811993Smckusick 	/*
24911993Smckusick 	 * Batch extraction of tape contents.
25011993Smckusick 	 */
25111993Smckusick 	case 'x':
25211993Smckusick 		setup();
25311993Smckusick 		extractdirs(1);
25411993Smckusick 		initsymtable((char *)0);
25511993Smckusick 		while (argc--) {
25611993Smckusick 			canon(*argv++, name);
25711993Smckusick 			ino = dirlookup(name);
25811993Smckusick 			if (ino == 0)
25911993Smckusick 				continue;
26011993Smckusick 			if (mflag)
26111993Smckusick 				pathcheck(name);
26211993Smckusick 			treescan(name, ino, addfile);
26311993Smckusick 		}
26411993Smckusick 		createfiles();
26511993Smckusick 		createlinks();
26611993Smckusick 		setdirmodes();
26711993Smckusick 		if (dflag)
26811993Smckusick 			checkrestore();
26911993Smckusick 		done(0);
2704843Smckusic 	}
2714843Smckusic }
272