121167Sdist /* 236105Sbostic * Copyright (c) 1983 The Regents of the University of California. 336105Sbostic * All rights reserved. 436105Sbostic * 542708Sbostic * %sccs.include.redist.c% 621167Sdist */ 721167Sdist 86846Smckusick #ifndef lint 921167Sdist char copyright[] = 1036105Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ 1121167Sdist All rights reserved.\n"; 1236105Sbostic #endif /* not lint */ 134610Smckusick 1421167Sdist #ifndef lint 15*56428Smckusick static char sccsid[] = "@(#)main.c 5.10 (Berkeley) 10/05/92"; 1636105Sbostic #endif /* not lint */ 1714564Ssam 1810312Smckusick /* 1910312Smckusick * Modified to recursively extract all files within a subtree 2010312Smckusick * (supressed by the h option) and recreate the heirarchical 2110312Smckusick * structure of that subtree and move extracted files to their 2210312Smckusick * proper homes (supressed by the m option). 2310312Smckusick * Includes the s (skip files) option for use with multiple 2410312Smckusick * dumps on a single tape. 254610Smckusick * 8/29/80 by Mike Litzkow 264610Smckusick * 2710312Smckusick * Modified to work on the new file system and to recover from 2810312Smckusick * tape read errors. 296846Smckusick * 1/19/82 by Kirk McKusick 306846Smckusick * 3111993Smckusick * Full incremental restore running entirely in user code and 3211993Smckusick * interactive tape browser. 3310312Smckusick * 1/19/83 by Kirk McKusick 344610Smckusick */ 354610Smckusick 3610312Smckusick #include "restore.h" 3723547Smckusick #include <protocols/dumprestore.h> 3837952Sbostic #include <sys/signal.h> 3937952Sbostic #include "pathnames.h" 404610Smckusick 4118496Smckusick int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 4234269Smckusick int hflag = 1, mflag = 1, Nflag = 0; 4310312Smckusick char command = '\0'; 4410312Smckusick long dumpnum = 1; 4511438Smckusick long volno = 0; 4618496Smckusick long ntrec; 475327Smckusic char *dumpmap; 485327Smckusic char *clrimap; 4910312Smckusick ino_t maxino; 5010312Smckusick time_t dumptime; 5111302Smckusick time_t dumpdate; 5211993Smckusick FILE *terminal; 534610Smckusick 54*56428Smckusick int 556846Smckusick main(argc, argv) 564700Smckusic int argc; 574700Smckusic char *argv[]; 584610Smckusick { 594610Smckusick register char *cp; 6011308Smckusick ino_t ino; 6137952Sbostic char *inputdev = _PATH_DEFTAPE; 6211308Smckusick char *symtbl = "./restoresymtable"; 6311993Smckusick char name[MAXPATHLEN]; 6439944Sbostic void onintr(); 654610Smckusick 6610312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 6711438Smckusick (void) signal(SIGINT, SIG_IGN); 6810312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 6911438Smckusick (void) signal(SIGTERM, SIG_IGN); 7011308Smckusick setlinebuf(stderr); 71*56428Smckusick if (argc < 2) 72*56428Smckusick usage(); 734610Smckusick argv++; 744610Smckusick argc -= 2; 7510202Smckusick command = '\0'; 764610Smckusick for (cp = *argv++; *cp; cp++) { 774610Smckusick switch (*cp) { 784610Smckusick case '-': 794610Smckusick break; 808302Smckusick case 'c': 818302Smckusick cvtflag++; 828302Smckusick break; 8310312Smckusick case 'd': 8410312Smckusick dflag++; 854610Smckusick break; 864610Smckusick case 'h': 8710202Smckusick hflag = 0; 884610Smckusick break; 894610Smckusick case 'm': 9010202Smckusick mflag = 0; 914610Smckusick break; 9234269Smckusick case 'N': 9334269Smckusick Nflag++; 9434269Smckusick break; 958374Smckusick case 'v': 968374Smckusick vflag++; 978374Smckusick break; 988374Smckusick case 'y': 998374Smckusick yflag++; 1008374Smckusick break; 10110312Smckusick case 'f': 10211400Smckusick if (argc < 1) { 10311400Smckusick fprintf(stderr, "missing device specifier\n"); 10411400Smckusick done(1); 10511400Smckusick } 10610312Smckusick inputdev = *argv++; 10710312Smckusick argc--; 10810312Smckusick break; 10917707Smckusick case 'b': 11017707Smckusick /* 11117707Smckusick * change default tape blocksize 11217707Smckusick */ 11318496Smckusick bflag++; 11417707Smckusick if (argc < 1) { 11517707Smckusick fprintf(stderr, "missing block size\n"); 11617707Smckusick done(1); 11717707Smckusick } 11817707Smckusick ntrec = atoi(*argv++); 11917707Smckusick if (ntrec <= 0) { 12017707Smckusick fprintf(stderr, "Block size must be a positive integer\n"); 12117707Smckusick done(1); 12217707Smckusick } 12317707Smckusick argc--; 12417707Smckusick break; 12510312Smckusick case 's': 12610312Smckusick /* 12710312Smckusick * dumpnum (skip to) for multifile dump tapes 12810312Smckusick */ 12911400Smckusick if (argc < 1) { 13011400Smckusick fprintf(stderr, "missing dump number\n"); 13111400Smckusick done(1); 13211400Smckusick } 13310312Smckusick dumpnum = atoi(*argv++); 13410312Smckusick if (dumpnum <= 0) { 13510312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 13610312Smckusick done(1); 13710312Smckusick } 13810312Smckusick argc--; 13910312Smckusick break; 1404610Smckusick case 't': 14110312Smckusick case 'R': 14210312Smckusick case 'r': 14310312Smckusick case 'x': 14411993Smckusick case 'i': 14510202Smckusick if (command != '\0') { 14610312Smckusick fprintf(stderr, 14711400Smckusick "%c and %c are mutually exclusive\n", 14811400Smckusick *cp, command); 149*56428Smckusick usage(); 15010202Smckusick } 15111400Smckusick command = *cp; 1524610Smckusick break; 1534610Smckusick default: 1544700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 155*56428Smckusick usage(); 1564610Smckusick } 1574610Smckusick } 15810202Smckusick if (command == '\0') { 15911993Smckusick fprintf(stderr, "must specify i, t, r, R, or x\n"); 160*56428Smckusick usage(); 16110202Smckusick } 16210312Smckusick setinput(inputdev); 16310202Smckusick if (argc == 0) { 16410312Smckusick argc = 1; 16510202Smckusick *--argv = "."; 16610202Smckusick } 16710312Smckusick switch (command) { 16811993Smckusick /* 16911993Smckusick * Interactive mode. 17011993Smckusick */ 17111993Smckusick case 'i': 17210312Smckusick setup(); 17311993Smckusick extractdirs(1); 17411438Smckusick initsymtable((char *)0); 17511993Smckusick runcmdshell(); 17610312Smckusick done(0); 17711993Smckusick /* 17811993Smckusick * Incremental restoration of a file system. 17911993Smckusick */ 18010312Smckusick case 'r': 18110312Smckusick setup(); 18210312Smckusick if (dumptime > 0) { 18311438Smckusick /* 18411438Smckusick * This is an incremental dump tape. 18511438Smckusick */ 18611438Smckusick vprintf(stdout, "Begin incremental restore\n"); 18710312Smckusick initsymtable(symtbl); 18811993Smckusick extractdirs(1); 18911438Smckusick removeoldleaves(); 19011438Smckusick vprintf(stdout, "Calculate node updates.\n"); 19111438Smckusick treescan(".", ROOTINO, nodeupdates); 19211438Smckusick findunreflinks(); 19311438Smckusick removeoldnodes(); 19410312Smckusick } else { 19511438Smckusick /* 19611438Smckusick * This is a level zero dump tape. 19711438Smckusick */ 19811438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 19911438Smckusick initsymtable((char *)0); 20011993Smckusick extractdirs(1); 20111438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 20211438Smckusick treescan(".", ROOTINO, nodeupdates); 2034843Smckusic } 20410312Smckusick createleaves(symtbl); 20510312Smckusick createlinks(); 20655880Smckusick setdirmodes(FORCE); 20710312Smckusick checkrestore(); 20810312Smckusick if (dflag) { 20910312Smckusick vprintf(stdout, "Verify the directory structure\n"); 21010312Smckusick treescan(".", ROOTINO, verifyfile); 2114610Smckusick } 21210312Smckusick dumpsymtable(symtbl, (long)1); 21310312Smckusick done(0); 21411993Smckusick /* 21511993Smckusick * Resume an incremental file system restoration. 21611993Smckusick */ 21710312Smckusick case 'R': 21810312Smckusick initsymtable(symtbl); 21911320Smckusick skipmaps(); 22011320Smckusick skipdirs(); 22110312Smckusick createleaves(symtbl); 22210312Smckusick createlinks(); 22355880Smckusick setdirmodes(FORCE); 22410312Smckusick checkrestore(); 22510312Smckusick dumpsymtable(symtbl, (long)1); 22610312Smckusick done(0); 22711993Smckusick /* 22811993Smckusick * List contents of tape. 22911993Smckusick */ 23011993Smckusick case 't': 23111993Smckusick setup(); 23211993Smckusick extractdirs(0); 23327264Smckusick initsymtable((char *)0); 23411993Smckusick while (argc--) { 23511993Smckusick canon(*argv++, name); 23611993Smckusick ino = dirlookup(name); 23711993Smckusick if (ino == 0) 23811993Smckusick continue; 23911993Smckusick treescan(name, ino, listfile); 24011993Smckusick } 24111993Smckusick done(0); 24211993Smckusick /* 24311993Smckusick * Batch extraction of tape contents. 24411993Smckusick */ 24511993Smckusick case 'x': 24611993Smckusick setup(); 24711993Smckusick extractdirs(1); 24811993Smckusick initsymtable((char *)0); 24911993Smckusick while (argc--) { 25011993Smckusick canon(*argv++, name); 25111993Smckusick ino = dirlookup(name); 25211993Smckusick if (ino == 0) 25311993Smckusick continue; 25411993Smckusick if (mflag) 25511993Smckusick pathcheck(name); 25611993Smckusick treescan(name, ino, addfile); 25711993Smckusick } 25811993Smckusick createfiles(); 25911993Smckusick createlinks(); 26055880Smckusick setdirmodes(0); 26111993Smckusick if (dflag) 26211993Smckusick checkrestore(); 26311993Smckusick done(0); 2644843Smckusic } 2654843Smckusic } 266*56428Smckusick 267*56428Smckusick usage() 268*56428Smckusick { 269*56428Smckusick (void)fprintf(stderr, "usage:\n%s%s%s%s%s", 270*56428Smckusick "\trestore tfhsvy [file file ...]\n", 271*56428Smckusick "\trestore xfhmsvy [file file ...]\n", 272*56428Smckusick "\trestore ifhmsvy\n", 273*56428Smckusick "\trestore rfsvy\n", 274*56428Smckusick "\trestore Rfsvy\n"); 275*56428Smckusick done(1); 276*56428Smckusick } 277