1*10312Smckusick /* Copyright (c) 1983 Regents of the University of California */ 24610Smckusick 36846Smckusick #ifndef lint 4*10312Smckusick static char sccsid[] = "@(#)main.c 3.6 (Berkeley) 83/01/16"; 56846Smckusick #endif 64610Smckusick 7*10312Smckusick /* 8*10312Smckusick * Modified to recursively extract all files within a subtree 9*10312Smckusick * (supressed by the h option) and recreate the heirarchical 10*10312Smckusick * structure of that subtree and move extracted files to their 11*10312Smckusick * proper homes (supressed by the m option). 12*10312Smckusick * Includes the s (skip files) option for use with multiple 13*10312Smckusick * dumps on a single tape. 144610Smckusick * 8/29/80 by Mike Litzkow 154610Smckusick * 16*10312Smckusick * Modified to work on the new file system and to recover from 17*10312Smckusick * tape read errors. 186846Smckusick * 1/19/82 by Kirk McKusick 196846Smckusick * 20*10312Smckusick * Full incremental restore running entirely in user code. 21*10312Smckusick * 1/19/83 by Kirk McKusick 224610Smckusick */ 234610Smckusick 24*10312Smckusick #include "restore.h" 254610Smckusick #include <signal.h> 264610Smckusick 27*10312Smckusick int cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 28*10312Smckusick int hflag = 1, mflag = 1; 29*10312Smckusick char command = '\0'; 30*10312Smckusick long dumpnum = 1; 31*10312Smckusick long volno = 1; 325327Smckusic char *dumpmap; 335327Smckusic char *clrimap; 34*10312Smckusick ino_t maxino; 35*10312Smckusick time_t dumptime; 36*10312Smckusick time_t dumpdate; 374610Smckusick 386846Smckusick main(argc, argv) 394700Smckusic int argc; 404700Smckusic char *argv[]; 414610Smckusick { 424610Smckusick register char *cp; 43*10312Smckusick ino_t ino; 44*10312Smckusick char *inputdev = "/dev/rmt8"; 45*10312Smckusick char *symtbl = "./restoresymtable"; 46*10312Smckusick char *dirmodefile = "./dirmodes"; 47*10312Smckusick char name[BUFSIZ]; 484700Smckusic int (*signal())(); 49*10312Smckusick extern int onintr(); 504610Smckusick 51*10312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 52*10312Smckusick (void) signal(SIGINT, SIG_IGN); 53*10312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 54*10312Smckusick (void) signal(SIGTERM, SIG_IGN); 55*10312Smckusick setlinebuf(stderr); 564610Smckusick if (argc < 2) { 574610Smckusick usage: 58*10312Smckusick fprintf(stderr, "Usage: restor xtfhmsvy file file... or restor rRfsvy\n"); 594700Smckusic done(1); 604610Smckusick } 614610Smckusick argv++; 624610Smckusick argc -= 2; 6310202Smckusick command = '\0'; 644610Smckusick for (cp = *argv++; *cp; cp++) { 654610Smckusick switch (*cp) { 664610Smckusick case '-': 674610Smckusick break; 688302Smckusick case 'c': 698302Smckusick cvtflag++; 708302Smckusick break; 71*10312Smckusick case 'd': 72*10312Smckusick dflag++; 734610Smckusick break; 744610Smckusick case 'h': 7510202Smckusick hflag = 0; 764610Smckusick break; 774610Smckusick case 'm': 7810202Smckusick mflag = 0; 794610Smckusick break; 808374Smckusick case 'v': 818374Smckusick vflag++; 828374Smckusick break; 838374Smckusick case 'y': 848374Smckusick yflag++; 858374Smckusick break; 86*10312Smckusick case 'f': 87*10312Smckusick if (argc < 1) { 88*10312Smckusick fprintf(stderr, "missing device specifier\n"); 89*10312Smckusick done(1); 90*10312Smckusick } 91*10312Smckusick inputdev = *argv++; 92*10312Smckusick argc--; 93*10312Smckusick break; 94*10312Smckusick case 's': 95*10312Smckusick /* 96*10312Smckusick * dumpnum (skip to) for multifile dump tapes 97*10312Smckusick */ 98*10312Smckusick if (argc < 1) { 99*10312Smckusick fprintf(stderr, "missing dump number\n"); 100*10312Smckusick done(1); 101*10312Smckusick } 102*10312Smckusick dumpnum = atoi(*argv++); 103*10312Smckusick if (dumpnum <= 0) { 104*10312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 105*10312Smckusick done(1); 106*10312Smckusick } 107*10312Smckusick argc--; 108*10312Smckusick break; 1094610Smckusick case 't': 110*10312Smckusick case 'R': 111*10312Smckusick case 'r': 112*10312Smckusick case 'x': 11310202Smckusick if (command != '\0') { 114*10312Smckusick fprintf(stderr, 115*10312Smckusick "%c and %c are mutually exclusive\n", 116*10312Smckusick *cp, command); 11710202Smckusick goto usage; 11810202Smckusick } 119*10312Smckusick command = *cp; 1204610Smckusick break; 1214610Smckusick default: 1224700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1234610Smckusick goto usage; 1244610Smckusick } 1254610Smckusick } 12610202Smckusick if (command == '\0') { 127*10312Smckusick fprintf(stderr, "must specify t, r, R, or x\n"); 12810202Smckusick goto usage; 12910202Smckusick } 130*10312Smckusick setinput(inputdev); 13110202Smckusick if (argc == 0) { 132*10312Smckusick argc = 1; 13310202Smckusick *--argv = "."; 13410202Smckusick } 135*10312Smckusick switch (command) { 136*10312Smckusick 137*10312Smckusick case 't': 138*10312Smckusick setup(); 139*10312Smckusick extractdirs((char *)0); 140*10312Smckusick while (argc--) { 141*10312Smckusick canon(*argv++, name); 142*10312Smckusick if ((ino = psearch(name)) == 0 || 143*10312Smckusick BIT(ino, dumpmap) == 0) { 144*10312Smckusick fprintf(stderr, "%s: not on tape\n", name); 1458505Smckusick continue; 146*10312Smckusick } 147*10312Smckusick if (hflag) 148*10312Smckusick treescan(name, ino, listfile); 1494837Smckusic else 150*10312Smckusick listfile(name, ino, inodetype(ino)); 1514837Smckusic } 152*10312Smckusick done(0); 1534837Smckusic 154*10312Smckusick case 'x': 155*10312Smckusick setup(); 156*10312Smckusick extractdirs(dirmodefile); 157*10312Smckusick initsymtable((char *)0); 158*10312Smckusick while (argc--) { 159*10312Smckusick canon(*argv++, name); 160*10312Smckusick if ((ino = psearch(name)) == 0 || 161*10312Smckusick BIT(ino, dumpmap) == 0) { 162*10312Smckusick fprintf(stderr, "%s: not on tape\n", name); 1636289Smckusick continue; 1646289Smckusick } 165*10312Smckusick if (mflag) 166*10312Smckusick pathcheck(name); 167*10312Smckusick if (hflag) 168*10312Smckusick treescan(name, ino, addfile); 169*10312Smckusick else 170*10312Smckusick addfile(name, ino, inodetype(ino)); 1715943Smckusic } 172*10312Smckusick createfiles(); 173*10312Smckusick createlinks(); 174*10312Smckusick setdirmodes(dirmodefile); 175*10312Smckusick if (dflag) 176*10312Smckusick checkrestore(); 177*10312Smckusick done(0); 1784843Smckusic 179*10312Smckusick case 'r': 180*10312Smckusick setup(); 181*10312Smckusick if (dumptime > 0) { 182*10312Smckusick /* 183*10312Smckusick * This is an incremental dump tape. 184*10312Smckusick */ 185*10312Smckusick vprintf(stdout, "Begin incremental restore\n"); 186*10312Smckusick initsymtable(symtbl); 187*10312Smckusick extractdirs(dirmodefile); 188*10312Smckusick removeoldleaves(); 189*10312Smckusick vprintf(stdout, "Calculate node updates.\n"); 190*10312Smckusick treescan(".", ROOTINO, nodeupdates); 191*10312Smckusick findunreflinks(); 192*10312Smckusick removeoldnodes(); 193*10312Smckusick } else { 194*10312Smckusick /* 195*10312Smckusick * This is a level zero dump tape. 196*10312Smckusick */ 197*10312Smckusick vprintf(stdout, "Begin level 0 restore\n"); 198*10312Smckusick initsymtable((char *)0); 199*10312Smckusick extractdirs(dirmodefile); 200*10312Smckusick vprintf(stdout, "Calculate extraction list.\n"); 201*10312Smckusick treescan(".", ROOTINO, nodeupdates); 2024843Smckusic } 203*10312Smckusick createleaves(symtbl); 204*10312Smckusick createlinks(); 205*10312Smckusick setdirmodes(dirmodefile); 206*10312Smckusick checkrestore(); 207*10312Smckusick if (dflag) { 208*10312Smckusick vprintf(stdout, "Verify the directory structure\n"); 209*10312Smckusick treescan(".", ROOTINO, verifyfile); 2104610Smckusick } 211*10312Smckusick dumpsymtable(symtbl, (long)1); 212*10312Smckusick done(0); 2134610Smckusick 214*10312Smckusick case 'R': 215*10312Smckusick initsymtable(symtbl); 216*10312Smckusick skipmaps(); 217*10312Smckusick skipdirs(); 218*10312Smckusick createleaves(symtbl); 219*10312Smckusick createlinks(); 220*10312Smckusick setdirmodes(dirmodefile); 221*10312Smckusick checkrestore(); 222*10312Smckusick dumpsymtable(symtbl, (long)1); 223*10312Smckusick done(0); 2244843Smckusic } 2254843Smckusic } 226