16846Smckusick #ifndef lint 2*18496Smckusick static char sccsid[] = "@(#)main.c 3.16 (Berkeley) 85/03/24"; 36846Smckusick #endif 44610Smckusick 514564Ssam /* Copyright (c) 1983 Regents of the University of California */ 614564Ssam 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 * 2011993Smckusick * Full incremental restore running entirely in user code and 2111993Smckusick * interactive tape browser. 2210312Smckusick * 1/19/83 by Kirk McKusick 234610Smckusick */ 244610Smckusick 2510312Smckusick #include "restore.h" 2617707Smckusick #include <dumprestor.h> 274610Smckusick #include <signal.h> 284610Smckusick 29*18496Smckusick int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 3010312Smckusick int hflag = 1, mflag = 1; 3110312Smckusick char command = '\0'; 3210312Smckusick long dumpnum = 1; 3311438Smckusick long volno = 0; 34*18496Smckusick long ntrec; 355327Smckusic char *dumpmap; 365327Smckusic char *clrimap; 3710312Smckusick ino_t maxino; 3810312Smckusick time_t dumptime; 3911302Smckusick time_t dumpdate; 4011993Smckusick FILE *terminal; 414610Smckusick 426846Smckusick main(argc, argv) 434700Smckusic int argc; 444700Smckusic char *argv[]; 454610Smckusick { 464610Smckusick register char *cp; 4711308Smckusick ino_t ino; 4810312Smckusick char *inputdev = "/dev/rmt8"; 4911308Smckusick char *symtbl = "./restoresymtable"; 5011993Smckusick char name[MAXPATHLEN]; 514700Smckusic int (*signal())(); 5210312Smckusick extern int onintr(); 534610Smckusick 5410312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 5511438Smckusick (void) signal(SIGINT, SIG_IGN); 5610312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 5711438Smckusick (void) signal(SIGTERM, SIG_IGN); 5811308Smckusick setlinebuf(stderr); 594610Smckusick if (argc < 2) { 604610Smckusick usage: 6111993Smckusick fprintf(stderr, "Usage:\n%s%s%s%s%s", 6211993Smckusick "\trestore tfhsvy [file file ...]\n", 6311993Smckusick "\trestore xfhmsvy [file file ...]\n", 6411993Smckusick "\trestore ifhmsvy\n", 6511993Smckusick "\trestore rfsvy\n", 6611993Smckusick "\trestore Rfsvy\n"); 674700Smckusic done(1); 684610Smckusick } 694610Smckusick argv++; 704610Smckusick argc -= 2; 7110202Smckusick command = '\0'; 724610Smckusick for (cp = *argv++; *cp; cp++) { 734610Smckusick switch (*cp) { 744610Smckusick case '-': 754610Smckusick break; 768302Smckusick case 'c': 778302Smckusick cvtflag++; 788302Smckusick break; 7910312Smckusick case 'd': 8010312Smckusick dflag++; 814610Smckusick break; 824610Smckusick case 'h': 8310202Smckusick hflag = 0; 844610Smckusick break; 854610Smckusick case 'm': 8610202Smckusick mflag = 0; 874610Smckusick break; 888374Smckusick case 'v': 898374Smckusick vflag++; 908374Smckusick break; 918374Smckusick case 'y': 928374Smckusick yflag++; 938374Smckusick break; 9410312Smckusick case 'f': 9511400Smckusick if (argc < 1) { 9611400Smckusick fprintf(stderr, "missing device specifier\n"); 9711400Smckusick done(1); 9811400Smckusick } 9910312Smckusick inputdev = *argv++; 10010312Smckusick argc--; 10110312Smckusick break; 10217707Smckusick case 'b': 10317707Smckusick /* 10417707Smckusick * change default tape blocksize 10517707Smckusick */ 106*18496Smckusick bflag++; 10717707Smckusick if (argc < 1) { 10817707Smckusick fprintf(stderr, "missing block size\n"); 10917707Smckusick done(1); 11017707Smckusick } 11117707Smckusick ntrec = atoi(*argv++); 11217707Smckusick if (ntrec <= 0) { 11317707Smckusick fprintf(stderr, "Block size must be a positive integer\n"); 11417707Smckusick done(1); 11517707Smckusick } 11617707Smckusick argc--; 11717707Smckusick break; 11810312Smckusick case 's': 11910312Smckusick /* 12010312Smckusick * dumpnum (skip to) for multifile dump tapes 12110312Smckusick */ 12211400Smckusick if (argc < 1) { 12311400Smckusick fprintf(stderr, "missing dump number\n"); 12411400Smckusick done(1); 12511400Smckusick } 12610312Smckusick dumpnum = atoi(*argv++); 12710312Smckusick if (dumpnum <= 0) { 12810312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 12910312Smckusick done(1); 13010312Smckusick } 13110312Smckusick argc--; 13210312Smckusick break; 1334610Smckusick case 't': 13410312Smckusick case 'R': 13510312Smckusick case 'r': 13610312Smckusick case 'x': 13711993Smckusick case 'i': 13810202Smckusick if (command != '\0') { 13910312Smckusick fprintf(stderr, 14011400Smckusick "%c and %c are mutually exclusive\n", 14111400Smckusick *cp, command); 14210202Smckusick goto usage; 14310202Smckusick } 14411400Smckusick command = *cp; 1454610Smckusick break; 1464610Smckusick default: 1474700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1484610Smckusick goto usage; 1494610Smckusick } 1504610Smckusick } 15110202Smckusick if (command == '\0') { 15211993Smckusick fprintf(stderr, "must specify i, t, r, R, or x\n"); 15310202Smckusick goto usage; 15410202Smckusick } 15510312Smckusick setinput(inputdev); 15610202Smckusick if (argc == 0) { 15710312Smckusick argc = 1; 15810202Smckusick *--argv = "."; 15910202Smckusick } 16010312Smckusick switch (command) { 16111993Smckusick /* 16211993Smckusick * Interactive mode. 16311993Smckusick */ 16411993Smckusick case 'i': 16510312Smckusick setup(); 16611993Smckusick extractdirs(1); 16711438Smckusick initsymtable((char *)0); 16811993Smckusick runcmdshell(); 16910312Smckusick done(0); 17011993Smckusick /* 17111993Smckusick * Incremental restoration of a file system. 17211993Smckusick */ 17310312Smckusick case 'r': 17410312Smckusick setup(); 17510312Smckusick if (dumptime > 0) { 17611438Smckusick /* 17711438Smckusick * This is an incremental dump tape. 17811438Smckusick */ 17911438Smckusick vprintf(stdout, "Begin incremental restore\n"); 18010312Smckusick initsymtable(symtbl); 18111993Smckusick extractdirs(1); 18211438Smckusick removeoldleaves(); 18311438Smckusick vprintf(stdout, "Calculate node updates.\n"); 18411438Smckusick treescan(".", ROOTINO, nodeupdates); 18511438Smckusick findunreflinks(); 18611438Smckusick removeoldnodes(); 18710312Smckusick } else { 18811438Smckusick /* 18911438Smckusick * This is a level zero dump tape. 19011438Smckusick */ 19111438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 19211438Smckusick initsymtable((char *)0); 19311993Smckusick extractdirs(1); 19411438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 19511438Smckusick treescan(".", ROOTINO, nodeupdates); 1964843Smckusic } 19710312Smckusick createleaves(symtbl); 19810312Smckusick createlinks(); 19911993Smckusick setdirmodes(); 20010312Smckusick checkrestore(); 20110312Smckusick if (dflag) { 20210312Smckusick vprintf(stdout, "Verify the directory structure\n"); 20310312Smckusick treescan(".", ROOTINO, verifyfile); 2044610Smckusick } 20510312Smckusick dumpsymtable(symtbl, (long)1); 20610312Smckusick done(0); 20711993Smckusick /* 20811993Smckusick * Resume an incremental file system restoration. 20911993Smckusick */ 21010312Smckusick case 'R': 21110312Smckusick initsymtable(symtbl); 21211320Smckusick skipmaps(); 21311320Smckusick skipdirs(); 21410312Smckusick createleaves(symtbl); 21510312Smckusick createlinks(); 21611993Smckusick setdirmodes(); 21710312Smckusick checkrestore(); 21810312Smckusick dumpsymtable(symtbl, (long)1); 21910312Smckusick done(0); 22011993Smckusick /* 22111993Smckusick * List contents of tape. 22211993Smckusick */ 22311993Smckusick case 't': 22411993Smckusick setup(); 22511993Smckusick extractdirs(0); 22611993Smckusick while (argc--) { 22711993Smckusick canon(*argv++, name); 22811993Smckusick ino = dirlookup(name); 22911993Smckusick if (ino == 0) 23011993Smckusick continue; 23111993Smckusick treescan(name, ino, listfile); 23211993Smckusick } 23311993Smckusick done(0); 23411993Smckusick /* 23511993Smckusick * Batch extraction of tape contents. 23611993Smckusick */ 23711993Smckusick case 'x': 23811993Smckusick setup(); 23911993Smckusick extractdirs(1); 24011993Smckusick initsymtable((char *)0); 24111993Smckusick while (argc--) { 24211993Smckusick canon(*argv++, name); 24311993Smckusick ino = dirlookup(name); 24411993Smckusick if (ino == 0) 24511993Smckusick continue; 24611993Smckusick if (mflag) 24711993Smckusick pathcheck(name); 24811993Smckusick treescan(name, ino, addfile); 24911993Smckusick } 25011993Smckusick createfiles(); 25111993Smckusick createlinks(); 25211993Smckusick setdirmodes(); 25311993Smckusick if (dflag) 25411993Smckusick checkrestore(); 25511993Smckusick done(0); 2564843Smckusic } 2574843Smckusic } 258