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