xref: /csrg-svn/local/ukc/dump/dumpmain.c (revision 32056)
132001Spc /*
232001Spc  * Copyright (c) 1980 Regents of the University of California.
332001Spc  * All rights reserved.  The Berkeley software License Agreement
432001Spc  * specifies the terms and conditions for redistribution.
532001Spc  */
632001Spc 
732001Spc #ifndef lint
8*32056Spc static char sccsid[] = "@(#)dumpmain.c	1.4 (UKC) 08/12/87	5.6 (Berkeley) 2/23/87";
932001Spc #endif not lint
1032001Spc 
1132001Spc #include "dump.h"
1232001Spc 
1332001Spc int	notify = 0;	/* notify operator flag */
1432001Spc int	blockswritten = 0;	/* number of blocks written on current tape */
1532001Spc int	tapeno = 0;	/* current tape number */
1632001Spc int	density = 0;	/* density in bytes/0.1" */
1732001Spc int	ntrec = NTREC;	/* # tape blocks in each tape record */
1832001Spc int	cartridge = 0;	/* Assume non-cartridge tape */
1932028Spc 
2032028Spc extern int labchk;	/* check labels */
2132028Spc int	rewindoffline;	/* put tape offline after every write */
2232028Spc 
2332001Spc #ifdef RDUMP
2432001Spc char	*host;
2532001Spc #endif
2632001Spc int	anydskipped;	/* set true in mark() if any directories are skipped */
2732001Spc 			/* this lets us avoid map pass 2 in some cases */
2832001Spc 
main(argc,argv)2932001Spc main(argc, argv)
3032001Spc 	int	argc;
3132001Spc 	char	*argv[];
3232001Spc {
3332001Spc 	char		*arg;
3432001Spc 	int		bflag = 0, i;
3532001Spc 	float		fetapes;
3632001Spc 	register	struct	fstab	*dt;
3732001Spc 
3832001Spc 	time(&(spcl.c_date));
3932001Spc 
4032001Spc 	tsize = 0;	/* Default later, based on 'c' option for cart tapes */
4132001Spc 	tape = TAPE;
4232001Spc 	disk = DISK;
4332001Spc 	increm = NINCREM;
4432001Spc 	temp = TEMP;
4532001Spc 	if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0) {
4632001Spc 		msg("TP_BSIZE must be a multiple of DEV_BSIZE\n");
4732001Spc 		dumpabort();
4832001Spc 	}
4932001Spc 	incno = '9';
5032001Spc 	uflag = 0;
5132001Spc 	arg = "u";
5232001Spc 	if(argc > 1) {
5332001Spc 		argv++;
5432001Spc 		argc--;
5532001Spc 		arg = *argv;
5632001Spc 		if (*arg == '-')
5732001Spc 			argc++;
5832001Spc 	}
5932001Spc 	while(*arg)
6032001Spc 	switch (*arg++) {
6132001Spc 	case 'w':
6232001Spc 		lastdump('w');		/* tell us only what has to be done */
6332001Spc 		exit(0);
6432001Spc 		break;
6532001Spc 	case 'W':			/* what to do */
6632001Spc 		lastdump('W');		/* tell us the current state of what has been done */
6732001Spc 		exit(0);		/* do nothing else */
6832001Spc 		break;
6932001Spc 
7032001Spc 	case 'f':			/* output file */
7132001Spc 		if(argc > 1) {
7232001Spc 			argv++;
7332001Spc 			argc--;
7432001Spc 			tape = *argv;
7532001Spc 		}
7632001Spc 		break;
7732001Spc 
7832001Spc 	case 'd':			/* density, in bits per inch */
7932001Spc 		if (argc > 1) {
8032001Spc 			argv++;
8132001Spc 			argc--;
8232001Spc 			density = atoi(*argv) / 10;
8332001Spc 			if (density >= 625 && !bflag)
8432001Spc 				ntrec = HIGHDENSITYTREC;
8532001Spc 		}
8632001Spc 		break;
8732001Spc 
8832001Spc 	case 's':			/* tape size, feet */
8932001Spc 		if(argc > 1) {
9032001Spc 			argv++;
9132001Spc 			argc--;
9232001Spc 			tsize = atol(*argv);
9332001Spc 			tsize *= 12L*10L;
9432001Spc 		}
9532001Spc 		break;
9632001Spc 
9732001Spc 	case 'b':			/* blocks per tape write */
9832001Spc 		if(argc > 1) {
9932001Spc 			argv++;
10032001Spc 			argc--;
10132001Spc 			bflag++;
10232001Spc 			ntrec = atol(*argv);
10332001Spc 		}
10432001Spc 		break;
10532001Spc 
10632001Spc 	case 'c':			/* Tape is cart. not 9-track */
10732001Spc 		cartridge++;
10832001Spc 		break;
10932001Spc 
11032001Spc 	case '0':			/* dump level */
11132001Spc 	case '1':
11232001Spc 	case '2':
11332001Spc 	case '3':
11432001Spc 	case '4':
11532001Spc 	case '5':
11632001Spc 	case '6':
11732001Spc 	case '7':
11832001Spc 	case '8':
11932001Spc 	case '9':
12032001Spc 		incno = arg[-1];
12132001Spc 		break;
12232001Spc 
12332001Spc 	case 'u':			/* update /etc/dumpdates */
12432001Spc 		uflag++;
12532001Spc 		break;
12632001Spc 
12732001Spc 	case 'n':			/* notify operators */
12832001Spc 		notify++;
12932001Spc 		break;
13032001Spc 
13132028Spc 	case 'l':			/* set a label format */
13232028Spc 		if (argc > 1) {
13332028Spc 			argv++;
13432028Spc 			argc--;
13532028Spc 			storelabel(*argv);
13632028Spc 		}
13732028Spc 		break;
13832028Spc 
13932028Spc 	case 'm':			/* set a label map */
14032028Spc 		if (argc > 1) {
14132028Spc 			argv++;
14232028Spc 			argc--;
14332028Spc 			storelabelmap(*argv);
14432028Spc 		}
14532028Spc 		break;
14632028Spc 
14732028Spc 	case 't':
14832028Spc 		labchk = 1;
14932028Spc 		break;
15032028Spc 
15132028Spc 	case 'o':
15232028Spc 		rewindoffline = 1;
15332028Spc 		break;
15432028Spc 
15532001Spc 	default:
15632001Spc 		fprintf(stderr, "bad key '%c%'\n", arg[-1]);
15732001Spc 		Exit(X_ABORT);
15832001Spc 	}
15932001Spc 	if(argc > 1) {
16032001Spc 		argv++;
16132001Spc 		argc--;
16232001Spc 		disk = *argv;
16332001Spc 	}
16432001Spc 	if (strcmp(tape, "-") == 0) {
16532001Spc 		pipeout++;
16632001Spc 		tape = "standard output";
16732001Spc 	}
16832001Spc 
16932001Spc 	/*
17032001Spc 	 * Determine how to default tape size and density
17132001Spc 	 *
17232001Spc 	 *         	density				tape size
17332001Spc 	 * 9-track	1600 bpi (160 bytes/.1")	2300 ft.
17432001Spc 	 * 9-track	6250 bpi (625 bytes/.1")	2300 ft.
17532001Spc  	 * cartridge	8000 bpi (100 bytes/.1")	1700 ft. (450*4 - slop)
17632001Spc 	 */
17732001Spc 	if (density == 0)
17832001Spc 		density = cartridge ? 100 : 160;
17932001Spc 	if (tsize == 0)
18032001Spc  		tsize = cartridge ? 1700L*120L : 2300L*120L;
18132001Spc 
18232001Spc #ifdef RDUMP
18332001Spc 	{ char *index();
18432001Spc 	  host = tape;
18532001Spc 	  tape = index(host, ':');
18632001Spc 	  if (tape == 0) {
18732001Spc 		msg("need keyletter ``f'' and device ``host:tape''\n");
18832001Spc 		exit(1);
18932001Spc 	  }
19032001Spc 	  *tape++ = 0;
19132001Spc 	  if (rmthost(host) == 0)
19232001Spc 		exit(X_ABORT);
19332001Spc 	}
19432001Spc 	setuid(getuid());	/* rmthost() is the only reason to be setuid */
19532001Spc #endif
19632001Spc 	if (signal(SIGHUP, sighup) == SIG_IGN)
19732001Spc 		signal(SIGHUP, SIG_IGN);
19832001Spc 	if (signal(SIGTRAP, sigtrap) == SIG_IGN)
19932001Spc 		signal(SIGTRAP, SIG_IGN);
20032001Spc 	if (signal(SIGFPE, sigfpe) == SIG_IGN)
20132001Spc 		signal(SIGFPE, SIG_IGN);
20232001Spc 	if (signal(SIGBUS, sigbus) == SIG_IGN)
20332001Spc 		signal(SIGBUS, SIG_IGN);
20432001Spc 	if (signal(SIGSEGV, sigsegv) == SIG_IGN)
20532001Spc 		signal(SIGSEGV, SIG_IGN);
20632001Spc 	if (signal(SIGTERM, sigterm) == SIG_IGN)
20732001Spc 		signal(SIGTERM, SIG_IGN);
20832001Spc 
20932001Spc 
21032001Spc 	if (signal(SIGINT, interrupt) == SIG_IGN)
21132001Spc 		signal(SIGINT, SIG_IGN);
21232001Spc 
21332001Spc 	set_operators();	/* /etc/group snarfed */
21432001Spc 	getfstab();		/* /etc/fstab snarfed */
21532001Spc 	/*
21632001Spc 	 *	disk can be either the full special file name,
21732001Spc 	 *	the suffix of the special file name,
21832001Spc 	 *	the special name missing the leading '/',
21932001Spc 	 *	the file system name with or without the leading '/'.
22032001Spc 	 */
22132001Spc 	dt = fstabsearch(disk);
22232003Spc 	if (dt != 0) {
22332001Spc 		disk = rawname(dt->fs_spec);
22432003Spc 		strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
22532003Spc 		strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
22632003Spc 	} else {
22732003Spc 		strncpy(spcl.c_dev, disk, NAMELEN);
22832003Spc 		strncpy(spcl.c_filesys, "an unlisted file system", NAMELEN);
22932003Spc 	}
23032028Spc 	strcpy(spcl.c_label, createlabel(0));
23132003Spc 	gethostname(spcl.c_host, NAMELEN);
23232003Spc 	spcl.c_level = incno - '0';
23332003Spc 	spcl.c_type = TS_TAPE;
23432001Spc 	getitime();		/* /etc/dumpdates snarfed */
23532001Spc 
23632001Spc 	msg("Date of this level %c dump: %s\n", incno, prdate(spcl.c_date));
23732001Spc  	msg("Date of last level %c dump: %s\n",
23832001Spc 		lastincno, prdate(spcl.c_ddate));
23932001Spc 	msg("Dumping %s ", disk);
24032028Spc 
24132001Spc 	if (dt != 0)
24232001Spc 		msgtail("(%s) ", dt->fs_file);
24332001Spc #ifdef RDUMP
24432001Spc 	msgtail("to %s on host %s\n", tape, host);
24532001Spc #else
24632001Spc 	msgtail("to %s\n", tape);
24732001Spc #endif
24832001Spc 
24932028Spc 	initialtape();	/* print label message if required */
25032028Spc 
25132028Spc 
25232001Spc 	fi = open(disk, 0);
25332001Spc 	if (fi < 0) {
25432001Spc 		msg("Cannot open %s\n", disk);
25532001Spc 		Exit(X_ABORT);
25632001Spc 	}
25732001Spc 	esize = 0;
25832001Spc 	sblock = (struct fs *)buf;
25932001Spc 	sync();
26032001Spc 	bread(SBLOCK, sblock, SBSIZE);
26132001Spc 	if (sblock->fs_magic != FS_MAGIC) {
26232001Spc 		msg("bad sblock magic number\n");
26332001Spc 		dumpabort();
26432001Spc 	}
26532001Spc 	msiz = roundup(howmany(sblock->fs_ipg * sblock->fs_ncg, NBBY),
26632001Spc 		TP_BSIZE);
26732001Spc 	clrmap = (char *)calloc(msiz, sizeof(char));
26832001Spc 	dirmap = (char *)calloc(msiz, sizeof(char));
26932001Spc 	nodmap = (char *)calloc(msiz, sizeof(char));
27032001Spc 
27132001Spc 	anydskipped = 0;
27232001Spc 	msg("mapping (Pass I) [regular files]\n");
27332001Spc 	pass(mark, (char *)NULL);		/* mark updates esize */
27432001Spc 
27532001Spc 	if (anydskipped) {
27632001Spc 		do {
27732001Spc 			msg("mapping (Pass II) [directories]\n");
27832001Spc 			nadded = 0;
27932001Spc 			pass(add, dirmap);
28032001Spc 		} while(nadded);
28132001Spc 	} else				/* keep the operators happy */
28232001Spc 		msg("mapping (Pass II) [directories]\n");
28332001Spc 
28432001Spc 	bmapest(clrmap);
28532001Spc 	bmapest(nodmap);
28632001Spc 
28732001Spc 	if (cartridge) {
28832001Spc 		/* Estimate number of tapes, assuming streaming stops at
28932001Spc 		   the end of each block written, and not in mid-block.
29032001Spc 		   Assume no erroneous blocks; this can be compensated for
29132001Spc 		   with an artificially low tape size. */
29232001Spc 		fetapes =
29332001Spc 		(	  esize		/* blocks */
29432001Spc 			* TP_BSIZE	/* bytes/block */
29532001Spc 			* (1.0/density)	/* 0.1" / byte */
29632001Spc 		  +
29732001Spc 			  esize		/* blocks */
29832001Spc 			* (1.0/ntrec)	/* streaming-stops per block */
29932001Spc 			* 15.48		/* 0.1" / streaming-stop */
30032001Spc 		) * (1.0 / tsize );	/* tape / 0.1" */
30132001Spc 	} else {
30232001Spc 		/* Estimate number of tapes, for old fashioned 9-track tape */
30332001Spc 		int tenthsperirg = (density == 625) ? 3 : 7;
30432001Spc 		fetapes =
30532001Spc 		(	  esize		/* blocks */
30632001Spc 			* TP_BSIZE	/* bytes / block */
30732001Spc 			* (1.0/density)	/* 0.1" / byte */
30832001Spc 		  +
30932001Spc 			  esize		/* blocks */
31032001Spc 			* (1.0/ntrec)	/* IRG's / block */
31132001Spc 			* tenthsperirg	/* 0.1" / IRG */
31232001Spc 		) * (1.0 / tsize );	/* tape / 0.1" */
31332001Spc 	}
31432001Spc 	etapes = fetapes;		/* truncating assignment */
31532001Spc 	etapes++;
31632001Spc 	/* count the nodemap on each additional tape */
31732001Spc 	for (i = 1; i < etapes; i++)
31832001Spc 		bmapest(nodmap);
31932001Spc 	esize += i + 10;	/* headers + 10 trailer blocks */
32032001Spc 	msg("estimated %ld tape blocks on %3.2f tape(s).\n", esize, fetapes);
32132001Spc 
32232028Spc 	labelest(fetapes);		/* check we have enough labels */
32332028Spc 
32432001Spc 	alloctape();			/* Allocate tape buffer */
32532001Spc 
32632001Spc 	otape();			/* bitmap is the first to tape write */
32732001Spc 	time(&(tstart_writing));
32832001Spc 	bitmap(clrmap, TS_CLRI);
32932001Spc 
33032001Spc 	msg("dumping (Pass III) [directories]\n");
33132001Spc  	pass(dirdump, dirmap);
33232001Spc 
33332001Spc 	msg("dumping (Pass IV) [regular files]\n");
33432001Spc 	pass(dump, nodmap);
33532001Spc 
33632001Spc 	spcl.c_type = TS_END;
33732001Spc #ifndef RDUMP
33832001Spc 	for(i=0; i<ntrec; i++)
33932001Spc 		spclrec();
34032001Spc #endif
34132001Spc 	msg("DUMP: %ld tape blocks on %d tape(s)\n",spcl.c_tapea,spcl.c_volume);
34232001Spc 	msg("DUMP IS DONE\n");
34332001Spc 
34432001Spc 	putitime();
34532001Spc #ifndef RDUMP
34632001Spc 	if (!pipeout) {
347*32056Spc 		rewind();
34832001Spc 		close(to);
34932001Spc 	}
35032001Spc #else
35132001Spc 	tflush(1);
35232001Spc 	rewind();
35332001Spc #endif
35432001Spc 	broadcast("DUMP IS DONE!\7\7\n");
35532001Spc 	Exit(X_FINOK);
35632001Spc }
35732001Spc 
sighup()35832001Spc int	sighup(){	msg("SIGHUP()  try rewriting\n"); sigAbort();}
sigtrap()35932001Spc int	sigtrap(){	msg("SIGTRAP()  try rewriting\n"); sigAbort();}
sigfpe()36032001Spc int	sigfpe(){	msg("SIGFPE()  try rewriting\n"); sigAbort();}
sigbus()36132001Spc int	sigbus(){	msg("SIGBUS()  try rewriting\n"); sigAbort();}
sigsegv()36232001Spc int	sigsegv(){	msg("SIGSEGV()  ABORTING!\n"); abort();}
sigalrm()36332001Spc int	sigalrm(){	msg("SIGALRM()  try rewriting\n"); sigAbort();}
sigterm()36432001Spc int	sigterm(){	msg("SIGTERM()  try rewriting\n"); sigAbort();}
36532001Spc 
sigAbort()36632001Spc sigAbort()
36732001Spc {
36832001Spc 	if (pipeout) {
36932001Spc 		msg("Unknown signal, cannot recover\n");
37032001Spc 		dumpabort();
37132001Spc 	}
37232001Spc 	msg("Rewriting attempted as response to unknown signal.\n");
37332001Spc 	fflush(stderr);
37432001Spc 	fflush(stdout);
37532001Spc 	close_rewind();
37632001Spc 	exit(X_REWRITE);
37732001Spc }
37832001Spc 
rawname(cp)37932001Spc char *rawname(cp)
38032001Spc 	char *cp;
38132001Spc {
38232001Spc 	static char rawbuf[32];
38332001Spc 	char *rindex();
38432001Spc 	char *dp = rindex(cp, '/');
38532001Spc 
38632001Spc 	if (dp == 0)
38732001Spc 		return (0);
38832001Spc 	*dp = 0;
38932001Spc 	strcpy(rawbuf, cp);
39032001Spc 	*dp = '/';
39132001Spc 	strcat(rawbuf, "/r");
39232001Spc 	strcat(rawbuf, dp+1);
39332001Spc 	return (rawbuf);
39432001Spc }
395