132001Spc /*
232001Spc * Copyright (c) 1980 Regents of the University of California.
332001Spc * All rights reserved. The Berkeley software License Agreement
432001Spc * specifies the terms and conditions for redistribution.
532001Spc */
632001Spc
732001Spc #ifndef lint
8*32056Spc static char sccsid[] = "@(#)dumpmain.c 1.4 (UKC) 08/12/87 5.6 (Berkeley) 2/23/87";
932001Spc #endif not lint
1032001Spc
1132001Spc #include "dump.h"
1232001Spc
1332001Spc int notify = 0; /* notify operator flag */
1432001Spc int blockswritten = 0; /* number of blocks written on current tape */
1532001Spc int tapeno = 0; /* current tape number */
1632001Spc int density = 0; /* density in bytes/0.1" */
1732001Spc int ntrec = NTREC; /* # tape blocks in each tape record */
1832001Spc int cartridge = 0; /* Assume non-cartridge tape */
1932028Spc
2032028Spc extern int labchk; /* check labels */
2132028Spc int rewindoffline; /* put tape offline after every write */
2232028Spc
2332001Spc #ifdef RDUMP
2432001Spc char *host;
2532001Spc #endif
2632001Spc int anydskipped; /* set true in mark() if any directories are skipped */
2732001Spc /* this lets us avoid map pass 2 in some cases */
2832001Spc
main(argc,argv)2932001Spc main(argc, argv)
3032001Spc int argc;
3132001Spc char *argv[];
3232001Spc {
3332001Spc char *arg;
3432001Spc int bflag = 0, i;
3532001Spc float fetapes;
3632001Spc register struct fstab *dt;
3732001Spc
3832001Spc time(&(spcl.c_date));
3932001Spc
4032001Spc tsize = 0; /* Default later, based on 'c' option for cart tapes */
4132001Spc tape = TAPE;
4232001Spc disk = DISK;
4332001Spc increm = NINCREM;
4432001Spc temp = TEMP;
4532001Spc if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0) {
4632001Spc msg("TP_BSIZE must be a multiple of DEV_BSIZE\n");
4732001Spc dumpabort();
4832001Spc }
4932001Spc incno = '9';
5032001Spc uflag = 0;
5132001Spc arg = "u";
5232001Spc if(argc > 1) {
5332001Spc argv++;
5432001Spc argc--;
5532001Spc arg = *argv;
5632001Spc if (*arg == '-')
5732001Spc argc++;
5832001Spc }
5932001Spc while(*arg)
6032001Spc switch (*arg++) {
6132001Spc case 'w':
6232001Spc lastdump('w'); /* tell us only what has to be done */
6332001Spc exit(0);
6432001Spc break;
6532001Spc case 'W': /* what to do */
6632001Spc lastdump('W'); /* tell us the current state of what has been done */
6732001Spc exit(0); /* do nothing else */
6832001Spc break;
6932001Spc
7032001Spc case 'f': /* output file */
7132001Spc if(argc > 1) {
7232001Spc argv++;
7332001Spc argc--;
7432001Spc tape = *argv;
7532001Spc }
7632001Spc break;
7732001Spc
7832001Spc case 'd': /* density, in bits per inch */
7932001Spc if (argc > 1) {
8032001Spc argv++;
8132001Spc argc--;
8232001Spc density = atoi(*argv) / 10;
8332001Spc if (density >= 625 && !bflag)
8432001Spc ntrec = HIGHDENSITYTREC;
8532001Spc }
8632001Spc break;
8732001Spc
8832001Spc case 's': /* tape size, feet */
8932001Spc if(argc > 1) {
9032001Spc argv++;
9132001Spc argc--;
9232001Spc tsize = atol(*argv);
9332001Spc tsize *= 12L*10L;
9432001Spc }
9532001Spc break;
9632001Spc
9732001Spc case 'b': /* blocks per tape write */
9832001Spc if(argc > 1) {
9932001Spc argv++;
10032001Spc argc--;
10132001Spc bflag++;
10232001Spc ntrec = atol(*argv);
10332001Spc }
10432001Spc break;
10532001Spc
10632001Spc case 'c': /* Tape is cart. not 9-track */
10732001Spc cartridge++;
10832001Spc break;
10932001Spc
11032001Spc case '0': /* dump level */
11132001Spc case '1':
11232001Spc case '2':
11332001Spc case '3':
11432001Spc case '4':
11532001Spc case '5':
11632001Spc case '6':
11732001Spc case '7':
11832001Spc case '8':
11932001Spc case '9':
12032001Spc incno = arg[-1];
12132001Spc break;
12232001Spc
12332001Spc case 'u': /* update /etc/dumpdates */
12432001Spc uflag++;
12532001Spc break;
12632001Spc
12732001Spc case 'n': /* notify operators */
12832001Spc notify++;
12932001Spc break;
13032001Spc
13132028Spc case 'l': /* set a label format */
13232028Spc if (argc > 1) {
13332028Spc argv++;
13432028Spc argc--;
13532028Spc storelabel(*argv);
13632028Spc }
13732028Spc break;
13832028Spc
13932028Spc case 'm': /* set a label map */
14032028Spc if (argc > 1) {
14132028Spc argv++;
14232028Spc argc--;
14332028Spc storelabelmap(*argv);
14432028Spc }
14532028Spc break;
14632028Spc
14732028Spc case 't':
14832028Spc labchk = 1;
14932028Spc break;
15032028Spc
15132028Spc case 'o':
15232028Spc rewindoffline = 1;
15332028Spc break;
15432028Spc
15532001Spc default:
15632001Spc fprintf(stderr, "bad key '%c%'\n", arg[-1]);
15732001Spc Exit(X_ABORT);
15832001Spc }
15932001Spc if(argc > 1) {
16032001Spc argv++;
16132001Spc argc--;
16232001Spc disk = *argv;
16332001Spc }
16432001Spc if (strcmp(tape, "-") == 0) {
16532001Spc pipeout++;
16632001Spc tape = "standard output";
16732001Spc }
16832001Spc
16932001Spc /*
17032001Spc * Determine how to default tape size and density
17132001Spc *
17232001Spc * density tape size
17332001Spc * 9-track 1600 bpi (160 bytes/.1") 2300 ft.
17432001Spc * 9-track 6250 bpi (625 bytes/.1") 2300 ft.
17532001Spc * cartridge 8000 bpi (100 bytes/.1") 1700 ft. (450*4 - slop)
17632001Spc */
17732001Spc if (density == 0)
17832001Spc density = cartridge ? 100 : 160;
17932001Spc if (tsize == 0)
18032001Spc tsize = cartridge ? 1700L*120L : 2300L*120L;
18132001Spc
18232001Spc #ifdef RDUMP
18332001Spc { char *index();
18432001Spc host = tape;
18532001Spc tape = index(host, ':');
18632001Spc if (tape == 0) {
18732001Spc msg("need keyletter ``f'' and device ``host:tape''\n");
18832001Spc exit(1);
18932001Spc }
19032001Spc *tape++ = 0;
19132001Spc if (rmthost(host) == 0)
19232001Spc exit(X_ABORT);
19332001Spc }
19432001Spc setuid(getuid()); /* rmthost() is the only reason to be setuid */
19532001Spc #endif
19632001Spc if (signal(SIGHUP, sighup) == SIG_IGN)
19732001Spc signal(SIGHUP, SIG_IGN);
19832001Spc if (signal(SIGTRAP, sigtrap) == SIG_IGN)
19932001Spc signal(SIGTRAP, SIG_IGN);
20032001Spc if (signal(SIGFPE, sigfpe) == SIG_IGN)
20132001Spc signal(SIGFPE, SIG_IGN);
20232001Spc if (signal(SIGBUS, sigbus) == SIG_IGN)
20332001Spc signal(SIGBUS, SIG_IGN);
20432001Spc if (signal(SIGSEGV, sigsegv) == SIG_IGN)
20532001Spc signal(SIGSEGV, SIG_IGN);
20632001Spc if (signal(SIGTERM, sigterm) == SIG_IGN)
20732001Spc signal(SIGTERM, SIG_IGN);
20832001Spc
20932001Spc
21032001Spc if (signal(SIGINT, interrupt) == SIG_IGN)
21132001Spc signal(SIGINT, SIG_IGN);
21232001Spc
21332001Spc set_operators(); /* /etc/group snarfed */
21432001Spc getfstab(); /* /etc/fstab snarfed */
21532001Spc /*
21632001Spc * disk can be either the full special file name,
21732001Spc * the suffix of the special file name,
21832001Spc * the special name missing the leading '/',
21932001Spc * the file system name with or without the leading '/'.
22032001Spc */
22132001Spc dt = fstabsearch(disk);
22232003Spc if (dt != 0) {
22332001Spc disk = rawname(dt->fs_spec);
22432003Spc strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
22532003Spc strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
22632003Spc } else {
22732003Spc strncpy(spcl.c_dev, disk, NAMELEN);
22832003Spc strncpy(spcl.c_filesys, "an unlisted file system", NAMELEN);
22932003Spc }
23032028Spc strcpy(spcl.c_label, createlabel(0));
23132003Spc gethostname(spcl.c_host, NAMELEN);
23232003Spc spcl.c_level = incno - '0';
23332003Spc spcl.c_type = TS_TAPE;
23432001Spc getitime(); /* /etc/dumpdates snarfed */
23532001Spc
23632001Spc msg("Date of this level %c dump: %s\n", incno, prdate(spcl.c_date));
23732001Spc msg("Date of last level %c dump: %s\n",
23832001Spc lastincno, prdate(spcl.c_ddate));
23932001Spc msg("Dumping %s ", disk);
24032028Spc
24132001Spc if (dt != 0)
24232001Spc msgtail("(%s) ", dt->fs_file);
24332001Spc #ifdef RDUMP
24432001Spc msgtail("to %s on host %s\n", tape, host);
24532001Spc #else
24632001Spc msgtail("to %s\n", tape);
24732001Spc #endif
24832001Spc
24932028Spc initialtape(); /* print label message if required */
25032028Spc
25132028Spc
25232001Spc fi = open(disk, 0);
25332001Spc if (fi < 0) {
25432001Spc msg("Cannot open %s\n", disk);
25532001Spc Exit(X_ABORT);
25632001Spc }
25732001Spc esize = 0;
25832001Spc sblock = (struct fs *)buf;
25932001Spc sync();
26032001Spc bread(SBLOCK, sblock, SBSIZE);
26132001Spc if (sblock->fs_magic != FS_MAGIC) {
26232001Spc msg("bad sblock magic number\n");
26332001Spc dumpabort();
26432001Spc }
26532001Spc msiz = roundup(howmany(sblock->fs_ipg * sblock->fs_ncg, NBBY),
26632001Spc TP_BSIZE);
26732001Spc clrmap = (char *)calloc(msiz, sizeof(char));
26832001Spc dirmap = (char *)calloc(msiz, sizeof(char));
26932001Spc nodmap = (char *)calloc(msiz, sizeof(char));
27032001Spc
27132001Spc anydskipped = 0;
27232001Spc msg("mapping (Pass I) [regular files]\n");
27332001Spc pass(mark, (char *)NULL); /* mark updates esize */
27432001Spc
27532001Spc if (anydskipped) {
27632001Spc do {
27732001Spc msg("mapping (Pass II) [directories]\n");
27832001Spc nadded = 0;
27932001Spc pass(add, dirmap);
28032001Spc } while(nadded);
28132001Spc } else /* keep the operators happy */
28232001Spc msg("mapping (Pass II) [directories]\n");
28332001Spc
28432001Spc bmapest(clrmap);
28532001Spc bmapest(nodmap);
28632001Spc
28732001Spc if (cartridge) {
28832001Spc /* Estimate number of tapes, assuming streaming stops at
28932001Spc the end of each block written, and not in mid-block.
29032001Spc Assume no erroneous blocks; this can be compensated for
29132001Spc with an artificially low tape size. */
29232001Spc fetapes =
29332001Spc ( esize /* blocks */
29432001Spc * TP_BSIZE /* bytes/block */
29532001Spc * (1.0/density) /* 0.1" / byte */
29632001Spc +
29732001Spc esize /* blocks */
29832001Spc * (1.0/ntrec) /* streaming-stops per block */
29932001Spc * 15.48 /* 0.1" / streaming-stop */
30032001Spc ) * (1.0 / tsize ); /* tape / 0.1" */
30132001Spc } else {
30232001Spc /* Estimate number of tapes, for old fashioned 9-track tape */
30332001Spc int tenthsperirg = (density == 625) ? 3 : 7;
30432001Spc fetapes =
30532001Spc ( esize /* blocks */
30632001Spc * TP_BSIZE /* bytes / block */
30732001Spc * (1.0/density) /* 0.1" / byte */
30832001Spc +
30932001Spc esize /* blocks */
31032001Spc * (1.0/ntrec) /* IRG's / block */
31132001Spc * tenthsperirg /* 0.1" / IRG */
31232001Spc ) * (1.0 / tsize ); /* tape / 0.1" */
31332001Spc }
31432001Spc etapes = fetapes; /* truncating assignment */
31532001Spc etapes++;
31632001Spc /* count the nodemap on each additional tape */
31732001Spc for (i = 1; i < etapes; i++)
31832001Spc bmapest(nodmap);
31932001Spc esize += i + 10; /* headers + 10 trailer blocks */
32032001Spc msg("estimated %ld tape blocks on %3.2f tape(s).\n", esize, fetapes);
32132001Spc
32232028Spc labelest(fetapes); /* check we have enough labels */
32332028Spc
32432001Spc alloctape(); /* Allocate tape buffer */
32532001Spc
32632001Spc otape(); /* bitmap is the first to tape write */
32732001Spc time(&(tstart_writing));
32832001Spc bitmap(clrmap, TS_CLRI);
32932001Spc
33032001Spc msg("dumping (Pass III) [directories]\n");
33132001Spc pass(dirdump, dirmap);
33232001Spc
33332001Spc msg("dumping (Pass IV) [regular files]\n");
33432001Spc pass(dump, nodmap);
33532001Spc
33632001Spc spcl.c_type = TS_END;
33732001Spc #ifndef RDUMP
33832001Spc for(i=0; i<ntrec; i++)
33932001Spc spclrec();
34032001Spc #endif
34132001Spc msg("DUMP: %ld tape blocks on %d tape(s)\n",spcl.c_tapea,spcl.c_volume);
34232001Spc msg("DUMP IS DONE\n");
34332001Spc
34432001Spc putitime();
34532001Spc #ifndef RDUMP
34632001Spc if (!pipeout) {
347*32056Spc rewind();
34832001Spc close(to);
34932001Spc }
35032001Spc #else
35132001Spc tflush(1);
35232001Spc rewind();
35332001Spc #endif
35432001Spc broadcast("DUMP IS DONE!\7\7\n");
35532001Spc Exit(X_FINOK);
35632001Spc }
35732001Spc
sighup()35832001Spc int sighup(){ msg("SIGHUP() try rewriting\n"); sigAbort();}
sigtrap()35932001Spc int sigtrap(){ msg("SIGTRAP() try rewriting\n"); sigAbort();}
sigfpe()36032001Spc int sigfpe(){ msg("SIGFPE() try rewriting\n"); sigAbort();}
sigbus()36132001Spc int sigbus(){ msg("SIGBUS() try rewriting\n"); sigAbort();}
sigsegv()36232001Spc int sigsegv(){ msg("SIGSEGV() ABORTING!\n"); abort();}
sigalrm()36332001Spc int sigalrm(){ msg("SIGALRM() try rewriting\n"); sigAbort();}
sigterm()36432001Spc int sigterm(){ msg("SIGTERM() try rewriting\n"); sigAbort();}
36532001Spc
sigAbort()36632001Spc sigAbort()
36732001Spc {
36832001Spc if (pipeout) {
36932001Spc msg("Unknown signal, cannot recover\n");
37032001Spc dumpabort();
37132001Spc }
37232001Spc msg("Rewriting attempted as response to unknown signal.\n");
37332001Spc fflush(stderr);
37432001Spc fflush(stdout);
37532001Spc close_rewind();
37632001Spc exit(X_REWRITE);
37732001Spc }
37832001Spc
rawname(cp)37932001Spc char *rawname(cp)
38032001Spc char *cp;
38132001Spc {
38232001Spc static char rawbuf[32];
38332001Spc char *rindex();
38432001Spc char *dp = rindex(cp, '/');
38532001Spc
38632001Spc if (dp == 0)
38732001Spc return (0);
38832001Spc *dp = 0;
38932001Spc strcpy(rawbuf, cp);
39032001Spc *dp = '/';
39132001Spc strcat(rawbuf, "/r");
39232001Spc strcat(rawbuf, dp+1);
39332001Spc return (rawbuf);
39432001Spc }
395