xref: /csrg-svn/local/ukc/dump/dumpmain.c (revision 32001)
1*32001Spc /*
2*32001Spc  * Copyright (c) 1980 Regents of the University of California.
3*32001Spc  * All rights reserved.  The Berkeley software License Agreement
4*32001Spc  * specifies the terms and conditions for redistribution.
5*32001Spc  */
6*32001Spc 
7*32001Spc #ifndef lint
8*32001Spc static char sccsid[] = "@(#)dumpmain.c	5.4 (Berkeley) 5/28/86";
9*32001Spc #endif not lint
10*32001Spc 
11*32001Spc #include "dump.h"
12*32001Spc 
13*32001Spc int	notify = 0;	/* notify operator flag */
14*32001Spc int	blockswritten = 0;	/* number of blocks written on current tape */
15*32001Spc int	tapeno = 0;	/* current tape number */
16*32001Spc int	density = 0;	/* density in bytes/0.1" */
17*32001Spc int	ntrec = NTREC;	/* # tape blocks in each tape record */
18*32001Spc int	cartridge = 0;	/* Assume non-cartridge tape */
19*32001Spc #ifdef RDUMP
20*32001Spc char	*host;
21*32001Spc #endif
22*32001Spc int	anydskipped;	/* set true in mark() if any directories are skipped */
23*32001Spc 			/* this lets us avoid map pass 2 in some cases */
24*32001Spc 
25*32001Spc main(argc, argv)
26*32001Spc 	int	argc;
27*32001Spc 	char	*argv[];
28*32001Spc {
29*32001Spc 	char		*arg;
30*32001Spc 	int		bflag = 0, i;
31*32001Spc 	float		fetapes;
32*32001Spc 	register	struct	fstab	*dt;
33*32001Spc 
34*32001Spc 	time(&(spcl.c_date));
35*32001Spc 
36*32001Spc 	tsize = 0;	/* Default later, based on 'c' option for cart tapes */
37*32001Spc 	tape = TAPE;
38*32001Spc 	disk = DISK;
39*32001Spc 	increm = NINCREM;
40*32001Spc 	temp = TEMP;
41*32001Spc 	if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0) {
42*32001Spc 		msg("TP_BSIZE must be a multiple of DEV_BSIZE\n");
43*32001Spc 		dumpabort();
44*32001Spc 	}
45*32001Spc 	incno = '9';
46*32001Spc 	uflag = 0;
47*32001Spc 	arg = "u";
48*32001Spc 	if(argc > 1) {
49*32001Spc 		argv++;
50*32001Spc 		argc--;
51*32001Spc 		arg = *argv;
52*32001Spc 		if (*arg == '-')
53*32001Spc 			argc++;
54*32001Spc 	}
55*32001Spc 	while(*arg)
56*32001Spc 	switch (*arg++) {
57*32001Spc 	case 'w':
58*32001Spc 		lastdump('w');		/* tell us only what has to be done */
59*32001Spc 		exit(0);
60*32001Spc 		break;
61*32001Spc 	case 'W':			/* what to do */
62*32001Spc 		lastdump('W');		/* tell us the current state of what has been done */
63*32001Spc 		exit(0);		/* do nothing else */
64*32001Spc 		break;
65*32001Spc 
66*32001Spc 	case 'f':			/* output file */
67*32001Spc 		if(argc > 1) {
68*32001Spc 			argv++;
69*32001Spc 			argc--;
70*32001Spc 			tape = *argv;
71*32001Spc 		}
72*32001Spc 		break;
73*32001Spc 
74*32001Spc 	case 'd':			/* density, in bits per inch */
75*32001Spc 		if (argc > 1) {
76*32001Spc 			argv++;
77*32001Spc 			argc--;
78*32001Spc 			density = atoi(*argv) / 10;
79*32001Spc 			if (density >= 625 && !bflag)
80*32001Spc 				ntrec = HIGHDENSITYTREC;
81*32001Spc 		}
82*32001Spc 		break;
83*32001Spc 
84*32001Spc 	case 's':			/* tape size, feet */
85*32001Spc 		if(argc > 1) {
86*32001Spc 			argv++;
87*32001Spc 			argc--;
88*32001Spc 			tsize = atol(*argv);
89*32001Spc 			tsize *= 12L*10L;
90*32001Spc 		}
91*32001Spc 		break;
92*32001Spc 
93*32001Spc 	case 'b':			/* blocks per tape write */
94*32001Spc 		if(argc > 1) {
95*32001Spc 			argv++;
96*32001Spc 			argc--;
97*32001Spc 			bflag++;
98*32001Spc 			ntrec = atol(*argv);
99*32001Spc 		}
100*32001Spc 		break;
101*32001Spc 
102*32001Spc 	case 'c':			/* Tape is cart. not 9-track */
103*32001Spc 		cartridge++;
104*32001Spc 		break;
105*32001Spc 
106*32001Spc 	case '0':			/* dump level */
107*32001Spc 	case '1':
108*32001Spc 	case '2':
109*32001Spc 	case '3':
110*32001Spc 	case '4':
111*32001Spc 	case '5':
112*32001Spc 	case '6':
113*32001Spc 	case '7':
114*32001Spc 	case '8':
115*32001Spc 	case '9':
116*32001Spc 		incno = arg[-1];
117*32001Spc 		break;
118*32001Spc 
119*32001Spc 	case 'u':			/* update /etc/dumpdates */
120*32001Spc 		uflag++;
121*32001Spc 		break;
122*32001Spc 
123*32001Spc 	case 'n':			/* notify operators */
124*32001Spc 		notify++;
125*32001Spc 		break;
126*32001Spc 
127*32001Spc 	default:
128*32001Spc 		fprintf(stderr, "bad key '%c%'\n", arg[-1]);
129*32001Spc 		Exit(X_ABORT);
130*32001Spc 	}
131*32001Spc 	if(argc > 1) {
132*32001Spc 		argv++;
133*32001Spc 		argc--;
134*32001Spc 		disk = *argv;
135*32001Spc 	}
136*32001Spc 	if (strcmp(tape, "-") == 0) {
137*32001Spc 		pipeout++;
138*32001Spc 		tape = "standard output";
139*32001Spc 	}
140*32001Spc 
141*32001Spc 	/*
142*32001Spc 	 * Determine how to default tape size and density
143*32001Spc 	 *
144*32001Spc 	 *         	density				tape size
145*32001Spc 	 * 9-track	1600 bpi (160 bytes/.1")	2300 ft.
146*32001Spc 	 * 9-track	6250 bpi (625 bytes/.1")	2300 ft.
147*32001Spc  	 * cartridge	8000 bpi (100 bytes/.1")	1700 ft. (450*4 - slop)
148*32001Spc 	 */
149*32001Spc 	if (density == 0)
150*32001Spc 		density = cartridge ? 100 : 160;
151*32001Spc 	if (tsize == 0)
152*32001Spc  		tsize = cartridge ? 1700L*120L : 2300L*120L;
153*32001Spc 
154*32001Spc #ifdef RDUMP
155*32001Spc 	{ char *index();
156*32001Spc 	  host = tape;
157*32001Spc 	  tape = index(host, ':');
158*32001Spc 	  if (tape == 0) {
159*32001Spc 		msg("need keyletter ``f'' and device ``host:tape''\n");
160*32001Spc 		exit(1);
161*32001Spc 	  }
162*32001Spc 	  *tape++ = 0;
163*32001Spc 	  if (rmthost(host) == 0)
164*32001Spc 		exit(X_ABORT);
165*32001Spc 	}
166*32001Spc 	setuid(getuid());	/* rmthost() is the only reason to be setuid */
167*32001Spc #endif
168*32001Spc 	if (signal(SIGHUP, sighup) == SIG_IGN)
169*32001Spc 		signal(SIGHUP, SIG_IGN);
170*32001Spc 	if (signal(SIGTRAP, sigtrap) == SIG_IGN)
171*32001Spc 		signal(SIGTRAP, SIG_IGN);
172*32001Spc 	if (signal(SIGFPE, sigfpe) == SIG_IGN)
173*32001Spc 		signal(SIGFPE, SIG_IGN);
174*32001Spc 	if (signal(SIGBUS, sigbus) == SIG_IGN)
175*32001Spc 		signal(SIGBUS, SIG_IGN);
176*32001Spc 	if (signal(SIGSEGV, sigsegv) == SIG_IGN)
177*32001Spc 		signal(SIGSEGV, SIG_IGN);
178*32001Spc 	if (signal(SIGTERM, sigterm) == SIG_IGN)
179*32001Spc 		signal(SIGTERM, SIG_IGN);
180*32001Spc 
181*32001Spc 
182*32001Spc 	if (signal(SIGINT, interrupt) == SIG_IGN)
183*32001Spc 		signal(SIGINT, SIG_IGN);
184*32001Spc 
185*32001Spc 	set_operators();	/* /etc/group snarfed */
186*32001Spc 	getfstab();		/* /etc/fstab snarfed */
187*32001Spc 	/*
188*32001Spc 	 *	disk can be either the full special file name,
189*32001Spc 	 *	the suffix of the special file name,
190*32001Spc 	 *	the special name missing the leading '/',
191*32001Spc 	 *	the file system name with or without the leading '/'.
192*32001Spc 	 */
193*32001Spc 	dt = fstabsearch(disk);
194*32001Spc 	if (dt != 0)
195*32001Spc 		disk = rawname(dt->fs_spec);
196*32001Spc 	getitime();		/* /etc/dumpdates snarfed */
197*32001Spc 
198*32001Spc 	msg("Date of this level %c dump: %s\n", incno, prdate(spcl.c_date));
199*32001Spc  	msg("Date of last level %c dump: %s\n",
200*32001Spc 		lastincno, prdate(spcl.c_ddate));
201*32001Spc 	msg("Dumping %s ", disk);
202*32001Spc 	if (dt != 0)
203*32001Spc 		msgtail("(%s) ", dt->fs_file);
204*32001Spc #ifdef RDUMP
205*32001Spc 	msgtail("to %s on host %s\n", tape, host);
206*32001Spc #else
207*32001Spc 	msgtail("to %s\n", tape);
208*32001Spc #endif
209*32001Spc 
210*32001Spc 	fi = open(disk, 0);
211*32001Spc 	if (fi < 0) {
212*32001Spc 		msg("Cannot open %s\n", disk);
213*32001Spc 		Exit(X_ABORT);
214*32001Spc 	}
215*32001Spc 	esize = 0;
216*32001Spc 	sblock = (struct fs *)buf;
217*32001Spc 	sync();
218*32001Spc 	bread(SBLOCK, sblock, SBSIZE);
219*32001Spc 	if (sblock->fs_magic != FS_MAGIC) {
220*32001Spc 		msg("bad sblock magic number\n");
221*32001Spc 		dumpabort();
222*32001Spc 	}
223*32001Spc 	msiz = roundup(howmany(sblock->fs_ipg * sblock->fs_ncg, NBBY),
224*32001Spc 		TP_BSIZE);
225*32001Spc 	clrmap = (char *)calloc(msiz, sizeof(char));
226*32001Spc 	dirmap = (char *)calloc(msiz, sizeof(char));
227*32001Spc 	nodmap = (char *)calloc(msiz, sizeof(char));
228*32001Spc 
229*32001Spc 	anydskipped = 0;
230*32001Spc 	msg("mapping (Pass I) [regular files]\n");
231*32001Spc 	pass(mark, (char *)NULL);		/* mark updates esize */
232*32001Spc 
233*32001Spc 	if (anydskipped) {
234*32001Spc 		do {
235*32001Spc 			msg("mapping (Pass II) [directories]\n");
236*32001Spc 			nadded = 0;
237*32001Spc 			pass(add, dirmap);
238*32001Spc 		} while(nadded);
239*32001Spc 	} else				/* keep the operators happy */
240*32001Spc 		msg("mapping (Pass II) [directories]\n");
241*32001Spc 
242*32001Spc 	bmapest(clrmap);
243*32001Spc 	bmapest(nodmap);
244*32001Spc 
245*32001Spc 	if (cartridge) {
246*32001Spc 		/* Estimate number of tapes, assuming streaming stops at
247*32001Spc 		   the end of each block written, and not in mid-block.
248*32001Spc 		   Assume no erroneous blocks; this can be compensated for
249*32001Spc 		   with an artificially low tape size. */
250*32001Spc 		fetapes =
251*32001Spc 		(	  esize		/* blocks */
252*32001Spc 			* TP_BSIZE	/* bytes/block */
253*32001Spc 			* (1.0/density)	/* 0.1" / byte */
254*32001Spc 		  +
255*32001Spc 			  esize		/* blocks */
256*32001Spc 			* (1.0/ntrec)	/* streaming-stops per block */
257*32001Spc 			* 15.48		/* 0.1" / streaming-stop */
258*32001Spc 		) * (1.0 / tsize );	/* tape / 0.1" */
259*32001Spc 	} else {
260*32001Spc 		/* Estimate number of tapes, for old fashioned 9-track tape */
261*32001Spc 		int tenthsperirg = (density == 625) ? 3 : 7;
262*32001Spc 		fetapes =
263*32001Spc 		(	  esize		/* blocks */
264*32001Spc 			* TP_BSIZE	/* bytes / block */
265*32001Spc 			* (1.0/density)	/* 0.1" / byte */
266*32001Spc 		  +
267*32001Spc 			  esize		/* blocks */
268*32001Spc 			* (1.0/ntrec)	/* IRG's / block */
269*32001Spc 			* tenthsperirg	/* 0.1" / IRG */
270*32001Spc 		) * (1.0 / tsize );	/* tape / 0.1" */
271*32001Spc 	}
272*32001Spc 	etapes = fetapes;		/* truncating assignment */
273*32001Spc 	etapes++;
274*32001Spc 	/* count the nodemap on each additional tape */
275*32001Spc 	for (i = 1; i < etapes; i++)
276*32001Spc 		bmapest(nodmap);
277*32001Spc 	esize += i + 10;	/* headers + 10 trailer blocks */
278*32001Spc 	msg("estimated %ld tape blocks on %3.2f tape(s).\n", esize, fetapes);
279*32001Spc 
280*32001Spc 	alloctape();			/* Allocate tape buffer */
281*32001Spc 
282*32001Spc 	otape();			/* bitmap is the first to tape write */
283*32001Spc 	time(&(tstart_writing));
284*32001Spc 	bitmap(clrmap, TS_CLRI);
285*32001Spc 
286*32001Spc 	msg("dumping (Pass III) [directories]\n");
287*32001Spc  	pass(dirdump, dirmap);
288*32001Spc 
289*32001Spc 	msg("dumping (Pass IV) [regular files]\n");
290*32001Spc 	pass(dump, nodmap);
291*32001Spc 
292*32001Spc 	spcl.c_type = TS_END;
293*32001Spc #ifndef RDUMP
294*32001Spc 	for(i=0; i<ntrec; i++)
295*32001Spc 		spclrec();
296*32001Spc #endif
297*32001Spc 	msg("DUMP: %ld tape blocks on %d tape(s)\n",spcl.c_tapea,spcl.c_volume);
298*32001Spc 	msg("DUMP IS DONE\n");
299*32001Spc 
300*32001Spc 	putitime();
301*32001Spc #ifndef RDUMP
302*32001Spc 	if (!pipeout) {
303*32001Spc 		close(to);
304*32001Spc 		rewind();
305*32001Spc 	}
306*32001Spc #else
307*32001Spc 	tflush(1);
308*32001Spc 	rewind();
309*32001Spc #endif
310*32001Spc 	broadcast("DUMP IS DONE!\7\7\n");
311*32001Spc 	Exit(X_FINOK);
312*32001Spc }
313*32001Spc 
314*32001Spc int	sighup(){	msg("SIGHUP()  try rewriting\n"); sigAbort();}
315*32001Spc int	sigtrap(){	msg("SIGTRAP()  try rewriting\n"); sigAbort();}
316*32001Spc int	sigfpe(){	msg("SIGFPE()  try rewriting\n"); sigAbort();}
317*32001Spc int	sigbus(){	msg("SIGBUS()  try rewriting\n"); sigAbort();}
318*32001Spc int	sigsegv(){	msg("SIGSEGV()  ABORTING!\n"); abort();}
319*32001Spc int	sigalrm(){	msg("SIGALRM()  try rewriting\n"); sigAbort();}
320*32001Spc int	sigterm(){	msg("SIGTERM()  try rewriting\n"); sigAbort();}
321*32001Spc 
322*32001Spc sigAbort()
323*32001Spc {
324*32001Spc 	if (pipeout) {
325*32001Spc 		msg("Unknown signal, cannot recover\n");
326*32001Spc 		dumpabort();
327*32001Spc 	}
328*32001Spc 	msg("Rewriting attempted as response to unknown signal.\n");
329*32001Spc 	fflush(stderr);
330*32001Spc 	fflush(stdout);
331*32001Spc 	close_rewind();
332*32001Spc 	exit(X_REWRITE);
333*32001Spc }
334*32001Spc 
335*32001Spc char *rawname(cp)
336*32001Spc 	char *cp;
337*32001Spc {
338*32001Spc 	static char rawbuf[32];
339*32001Spc 	char *rindex();
340*32001Spc 	char *dp = rindex(cp, '/');
341*32001Spc 
342*32001Spc 	if (dp == 0)
343*32001Spc 		return (0);
344*32001Spc 	*dp = 0;
345*32001Spc 	strcpy(rawbuf, cp);
346*32001Spc 	*dp = '/';
347*32001Spc 	strcat(rawbuf, "/r");
348*32001Spc 	strcat(rawbuf, dp+1);
349*32001Spc 	return (rawbuf);
350*32001Spc }
351