121167Sdist /* 2*36105Sbostic * Copyright (c) 1983 The Regents of the University of California. 3*36105Sbostic * All rights reserved. 4*36105Sbostic * 5*36105Sbostic * Redistribution and use in source and binary forms are permitted 6*36105Sbostic * provided that the above copyright notice and this paragraph are 7*36105Sbostic * duplicated in all such forms and that any documentation, 8*36105Sbostic * advertising materials, and other materials related to such 9*36105Sbostic * distribution and use acknowledge that the software was developed 10*36105Sbostic * by the University of California, Berkeley. The name of the 11*36105Sbostic * University may not be used to endorse or promote products derived 12*36105Sbostic * from this software without specific prior written permission. 13*36105Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*36105Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*36105Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621167Sdist */ 1721167Sdist 186846Smckusick #ifndef lint 1921167Sdist char copyright[] = 20*36105Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ 2121167Sdist All rights reserved.\n"; 22*36105Sbostic #endif /* not lint */ 234610Smckusick 2421167Sdist #ifndef lint 25*36105Sbostic static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 10/24/88"; 26*36105Sbostic #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> 484610Smckusick #include <signal.h> 494610Smckusick 5018496Smckusick int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 5134269Smckusick int hflag = 1, mflag = 1, Nflag = 0; 5210312Smckusick char command = '\0'; 5310312Smckusick long dumpnum = 1; 5411438Smckusick long volno = 0; 5518496Smckusick long ntrec; 565327Smckusic char *dumpmap; 575327Smckusic char *clrimap; 5810312Smckusick ino_t maxino; 5910312Smckusick time_t dumptime; 6011302Smckusick time_t dumpdate; 6111993Smckusick FILE *terminal; 624610Smckusick 636846Smckusick main(argc, argv) 644700Smckusic int argc; 654700Smckusic char *argv[]; 664610Smckusick { 674610Smckusick register char *cp; 6811308Smckusick ino_t ino; 6910312Smckusick char *inputdev = "/dev/rmt8"; 7011308Smckusick char *symtbl = "./restoresymtable"; 7111993Smckusick char name[MAXPATHLEN]; 724700Smckusic int (*signal())(); 7310312Smckusick extern int onintr(); 744610Smckusick 7510312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 7611438Smckusick (void) signal(SIGINT, SIG_IGN); 7710312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 7811438Smckusick (void) signal(SIGTERM, SIG_IGN); 7911308Smckusick setlinebuf(stderr); 804610Smckusick if (argc < 2) { 814610Smckusick usage: 8211993Smckusick fprintf(stderr, "Usage:\n%s%s%s%s%s", 8311993Smckusick "\trestore tfhsvy [file file ...]\n", 8411993Smckusick "\trestore xfhmsvy [file file ...]\n", 8511993Smckusick "\trestore ifhmsvy\n", 8611993Smckusick "\trestore rfsvy\n", 8711993Smckusick "\trestore Rfsvy\n"); 884700Smckusic done(1); 894610Smckusick } 904610Smckusick argv++; 914610Smckusick argc -= 2; 9210202Smckusick command = '\0'; 934610Smckusick for (cp = *argv++; *cp; cp++) { 944610Smckusick switch (*cp) { 954610Smckusick case '-': 964610Smckusick break; 978302Smckusick case 'c': 988302Smckusick cvtflag++; 998302Smckusick break; 10010312Smckusick case 'd': 10110312Smckusick dflag++; 1024610Smckusick break; 1034610Smckusick case 'h': 10410202Smckusick hflag = 0; 1054610Smckusick break; 1064610Smckusick case 'm': 10710202Smckusick mflag = 0; 1084610Smckusick break; 10934269Smckusick case 'N': 11034269Smckusick Nflag++; 11134269Smckusick break; 1128374Smckusick case 'v': 1138374Smckusick vflag++; 1148374Smckusick break; 1158374Smckusick case 'y': 1168374Smckusick yflag++; 1178374Smckusick break; 11810312Smckusick case 'f': 11911400Smckusick if (argc < 1) { 12011400Smckusick fprintf(stderr, "missing device specifier\n"); 12111400Smckusick done(1); 12211400Smckusick } 12310312Smckusick inputdev = *argv++; 12410312Smckusick argc--; 12510312Smckusick break; 12617707Smckusick case 'b': 12717707Smckusick /* 12817707Smckusick * change default tape blocksize 12917707Smckusick */ 13018496Smckusick bflag++; 13117707Smckusick if (argc < 1) { 13217707Smckusick fprintf(stderr, "missing block size\n"); 13317707Smckusick done(1); 13417707Smckusick } 13517707Smckusick ntrec = atoi(*argv++); 13617707Smckusick if (ntrec <= 0) { 13717707Smckusick fprintf(stderr, "Block size must be a positive integer\n"); 13817707Smckusick done(1); 13917707Smckusick } 14017707Smckusick argc--; 14117707Smckusick break; 14210312Smckusick case 's': 14310312Smckusick /* 14410312Smckusick * dumpnum (skip to) for multifile dump tapes 14510312Smckusick */ 14611400Smckusick if (argc < 1) { 14711400Smckusick fprintf(stderr, "missing dump number\n"); 14811400Smckusick done(1); 14911400Smckusick } 15010312Smckusick dumpnum = atoi(*argv++); 15110312Smckusick if (dumpnum <= 0) { 15210312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 15310312Smckusick done(1); 15410312Smckusick } 15510312Smckusick argc--; 15610312Smckusick break; 1574610Smckusick case 't': 15810312Smckusick case 'R': 15910312Smckusick case 'r': 16010312Smckusick case 'x': 16111993Smckusick case 'i': 16210202Smckusick if (command != '\0') { 16310312Smckusick fprintf(stderr, 16411400Smckusick "%c and %c are mutually exclusive\n", 16511400Smckusick *cp, command); 16610202Smckusick goto usage; 16710202Smckusick } 16811400Smckusick command = *cp; 1694610Smckusick break; 1704610Smckusick default: 1714700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1724610Smckusick goto usage; 1734610Smckusick } 1744610Smckusick } 17510202Smckusick if (command == '\0') { 17611993Smckusick fprintf(stderr, "must specify i, t, r, R, or x\n"); 17710202Smckusick goto usage; 17810202Smckusick } 17910312Smckusick setinput(inputdev); 18010202Smckusick if (argc == 0) { 18110312Smckusick argc = 1; 18210202Smckusick *--argv = "."; 18310202Smckusick } 18410312Smckusick switch (command) { 18511993Smckusick /* 18611993Smckusick * Interactive mode. 18711993Smckusick */ 18811993Smckusick case 'i': 18910312Smckusick setup(); 19011993Smckusick extractdirs(1); 19111438Smckusick initsymtable((char *)0); 19211993Smckusick runcmdshell(); 19310312Smckusick done(0); 19411993Smckusick /* 19511993Smckusick * Incremental restoration of a file system. 19611993Smckusick */ 19710312Smckusick case 'r': 19810312Smckusick setup(); 19910312Smckusick if (dumptime > 0) { 20011438Smckusick /* 20111438Smckusick * This is an incremental dump tape. 20211438Smckusick */ 20311438Smckusick vprintf(stdout, "Begin incremental restore\n"); 20410312Smckusick initsymtable(symtbl); 20511993Smckusick extractdirs(1); 20611438Smckusick removeoldleaves(); 20711438Smckusick vprintf(stdout, "Calculate node updates.\n"); 20811438Smckusick treescan(".", ROOTINO, nodeupdates); 20911438Smckusick findunreflinks(); 21011438Smckusick removeoldnodes(); 21110312Smckusick } else { 21211438Smckusick /* 21311438Smckusick * This is a level zero dump tape. 21411438Smckusick */ 21511438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 21611438Smckusick initsymtable((char *)0); 21711993Smckusick extractdirs(1); 21811438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 21911438Smckusick treescan(".", ROOTINO, nodeupdates); 2204843Smckusic } 22110312Smckusick createleaves(symtbl); 22210312Smckusick createlinks(); 22311993Smckusick setdirmodes(); 22410312Smckusick checkrestore(); 22510312Smckusick if (dflag) { 22610312Smckusick vprintf(stdout, "Verify the directory structure\n"); 22710312Smckusick treescan(".", ROOTINO, verifyfile); 2284610Smckusick } 22910312Smckusick dumpsymtable(symtbl, (long)1); 23010312Smckusick done(0); 23111993Smckusick /* 23211993Smckusick * Resume an incremental file system restoration. 23311993Smckusick */ 23410312Smckusick case 'R': 23510312Smckusick initsymtable(symtbl); 23611320Smckusick skipmaps(); 23711320Smckusick skipdirs(); 23810312Smckusick createleaves(symtbl); 23910312Smckusick createlinks(); 24011993Smckusick setdirmodes(); 24110312Smckusick checkrestore(); 24210312Smckusick dumpsymtable(symtbl, (long)1); 24310312Smckusick done(0); 24411993Smckusick /* 24511993Smckusick * List contents of tape. 24611993Smckusick */ 24711993Smckusick case 't': 24811993Smckusick setup(); 24911993Smckusick extractdirs(0); 25027264Smckusick initsymtable((char *)0); 25111993Smckusick while (argc--) { 25211993Smckusick canon(*argv++, name); 25311993Smckusick ino = dirlookup(name); 25411993Smckusick if (ino == 0) 25511993Smckusick continue; 25611993Smckusick treescan(name, ino, listfile); 25711993Smckusick } 25811993Smckusick done(0); 25911993Smckusick /* 26011993Smckusick * Batch extraction of tape contents. 26111993Smckusick */ 26211993Smckusick case 'x': 26311993Smckusick setup(); 26411993Smckusick extractdirs(1); 26511993Smckusick initsymtable((char *)0); 26611993Smckusick while (argc--) { 26711993Smckusick canon(*argv++, name); 26811993Smckusick ino = dirlookup(name); 26911993Smckusick if (ino == 0) 27011993Smckusick continue; 27111993Smckusick if (mflag) 27211993Smckusick pathcheck(name); 27311993Smckusick treescan(name, ino, addfile); 27411993Smckusick } 27511993Smckusick createfiles(); 27611993Smckusick createlinks(); 27711993Smckusick setdirmodes(); 27811993Smckusick if (dflag) 27911993Smckusick checkrestore(); 28011993Smckusick done(0); 2814843Smckusic } 2824843Smckusic } 283