|
|
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/rmt8"; ! 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 'R': ! 117: case 'r': ! 118: case 'x': ! 119: case 'i': ! 120: if (command != '\0') { ! 121: fprintf(stderr, ! 122: "%c and %c are mutually exclusive\n", ! 123: *cp, command); ! 124: goto usage; ! 125: } ! 126: command = *cp; ! 127: break; ! 128: default: ! 129: fprintf(stderr, "Bad key character %c\n", *cp); ! 130: goto usage; ! 131: } ! 132: } ! 133: if (command == '\0') { ! 134: fprintf(stderr, "must specify i, t, r, R, or x\n"); ! 135: goto usage; ! 136: } ! 137: setinput(inputdev); ! 138: if (argc == 0) { ! 139: argc = 1; ! 140: *--argv = "."; ! 141: } ! 142: switch (command) { ! 143: /* ! 144: * Interactive mode. ! 145: */ ! 146: case 'i': ! 147: setup(); ! 148: extractdirs(1); ! 149: initsymtable((char *)0); ! 150: runcmdshell(); ! 151: done(0); ! 152: /* ! 153: * Incremental restoration of a file system. ! 154: */ ! 155: case 'r': ! 156: setup(); ! 157: if (dumptime > 0) { ! 158: /* ! 159: * This is an incremental dump tape. ! 160: */ ! 161: vprintf(stdout, "Begin incremental restore\n"); ! 162: initsymtable(symtbl); ! 163: extractdirs(1); ! 164: removeoldleaves(); ! 165: vprintf(stdout, "Calculate node updates.\n"); ! 166: treescan(".", ROOTINO, nodeupdates); ! 167: findunreflinks(); ! 168: removeoldnodes(); ! 169: } else { ! 170: /* ! 171: * This is a level zero dump tape. ! 172: */ ! 173: vprintf(stdout, "Begin level 0 restore\n"); ! 174: initsymtable((char *)0); ! 175: extractdirs(1); ! 176: vprintf(stdout, "Calculate extraction list.\n"); ! 177: treescan(".", ROOTINO, nodeupdates); ! 178: } ! 179: createleaves(symtbl); ! 180: createlinks(); ! 181: setdirmodes(); ! 182: checkrestore(); ! 183: if (dflag) { ! 184: vprintf(stdout, "Verify the directory structure\n"); ! 185: treescan(".", ROOTINO, verifyfile); ! 186: } ! 187: dumpsymtable(symtbl, (long)1); ! 188: done(0); ! 189: /* ! 190: * Resume an incremental file system restoration. ! 191: */ ! 192: case 'R': ! 193: initsymtable(symtbl); ! 194: skipmaps(); ! 195: skipdirs(); ! 196: createleaves(symtbl); ! 197: createlinks(); ! 198: setdirmodes(); ! 199: checkrestore(); ! 200: dumpsymtable(symtbl, (long)1); ! 201: done(0); ! 202: /* ! 203: * List contents of tape. ! 204: */ ! 205: case 't': ! 206: setup(); ! 207: extractdirs(0); ! 208: while (argc--) { ! 209: canon(*argv++, name); ! 210: ino = dirlookup(name); ! 211: if (ino == 0) ! 212: continue; ! 213: treescan(name, ino, listfile); ! 214: } ! 215: done(0); ! 216: /* ! 217: * Batch extraction of tape contents. ! 218: */ ! 219: case 'x': ! 220: setup(); ! 221: extractdirs(1); ! 222: initsymtable((char *)0); ! 223: while (argc--) { ! 224: canon(*argv++, name); ! 225: ino = dirlookup(name); ! 226: if (ino == 0) ! 227: continue; ! 228: if (mflag) ! 229: pathcheck(name); ! 230: treescan(name, ino, addfile); ! 231: } ! 232: createfiles(); ! 233: createlinks(); ! 234: setdirmodes(); ! 235: if (dflag) ! 236: checkrestore(); ! 237: done(0); ! 238: } ! 239: } ! 240: ! 241: /* ! 242: * Read and execute commands from the terminal. ! 243: */ ! 244: runcmdshell() ! 245: { ! 246: register struct entry *np; ! 247: ino_t ino; ! 248: char curdir[MAXPATHLEN]; ! 249: char name[MAXPATHLEN]; ! 250: char cmd[BUFSIZ]; ! 251: ! 252: canon("/", curdir); ! 253: loop: ! 254: getcmd(curdir, cmd, name); ! 255: switch (cmd[0]) { ! 256: /* ! 257: * Add elements to the extraction list. ! 258: */ ! 259: case 'a': ! 260: ino = dirlookup(name); ! 261: if (ino == 0) ! 262: break; ! 263: if (mflag) ! 264: pathcheck(name); ! 265: treescan(name, ino, addfile); ! 266: break; ! 267: /* ! 268: * Change working directory. ! 269: */ ! 270: case 'c': ! 271: ino = dirlookup(name); ! 272: if (ino == 0) ! 273: break; ! 274: if (inodetype(ino) == LEAF) { ! 275: fprintf(stderr, "%s: not a directory\n", name); ! 276: break; ! 277: } ! 278: (void) strcpy(curdir, name); ! 279: break; ! 280: /* ! 281: * Delete elements from the extraction list. ! 282: */ ! 283: case 'd': ! 284: np = lookupname(name); ! 285: if (np == NIL || (np->e_flags & NEW) == 0) { ! 286: fprintf(stderr, "%s: not on extraction list\n", name); ! 287: break; ! 288: } ! 289: treescan(name, np->e_ino, deletefile); ! 290: break; ! 291: /* ! 292: * Extract the requested list. ! 293: */ ! 294: case 'e': ! 295: createfiles(); ! 296: createlinks(); ! 297: setdirmodes(); ! 298: if (dflag) ! 299: checkrestore(); ! 300: volno = 0; ! 301: break; ! 302: /* ! 303: * List available commands. ! 304: */ ! 305: case 'h': ! 306: case '?': ! 307: fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", ! 308: "Available commands are:\n", ! 309: "\tls [arg] - list directory\n", ! 310: "\tcd arg - change directory\n", ! 311: "\tpwd - print current directory\n", ! 312: "\tadd [arg] - add `arg' to list of", ! 313: " files to be extracted\n", ! 314: "\tdelete [arg] - delete `arg' from", ! 315: " list of files to be extracted\n", ! 316: "\textract - extract requested files\n", ! 317: "\tquit - immediately exit program\n", ! 318: "\tverbose - toggle verbose flag", ! 319: " (useful with ``ls'')\n", ! 320: "\thelp or `?' - print this list\n", ! 321: "If no `arg' is supplied, the current", ! 322: " directory is used\n"); ! 323: break; ! 324: /* ! 325: * List a directory. ! 326: */ ! 327: case 'l': ! 328: ino = dirlookup(name); ! 329: if (ino == 0) ! 330: break; ! 331: printlist(name, ino); ! 332: break; ! 333: /* ! 334: * Print current directory. ! 335: */ ! 336: case 'p': ! 337: if (curdir[1] == '\0') ! 338: fprintf(stderr, "/\n"); ! 339: else ! 340: fprintf(stderr, "%s\n", &curdir[1]); ! 341: break; ! 342: /* ! 343: * Quit. ! 344: */ ! 345: case 'q': ! 346: case 'x': ! 347: return; ! 348: /* ! 349: * Toggle verbose mode. ! 350: */ ! 351: case 'v': ! 352: if (vflag) { ! 353: fprintf(stderr, "verbose mode off\n"); ! 354: vflag = 0; ! 355: break; ! 356: } ! 357: fprintf(stderr, "verbose mode on\n"); ! 358: vflag++; ! 359: break; ! 360: /* ! 361: * Turn on debugging. ! 362: */ ! 363: case 'D': ! 364: if (dflag) { ! 365: fprintf(stderr, "debugging mode off\n"); ! 366: dflag = 0; ! 367: break; ! 368: } ! 369: fprintf(stderr, "debugging mode on\n"); ! 370: dflag++; ! 371: break; ! 372: /* ! 373: * Unknown command. ! 374: */ ! 375: default: ! 376: fprintf(stderr, "%s: unknown command; type ? for help\n", cmd); ! 377: break; ! 378: } ! 379: goto loop; ! 380: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.