110312Smckusick /* Copyright (c) 1983 Regents of the University of California */ 24610Smckusick 36846Smckusick #ifndef lint 4*11438Smckusick static char sccsid[] = "@(#)main.c 3.7 (Berkeley) 83/03/08"; 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; 31*11438Smckusick long volno = 0; 325327Smckusic char *dumpmap; 335327Smckusic char *clrimap; 3410312Smckusick ino_t maxino; 3510312Smckusick time_t dumptime; 3611302Smckusick time_t dumpdate; 374610Smckusick 386846Smckusick main(argc, argv) 394700Smckusic int argc; 404700Smckusic char *argv[]; 414610Smckusick { 424610Smckusick register char *cp; 4311308Smckusick ino_t ino; 4410312Smckusick char *inputdev = "/dev/rmt8"; 4511308Smckusick char *symtbl = "./restoresymtable"; 4611308Smckusick char *dirmodefile = "./dirmodes"; 4711320Smckusick char name[BUFSIZ]; 484700Smckusic int (*signal())(); 4910312Smckusick extern int onintr(); 504610Smckusick 5110312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 52*11438Smckusick (void) signal(SIGINT, SIG_IGN); 5310312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 54*11438Smckusick (void) signal(SIGTERM, SIG_IGN); 5511308Smckusick setlinebuf(stderr); 564610Smckusick if (argc < 2) { 574610Smckusick usage: 5810312Smckusick 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; 7110312Smckusick case 'd': 7210312Smckusick 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; 8610312Smckusick case 'f': 8711400Smckusick if (argc < 1) { 8811400Smckusick fprintf(stderr, "missing device specifier\n"); 8911400Smckusick done(1); 9011400Smckusick } 9110312Smckusick inputdev = *argv++; 9210312Smckusick argc--; 9310312Smckusick break; 9410312Smckusick case 's': 9510312Smckusick /* 9610312Smckusick * dumpnum (skip to) for multifile dump tapes 9710312Smckusick */ 9811400Smckusick if (argc < 1) { 9911400Smckusick fprintf(stderr, "missing dump number\n"); 10011400Smckusick done(1); 10111400Smckusick } 10210312Smckusick dumpnum = atoi(*argv++); 10310312Smckusick if (dumpnum <= 0) { 10410312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 10510312Smckusick done(1); 10610312Smckusick } 10710312Smckusick argc--; 10810312Smckusick break; 1094610Smckusick case 't': 11010312Smckusick case 'R': 11110312Smckusick case 'r': 11210312Smckusick case 'x': 11310202Smckusick if (command != '\0') { 11410312Smckusick fprintf(stderr, 11511400Smckusick "%c and %c are mutually exclusive\n", 11611400Smckusick *cp, command); 11710202Smckusick goto usage; 11810202Smckusick } 11911400Smckusick command = *cp; 1204610Smckusick break; 1214610Smckusick default: 1224700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1234610Smckusick goto usage; 1244610Smckusick } 1254610Smckusick } 12610202Smckusick if (command == '\0') { 12710312Smckusick fprintf(stderr, "must specify t, r, R, or x\n"); 12810202Smckusick goto usage; 12910202Smckusick } 13010312Smckusick setinput(inputdev); 13110202Smckusick if (argc == 0) { 13210312Smckusick argc = 1; 13310202Smckusick *--argv = "."; 13410202Smckusick } 13510312Smckusick switch (command) { 13610312Smckusick 13710312Smckusick case 't': 13810312Smckusick setup(); 13910312Smckusick extractdirs((char *)0); 14010312Smckusick while (argc--) { 14111320Smckusick canon(*argv++, name); 14211320Smckusick if ((ino = psearch(name)) == 0 || 14310312Smckusick BIT(ino, dumpmap) == 0) { 14411320Smckusick fprintf(stderr, "%s: not on tape\n", name); 1458505Smckusick continue; 14610312Smckusick } 14711400Smckusick if (hflag) 14811400Smckusick treescan(name, ino, listfile); 14911400Smckusick else 15011400Smckusick listfile(name, ino, inodetype(ino)); 1514837Smckusic } 15210312Smckusick done(0); 1534837Smckusic 15410312Smckusick case 'x': 15510312Smckusick setup(); 15610312Smckusick extractdirs(dirmodefile); 157*11438Smckusick initsymtable((char *)0); 15810312Smckusick while (argc--) { 15911320Smckusick canon(*argv++, name); 16011320Smckusick if ((ino = psearch(name)) == 0 || 16110312Smckusick BIT(ino, dumpmap) == 0) { 16211320Smckusick fprintf(stderr, "%s: not on tape\n", name); 1636289Smckusick continue; 1646289Smckusick } 16510312Smckusick if (mflag) 166*11438Smckusick pathcheck(name); 16710312Smckusick if (hflag) 16811320Smckusick treescan(name, ino, addfile); 16910312Smckusick else 17011320Smckusick addfile(name, ino, inodetype(ino)); 1715943Smckusic } 17210312Smckusick createfiles(); 17311308Smckusick createlinks(); 17410312Smckusick setdirmodes(dirmodefile); 17510312Smckusick if (dflag) 17610312Smckusick checkrestore(); 17710312Smckusick done(0); 1784843Smckusic 17910312Smckusick case 'r': 18010312Smckusick setup(); 18110312Smckusick if (dumptime > 0) { 182*11438Smckusick /* 183*11438Smckusick * This is an incremental dump tape. 184*11438Smckusick */ 185*11438Smckusick vprintf(stdout, "Begin incremental restore\n"); 18610312Smckusick initsymtable(symtbl); 187*11438Smckusick extractdirs(dirmodefile); 188*11438Smckusick removeoldleaves(); 189*11438Smckusick vprintf(stdout, "Calculate node updates.\n"); 190*11438Smckusick treescan(".", ROOTINO, nodeupdates); 191*11438Smckusick findunreflinks(); 192*11438Smckusick removeoldnodes(); 19310312Smckusick } else { 194*11438Smckusick /* 195*11438Smckusick * This is a level zero dump tape. 196*11438Smckusick */ 197*11438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 198*11438Smckusick initsymtable((char *)0); 199*11438Smckusick extractdirs(dirmodefile); 200*11438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 201*11438Smckusick treescan(".", ROOTINO, nodeupdates); 2024843Smckusic } 20310312Smckusick createleaves(symtbl); 20410312Smckusick createlinks(); 20510312Smckusick setdirmodes(dirmodefile); 20610312Smckusick checkrestore(); 20710312Smckusick if (dflag) { 20810312Smckusick vprintf(stdout, "Verify the directory structure\n"); 20910312Smckusick treescan(".", ROOTINO, verifyfile); 2104610Smckusick } 21110312Smckusick dumpsymtable(symtbl, (long)1); 21210312Smckusick done(0); 2134610Smckusick 21410312Smckusick case 'R': 21510312Smckusick initsymtable(symtbl); 21611320Smckusick skipmaps(); 21711320Smckusick skipdirs(); 21810312Smckusick createleaves(symtbl); 21910312Smckusick createlinks(); 22010312Smckusick setdirmodes(dirmodefile); 22110312Smckusick checkrestore(); 22210312Smckusick dumpsymtable(symtbl, (long)1); 22310312Smckusick done(0); 2244843Smckusic } 2254843Smckusic } 226