1: /* 2: * Copyright (c) 1983 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: char copyright[] = 9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)main.c 5.3 (Berkeley) 4/23/86"; 15: #endif not lint 16: 17: /* 18: * Modified to recursively extract all files within a subtree 19: * (supressed by the h option) and recreate the heirarchical 20: * structure of that subtree and move extracted files to their 21: * proper homes (supressed by the m option). 22: * Includes the s (skip files) option for use with multiple 23: * dumps on a single tape. 24: * 8/29/80 by Mike Litzkow 25: * 26: * Modified to work on the new file system and to recover from 27: * tape read errors. 28: * 1/19/82 by Kirk McKusick 29: * 30: * Full incremental restore running entirely in user code and 31: * interactive tape browser. 32: * 1/19/83 by Kirk McKusick 33: */ 34: 35: #include "restore.h" 36: #include <protocols/dumprestore.h> 37: #include <signal.h> 38: 39: int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 40: int hflag = 1, mflag = 1; 41: char command = '\0'; 42: long dumpnum = 1; 43: long volno = 0; 44: long ntrec; 45: char *dumpmap; 46: char *clrimap; 47: ino_t maxino; 48: time_t dumptime; 49: time_t dumpdate; 50: FILE *terminal; 51: 52: main(argc, argv) 53: int argc; 54: char *argv[]; 55: { 56: register char *cp; 57: ino_t ino; 58: char *inputdev = "/dev/rmt8"; 59: char *symtbl = "./restoresymtable"; 60: char name[MAXPATHLEN]; 61: int (*signal())(); 62: extern int onintr(); 63: 64: if (signal(SIGINT, onintr) == SIG_IGN) 65: (void) signal(SIGINT, SIG_IGN); 66: if (signal(SIGTERM, onintr) == SIG_IGN) 67: (void) signal(SIGTERM, SIG_IGN); 68: setlinebuf(stderr); 69: if (argc < 2) { 70: usage: 71: fprintf(stderr, "Usage:\n%s%s%s%s%s", 72: "\trestore tfhsvy [file file ...]\n", 73: "\trestore xfhmsvy [file file ...]\n", 74: "\trestore ifhmsvy\n", 75: "\trestore rfsvy\n", 76: "\trestore Rfsvy\n"); 77: done(1); 78: } 79: argv++; 80: argc -= 2; 81: command = '\0'; 82: for (cp = *argv++; *cp; cp++) { 83: switch (*cp) { 84: case '-': 85: break; 86: case 'c': 87: cvtflag++; 88: break; 89: case 'd': 90: dflag++; 91: break; 92: case 'h': 93: hflag = 0; 94: break; 95: case 'm': 96: mflag = 0; 97: break; 98: case 'v': 99: vflag++; 100: break; 101: case 'y': 102: yflag++; 103: break; 104: case 'f': 105: if (argc < 1) { 106: fprintf(stderr, "missing device specifier\n"); 107: done(1); 108: } 109: inputdev = *argv++; 110: argc--; 111: break; 112: case 'b': 113: /* 114: * change default tape blocksize 115: */ 116: bflag++; 117: if (argc < 1) { 118: fprintf(stderr, "missing block size\n"); 119: done(1); 120: } 121: ntrec = atoi(*argv++); 122: if (ntrec <= 0) { 123: fprintf(stderr, "Block size must be a positive integer\n"); 124: done(1); 125: } 126: argc--; 127: break; 128: case 's': 129: /* 130: * dumpnum (skip to) for multifile dump tapes 131: */ 132: if (argc < 1) { 133: fprintf(stderr, "missing dump number\n"); 134: done(1); 135: } 136: dumpnum = atoi(*argv++); 137: if (dumpnum <= 0) { 138: fprintf(stderr, "Dump number must be a positive integer\n"); 139: done(1); 140: } 141: argc--; 142: break; 143: case 't': 144: case 'R': 145: case 'r': 146: case 'x': 147: case 'i': 148: if (command != '\0') { 149: fprintf(stderr, 150: "%c and %c are mutually exclusive\n", 151: *cp, command); 152: goto usage; 153: } 154: command = *cp; 155: break; 156: default: 157: fprintf(stderr, "Bad key character %c\n", *cp); 158: goto usage; 159: } 160: } 161: if (command == '\0') { 162: fprintf(stderr, "must specify i, t, r, R, or x\n"); 163: goto usage; 164: } 165: setinput(inputdev); 166: if (argc == 0) { 167: argc = 1; 168: *--argv = "."; 169: } 170: switch (command) { 171: /* 172: * Interactive mode. 173: */ 174: case 'i': 175: setup(); 176: extractdirs(1); 177: initsymtable((char *)0); 178: runcmdshell(); 179: done(0); 180: /* 181: * Incremental restoration of a file system. 182: */ 183: case 'r': 184: setup(); 185: if (dumptime > 0) { 186: /* 187: * This is an incremental dump tape. 188: */ 189: vprintf(stdout, "Begin incremental restore\n"); 190: initsymtable(symtbl); 191: extractdirs(1); 192: removeoldleaves(); 193: vprintf(stdout, "Calculate node updates.\n"); 194: treescan(".", ROOTINO, nodeupdates); 195: findunreflinks(); 196: removeoldnodes(); 197: } else { 198: /* 199: * This is a level zero dump tape. 200: */ 201: vprintf(stdout, "Begin level 0 restore\n"); 202: initsymtable((char *)0); 203: extractdirs(1); 204: vprintf(stdout, "Calculate extraction list.\n"); 205: treescan(".", ROOTINO, nodeupdates); 206: } 207: createleaves(symtbl); 208: createlinks(); 209: setdirmodes(); 210: checkrestore(); 211: if (dflag) { 212: vprintf(stdout, "Verify the directory structure\n"); 213: treescan(".", ROOTINO, verifyfile); 214: } 215: dumpsymtable(symtbl, (long)1); 216: done(0); 217: /* 218: * Resume an incremental file system restoration. 219: */ 220: case 'R': 221: initsymtable(symtbl); 222: skipmaps(); 223: skipdirs(); 224: createleaves(symtbl); 225: createlinks(); 226: setdirmodes(); 227: checkrestore(); 228: dumpsymtable(symtbl, (long)1); 229: done(0); 230: /* 231: * List contents of tape. 232: */ 233: case 't': 234: setup(); 235: extractdirs(0); 236: initsymtable((char *)0); 237: while (argc--) { 238: canon(*argv++, name); 239: ino = dirlookup(name); 240: if (ino == 0) 241: continue; 242: treescan(name, ino, listfile); 243: } 244: done(0); 245: /* 246: * Batch extraction of tape contents. 247: */ 248: case 'x': 249: setup(); 250: extractdirs(1); 251: initsymtable((char *)0); 252: while (argc--) { 253: canon(*argv++, name); 254: ino = dirlookup(name); 255: if (ino == 0) 256: continue; 257: if (mflag) 258: pathcheck(name); 259: treescan(name, ino, addfile); 260: } 261: createfiles(); 262: createlinks(); 263: setdirmodes(); 264: if (dflag) 265: checkrestore(); 266: done(0); 267: } 268: }