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