110312Smckusick /* Copyright (c) 1983 Regents of the University of California */ 24610Smckusick 36846Smckusick #ifndef lint 4*11302Smckusick static char sccsid[] = "@(#)main.c 3.2 (Berkeley) 83/02/26"; 56846Smckusick #endif 64610Smckusick 710312Smckusick /* 810312Smckusick * Modified to recursively extract all files within a subtree 910312Smckusick * (supressed by the h option) and recreate the heirarchical 1010312Smckusick * structure of that subtree and move extracted files to their 1110312Smckusick * proper homes (supressed by the m option). 1210312Smckusick * Includes the s (skip files) option for use with multiple 1310312Smckusick * dumps on a single tape. 144610Smckusick * 8/29/80 by Mike Litzkow 154610Smckusick * 1610312Smckusick * Modified to work on the new file system and to recover from 1710312Smckusick * tape read errors. 186846Smckusick * 1/19/82 by Kirk McKusick 196846Smckusick * 2010312Smckusick * Full incremental restore running entirely in user code. 2110312Smckusick * 1/19/83 by Kirk McKusick 224610Smckusick */ 234610Smckusick 2410312Smckusick #include "restore.h" 254610Smckusick #include <signal.h> 264610Smckusick 2710312Smckusick int cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 2810312Smckusick int hflag = 1, mflag = 1; 2910312Smckusick char command = '\0'; 3010312Smckusick long dumpnum = 1; 3110312Smckusick long volno = 1; 325327Smckusic char *dumpmap; 335327Smckusic char *clrimap; 3410312Smckusick ino_t maxino; 3510312Smckusick time_t dumptime; 36*11302Smckusick time_t dumpdate; 3711125Smckusick struct entry **entry; 384610Smckusick 396846Smckusick main(argc, argv) 404700Smckusic int argc; 414700Smckusic char *argv[]; 424610Smckusick { 434610Smckusick register char *cp; 4410312Smckusick char *inputdev = "/dev/rmt8"; 4511125Smckusick char *symtbl = "./lost+found/restoresymtable"; 4611125Smckusick char *dirmodefile = "./lost+found/dirmodes"; 474700Smckusic int (*signal())(); 4810312Smckusick extern int onintr(); 4911125Smckusick ino_t ino; 504610Smckusick 5110312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 5211125Smckusick signal(SIGINT, SIG_IGN); 5310312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 5411125Smckusick signal(SIGTERM, SIG_IGN); 554610Smckusick if (argc < 2) { 564610Smckusick usage: 5710312Smckusick fprintf(stderr, "Usage: restor xtfhmsvy file file... or restor rRfsvy\n"); 584700Smckusic done(1); 594610Smckusick } 604610Smckusick argv++; 614610Smckusick argc -= 2; 6210202Smckusick command = '\0'; 634610Smckusick for (cp = *argv++; *cp; cp++) { 644610Smckusick switch (*cp) { 654610Smckusick case '-': 664610Smckusick break; 678302Smckusick case 'c': 688302Smckusick cvtflag++; 698302Smckusick break; 7010312Smckusick case 'd': 7110312Smckusick dflag++; 724610Smckusick break; 734610Smckusick case 'h': 7410202Smckusick hflag = 0; 754610Smckusick break; 764610Smckusick case 'm': 7710202Smckusick mflag = 0; 784610Smckusick break; 798374Smckusick case 'v': 808374Smckusick vflag++; 818374Smckusick break; 828374Smckusick case 'y': 838374Smckusick yflag++; 848374Smckusick break; 8510312Smckusick case 'f': 8610312Smckusick inputdev = *argv++; 8710312Smckusick argc--; 8810312Smckusick break; 8910312Smckusick case 's': 9010312Smckusick /* 9110312Smckusick * dumpnum (skip to) for multifile dump tapes 9210312Smckusick */ 9310312Smckusick dumpnum = atoi(*argv++); 9410312Smckusick if (dumpnum <= 0) { 9510312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 9610312Smckusick done(1); 9710312Smckusick } 9810312Smckusick argc--; 9910312Smckusick break; 1004610Smckusick case 't': 10111125Smckusick if (command != '\0') { 10211125Smckusick fprintf(stderr, 10311125Smckusick "t and %c are mutually exclusive\n", 10411125Smckusick command); 10511125Smckusick goto usage; 10611125Smckusick } 10711125Smckusick command = 't'; 108*11302Smckusick break; 10910312Smckusick case 'R': 11011125Smckusick if (command != '\0') { 11111125Smckusick fprintf(stderr, 11211125Smckusick "R and %c are mutually exclusive\n", 11311125Smckusick command); 11411125Smckusick goto usage; 11511125Smckusick } 11611125Smckusick command = 'R'; 117*11302Smckusick break; 11810312Smckusick case 'r': 11911125Smckusick if (command != '\0') { 12011125Smckusick fprintf(stderr, 12111125Smckusick "r and %c are mutually exclusive\n", 12211125Smckusick command); 12311125Smckusick goto usage; 12411125Smckusick } 12511125Smckusick command = 'r'; 126*11302Smckusick break; 12710312Smckusick case 'x': 12810202Smckusick if (command != '\0') { 12910312Smckusick fprintf(stderr, 13011125Smckusick "x and %c are mutually exclusive\n", 13111125Smckusick command); 13210202Smckusick goto usage; 13310202Smckusick } 13411125Smckusick command = 'x'; 1354610Smckusick break; 1364610Smckusick default: 1374700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1384610Smckusick goto usage; 1394610Smckusick } 1404610Smckusick } 14110202Smckusick if (command == '\0') { 14210312Smckusick fprintf(stderr, "must specify t, r, R, or x\n"); 14310202Smckusick goto usage; 14410202Smckusick } 14510312Smckusick setinput(inputdev); 14610202Smckusick if (argc == 0) { 14710312Smckusick argc = 1; 14810202Smckusick *--argv = "."; 14910202Smckusick } 15010312Smckusick switch (command) { 15110312Smckusick 15210312Smckusick case 't': 15310312Smckusick setup(); 15410312Smckusick extractdirs((char *)0); 15510312Smckusick while (argc--) { 15611125Smckusick if ((ino = psearch(*argv)) == 0 || 15710312Smckusick BIT(ino, dumpmap) == 0) { 15811125Smckusick fprintf(stderr, "%s: not on tape\n", *argv++); 1598505Smckusick continue; 16010312Smckusick } 16111125Smckusick treescan(*argv++, ino, listfile); 1624837Smckusic } 16310312Smckusick done(0); 1644837Smckusic 16510312Smckusick case 'x': 16610312Smckusick setup(); 16710312Smckusick extractdirs(dirmodefile); 16811125Smckusick entry = (struct entry **) 16911125Smckusick calloc((int)maxino, sizeof(struct entry *)); 17011125Smckusick if (entry == (struct entry **)NIL) 17111125Smckusick panic("no memory for entry table\n"); 17211125Smckusick (void)addentry(".", ROOTINO, NODE); 17310312Smckusick while (argc--) { 17411125Smckusick if ((ino = psearch(*argv)) == 0 || 17510312Smckusick BIT(ino, dumpmap) == 0) { 17611125Smckusick fprintf(stderr, "%s: not on tape\n", *argv++); 1776289Smckusick continue; 1786289Smckusick } 17910312Smckusick if (mflag) 18011125Smckusick pathcheck(*argv, NEW); 18110312Smckusick if (hflag) 18211125Smckusick treescan(*argv++, ino, addfile); 18310312Smckusick else 18411125Smckusick addfile(*argv++, ino, LEAF); 1855943Smckusic } 18610312Smckusick createfiles(); 18710312Smckusick setdirmodes(dirmodefile); 18810312Smckusick if (dflag) 18910312Smckusick checkrestore(); 19010312Smckusick done(0); 1914843Smckusic 19210312Smckusick case 'r': 19310312Smckusick setup(); 19410312Smckusick if (dumptime > 0) { 19510312Smckusick initsymtable(symtbl); 19610312Smckusick } else { 19711125Smckusick entry = (struct entry **) 19811125Smckusick calloc((int)maxino, sizeof(struct entry *)); 19911125Smckusick if (entry == (struct entry **)NIL) 20011125Smckusick panic("no memory for entry table\n"); 20111125Smckusick (void)addentry(".", ROOTINO, NODE); 2024843Smckusic } 203*11302Smckusick extractdirs(dirmodefile); 20411125Smckusick markremove(); 20511125Smckusick if ((ino = psearch(".")) == 0 || BIT(ino, dumpmap) == 0) 20611125Smckusick panic("Root directory is not on tape\n"); 20711125Smckusick vprintf(stdout, "Calculate extraction list.\n"); 20811125Smckusick treescan(".", ino, markfile); 20911125Smckusick findunref(); 21011125Smckusick removeleaves(); 21111125Smckusick renamenodes(); 21211125Smckusick createnodes(); 21311125Smckusick renameleaves(); 21411125Smckusick removenodes(); 21510312Smckusick createleaves(symtbl); 21610312Smckusick createlinks(); 21710312Smckusick setdirmodes(dirmodefile); 21810312Smckusick checkrestore(); 21910312Smckusick if (dflag) { 22010312Smckusick vprintf(stdout, "Verify the directory structure\n"); 22110312Smckusick treescan(".", ROOTINO, verifyfile); 2224610Smckusick } 22310312Smckusick dumpsymtable(symtbl, (long)1); 22410312Smckusick done(0); 2254610Smckusick 22610312Smckusick case 'R': 22710312Smckusick initsymtable(symtbl); 22810312Smckusick createleaves(symtbl); 22910312Smckusick createlinks(); 23010312Smckusick setdirmodes(dirmodefile); 23110312Smckusick checkrestore(); 23210312Smckusick dumpsymtable(symtbl, (long)1); 23310312Smckusick done(0); 2344843Smckusic } 2354843Smckusic } 236