121167Sdist /* 236105Sbostic * Copyright (c) 1983 The Regents of the University of California. 336105Sbostic * All rights reserved. 436105Sbostic * 5*42708Sbostic * %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*42708Sbostic static char sccsid[] = "@(#)main.c 5.8 (Berkeley) 06/01/90"; 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 546846Smckusick main(argc, argv) 554700Smckusic int argc; 564700Smckusic char *argv[]; 574610Smckusick { 584610Smckusick register char *cp; 5911308Smckusick ino_t ino; 6037952Sbostic char *inputdev = _PATH_DEFTAPE; 6111308Smckusick char *symtbl = "./restoresymtable"; 6211993Smckusick char name[MAXPATHLEN]; 6339944Sbostic void onintr(); 644610Smckusick 6510312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 6611438Smckusick (void) signal(SIGINT, SIG_IGN); 6710312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 6811438Smckusick (void) signal(SIGTERM, SIG_IGN); 6911308Smckusick setlinebuf(stderr); 704610Smckusick if (argc < 2) { 714610Smckusick usage: 7211993Smckusick fprintf(stderr, "Usage:\n%s%s%s%s%s", 7311993Smckusick "\trestore tfhsvy [file file ...]\n", 7411993Smckusick "\trestore xfhmsvy [file file ...]\n", 7511993Smckusick "\trestore ifhmsvy\n", 7611993Smckusick "\trestore rfsvy\n", 7711993Smckusick "\trestore Rfsvy\n"); 784700Smckusic done(1); 794610Smckusick } 804610Smckusick argv++; 814610Smckusick argc -= 2; 8210202Smckusick command = '\0'; 834610Smckusick for (cp = *argv++; *cp; cp++) { 844610Smckusick switch (*cp) { 854610Smckusick case '-': 864610Smckusick break; 878302Smckusick case 'c': 888302Smckusick cvtflag++; 898302Smckusick break; 9010312Smckusick case 'd': 9110312Smckusick dflag++; 924610Smckusick break; 934610Smckusick case 'h': 9410202Smckusick hflag = 0; 954610Smckusick break; 964610Smckusick case 'm': 9710202Smckusick mflag = 0; 984610Smckusick break; 9934269Smckusick case 'N': 10034269Smckusick Nflag++; 10134269Smckusick break; 1028374Smckusick case 'v': 1038374Smckusick vflag++; 1048374Smckusick break; 1058374Smckusick case 'y': 1068374Smckusick yflag++; 1078374Smckusick break; 10810312Smckusick case 'f': 10911400Smckusick if (argc < 1) { 11011400Smckusick fprintf(stderr, "missing device specifier\n"); 11111400Smckusick done(1); 11211400Smckusick } 11310312Smckusick inputdev = *argv++; 11410312Smckusick argc--; 11510312Smckusick break; 11617707Smckusick case 'b': 11717707Smckusick /* 11817707Smckusick * change default tape blocksize 11917707Smckusick */ 12018496Smckusick bflag++; 12117707Smckusick if (argc < 1) { 12217707Smckusick fprintf(stderr, "missing block size\n"); 12317707Smckusick done(1); 12417707Smckusick } 12517707Smckusick ntrec = atoi(*argv++); 12617707Smckusick if (ntrec <= 0) { 12717707Smckusick fprintf(stderr, "Block size must be a positive integer\n"); 12817707Smckusick done(1); 12917707Smckusick } 13017707Smckusick argc--; 13117707Smckusick break; 13210312Smckusick case 's': 13310312Smckusick /* 13410312Smckusick * dumpnum (skip to) for multifile dump tapes 13510312Smckusick */ 13611400Smckusick if (argc < 1) { 13711400Smckusick fprintf(stderr, "missing dump number\n"); 13811400Smckusick done(1); 13911400Smckusick } 14010312Smckusick dumpnum = atoi(*argv++); 14110312Smckusick if (dumpnum <= 0) { 14210312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 14310312Smckusick done(1); 14410312Smckusick } 14510312Smckusick argc--; 14610312Smckusick break; 1474610Smckusick case 't': 14810312Smckusick case 'R': 14910312Smckusick case 'r': 15010312Smckusick case 'x': 15111993Smckusick case 'i': 15210202Smckusick if (command != '\0') { 15310312Smckusick fprintf(stderr, 15411400Smckusick "%c and %c are mutually exclusive\n", 15511400Smckusick *cp, command); 15610202Smckusick goto usage; 15710202Smckusick } 15811400Smckusick command = *cp; 1594610Smckusick break; 1604610Smckusick default: 1614700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1624610Smckusick goto usage; 1634610Smckusick } 1644610Smckusick } 16510202Smckusick if (command == '\0') { 16611993Smckusick fprintf(stderr, "must specify i, t, r, R, or x\n"); 16710202Smckusick goto usage; 16810202Smckusick } 16910312Smckusick setinput(inputdev); 17010202Smckusick if (argc == 0) { 17110312Smckusick argc = 1; 17210202Smckusick *--argv = "."; 17310202Smckusick } 17410312Smckusick switch (command) { 17511993Smckusick /* 17611993Smckusick * Interactive mode. 17711993Smckusick */ 17811993Smckusick case 'i': 17910312Smckusick setup(); 18011993Smckusick extractdirs(1); 18111438Smckusick initsymtable((char *)0); 18211993Smckusick runcmdshell(); 18310312Smckusick done(0); 18411993Smckusick /* 18511993Smckusick * Incremental restoration of a file system. 18611993Smckusick */ 18710312Smckusick case 'r': 18810312Smckusick setup(); 18910312Smckusick if (dumptime > 0) { 19011438Smckusick /* 19111438Smckusick * This is an incremental dump tape. 19211438Smckusick */ 19311438Smckusick vprintf(stdout, "Begin incremental restore\n"); 19410312Smckusick initsymtable(symtbl); 19511993Smckusick extractdirs(1); 19611438Smckusick removeoldleaves(); 19711438Smckusick vprintf(stdout, "Calculate node updates.\n"); 19811438Smckusick treescan(".", ROOTINO, nodeupdates); 19911438Smckusick findunreflinks(); 20011438Smckusick removeoldnodes(); 20110312Smckusick } else { 20211438Smckusick /* 20311438Smckusick * This is a level zero dump tape. 20411438Smckusick */ 20511438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 20611438Smckusick initsymtable((char *)0); 20711993Smckusick extractdirs(1); 20811438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 20911438Smckusick treescan(".", ROOTINO, nodeupdates); 2104843Smckusic } 21110312Smckusick createleaves(symtbl); 21210312Smckusick createlinks(); 21311993Smckusick setdirmodes(); 21410312Smckusick checkrestore(); 21510312Smckusick if (dflag) { 21610312Smckusick vprintf(stdout, "Verify the directory structure\n"); 21710312Smckusick treescan(".", ROOTINO, verifyfile); 2184610Smckusick } 21910312Smckusick dumpsymtable(symtbl, (long)1); 22010312Smckusick done(0); 22111993Smckusick /* 22211993Smckusick * Resume an incremental file system restoration. 22311993Smckusick */ 22410312Smckusick case 'R': 22510312Smckusick initsymtable(symtbl); 22611320Smckusick skipmaps(); 22711320Smckusick skipdirs(); 22810312Smckusick createleaves(symtbl); 22910312Smckusick createlinks(); 23011993Smckusick setdirmodes(); 23110312Smckusick checkrestore(); 23210312Smckusick dumpsymtable(symtbl, (long)1); 23310312Smckusick done(0); 23411993Smckusick /* 23511993Smckusick * List contents of tape. 23611993Smckusick */ 23711993Smckusick case 't': 23811993Smckusick setup(); 23911993Smckusick extractdirs(0); 24027264Smckusick initsymtable((char *)0); 24111993Smckusick while (argc--) { 24211993Smckusick canon(*argv++, name); 24311993Smckusick ino = dirlookup(name); 24411993Smckusick if (ino == 0) 24511993Smckusick continue; 24611993Smckusick treescan(name, ino, listfile); 24711993Smckusick } 24811993Smckusick done(0); 24911993Smckusick /* 25011993Smckusick * Batch extraction of tape contents. 25111993Smckusick */ 25211993Smckusick case 'x': 25311993Smckusick setup(); 25411993Smckusick extractdirs(1); 25511993Smckusick initsymtable((char *)0); 25611993Smckusick while (argc--) { 25711993Smckusick canon(*argv++, name); 25811993Smckusick ino = dirlookup(name); 25911993Smckusick if (ino == 0) 26011993Smckusick continue; 26111993Smckusick if (mflag) 26211993Smckusick pathcheck(name); 26311993Smckusick treescan(name, ino, addfile); 26411993Smckusick } 26511993Smckusick createfiles(); 26611993Smckusick createlinks(); 26711993Smckusick setdirmodes(); 26811993Smckusick if (dflag) 26911993Smckusick checkrestore(); 27011993Smckusick done(0); 2714843Smckusic } 2724843Smckusic } 273