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