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[] = "@(#)main.c 5.8 (Berkeley) 05/11/89"; 9 #endif not lint 10 11 #include "dump.h" 12 #include "pathnames.h" 13 14 int notify = 0; /* notify operator flag */ 15 int blockswritten = 0; /* number of blocks written on current tape */ 16 int tapeno = 0; /* current tape number */ 17 int density = 0; /* density in bytes/0.1" */ 18 int ntrec = NTREC; /* # tape blocks in each tape record */ 19 int cartridge = 0; /* Assume non-cartridge tape */ 20 long dev_bsize = 1; /* recalculated below */ 21 #ifdef RDUMP 22 char *host; 23 #endif 24 int anydskipped; /* set true in mark() if any directories are skipped */ 25 /* this lets us avoid map pass 2 in some cases */ 26 27 main(argc, argv) 28 int argc; 29 char *argv[]; 30 { 31 char *arg; 32 int bflag = 0, i; 33 float fetapes; 34 register struct fstab *dt; 35 36 time(&(spcl.c_date)); 37 38 tsize = 0; /* Default later, based on 'c' option for cart tapes */ 39 tape = _PATH_DEFTAPE; 40 disk = _PATH_DEFDISK; 41 increm = _PATH_DUMPDATES; 42 temp = _PATH_DTMP; 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 } 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++) { 59 case 'w': 60 lastdump('w'); /* tell us only what has to be done */ 61 exit(0); 62 break; 63 case 'W': /* what to do */ 64 lastdump('W'); /* tell us the current state of what has been done */ 65 exit(0); /* do nothing else */ 66 break; 67 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; 81 if (density >= 625 && !bflag) 82 ntrec = HIGHDENSITYTREC; 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 95 case 'b': /* blocks per tape write */ 96 if(argc > 1) { 97 argv++; 98 argc--; 99 bflag++; 100 ntrec = atol(*argv); 101 } 102 break; 103 104 case 'c': /* Tape is cart. not 9-track */ 105 cartridge++; 106 break; 107 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: 130 fprintf(stderr, "bad key '%c%'\n", arg[-1]); 131 Exit(X_ABORT); 132 } 133 if(argc > 1) { 134 argv++; 135 argc--; 136 disk = *argv; 137 } 138 if (strcmp(tape, "-") == 0) { 139 pipeout++; 140 tape = "standard output"; 141 } 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. 149 * cartridge 8000 bpi (100 bytes/.1") 1700 ft. (450*4 - slop) 150 */ 151 if (density == 0) 152 density = cartridge ? 100 : 160; 153 if (tsize == 0) 154 tsize = cartridge ? 1700L*120L : 2300L*120L; 155 156 #ifdef RDUMP 157 { char *index(); 158 host = tape; 159 tape = index(host, ':'); 160 if (tape == 0) { 161 msg("need keyletter ``f'' and device ``host:tape''\n"); 162 exit(1); 163 } 164 *tape++ = 0; 165 if (rmthost(host) == 0) 166 exit(X_ABORT); 167 } 168 setuid(getuid()); /* rmthost() is the only reason to be setuid */ 169 #endif 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); 196 if (dt != 0) { 197 disk = rawname(dt->fs_spec); 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; 208 getitime(); /* /etc/dumpdates snarfed */ 209 210 msg("Date of this level %c dump: %s\n", incno, prdate(spcl.c_date)); 211 msg("Date of last level %c dump: %s\n", 212 lastincno, prdate(spcl.c_ddate)); 213 msg("Dumping %s ", disk); 214 if (dt != 0) 215 msgtail("(%s) ", dt->fs_file); 216 #ifdef RDUMP 217 msgtail("to %s on host %s\n", tape, host); 218 #else 219 msgtail("to %s\n", tape); 220 #endif 221 222 fi = open(disk, 0); 223 if (fi < 0) { 224 msg("Cannot open %s\n", disk); 225 Exit(X_ABORT); 226 } 227 esize = 0; 228 sblock = (struct fs *)buf; 229 sync(); 230 bread(SBOFF, sblock, SBSIZE); 231 if (sblock->fs_magic != FS_MAGIC) { 232 msg("bad sblock magic number\n"); 233 dumpabort(); 234 } 235 dev_bsize = sblock->fs_fsize / fsbtodb(sblock, 1); 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)); 241 242 anydskipped = 0; 243 msg("mapping (Pass I) [regular files]\n"); 244 pass(mark, (char *)NULL); /* mark updates esize */ 245 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 */ 253 msg("mapping (Pass II) [directories]\n"); 254 255 bmapest(clrmap); 256 bmapest(nodmap); 257 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 = 276 ( esize /* blocks */ 277 * TP_BSIZE /* bytes / block */ 278 * (1.0/density) /* 0.1" / byte */ 279 + 280 esize /* blocks */ 281 * (1.0/ntrec) /* IRG's / block */ 282 * tenthsperirg /* 0.1" / IRG */ 283 ) * (1.0 / tsize ); /* tape / 0.1" */ 284 } 285 etapes = fetapes; /* truncating assignment */ 286 etapes++; 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 */ 291 msg("estimated %ld tape blocks on %3.2f tape(s).\n", esize, fetapes); 292 293 alloctape(); /* Allocate tape buffer */ 294 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"); 300 pass(dirdump, dirmap); 301 302 msg("dumping (Pass IV) [regular files]\n"); 303 pass(dump, nodmap); 304 305 spcl.c_type = TS_END; 306 #ifndef RDUMP 307 for(i=0; i<ntrec; i++) 308 spclrec(); 309 #endif 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(); 314 #ifndef RDUMP 315 if (!pipeout) { 316 close(to); 317 rewind(); 318 } 319 #else 320 tflush(1); 321 rewind(); 322 #endif 323 broadcast("DUMP IS DONE!\7\7\n"); 324 Exit(X_FINOK); 325 } 326 327 int sighup(){ msg("SIGHUP() try rewriting\n"); sigAbort();} 328 int sigtrap(){ msg("SIGTRAP() try rewriting\n"); sigAbort();} 329 int sigfpe(){ msg("SIGFPE() try rewriting\n"); sigAbort();} 330 int sigbus(){ msg("SIGBUS() try rewriting\n"); sigAbort();} 331 int sigsegv(){ msg("SIGSEGV() ABORTING!\n"); abort();} 332 int sigalrm(){ msg("SIGALRM() try rewriting\n"); sigAbort();} 333 int sigterm(){ msg("SIGTERM() try rewriting\n"); sigAbort();} 334 335 sigAbort() 336 { 337 if (pipeout) { 338 msg("Unknown signal, cannot recover\n"); 339 dumpabort(); 340 } 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 348 char *rawname(cp) 349 char *cp; 350 { 351 static char rawbuf[32]; 352 char *rindex(); 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 } 364