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*32028Spc static char sccsid[] = "@(#)dumpmain.c 1.3 (UKC) 08/08/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 */ 19*32028Spc 20*32028Spc extern int labchk; /* check labels */ 21*32028Spc int rewindoffline; /* put tape offline after every write */ 22*32028Spc 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 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 131*32028Spc case 'l': /* set a label format */ 132*32028Spc if (argc > 1) { 133*32028Spc argv++; 134*32028Spc argc--; 135*32028Spc storelabel(*argv); 136*32028Spc } 137*32028Spc break; 138*32028Spc 139*32028Spc case 'm': /* set a label map */ 140*32028Spc if (argc > 1) { 141*32028Spc argv++; 142*32028Spc argc--; 143*32028Spc storelabelmap(*argv); 144*32028Spc } 145*32028Spc break; 146*32028Spc 147*32028Spc case 't': 148*32028Spc labchk = 1; 149*32028Spc break; 150*32028Spc 151*32028Spc case 'o': 152*32028Spc rewindoffline = 1; 153*32028Spc break; 154*32028Spc 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 } 230*32028Spc 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); 240*32028Spc 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 249*32028Spc initialtape(); /* print label message if required */ 250*32028Spc 251*32028Spc 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 322*32028Spc labelest(fetapes); /* check we have enough labels */ 323*32028Spc 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) { 34732001Spc close(to); 34832001Spc rewind(); 34932001Spc } 35032001Spc #else 35132001Spc tflush(1); 35232001Spc rewind(); 35332001Spc #endif 35432001Spc broadcast("DUMP IS DONE!\7\7\n"); 35532001Spc Exit(X_FINOK); 35632001Spc } 35732001Spc 35832001Spc int sighup(){ msg("SIGHUP() try rewriting\n"); sigAbort();} 35932001Spc int sigtrap(){ msg("SIGTRAP() try rewriting\n"); sigAbort();} 36032001Spc int sigfpe(){ msg("SIGFPE() try rewriting\n"); sigAbort();} 36132001Spc int sigbus(){ msg("SIGBUS() try rewriting\n"); sigAbort();} 36232001Spc int sigsegv(){ msg("SIGSEGV() ABORTING!\n"); abort();} 36332001Spc int sigalrm(){ msg("SIGALRM() try rewriting\n"); sigAbort();} 36432001Spc int sigterm(){ msg("SIGTERM() try rewriting\n"); sigAbort();} 36532001Spc 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 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