110312Smckusick /* Copyright (c) 1983 Regents of the University of California */ 24610Smckusick 36846Smckusick #ifndef lint 4*11320Smckusick static char sccsid[] = "@(#)main.c 3.4 (Berkeley) 83/02/28"; 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; 4411308Smckusick ino_t ino; 4510312Smckusick char *inputdev = "/dev/rmt8"; 4611308Smckusick char *symtbl = "./restoresymtable"; 4711308Smckusick char *dirmodefile = "./dirmodes"; 48*11320Smckusick char name[BUFSIZ]; 494700Smckusic int (*signal())(); 5010312Smckusick extern int onintr(); 514610Smckusick 5210312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 5311125Smckusick signal(SIGINT, SIG_IGN); 5410312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 5511125Smckusick signal(SIGTERM, SIG_IGN); 5611308Smckusick setlinebuf(stderr); 574610Smckusick if (argc < 2) { 584610Smckusick usage: 5910312Smckusick fprintf(stderr, "Usage: restor xtfhmsvy file file... or restor rRfsvy\n"); 604700Smckusic done(1); 614610Smckusick } 624610Smckusick argv++; 634610Smckusick argc -= 2; 6410202Smckusick command = '\0'; 654610Smckusick for (cp = *argv++; *cp; cp++) { 664610Smckusick switch (*cp) { 674610Smckusick case '-': 684610Smckusick break; 698302Smckusick case 'c': 708302Smckusick cvtflag++; 718302Smckusick break; 7210312Smckusick case 'd': 7310312Smckusick dflag++; 744610Smckusick break; 754610Smckusick case 'h': 7610202Smckusick hflag = 0; 774610Smckusick break; 784610Smckusick case 'm': 7910202Smckusick mflag = 0; 804610Smckusick break; 818374Smckusick case 'v': 828374Smckusick vflag++; 838374Smckusick break; 848374Smckusick case 'y': 858374Smckusick yflag++; 868374Smckusick break; 8710312Smckusick case 'f': 8810312Smckusick inputdev = *argv++; 8910312Smckusick argc--; 9010312Smckusick break; 9110312Smckusick case 's': 9210312Smckusick /* 9310312Smckusick * dumpnum (skip to) for multifile dump tapes 9410312Smckusick */ 9510312Smckusick dumpnum = atoi(*argv++); 9610312Smckusick if (dumpnum <= 0) { 9710312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 9810312Smckusick done(1); 9910312Smckusick } 10010312Smckusick argc--; 10110312Smckusick break; 1024610Smckusick case 't': 10311125Smckusick if (command != '\0') { 10411125Smckusick fprintf(stderr, 10511125Smckusick "t and %c are mutually exclusive\n", 10611125Smckusick command); 10711125Smckusick goto usage; 10811125Smckusick } 10911125Smckusick command = 't'; 11011302Smckusick break; 11110312Smckusick case 'R': 11211125Smckusick if (command != '\0') { 11311125Smckusick fprintf(stderr, 11411125Smckusick "R and %c are mutually exclusive\n", 11511125Smckusick command); 11611125Smckusick goto usage; 11711125Smckusick } 11811125Smckusick command = 'R'; 11911302Smckusick break; 12010312Smckusick case 'r': 12111125Smckusick if (command != '\0') { 12211125Smckusick fprintf(stderr, 12311125Smckusick "r and %c are mutually exclusive\n", 12411125Smckusick command); 12511125Smckusick goto usage; 12611125Smckusick } 12711125Smckusick command = 'r'; 12811302Smckusick break; 12910312Smckusick case 'x': 13010202Smckusick if (command != '\0') { 13110312Smckusick fprintf(stderr, 13211125Smckusick "x and %c are mutually exclusive\n", 13311125Smckusick command); 13410202Smckusick goto usage; 13510202Smckusick } 13611125Smckusick command = 'x'; 1374610Smckusick break; 1384610Smckusick default: 1394700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1404610Smckusick goto usage; 1414610Smckusick } 1424610Smckusick } 14310202Smckusick if (command == '\0') { 14410312Smckusick fprintf(stderr, "must specify t, r, R, or x\n"); 14510202Smckusick goto usage; 14610202Smckusick } 14710312Smckusick setinput(inputdev); 14810202Smckusick if (argc == 0) { 14910312Smckusick argc = 1; 15010202Smckusick *--argv = "."; 15110202Smckusick } 15210312Smckusick switch (command) { 15310312Smckusick 15410312Smckusick case 't': 15510312Smckusick setup(); 15610312Smckusick extractdirs((char *)0); 15710312Smckusick while (argc--) { 158*11320Smckusick canon(*argv++, name); 159*11320Smckusick if ((ino = psearch(name)) == 0 || 16010312Smckusick BIT(ino, dumpmap) == 0) { 161*11320Smckusick fprintf(stderr, "%s: not on tape\n", name); 1628505Smckusick continue; 16310312Smckusick } 164*11320Smckusick treescan(name, ino, listfile); 1654837Smckusic } 16610312Smckusick done(0); 1674837Smckusic 16810312Smckusick case 'x': 16910312Smckusick setup(); 17010312Smckusick extractdirs(dirmodefile); 17111125Smckusick entry = (struct entry **) 17211125Smckusick calloc((int)maxino, sizeof(struct entry *)); 17311125Smckusick if (entry == (struct entry **)NIL) 17411125Smckusick panic("no memory for entry table\n"); 17511125Smckusick (void)addentry(".", ROOTINO, NODE); 17610312Smckusick while (argc--) { 177*11320Smckusick canon(*argv++, name); 178*11320Smckusick if ((ino = psearch(name)) == 0 || 17910312Smckusick BIT(ino, dumpmap) == 0) { 180*11320Smckusick fprintf(stderr, "%s: not on tape\n", name); 1816289Smckusick continue; 1826289Smckusick } 18310312Smckusick if (mflag) 184*11320Smckusick pathcheck(name, NULL); 18510312Smckusick if (hflag) 186*11320Smckusick treescan(name, ino, addfile); 18710312Smckusick else 188*11320Smckusick addfile(name, ino, inodetype(ino)); 1895943Smckusic } 19010312Smckusick createfiles(); 19111308Smckusick createlinks(); 19210312Smckusick setdirmodes(dirmodefile); 19310312Smckusick if (dflag) 19410312Smckusick checkrestore(); 19510312Smckusick done(0); 1964843Smckusic 19710312Smckusick case 'r': 19810312Smckusick setup(); 19910312Smckusick if (dumptime > 0) { 20010312Smckusick initsymtable(symtbl); 20110312Smckusick } else { 20211125Smckusick entry = (struct entry **) 20311125Smckusick calloc((int)maxino, sizeof(struct entry *)); 20411125Smckusick if (entry == (struct entry **)NIL) 20511125Smckusick panic("no memory for entry table\n"); 20611125Smckusick (void)addentry(".", ROOTINO, NODE); 2074843Smckusic } 20811302Smckusick extractdirs(dirmodefile); 20911125Smckusick markremove(); 21011125Smckusick if ((ino = psearch(".")) == 0 || BIT(ino, dumpmap) == 0) 21111125Smckusick panic("Root directory is not on tape\n"); 21211125Smckusick vprintf(stdout, "Calculate extraction list.\n"); 21311125Smckusick treescan(".", ino, markfile); 21411125Smckusick findunref(); 21511125Smckusick removeleaves(); 21611125Smckusick renamenodes(); 21711125Smckusick createnodes(); 21811125Smckusick renameleaves(); 21911125Smckusick removenodes(); 22010312Smckusick createleaves(symtbl); 22110312Smckusick createlinks(); 22210312Smckusick setdirmodes(dirmodefile); 22310312Smckusick checkrestore(); 22410312Smckusick if (dflag) { 22510312Smckusick vprintf(stdout, "Verify the directory structure\n"); 22610312Smckusick treescan(".", ROOTINO, verifyfile); 2274610Smckusick } 22810312Smckusick dumpsymtable(symtbl, (long)1); 22910312Smckusick done(0); 2304610Smckusick 23110312Smckusick case 'R': 23210312Smckusick initsymtable(symtbl); 233*11320Smckusick skipmaps(); 234*11320Smckusick skipdirs(); 23510312Smckusick createleaves(symtbl); 23610312Smckusick createlinks(); 23710312Smckusick setdirmodes(dirmodefile); 23810312Smckusick checkrestore(); 23910312Smckusick dumpsymtable(symtbl, (long)1); 24010312Smckusick done(0); 2414843Smckusic } 2424843Smckusic } 243