121167Sdist /* 236105Sbostic * Copyright (c) 1983 The Regents of the University of California. 336105Sbostic * All rights reserved. 436105Sbostic * 536105Sbostic * Redistribution and use in source and binary forms are permitted 636105Sbostic * provided that the above copyright notice and this paragraph are 736105Sbostic * duplicated in all such forms and that any documentation, 836105Sbostic * advertising materials, and other materials related to such 936105Sbostic * distribution and use acknowledge that the software was developed 1036105Sbostic * by the University of California, Berkeley. The name of the 1136105Sbostic * University may not be used to endorse or promote products derived 1236105Sbostic * from this software without specific prior written permission. 1336105Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1436105Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536105Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621167Sdist */ 1721167Sdist 186846Smckusick #ifndef lint 1921167Sdist char copyright[] = 2036105Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ 2121167Sdist All rights reserved.\n"; 2236105Sbostic #endif /* not lint */ 234610Smckusick 2421167Sdist #ifndef lint 25*37952Sbostic static char sccsid[] = "@(#)main.c 5.6 (Berkeley) 05/11/89"; 2636105Sbostic #endif /* not lint */ 2714564Ssam 2810312Smckusick /* 2910312Smckusick * Modified to recursively extract all files within a subtree 3010312Smckusick * (supressed by the h option) and recreate the heirarchical 3110312Smckusick * structure of that subtree and move extracted files to their 3210312Smckusick * proper homes (supressed by the m option). 3310312Smckusick * Includes the s (skip files) option for use with multiple 3410312Smckusick * dumps on a single tape. 354610Smckusick * 8/29/80 by Mike Litzkow 364610Smckusick * 3710312Smckusick * Modified to work on the new file system and to recover from 3810312Smckusick * tape read errors. 396846Smckusick * 1/19/82 by Kirk McKusick 406846Smckusick * 4111993Smckusick * Full incremental restore running entirely in user code and 4211993Smckusick * interactive tape browser. 4310312Smckusick * 1/19/83 by Kirk McKusick 444610Smckusick */ 454610Smckusick 4610312Smckusick #include "restore.h" 4723547Smckusick #include <protocols/dumprestore.h> 48*37952Sbostic #include <sys/signal.h> 49*37952Sbostic #include "pathnames.h" 504610Smckusick 5118496Smckusick int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 5234269Smckusick int hflag = 1, mflag = 1, Nflag = 0; 5310312Smckusick char command = '\0'; 5410312Smckusick long dumpnum = 1; 5511438Smckusick long volno = 0; 5618496Smckusick long ntrec; 575327Smckusic char *dumpmap; 585327Smckusic char *clrimap; 5910312Smckusick ino_t maxino; 6010312Smckusick time_t dumptime; 6111302Smckusick time_t dumpdate; 6211993Smckusick FILE *terminal; 634610Smckusick 646846Smckusick main(argc, argv) 654700Smckusic int argc; 664700Smckusic char *argv[]; 674610Smckusick { 684610Smckusick register char *cp; 6911308Smckusick ino_t ino; 70*37952Sbostic char *inputdev = _PATH_DEFTAPE; 7111308Smckusick char *symtbl = "./restoresymtable"; 7211993Smckusick char name[MAXPATHLEN]; 734700Smckusic int (*signal())(); 7410312Smckusick extern int onintr(); 754610Smckusick 7610312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 7711438Smckusick (void) signal(SIGINT, SIG_IGN); 7810312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 7911438Smckusick (void) signal(SIGTERM, SIG_IGN); 8011308Smckusick setlinebuf(stderr); 814610Smckusick if (argc < 2) { 824610Smckusick usage: 8311993Smckusick fprintf(stderr, "Usage:\n%s%s%s%s%s", 8411993Smckusick "\trestore tfhsvy [file file ...]\n", 8511993Smckusick "\trestore xfhmsvy [file file ...]\n", 8611993Smckusick "\trestore ifhmsvy\n", 8711993Smckusick "\trestore rfsvy\n", 8811993Smckusick "\trestore Rfsvy\n"); 894700Smckusic done(1); 904610Smckusick } 914610Smckusick argv++; 924610Smckusick argc -= 2; 9310202Smckusick command = '\0'; 944610Smckusick for (cp = *argv++; *cp; cp++) { 954610Smckusick switch (*cp) { 964610Smckusick case '-': 974610Smckusick break; 988302Smckusick case 'c': 998302Smckusick cvtflag++; 1008302Smckusick break; 10110312Smckusick case 'd': 10210312Smckusick dflag++; 1034610Smckusick break; 1044610Smckusick case 'h': 10510202Smckusick hflag = 0; 1064610Smckusick break; 1074610Smckusick case 'm': 10810202Smckusick mflag = 0; 1094610Smckusick break; 11034269Smckusick case 'N': 11134269Smckusick Nflag++; 11234269Smckusick break; 1138374Smckusick case 'v': 1148374Smckusick vflag++; 1158374Smckusick break; 1168374Smckusick case 'y': 1178374Smckusick yflag++; 1188374Smckusick break; 11910312Smckusick case 'f': 12011400Smckusick if (argc < 1) { 12111400Smckusick fprintf(stderr, "missing device specifier\n"); 12211400Smckusick done(1); 12311400Smckusick } 12410312Smckusick inputdev = *argv++; 12510312Smckusick argc--; 12610312Smckusick break; 12717707Smckusick case 'b': 12817707Smckusick /* 12917707Smckusick * change default tape blocksize 13017707Smckusick */ 13118496Smckusick bflag++; 13217707Smckusick if (argc < 1) { 13317707Smckusick fprintf(stderr, "missing block size\n"); 13417707Smckusick done(1); 13517707Smckusick } 13617707Smckusick ntrec = atoi(*argv++); 13717707Smckusick if (ntrec <= 0) { 13817707Smckusick fprintf(stderr, "Block size must be a positive integer\n"); 13917707Smckusick done(1); 14017707Smckusick } 14117707Smckusick argc--; 14217707Smckusick break; 14310312Smckusick case 's': 14410312Smckusick /* 14510312Smckusick * dumpnum (skip to) for multifile dump tapes 14610312Smckusick */ 14711400Smckusick if (argc < 1) { 14811400Smckusick fprintf(stderr, "missing dump number\n"); 14911400Smckusick done(1); 15011400Smckusick } 15110312Smckusick dumpnum = atoi(*argv++); 15210312Smckusick if (dumpnum <= 0) { 15310312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 15410312Smckusick done(1); 15510312Smckusick } 15610312Smckusick argc--; 15710312Smckusick break; 1584610Smckusick case 't': 15910312Smckusick case 'R': 16010312Smckusick case 'r': 16110312Smckusick case 'x': 16211993Smckusick case 'i': 16310202Smckusick if (command != '\0') { 16410312Smckusick fprintf(stderr, 16511400Smckusick "%c and %c are mutually exclusive\n", 16611400Smckusick *cp, command); 16710202Smckusick goto usage; 16810202Smckusick } 16911400Smckusick command = *cp; 1704610Smckusick break; 1714610Smckusick default: 1724700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1734610Smckusick goto usage; 1744610Smckusick } 1754610Smckusick } 17610202Smckusick if (command == '\0') { 17711993Smckusick fprintf(stderr, "must specify i, t, r, R, or x\n"); 17810202Smckusick goto usage; 17910202Smckusick } 18010312Smckusick setinput(inputdev); 18110202Smckusick if (argc == 0) { 18210312Smckusick argc = 1; 18310202Smckusick *--argv = "."; 18410202Smckusick } 18510312Smckusick switch (command) { 18611993Smckusick /* 18711993Smckusick * Interactive mode. 18811993Smckusick */ 18911993Smckusick case 'i': 19010312Smckusick setup(); 19111993Smckusick extractdirs(1); 19211438Smckusick initsymtable((char *)0); 19311993Smckusick runcmdshell(); 19410312Smckusick done(0); 19511993Smckusick /* 19611993Smckusick * Incremental restoration of a file system. 19711993Smckusick */ 19810312Smckusick case 'r': 19910312Smckusick setup(); 20010312Smckusick if (dumptime > 0) { 20111438Smckusick /* 20211438Smckusick * This is an incremental dump tape. 20311438Smckusick */ 20411438Smckusick vprintf(stdout, "Begin incremental restore\n"); 20510312Smckusick initsymtable(symtbl); 20611993Smckusick extractdirs(1); 20711438Smckusick removeoldleaves(); 20811438Smckusick vprintf(stdout, "Calculate node updates.\n"); 20911438Smckusick treescan(".", ROOTINO, nodeupdates); 21011438Smckusick findunreflinks(); 21111438Smckusick removeoldnodes(); 21210312Smckusick } else { 21311438Smckusick /* 21411438Smckusick * This is a level zero dump tape. 21511438Smckusick */ 21611438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 21711438Smckusick initsymtable((char *)0); 21811993Smckusick extractdirs(1); 21911438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 22011438Smckusick treescan(".", ROOTINO, nodeupdates); 2214843Smckusic } 22210312Smckusick createleaves(symtbl); 22310312Smckusick createlinks(); 22411993Smckusick setdirmodes(); 22510312Smckusick checkrestore(); 22610312Smckusick if (dflag) { 22710312Smckusick vprintf(stdout, "Verify the directory structure\n"); 22810312Smckusick treescan(".", ROOTINO, verifyfile); 2294610Smckusick } 23010312Smckusick dumpsymtable(symtbl, (long)1); 23110312Smckusick done(0); 23211993Smckusick /* 23311993Smckusick * Resume an incremental file system restoration. 23411993Smckusick */ 23510312Smckusick case 'R': 23610312Smckusick initsymtable(symtbl); 23711320Smckusick skipmaps(); 23811320Smckusick skipdirs(); 23910312Smckusick createleaves(symtbl); 24010312Smckusick createlinks(); 24111993Smckusick setdirmodes(); 24210312Smckusick checkrestore(); 24310312Smckusick dumpsymtable(symtbl, (long)1); 24410312Smckusick done(0); 24511993Smckusick /* 24611993Smckusick * List contents of tape. 24711993Smckusick */ 24811993Smckusick case 't': 24911993Smckusick setup(); 25011993Smckusick extractdirs(0); 25127264Smckusick initsymtable((char *)0); 25211993Smckusick while (argc--) { 25311993Smckusick canon(*argv++, name); 25411993Smckusick ino = dirlookup(name); 25511993Smckusick if (ino == 0) 25611993Smckusick continue; 25711993Smckusick treescan(name, ino, listfile); 25811993Smckusick } 25911993Smckusick done(0); 26011993Smckusick /* 26111993Smckusick * Batch extraction of tape contents. 26211993Smckusick */ 26311993Smckusick case 'x': 26411993Smckusick setup(); 26511993Smckusick extractdirs(1); 26611993Smckusick initsymtable((char *)0); 26711993Smckusick while (argc--) { 26811993Smckusick canon(*argv++, name); 26911993Smckusick ino = dirlookup(name); 27011993Smckusick if (ino == 0) 27111993Smckusick continue; 27211993Smckusick if (mflag) 27311993Smckusick pathcheck(name); 27411993Smckusick treescan(name, ino, addfile); 27511993Smckusick } 27611993Smckusick createfiles(); 27711993Smckusick createlinks(); 27811993Smckusick setdirmodes(); 27911993Smckusick if (dflag) 28011993Smckusick checkrestore(); 28111993Smckusick done(0); 2824843Smckusic } 2834843Smckusic } 284