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