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