xref: /csrg-svn/sbin/restore/main.c (revision 37952)
121167Sdist /*
236105Sbostic  * Copyright (c) 1983 The Regents of the University of California.
336105Sbostic  * All rights reserved.
436105Sbostic  *
536105Sbostic  * Redistribution and use in source and binary forms are permitted
636105Sbostic  * provided that the above copyright notice and this paragraph are
736105Sbostic  * duplicated in all such forms and that any documentation,
836105Sbostic  * advertising materials, and other materials related to such
936105Sbostic  * distribution and use acknowledge that the software was developed
1036105Sbostic  * by the University of California, Berkeley.  The name of the
1136105Sbostic  * University may not be used to endorse or promote products derived
1236105Sbostic  * from this software without specific prior written permission.
1336105Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1436105Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1536105Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621167Sdist  */
1721167Sdist 
186846Smckusick #ifndef lint
1921167Sdist char copyright[] =
2036105Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
2121167Sdist  All rights reserved.\n";
2236105Sbostic #endif /* not lint */
234610Smckusick 
2421167Sdist #ifndef lint
25*37952Sbostic static char sccsid[] = "@(#)main.c	5.6 (Berkeley) 05/11/89";
2636105Sbostic #endif /* not lint */
2714564Ssam 
2810312Smckusick /*
2910312Smckusick  *	Modified to recursively extract all files within a subtree
3010312Smckusick  *	(supressed by the h option) and recreate the heirarchical
3110312Smckusick  *	structure of that subtree and move extracted files to their
3210312Smckusick  *	proper homes (supressed by the m option).
3310312Smckusick  *	Includes the s (skip files) option for use with multiple
3410312Smckusick  *	dumps on a single tape.
354610Smckusick  *	8/29/80		by Mike Litzkow
364610Smckusick  *
3710312Smckusick  *	Modified to work on the new file system and to recover from
3810312Smckusick  *	tape read errors.
396846Smckusick  *	1/19/82		by Kirk McKusick
406846Smckusick  *
4111993Smckusick  *	Full incremental restore running entirely in user code and
4211993Smckusick  *	interactive tape browser.
4310312Smckusick  *	1/19/83		by Kirk McKusick
444610Smckusick  */
454610Smckusick 
4610312Smckusick #include "restore.h"
4723547Smckusick #include <protocols/dumprestore.h>
48*37952Sbostic #include <sys/signal.h>
49*37952Sbostic #include "pathnames.h"
504610Smckusick 
5118496Smckusick int	bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
5234269Smckusick int	hflag = 1, mflag = 1, Nflag = 0;
5310312Smckusick char	command = '\0';
5410312Smckusick long	dumpnum = 1;
5511438Smckusick long	volno = 0;
5618496Smckusick long	ntrec;
575327Smckusic char	*dumpmap;
585327Smckusic char	*clrimap;
5910312Smckusick ino_t	maxino;
6010312Smckusick time_t	dumptime;
6111302Smckusick time_t	dumpdate;
6211993Smckusick FILE 	*terminal;
634610Smckusick 
646846Smckusick main(argc, argv)
654700Smckusic 	int argc;
664700Smckusic 	char *argv[];
674610Smckusick {
684610Smckusick 	register char *cp;
6911308Smckusick 	ino_t ino;
70*37952Sbostic 	char *inputdev = _PATH_DEFTAPE;
7111308Smckusick 	char *symtbl = "./restoresymtable";
7211993Smckusick 	char name[MAXPATHLEN];
734700Smckusic 	int (*signal())();
7410312Smckusick 	extern int onintr();
754610Smckusick 
7610312Smckusick 	if (signal(SIGINT, onintr) == SIG_IGN)
7711438Smckusick 		(void) signal(SIGINT, SIG_IGN);
7810312Smckusick 	if (signal(SIGTERM, onintr) == SIG_IGN)
7911438Smckusick 		(void) signal(SIGTERM, SIG_IGN);
8011308Smckusick 	setlinebuf(stderr);
814610Smckusick 	if (argc < 2) {
824610Smckusick usage:
8311993Smckusick 		fprintf(stderr, "Usage:\n%s%s%s%s%s",
8411993Smckusick 			"\trestore tfhsvy [file file ...]\n",
8511993Smckusick 			"\trestore xfhmsvy [file file ...]\n",
8611993Smckusick 			"\trestore ifhmsvy\n",
8711993Smckusick 			"\trestore rfsvy\n",
8811993Smckusick 			"\trestore Rfsvy\n");
894700Smckusic 		done(1);
904610Smckusick 	}
914610Smckusick 	argv++;
924610Smckusick 	argc -= 2;
9310202Smckusick 	command = '\0';
944610Smckusick 	for (cp = *argv++; *cp; cp++) {
954610Smckusick 		switch (*cp) {
964610Smckusick 		case '-':
974610Smckusick 			break;
988302Smckusick 		case 'c':
998302Smckusick 			cvtflag++;
1008302Smckusick 			break;
10110312Smckusick 		case 'd':
10210312Smckusick 			dflag++;
1034610Smckusick 			break;
1044610Smckusick 		case 'h':
10510202Smckusick 			hflag = 0;
1064610Smckusick 			break;
1074610Smckusick 		case 'm':
10810202Smckusick 			mflag = 0;
1094610Smckusick 			break;
11034269Smckusick 		case 'N':
11134269Smckusick 			Nflag++;
11234269Smckusick 			break;
1138374Smckusick 		case 'v':
1148374Smckusick 			vflag++;
1158374Smckusick 			break;
1168374Smckusick 		case 'y':
1178374Smckusick 			yflag++;
1188374Smckusick 			break;
11910312Smckusick 		case 'f':
12011400Smckusick 			if (argc < 1) {
12111400Smckusick 				fprintf(stderr, "missing device specifier\n");
12211400Smckusick 				done(1);
12311400Smckusick 			}
12410312Smckusick 			inputdev = *argv++;
12510312Smckusick 			argc--;
12610312Smckusick 			break;
12717707Smckusick 		case 'b':
12817707Smckusick 			/*
12917707Smckusick 			 * change default tape blocksize
13017707Smckusick 			 */
13118496Smckusick 			bflag++;
13217707Smckusick 			if (argc < 1) {
13317707Smckusick 				fprintf(stderr, "missing block size\n");
13417707Smckusick 				done(1);
13517707Smckusick 			}
13617707Smckusick 			ntrec = atoi(*argv++);
13717707Smckusick 			if (ntrec <= 0) {
13817707Smckusick 				fprintf(stderr, "Block size must be a positive integer\n");
13917707Smckusick 				done(1);
14017707Smckusick 			}
14117707Smckusick 			argc--;
14217707Smckusick 			break;
14310312Smckusick 		case 's':
14410312Smckusick 			/*
14510312Smckusick 			 * dumpnum (skip to) for multifile dump tapes
14610312Smckusick 			 */
14711400Smckusick 			if (argc < 1) {
14811400Smckusick 				fprintf(stderr, "missing dump number\n");
14911400Smckusick 				done(1);
15011400Smckusick 			}
15110312Smckusick 			dumpnum = atoi(*argv++);
15210312Smckusick 			if (dumpnum <= 0) {
15310312Smckusick 				fprintf(stderr, "Dump number must be a positive integer\n");
15410312Smckusick 				done(1);
15510312Smckusick 			}
15610312Smckusick 			argc--;
15710312Smckusick 			break;
1584610Smckusick 		case 't':
15910312Smckusick 		case 'R':
16010312Smckusick 		case 'r':
16110312Smckusick 		case 'x':
16211993Smckusick 		case 'i':
16310202Smckusick 			if (command != '\0') {
16410312Smckusick 				fprintf(stderr,
16511400Smckusick 					"%c and %c are mutually exclusive\n",
16611400Smckusick 					*cp, command);
16710202Smckusick 				goto usage;
16810202Smckusick 			}
16911400Smckusick 			command = *cp;
1704610Smckusick 			break;
1714610Smckusick 		default:
1724700Smckusic 			fprintf(stderr, "Bad key character %c\n", *cp);
1734610Smckusick 			goto usage;
1744610Smckusick 		}
1754610Smckusick 	}
17610202Smckusick 	if (command == '\0') {
17711993Smckusick 		fprintf(stderr, "must specify i, t, r, R, or x\n");
17810202Smckusick 		goto usage;
17910202Smckusick 	}
18010312Smckusick 	setinput(inputdev);
18110202Smckusick 	if (argc == 0) {
18210312Smckusick 		argc = 1;
18310202Smckusick 		*--argv = ".";
18410202Smckusick 	}
18510312Smckusick 	switch (command) {
18611993Smckusick 	/*
18711993Smckusick 	 * Interactive mode.
18811993Smckusick 	 */
18911993Smckusick 	case 'i':
19010312Smckusick 		setup();
19111993Smckusick 		extractdirs(1);
19211438Smckusick 		initsymtable((char *)0);
19311993Smckusick 		runcmdshell();
19410312Smckusick 		done(0);
19511993Smckusick 	/*
19611993Smckusick 	 * Incremental restoration of a file system.
19711993Smckusick 	 */
19810312Smckusick 	case 'r':
19910312Smckusick 		setup();
20010312Smckusick 		if (dumptime > 0) {
20111438Smckusick 			/*
20211438Smckusick 			 * This is an incremental dump tape.
20311438Smckusick 			 */
20411438Smckusick 			vprintf(stdout, "Begin incremental restore\n");
20510312Smckusick 			initsymtable(symtbl);
20611993Smckusick 			extractdirs(1);
20711438Smckusick 			removeoldleaves();
20811438Smckusick 			vprintf(stdout, "Calculate node updates.\n");
20911438Smckusick 			treescan(".", ROOTINO, nodeupdates);
21011438Smckusick 			findunreflinks();
21111438Smckusick 			removeoldnodes();
21210312Smckusick 		} else {
21311438Smckusick 			/*
21411438Smckusick 			 * This is a level zero dump tape.
21511438Smckusick 			 */
21611438Smckusick 			vprintf(stdout, "Begin level 0 restore\n");
21711438Smckusick 			initsymtable((char *)0);
21811993Smckusick 			extractdirs(1);
21911438Smckusick 			vprintf(stdout, "Calculate extraction list.\n");
22011438Smckusick 			treescan(".", ROOTINO, nodeupdates);
2214843Smckusic 		}
22210312Smckusick 		createleaves(symtbl);
22310312Smckusick 		createlinks();
22411993Smckusick 		setdirmodes();
22510312Smckusick 		checkrestore();
22610312Smckusick 		if (dflag) {
22710312Smckusick 			vprintf(stdout, "Verify the directory structure\n");
22810312Smckusick 			treescan(".", ROOTINO, verifyfile);
2294610Smckusick 		}
23010312Smckusick 		dumpsymtable(symtbl, (long)1);
23110312Smckusick 		done(0);
23211993Smckusick 	/*
23311993Smckusick 	 * Resume an incremental file system restoration.
23411993Smckusick 	 */
23510312Smckusick 	case 'R':
23610312Smckusick 		initsymtable(symtbl);
23711320Smckusick 		skipmaps();
23811320Smckusick 		skipdirs();
23910312Smckusick 		createleaves(symtbl);
24010312Smckusick 		createlinks();
24111993Smckusick 		setdirmodes();
24210312Smckusick 		checkrestore();
24310312Smckusick 		dumpsymtable(symtbl, (long)1);
24410312Smckusick 		done(0);
24511993Smckusick 	/*
24611993Smckusick 	 * List contents of tape.
24711993Smckusick 	 */
24811993Smckusick 	case 't':
24911993Smckusick 		setup();
25011993Smckusick 		extractdirs(0);
25127264Smckusick 		initsymtable((char *)0);
25211993Smckusick 		while (argc--) {
25311993Smckusick 			canon(*argv++, name);
25411993Smckusick 			ino = dirlookup(name);
25511993Smckusick 			if (ino == 0)
25611993Smckusick 				continue;
25711993Smckusick 			treescan(name, ino, listfile);
25811993Smckusick 		}
25911993Smckusick 		done(0);
26011993Smckusick 	/*
26111993Smckusick 	 * Batch extraction of tape contents.
26211993Smckusick 	 */
26311993Smckusick 	case 'x':
26411993Smckusick 		setup();
26511993Smckusick 		extractdirs(1);
26611993Smckusick 		initsymtable((char *)0);
26711993Smckusick 		while (argc--) {
26811993Smckusick 			canon(*argv++, name);
26911993Smckusick 			ino = dirlookup(name);
27011993Smckusick 			if (ino == 0)
27111993Smckusick 				continue;
27211993Smckusick 			if (mflag)
27311993Smckusick 				pathcheck(name);
27411993Smckusick 			treescan(name, ino, addfile);
27511993Smckusick 		}
27611993Smckusick 		createfiles();
27711993Smckusick 		createlinks();
27811993Smckusick 		setdirmodes();
27911993Smckusick 		if (dflag)
28011993Smckusick 			checkrestore();
28111993Smckusick 		done(0);
2824843Smckusic 	}
2834843Smckusic }
284