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