xref: /csrg-svn/sbin/restore/main.c (revision 27264)
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*27264Smckusick static char sccsid[] = "@(#)main.c	5.3 (Berkeley) 04/23/86";
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;
4010312Smckusick int	hflag = 1, mflag = 1;
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;
988374Smckusick 		case 'v':
998374Smckusick 			vflag++;
1008374Smckusick 			break;
1018374Smckusick 		case 'y':
1028374Smckusick 			yflag++;
1038374Smckusick 			break;
10410312Smckusick 		case 'f':
10511400Smckusick 			if (argc < 1) {
10611400Smckusick 				fprintf(stderr, "missing device specifier\n");
10711400Smckusick 				done(1);
10811400Smckusick 			}
10910312Smckusick 			inputdev = *argv++;
11010312Smckusick 			argc--;
11110312Smckusick 			break;
11217707Smckusick 		case 'b':
11317707Smckusick 			/*
11417707Smckusick 			 * change default tape blocksize
11517707Smckusick 			 */
11618496Smckusick 			bflag++;
11717707Smckusick 			if (argc < 1) {
11817707Smckusick 				fprintf(stderr, "missing block size\n");
11917707Smckusick 				done(1);
12017707Smckusick 			}
12117707Smckusick 			ntrec = atoi(*argv++);
12217707Smckusick 			if (ntrec <= 0) {
12317707Smckusick 				fprintf(stderr, "Block size must be a positive integer\n");
12417707Smckusick 				done(1);
12517707Smckusick 			}
12617707Smckusick 			argc--;
12717707Smckusick 			break;
12810312Smckusick 		case 's':
12910312Smckusick 			/*
13010312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
13110312Smckusick 			 */
13211400Smckusick 			if (argc < 1) {
13311400Smckusick 				fprintf(stderr, "missing dump number\n");
13411400Smckusick 				done(1);
13511400Smckusick 			}
13610312Smckusick 			dumpnum = atoi(*argv++);
13710312Smckusick 			if (dumpnum <= 0) {
13810312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
13910312Smckusick 				done(1);
14010312Smckusick 			}
14110312Smckusick 			argc--;
14210312Smckusick 			break;
1434610Smckusick 		case 't':
14410312Smckusick 		case 'R':
14510312Smckusick 		case 'r':
14610312Smckusick 		case 'x':
14711993Smckusick 		case 'i':
14810202Smckusick 			if (command != '\0') {
14910312Smckusick 				fprintf(stderr,
15011400Smckusick 					"%c and %c are mutually exclusive\n",
15111400Smckusick 					*cp, command);
15210202Smckusick 				goto usage;
15310202Smckusick 			}
15411400Smckusick 			command = *cp;
1554610Smckusick 			break;
1564610Smckusick 		default:
1574700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1584610Smckusick 			goto usage;
1594610Smckusick 		}
1604610Smckusick 	}
16110202Smckusick 	if (command == '\0') {
16211993Smckusick 		fprintf(stderr, "must specify i, t, r, R, or x\n");
16310202Smckusick 		goto usage;
16410202Smckusick 	}
16510312Smckusick 	setinput(inputdev);
16610202Smckusick 	if (argc == 0) {
16710312Smckusick 		argc = 1;
16810202Smckusick 		*--argv = ".";
16910202Smckusick 	}
17010312Smckusick 	switch (command) {
17111993Smckusick 	/*
17211993Smckusick 	 * Interactive mode.
17311993Smckusick 	 */
17411993Smckusick 	case 'i':
17510312Smckusick 		setup();
17611993Smckusick 		extractdirs(1);
17711438Smckusick 		initsymtable((char *)0);
17811993Smckusick 		runcmdshell();
17910312Smckusick 		done(0);
18011993Smckusick 	/*
18111993Smckusick 	 * Incremental restoration of a file system.
18211993Smckusick 	 */
18310312Smckusick 	case 'r':
18410312Smckusick 		setup();
18510312Smckusick 		if (dumptime > 0) {
18611438Smckusick 			/*
18711438Smckusick 			 * This is an incremental dump tape.
18811438Smckusick 			 */
18911438Smckusick 			vprintf(stdout, "Begin incremental restore\n");
19010312Smckusick 			initsymtable(symtbl);
19111993Smckusick 			extractdirs(1);
19211438Smckusick 			removeoldleaves();
19311438Smckusick 			vprintf(stdout, "Calculate node updates.\n");
19411438Smckusick 			treescan(".", ROOTINO, nodeupdates);
19511438Smckusick 			findunreflinks();
19611438Smckusick 			removeoldnodes();
19710312Smckusick 		} else {
19811438Smckusick 			/*
19911438Smckusick 			 * This is a level zero dump tape.
20011438Smckusick 			 */
20111438Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
20211438Smckusick 			initsymtable((char *)0);
20311993Smckusick 			extractdirs(1);
20411438Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
20511438Smckusick 			treescan(".", ROOTINO, nodeupdates);
2064843Smckusic 		}
20710312Smckusick 		createleaves(symtbl);
20810312Smckusick 		createlinks();
20911993Smckusick 		setdirmodes();
21010312Smckusick 		checkrestore();
21110312Smckusick 		if (dflag) {
21210312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
21310312Smckusick 			treescan(".", ROOTINO, verifyfile);
2144610Smckusick 		}
21510312Smckusick 		dumpsymtable(symtbl, (long)1);
21610312Smckusick 		done(0);
21711993Smckusick 	/*
21811993Smckusick 	 * Resume an incremental file system restoration.
21911993Smckusick 	 */
22010312Smckusick 	case 'R':
22110312Smckusick 		initsymtable(symtbl);
22211320Smckusick 		skipmaps();
22311320Smckusick 		skipdirs();
22410312Smckusick 		createleaves(symtbl);
22510312Smckusick 		createlinks();
22611993Smckusick 		setdirmodes();
22710312Smckusick 		checkrestore();
22810312Smckusick 		dumpsymtable(symtbl, (long)1);
22910312Smckusick 		done(0);
23011993Smckusick 	/*
23111993Smckusick 	 * List contents of tape.
23211993Smckusick 	 */
23311993Smckusick 	case 't':
23411993Smckusick 		setup();
23511993Smckusick 		extractdirs(0);
236*27264Smckusick 		initsymtable((char *)0);
23711993Smckusick 		while (argc--) {
23811993Smckusick 			canon(*argv++, name);
23911993Smckusick 			ino = dirlookup(name);
24011993Smckusick 			if (ino == 0)
24111993Smckusick 				continue;
24211993Smckusick 			treescan(name, ino, listfile);
24311993Smckusick 		}
24411993Smckusick 		done(0);
24511993Smckusick 	/*
24611993Smckusick 	 * Batch extraction of tape contents.
24711993Smckusick 	 */
24811993Smckusick 	case 'x':
24911993Smckusick 		setup();
25011993Smckusick 		extractdirs(1);
25111993Smckusick 		initsymtable((char *)0);
25211993Smckusick 		while (argc--) {
25311993Smckusick 			canon(*argv++, name);
25411993Smckusick 			ino = dirlookup(name);
25511993Smckusick 			if (ino == 0)
25611993Smckusick 				continue;
25711993Smckusick 			if (mflag)
25811993Smckusick 				pathcheck(name);
25911993Smckusick 			treescan(name, ino, addfile);
26011993Smckusick 		}
26111993Smckusick 		createfiles();
26211993Smckusick 		createlinks();
26311993Smckusick 		setdirmodes();
26411993Smckusick 		if (dflag)
26511993Smckusick 			checkrestore();
26611993Smckusick 		done(0);
2674843Smckusic 	}
2684843Smckusic }
269