110312Smckusick /* Copyright (c) 1983 Regents of the University of California */ 24610Smckusick 36846Smckusick #ifndef lint 4*11308Smckusick static char sccsid[] = "@(#)main.c 3.3 (Berkeley) 83/02/27"; 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; 3611302Smckusick time_t dumpdate; 3711125Smckusick struct entry **entry; 384610Smckusick 396846Smckusick main(argc, argv) 404700Smckusic int argc; 414700Smckusic char *argv[]; 424610Smckusick { 434610Smckusick register char *cp; 44*11308Smckusick ino_t ino; 4510312Smckusick char *inputdev = "/dev/rmt8"; 46*11308Smckusick char *symtbl = "./restoresymtable"; 47*11308Smckusick char *dirmodefile = "./dirmodes"; 484700Smckusic int (*signal())(); 4910312Smckusick extern int onintr(); 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); 55*11308Smckusick 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': 8710312Smckusick inputdev = *argv++; 8810312Smckusick argc--; 8910312Smckusick break; 9010312Smckusick case 's': 9110312Smckusick /* 9210312Smckusick * dumpnum (skip to) for multifile dump tapes 9310312Smckusick */ 9410312Smckusick dumpnum = atoi(*argv++); 9510312Smckusick if (dumpnum <= 0) { 9610312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 9710312Smckusick done(1); 9810312Smckusick } 9910312Smckusick argc--; 10010312Smckusick break; 1014610Smckusick case 't': 10211125Smckusick if (command != '\0') { 10311125Smckusick fprintf(stderr, 10411125Smckusick "t and %c are mutually exclusive\n", 10511125Smckusick command); 10611125Smckusick goto usage; 10711125Smckusick } 10811125Smckusick command = 't'; 10911302Smckusick break; 11010312Smckusick case 'R': 11111125Smckusick if (command != '\0') { 11211125Smckusick fprintf(stderr, 11311125Smckusick "R and %c are mutually exclusive\n", 11411125Smckusick command); 11511125Smckusick goto usage; 11611125Smckusick } 11711125Smckusick command = 'R'; 11811302Smckusick break; 11910312Smckusick case 'r': 12011125Smckusick if (command != '\0') { 12111125Smckusick fprintf(stderr, 12211125Smckusick "r and %c are mutually exclusive\n", 12311125Smckusick command); 12411125Smckusick goto usage; 12511125Smckusick } 12611125Smckusick command = 'r'; 12711302Smckusick break; 12810312Smckusick case 'x': 12910202Smckusick if (command != '\0') { 13010312Smckusick fprintf(stderr, 13111125Smckusick "x and %c are mutually exclusive\n", 13211125Smckusick command); 13310202Smckusick goto usage; 13410202Smckusick } 13511125Smckusick command = 'x'; 1364610Smckusick break; 1374610Smckusick default: 1384700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1394610Smckusick goto usage; 1404610Smckusick } 1414610Smckusick } 14210202Smckusick if (command == '\0') { 14310312Smckusick fprintf(stderr, "must specify t, r, R, or x\n"); 14410202Smckusick goto usage; 14510202Smckusick } 14610312Smckusick setinput(inputdev); 14710202Smckusick if (argc == 0) { 14810312Smckusick argc = 1; 14910202Smckusick *--argv = "."; 15010202Smckusick } 15110312Smckusick switch (command) { 15210312Smckusick 15310312Smckusick case 't': 15410312Smckusick setup(); 15510312Smckusick extractdirs((char *)0); 15610312Smckusick while (argc--) { 15711125Smckusick if ((ino = psearch(*argv)) == 0 || 15810312Smckusick BIT(ino, dumpmap) == 0) { 15911125Smckusick fprintf(stderr, "%s: not on tape\n", *argv++); 1608505Smckusick continue; 16110312Smckusick } 16211125Smckusick treescan(*argv++, ino, listfile); 1634837Smckusic } 16410312Smckusick done(0); 1654837Smckusic 16610312Smckusick case 'x': 16710312Smckusick setup(); 16810312Smckusick extractdirs(dirmodefile); 16911125Smckusick entry = (struct entry **) 17011125Smckusick calloc((int)maxino, sizeof(struct entry *)); 17111125Smckusick if (entry == (struct entry **)NIL) 17211125Smckusick panic("no memory for entry table\n"); 17311125Smckusick (void)addentry(".", ROOTINO, NODE); 17410312Smckusick while (argc--) { 17511125Smckusick if ((ino = psearch(*argv)) == 0 || 17610312Smckusick BIT(ino, dumpmap) == 0) { 17711125Smckusick fprintf(stderr, "%s: not on tape\n", *argv++); 1786289Smckusick continue; 1796289Smckusick } 18010312Smckusick if (mflag) 18111125Smckusick pathcheck(*argv, NEW); 18210312Smckusick if (hflag) 18311125Smckusick treescan(*argv++, ino, addfile); 18410312Smckusick else 18511125Smckusick addfile(*argv++, ino, LEAF); 1865943Smckusic } 187*11308Smckusick createnodes(); 18810312Smckusick createfiles(); 189*11308Smckusick createlinks(); 19010312Smckusick setdirmodes(dirmodefile); 19110312Smckusick if (dflag) 19210312Smckusick checkrestore(); 19310312Smckusick done(0); 1944843Smckusic 19510312Smckusick case 'r': 19610312Smckusick setup(); 19710312Smckusick if (dumptime > 0) { 19810312Smckusick initsymtable(symtbl); 19910312Smckusick } else { 20011125Smckusick entry = (struct entry **) 20111125Smckusick calloc((int)maxino, sizeof(struct entry *)); 20211125Smckusick if (entry == (struct entry **)NIL) 20311125Smckusick panic("no memory for entry table\n"); 20411125Smckusick (void)addentry(".", ROOTINO, NODE); 2054843Smckusic } 20611302Smckusick extractdirs(dirmodefile); 20711125Smckusick markremove(); 20811125Smckusick if ((ino = psearch(".")) == 0 || BIT(ino, dumpmap) == 0) 20911125Smckusick panic("Root directory is not on tape\n"); 21011125Smckusick vprintf(stdout, "Calculate extraction list.\n"); 21111125Smckusick treescan(".", ino, markfile); 21211125Smckusick findunref(); 21311125Smckusick removeleaves(); 21411125Smckusick renamenodes(); 21511125Smckusick createnodes(); 21611125Smckusick renameleaves(); 21711125Smckusick removenodes(); 21810312Smckusick createleaves(symtbl); 21910312Smckusick createlinks(); 22010312Smckusick setdirmodes(dirmodefile); 22110312Smckusick checkrestore(); 22210312Smckusick if (dflag) { 22310312Smckusick vprintf(stdout, "Verify the directory structure\n"); 22410312Smckusick treescan(".", ROOTINO, verifyfile); 2254610Smckusick } 22610312Smckusick dumpsymtable(symtbl, (long)1); 22710312Smckusick done(0); 2284610Smckusick 22910312Smckusick case 'R': 23010312Smckusick initsymtable(symtbl); 23110312Smckusick createleaves(symtbl); 23210312Smckusick createlinks(); 23310312Smckusick setdirmodes(dirmodefile); 23410312Smckusick checkrestore(); 23510312Smckusick dumpsymtable(symtbl, (long)1); 23610312Smckusick done(0); 2374843Smckusic } 2384843Smckusic } 239