xref: /csrg-svn/sbin/dump/main.c (revision 10910)
1*10910Ssam static	char *sccsid = "@(#)main.c	1.11 (Berkeley) 02/11/83";
21423Sroot #include "dump.h"
31423Sroot 
41423Sroot int	notify = 0;	/* notify operator flag */
51423Sroot int	blockswritten = 0;	/* number of blocks written on current tape */
61423Sroot int	tapeno = 0;	/* current tape number */
7*10910Ssam int	density = 0;	/* density in bytes/0.1" */
8*10910Ssam int	ntrec = NTREC;	/* # tape blocks in each tape record */
9*10910Ssam int	cartridge = 0;	/* Assume non-cartridge tape */
106882Ssam #ifdef RDUMP
116882Ssam char	*host;
126882Ssam #endif
131423Sroot 
141423Sroot main(argc, argv)
151423Sroot 	int	argc;
161423Sroot 	char	*argv[];
171423Sroot {
181423Sroot 	char		*arg;
195328Smckusic 	int		i;
201423Sroot 	float		fetapes;
211423Sroot 	register	struct	fstab	*dt;
221423Sroot 
231423Sroot 	time(&(spcl.c_date));
241423Sroot 
25*10910Ssam 	tsize = 0;	/* Default later, based on 'c' option for cart tapes */
261423Sroot 	tape = TAPE;
271423Sroot 	disk = DISK;
281423Sroot 	increm = NINCREM;
295328Smckusic 	if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0) {
305328Smckusic 		msg("TP_BSIZE must be a multiple of DEV_BSIZE\n");
315328Smckusic 		dumpabort();
325328Smckusic 	}
331423Sroot 	incno = '9';
341423Sroot 	uflag = 0;
351423Sroot 	arg = "u";
361423Sroot 	if(argc > 1) {
371423Sroot 		argv++;
381423Sroot 		argc--;
391423Sroot 		arg = *argv;
401423Sroot 		if (*arg == '-')
411423Sroot 			argc++;
421423Sroot 	}
431423Sroot 	while(*arg)
441423Sroot 	switch (*arg++) {
451463Sroot 	case 'w':
461463Sroot 		lastdump('w');		/* tell us only what has to be done */
471463Sroot 		exit(0);
481463Sroot 		break;
491423Sroot 	case 'W':			/* what to do */
501463Sroot 		lastdump('W');		/* tell us the current state of what has been done */
511423Sroot 		exit(0);		/* do nothing else */
521423Sroot 		break;
531423Sroot 
541423Sroot 	case 'J':			/* update old to new */
551423Sroot 		o_nconvert();
561423Sroot 		exit(0);		/* do nothing else */
571423Sroot 		break;
581423Sroot 
591423Sroot 	case 'f':			/* output file */
601423Sroot 		if(argc > 1) {
611423Sroot 			argv++;
621423Sroot 			argc--;
631423Sroot 			tape = *argv;
641423Sroot 		}
651423Sroot 		break;
661423Sroot 
671423Sroot 	case 'd':			/* density, in bits per inch */
681423Sroot 		if (argc > 1) {
691423Sroot 			argv++;
701423Sroot 			argc--;
711423Sroot 			density = atoi(*argv) / 10;
721423Sroot 		}
731423Sroot 		break;
741423Sroot 
751423Sroot 	case 's':			/* tape size, feet */
761423Sroot 		if(argc > 1) {
771423Sroot 			argv++;
781423Sroot 			argc--;
791423Sroot 			tsize = atol(*argv);
801423Sroot 			tsize *= 12L*10L;
811423Sroot 		}
821423Sroot 		break;
831423Sroot 
84*10910Ssam 	case 'b':			/* blocks per tape write */
85*10910Ssam 		if(argc > 1) {
86*10910Ssam 			argv++;
87*10910Ssam 			argc--;
88*10910Ssam 			ntrec = atol(*argv);
89*10910Ssam 		}
90*10910Ssam 		break;
91*10910Ssam 
92*10910Ssam 	case 'c':			/* Tape is cart. not 9-track */
93*10910Ssam 		cartridge++;
94*10910Ssam 		break;
95*10910Ssam 
961423Sroot 	case '0':			/* dump level */
971423Sroot 	case '1':
981423Sroot 	case '2':
991423Sroot 	case '3':
1001423Sroot 	case '4':
1011423Sroot 	case '5':
1021423Sroot 	case '6':
1031423Sroot 	case '7':
1041423Sroot 	case '8':
1051423Sroot 	case '9':
1061423Sroot 		incno = arg[-1];
1071423Sroot 		break;
1081423Sroot 
1091423Sroot 	case 'u':			/* update /etc/dumpdates */
1101423Sroot 		uflag++;
1111423Sroot 		break;
1121423Sroot 
1131423Sroot 	case 'n':			/* notify operators */
1141423Sroot 		notify++;
1151423Sroot 		break;
1161423Sroot 
1171423Sroot 	default:
1181423Sroot 		printf("bad key '%c%'\n", arg[-1]);
1191423Sroot 		Exit(X_ABORT);
1201423Sroot 	}
1211423Sroot 	if(argc > 1) {
1221423Sroot 		argv++;
1231423Sroot 		argc--;
1241423Sroot 		disk = *argv;
1251423Sroot 	}
126*10910Ssam 
127*10910Ssam 	/*
128*10910Ssam 	 * Determine how to default tape size and density
129*10910Ssam 	 *
130*10910Ssam 	 *         	density				tape size
131*10910Ssam 	 * 9-track	1600 bpi (160 bytes/.1")	2300 ft.
132*10910Ssam 	 * 9-track	6250 bpi (625 bytes/.1")	2300 ft.
133*10910Ssam 	 * cartridge	8000 bpi (100 bytes/.1")	4000 ft. (450*9 - slop)
134*10910Ssam 	 */
135*10910Ssam 	if (density == 0)
136*10910Ssam 		density = cartridge ? 100 : 160;
137*10910Ssam 	if (tsize == 0)
138*10910Ssam 		tsize = cartridge ? 4000L*120L : 2300L*120L;
139*10910Ssam 
1406886Ssam #ifdef RDUMP
1416886Ssam 	{ char *index();
1426886Ssam 	  host = tape;
1436886Ssam 	  tape = index(host, ':');
1446886Ssam 	  if (tape == 0) {
1456886Ssam 		msg("need keyletter ``f'' and device ``host:tape''");
1466886Ssam 		exit(1);
1476886Ssam 	  }
1486886Ssam 	  *tape++ = 0;
1496886Ssam 	  if (rmthost(host) == 0)
1506886Ssam 		exit(X_ABORT);
1516886Ssam 	}
1526886Ssam #endif
1531423Sroot 	if (signal(SIGHUP, sighup) == SIG_IGN)
1541423Sroot 		signal(SIGHUP, SIG_IGN);
1551423Sroot 	if (signal(SIGTRAP, sigtrap) == SIG_IGN)
1561423Sroot 		signal(SIGTRAP, SIG_IGN);
1571423Sroot 	if (signal(SIGFPE, sigfpe) == SIG_IGN)
1581423Sroot 		signal(SIGFPE, SIG_IGN);
1591423Sroot 	if (signal(SIGBUS, sigbus) == SIG_IGN)
1601423Sroot 		signal(SIGBUS, SIG_IGN);
1611423Sroot 	if (signal(SIGSEGV, sigsegv) == SIG_IGN)
1621423Sroot 		signal(SIGSEGV, SIG_IGN);
1631423Sroot 	if (signal(SIGTERM, sigterm) == SIG_IGN)
1641423Sroot 		signal(SIGTERM, SIG_IGN);
1651423Sroot 
1661423Sroot 
1671423Sroot 	if (signal(SIGINT, interrupt) == SIG_IGN)
1681423Sroot 		signal(SIGINT, SIG_IGN);
1691423Sroot 
1701423Sroot 	set_operators();	/* /etc/group snarfed */
1711423Sroot 	getfstab();		/* /etc/fstab snarfed */
1721423Sroot 	/*
1731423Sroot 	 *	disk can be either the full special file name,
1741423Sroot 	 *	the suffix of the special file name,
1751423Sroot 	 *	the special name missing the leading '/',
1761423Sroot 	 *	the file system name with or without the leading '/'.
1771423Sroot 	 */
1781423Sroot 	dt = fstabsearch(disk);
1791423Sroot 	if (dt != 0)
1801423Sroot 		disk = rawname(dt->fs_spec);
1811423Sroot 	getitime();		/* /etc/dumpdates snarfed */
1821423Sroot 
1831423Sroot 	msg("Date of this level %c dump: %s\n", incno, prdate(spcl.c_date));
1841423Sroot 	msg("Date of last level %c dump: %s\n", incno, prdate(spcl.c_ddate));
1851423Sroot 	msg("Dumping %s ", disk);
1861423Sroot 	if (dt != 0)
1871423Sroot 		msgtail("(%s) ", dt->fs_file);
1888506Smckusick #ifdef RDUMP
1898506Smckusick 	msgtail("to %s on host %s\n", tape, host);
1908506Smckusick #else
1918371Smckusick 	msgtail("to %s\n", tape);
1926882Ssam #endif
1931423Sroot 
1941423Sroot 	fi = open(disk, 0);
1951423Sroot 	if (fi < 0) {
1961423Sroot 		msg("Cannot open %s\n", disk);
1971423Sroot 		Exit(X_ABORT);
1981423Sroot 	}
1991423Sroot 	esize = 0;
2005328Smckusic 	sblock = (struct fs *)buf;
2015328Smckusic 	sync();
2025342Smckusic 	bread(SBLOCK, sblock, SBSIZE);
2035328Smckusic 	if (sblock->fs_magic != FS_MAGIC) {
2045328Smckusic 		msg("bad sblock magic number\n");
2055328Smckusic 		dumpabort();
2065328Smckusic 	}
2075328Smckusic 	msiz = roundup(howmany(sblock->fs_ipg * sblock->fs_ncg, NBBY),
2085328Smckusic 		TP_BSIZE);
2095328Smckusic 	clrmap = (char *)calloc(msiz, sizeof(char));
2105328Smckusic 	dirmap = (char *)calloc(msiz, sizeof(char));
2115328Smckusic 	nodmap = (char *)calloc(msiz, sizeof(char));
2121423Sroot 
2131423Sroot 	msg("mapping (Pass I) [regular files]\n");
2145328Smckusic 	pass(mark, (char *)NULL);		/* mark updates esize */
2151423Sroot 
2161423Sroot 	do {
2171423Sroot 		msg("mapping (Pass II) [directories]\n");
2181423Sroot 		nadded = 0;
2191423Sroot 		pass(add, dirmap);
2201423Sroot 	} while(nadded);
2211423Sroot 
2221423Sroot 	bmapest(clrmap);
2231423Sroot 	bmapest(nodmap);
2241423Sroot 
225*10910Ssam 	if (cartridge) {
226*10910Ssam 		/* Estimate number of tapes, assuming streaming stops at
227*10910Ssam 		   the end of each block written, and not in mid-block.
228*10910Ssam 		   Assume no erroneous blocks; this can be compensated for
229*10910Ssam 		   with an artificially low tape size. */
230*10910Ssam 		fetapes =
2315328Smckusic 		(	  esize		/* blocks */
232*10910Ssam 			* TP_BSIZE	/* bytes/block */
233*10910Ssam 			* (1.0/density)	/* 0.1" / byte */
234*10910Ssam 		  +
235*10910Ssam 			  esize		/* blocks */
236*10910Ssam 			* (1.0/ntrec)	/* streaming-stops per block */
237*10910Ssam 			* 15.48		/* 0.1" / streaming-stop */
238*10910Ssam 		) * (1.0 / tsize );	/* tape / 0.1" */
239*10910Ssam 	} else {
240*10910Ssam 		/* Estimate number of tapes, for old fashioned 9-track tape */
241*10910Ssam 		int tenthsperirg = (density == 625) ? 3 : 7;
242*10910Ssam 		fetapes =
243*10910Ssam 		(	  esize		/* blocks */
2445328Smckusic 			* TP_BSIZE	/* bytes / block */
2455328Smckusic 			* (1.0/density)	/* 0.1" / byte */
2461423Sroot 		  +
2475328Smckusic 			  esize		/* blocks */
248*10910Ssam 			* (1.0/ntrec)	/* IRG's / block */
249*10910Ssam 			* tenthsperirg	/* 0.1" / IRG */
2505328Smckusic 			* 7		/* 0.1" / IRG */
251*10910Ssam 		) * (1.0 / tsize );	/* tape / 0.1" */
252*10910Ssam 	}
2531423Sroot 	etapes = fetapes;		/* truncating assignment */
2541423Sroot 	etapes++;
2555328Smckusic 	/* count the nodemap on each additional tape */
2565328Smckusic 	for (i = 1; i < etapes; i++)
2575328Smckusic 		bmapest(nodmap);
2585328Smckusic 	esize += i + 10;	/* headers + 10 trailer blocks */
2591423Sroot 	msg("estimated %ld tape blocks on %3.2f tape(s).\n", esize, fetapes);
2601423Sroot 
261*10910Ssam 	alloctape();			/* Allocate tape buffer */
262*10910Ssam 
2631423Sroot 	otape();			/* bitmap is the first to tape write */
2641423Sroot 	time(&(tstart_writing));
2651423Sroot 	bitmap(clrmap, TS_CLRI);
2661423Sroot 
2671423Sroot 	msg("dumping (Pass III) [directories]\n");
2681423Sroot 	pass(dump, dirmap);
2691423Sroot 
2701423Sroot 	msg("dumping (Pass IV) [regular files]\n");
2711423Sroot 	pass(dump, nodmap);
2721423Sroot 
2731423Sroot 	spcl.c_type = TS_END;
2746882Ssam #ifndef RDUMP
275*10910Ssam 	for(i=0; i<ntrec; i++)
2761423Sroot 		spclrec();
2776882Ssam #endif
2781423Sroot 	msg("DUMP: %ld tape blocks on %d tape(s)\n",spcl.c_tapea,spcl.c_volume);
2791423Sroot 	msg("DUMP IS DONE\n");
2801423Sroot 
2811423Sroot 	putitime();
2826882Ssam #ifndef RDUMP
2831423Sroot 	close(to);
2846882Ssam #else
2856882Ssam 	tflush(1);
2866882Ssam #endif
2871423Sroot 	rewind();
2881423Sroot 	broadcast("DUMP IS DONE!\7\7\n");
2891423Sroot 	Exit(X_FINOK);
2901423Sroot }
2911423Sroot 
2921423Sroot int	sighup(){	msg("SIGHUP()  try rewriting\n"); sigAbort();}
2931423Sroot int	sigtrap(){	msg("SIGTRAP()  try rewriting\n"); sigAbort();}
2941423Sroot int	sigfpe(){	msg("SIGFPE()  try rewriting\n"); sigAbort();}
2951423Sroot int	sigbus(){	msg("SIGBUS()  try rewriting\n"); sigAbort();}
2961423Sroot int	sigsegv(){	msg("SIGSEGV()  ABORTING!\n"); abort();}
2971423Sroot int	sigalrm(){	msg("SIGALRM()  try rewriting\n"); sigAbort();}
2981423Sroot int	sigterm(){	msg("SIGTERM()  try rewriting\n"); sigAbort();}
2991423Sroot 
3001423Sroot sigAbort()
3011423Sroot {
3021423Sroot 	msg("Rewriting attempted as response to unknown signal.\n");
3031423Sroot 	fflush(stderr);
3041423Sroot 	fflush(stdout);
3051423Sroot 	close_rewind();
3061423Sroot 	exit(X_REWRITE);
3071423Sroot }
3081423Sroot 
3091423Sroot char *rawname(cp)
3101423Sroot 	char *cp;
3111423Sroot {
3121423Sroot 	static char rawbuf[32];
3134608Smckusic 	char *rindex();
3141423Sroot 	char *dp = rindex(cp, '/');
3151423Sroot 
3161423Sroot 	if (dp == 0)
3171423Sroot 		return (0);
3181423Sroot 	*dp = 0;
3191423Sroot 	strcpy(rawbuf, cp);
3201423Sroot 	*dp = '/';
3211423Sroot 	strcat(rawbuf, "/r");
3221423Sroot 	strcat(rawbuf, dp+1);
3231423Sroot 	return (rawbuf);
3241423Sroot }
325