|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)main.c 3.12 (Berkeley) 83/08/11"; ! 3: #endif ! 4: ! 5: /* Copyright (c) 1983 Regents of the University of California */ ! 6: ! 7: /* ! 8: * Modified to recursively extract all files within a subtree ! 9: * (supressed by the h option) and recreate the heirarchical ! 10: * structure of that subtree and move extracted files to their ! 11: * proper homes (supressed by the m option). ! 12: * Includes the s (skip files) option for use with multiple ! 13: * dumps on a single tape. ! 14: * 8/29/80 by Mike Litzkow ! 15: * ! 16: * Modified to work on the new file system and to recover from ! 17: * tape read errors. ! 18: * 1/19/82 by Kirk McKusick ! 19: * ! 20: * Full incremental restore running entirely in user code and ! 21: * interactive tape browser. ! 22: * 1/19/83 by Kirk McKusick ! 23: */ ! 24: ! 25: #include "restore.h" ! 26: #include <signal.h> ! 27: ! 28: int cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; ! 29: int hflag = 1, mflag = 1; ! 30: char command = '\0'; ! 31: long dumpnum = 1; ! 32: long volno = 0; ! 33: char *dumpmap; ! 34: char *clrimap; ! 35: ino_t maxino; ! 36: time_t dumptime; ! 37: time_t dumpdate; ! 38: FILE *terminal; ! 39: ! 40: main(argc, argv) ! 41: int argc; ! 42: char *argv[]; ! 43: { ! 44: register char *cp; ! 45: ino_t ino; ! 46: char *inputdev = "/dev/rcy0s"; ! 47: char *symtbl = "./restoresymtable"; ! 48: char name[MAXPATHLEN]; ! 49: int (*signal())(); ! 50: extern int onintr(); ! 51: ! 52: if (signal(SIGINT, onintr) == SIG_IGN) ! 53: (void) signal(SIGINT, SIG_IGN); ! 54: if (signal(SIGTERM, onintr) == SIG_IGN) ! 55: (void) signal(SIGTERM, SIG_IGN); ! 56: setlinebuf(stderr); ! 57: if (argc < 2) { ! 58: usage: ! 59: fprintf(stderr, "Usage:\n%s%s%s%s%s", ! 60: "\trestore tfhsvy [file file ...]\n", ! 61: "\trestore xfhmsvy [file file ...]\n", ! 62: "\trestore ifhmsvy\n", ! 63: "\trestore rfsvy\n", ! 64: "\trestore Rfsvy\n"); ! 65: done(1); ! 66: } ! 67: argv++; ! 68: argc -= 2; ! 69: command = '\0'; ! 70: for (cp = *argv++; *cp; cp++) { ! 71: switch (*cp) { ! 72: case '-': ! 73: break; ! 74: case 'c': ! 75: cvtflag++; ! 76: break; ! 77: case 'd': ! 78: dflag++; ! 79: break; ! 80: case 'h': ! 81: hflag = 0; ! 82: break; ! 83: case 'm': ! 84: mflag = 0; ! 85: break; ! 86: case 'v': ! 87: vflag++; ! 88: break; ! 89: case 'y': ! 90: yflag++; ! 91: break; ! 92: case 'f': ! 93: if (argc < 1) { ! 94: fprintf(stderr, "missing device specifier\n"); ! 95: done(1); ! 96: } ! 97: inputdev = *argv++; ! 98: argc--; ! 99: break; ! 100: case 's': ! 101: /* ! 102: * dumpnum (skip to) for multifile dump tapes ! 103: */ ! 104: if (argc < 1) { ! 105: fprintf(stderr, "missing dump number\n"); ! 106: done(1); ! 107: } ! 108: dumpnum = atoi(*argv++); ! 109: if (dumpnum <= 0) { ! 110: fprintf(stderr, "Dump number must be a positive integer\n"); ! 111: done(1); ! 112: } ! 113: argc--; ! 114: break; ! 115: case 't': ! 116: case 'T': ! 117: case 'R': ! 118: case 'r': ! 119: case 'x': ! 120: case 'X': ! 121: case 'i': ! 122: if (command != '\0') { ! 123: fprintf(stderr, ! 124: "%c and %c are mutually exclusive\n", ! 125: *cp, command); ! 126: goto usage; ! 127: } ! 128: command = *cp; ! 129: break; ! 130: default: ! 131: fprintf(stderr, "Bad key character %c\n", *cp); ! 132: goto usage; ! 133: } ! 134: } ! 135: if (command == '\0') { ! 136: fprintf(stderr, "must specify i, T, r, R, or x\n"); ! 137: goto usage; ! 138: } ! 139: setinput(inputdev); ! 140: if (argc == 0) { ! 141: argc = 1; ! 142: *--argv = "."; ! 143: } ! 144: switch (command) { ! 145: /* ! 146: * Interactive mode. ! 147: */ ! 148: case 'i': ! 149: setup(); ! 150: extractdirs(1); ! 151: initsymtable((char *)0); ! 152: runcmdshell(); ! 153: done(0); ! 154: /* ! 155: * Incremental restoration of a file system. ! 156: */ ! 157: case 'r': ! 158: setup(); ! 159: if (dumptime > 0) { ! 160: /* ! 161: * This is an incremental dump tape. ! 162: */ ! 163: vprintf(stdout, "Begin incremental restore\n"); ! 164: initsymtable(symtbl); ! 165: extractdirs(1); ! 166: removeoldleaves(); ! 167: vprintf(stdout, "Calculate node updates.\n"); ! 168: treescan(".", ROOTINO, nodeupdates); ! 169: findunreflinks(); ! 170: removeoldnodes(); ! 171: } else { ! 172: /* ! 173: * This is a level zero dump tape. ! 174: */ ! 175: vprintf(stdout, "Begin level 0 restore\n"); ! 176: initsymtable((char *)0); ! 177: extractdirs(1); ! 178: vprintf(stdout, "Calculate extraction list.\n"); ! 179: treescan(".", ROOTINO, nodeupdates); ! 180: } ! 181: createleaves(symtbl); ! 182: createlinks(); ! 183: setdirmodes(); ! 184: checkrestore(); ! 185: if (dflag) { ! 186: vprintf(stdout, "Verify the directory structure\n"); ! 187: treescan(".", ROOTINO, verifyfile); ! 188: } ! 189: dumpsymtable(symtbl, (long)1); ! 190: done(0); ! 191: /* ! 192: * Resume an incremental file system restoration. ! 193: */ ! 194: case 'R': ! 195: initsymtable(symtbl); ! 196: skipmaps(); ! 197: skipdirs(); ! 198: createleaves(symtbl); ! 199: createlinks(); ! 200: setdirmodes(); ! 201: checkrestore(); ! 202: dumpsymtable(symtbl, (long)1); ! 203: done(0); ! 204: /* ! 205: * Give dump dates of tape. ! 206: */ ! 207: case 'T': ! 208: setup(); ! 209: done(0); ! 210: /* ! 211: * List contents of tape. ! 212: */ ! 213: case 't': ! 214: setup(); ! 215: extractdirs(0); ! 216: while (argc--) { ! 217: canon(*argv++, name); ! 218: ino = dirlookup(name); ! 219: if (ino == 0) ! 220: continue; ! 221: treescan(name, ino, listfile); ! 222: } ! 223: done(0); ! 224: /* ! 225: * Batch extraction of tape contents. ! 226: */ ! 227: case 'x': ! 228: case 'X': ! 229: setup(); ! 230: extractdirs(1); ! 231: initsymtable((char *)0); ! 232: while (argc--) { ! 233: canon(*argv++, name); ! 234: ino = dirlookup(name); ! 235: if (ino == 0) ! 236: continue; ! 237: if (mflag) ! 238: pathcheck(name); ! 239: treescan(name, ino, addfile); ! 240: } ! 241: createfiles(); ! 242: createlinks(); ! 243: setdirmodes(); ! 244: if (dflag) ! 245: checkrestore(); ! 246: done(0); ! 247: } ! 248: } ! 249: ! 250: /* ! 251: * Read and execute commands from the terminal. ! 252: */ ! 253: runcmdshell() ! 254: { ! 255: register struct entry *np; ! 256: ino_t ino; ! 257: char curdir[MAXPATHLEN]; ! 258: char name[MAXPATHLEN]; ! 259: char cmd[BUFSIZ]; ! 260: ! 261: canon("/", curdir); ! 262: loop: ! 263: getcmd(curdir, cmd, name); ! 264: switch (cmd[0]) { ! 265: /* ! 266: * Add elements to the extraction list. ! 267: */ ! 268: case 'a': ! 269: ino = dirlookup(name); ! 270: if (ino == 0) ! 271: break; ! 272: if (mflag) ! 273: pathcheck(name); ! 274: treescan(name, ino, addfile); ! 275: break; ! 276: /* ! 277: * Change working directory. ! 278: */ ! 279: case 'c': ! 280: ino = dirlookup(name); ! 281: if (ino == 0) ! 282: break; ! 283: if (inodetype(ino) == LEAF) { ! 284: fprintf(stderr, "%s: not a directory\n", name); ! 285: break; ! 286: } ! 287: (void) strcpy(curdir, name); ! 288: break; ! 289: /* ! 290: * Delete elements from the extraction list. ! 291: */ ! 292: case 'd': ! 293: np = lookupname(name); ! 294: if (np == NIL || (np->e_flags & NEW) == 0) { ! 295: fprintf(stderr, "%s: not on extraction list\n", name); ! 296: break; ! 297: } ! 298: treescan(name, np->e_ino, deletefile); ! 299: break; ! 300: /* ! 301: * Extract the requested list. ! 302: */ ! 303: case 'e': ! 304: createfiles(); ! 305: createlinks(); ! 306: setdirmodes(); ! 307: if (dflag) ! 308: checkrestore(); ! 309: volno = 0; ! 310: break; ! 311: /* ! 312: * List available commands. ! 313: */ ! 314: case 'h': ! 315: case '?': ! 316: fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", ! 317: "Available commands are:\n", ! 318: "\tls [arg] - list directory\n", ! 319: "\tcd arg - change directory\n", ! 320: "\tpwd - print current directory\n", ! 321: "\tadd [arg] - add `arg' to list of", ! 322: " files to be extracted\n", ! 323: "\tdelete [arg] - delete `arg' from", ! 324: " list of files to be extracted\n", ! 325: "\textract - extract requested files\n", ! 326: "\tquit - immediately exit program\n", ! 327: "\tverbose - toggle verbose flag", ! 328: " (useful with ``ls'')\n", ! 329: "\thelp or `?' - print this list\n", ! 330: "If no `arg' is supplied, the current", ! 331: " directory is used\n"); ! 332: break; ! 333: /* ! 334: * List a directory. ! 335: */ ! 336: case 'l': ! 337: ino = dirlookup(name); ! 338: if (ino == 0) ! 339: break; ! 340: printlist(name, ino); ! 341: break; ! 342: /* ! 343: * Print current directory. ! 344: */ ! 345: case 'p': ! 346: if (curdir[1] == '\0') ! 347: fprintf(stderr, "/\n"); ! 348: else ! 349: fprintf(stderr, "%s\n", &curdir[1]); ! 350: break; ! 351: /* ! 352: * Quit. ! 353: */ ! 354: case 'q': ! 355: case 'x': ! 356: return; ! 357: /* ! 358: * Toggle verbose mode. ! 359: */ ! 360: case 'v': ! 361: if (vflag) { ! 362: fprintf(stderr, "verbose mode off\n"); ! 363: vflag = 0; ! 364: break; ! 365: } ! 366: fprintf(stderr, "verbose mode on\n"); ! 367: vflag++; ! 368: break; ! 369: /* ! 370: * Turn on debugging. ! 371: */ ! 372: case 'D': ! 373: if (dflag) { ! 374: fprintf(stderr, "debugging mode off\n"); ! 375: dflag = 0; ! 376: break; ! 377: } ! 378: fprintf(stderr, "debugging mode on\n"); ! 379: dflag++; ! 380: break; ! 381: /* ! 382: * Unknown command. ! 383: */ ! 384: default: ! 385: fprintf(stderr, "%s: unknown command; type ? for help\n", cmd); ! 386: break; ! 387: } ! 388: goto loop; ! 389: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.