121167Sdist /* 221167Sdist * Copyright (c) 1983 Regents of the University of California. 321167Sdist * All rights reserved. The Berkeley software License Agreement 421167Sdist * specifies the terms and conditions for redistribution. 521167Sdist */ 621167Sdist 76846Smckusick #ifndef lint 821167Sdist char copyright[] = 921167Sdist "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 1021167Sdist All rights reserved.\n"; 1121167Sdist #endif not lint 124610Smckusick 1321167Sdist #ifndef lint 14*34269Smckusick static char sccsid[] = "@(#)main.c 5.4 (Berkeley) 05/13/88"; 1521167Sdist #endif not lint 1614564Ssam 1710312Smckusick /* 1810312Smckusick * Modified to recursively extract all files within a subtree 1910312Smckusick * (supressed by the h option) and recreate the heirarchical 2010312Smckusick * structure of that subtree and move extracted files to their 2110312Smckusick * proper homes (supressed by the m option). 2210312Smckusick * Includes the s (skip files) option for use with multiple 2310312Smckusick * dumps on a single tape. 244610Smckusick * 8/29/80 by Mike Litzkow 254610Smckusick * 2610312Smckusick * Modified to work on the new file system and to recover from 2710312Smckusick * tape read errors. 286846Smckusick * 1/19/82 by Kirk McKusick 296846Smckusick * 3011993Smckusick * Full incremental restore running entirely in user code and 3111993Smckusick * interactive tape browser. 3210312Smckusick * 1/19/83 by Kirk McKusick 334610Smckusick */ 344610Smckusick 3510312Smckusick #include "restore.h" 3623547Smckusick #include <protocols/dumprestore.h> 374610Smckusick #include <signal.h> 384610Smckusick 3918496Smckusick int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 40*34269Smckusick int hflag = 1, mflag = 1, Nflag = 0; 4110312Smckusick char command = '\0'; 4210312Smckusick long dumpnum = 1; 4311438Smckusick long volno = 0; 4418496Smckusick long ntrec; 455327Smckusic char *dumpmap; 465327Smckusic char *clrimap; 4710312Smckusick ino_t maxino; 4810312Smckusick time_t dumptime; 4911302Smckusick time_t dumpdate; 5011993Smckusick FILE *terminal; 514610Smckusick 526846Smckusick main(argc, argv) 534700Smckusic int argc; 544700Smckusic char *argv[]; 554610Smckusick { 564610Smckusick register char *cp; 5711308Smckusick ino_t ino; 5810312Smckusick char *inputdev = "/dev/rmt8"; 5911308Smckusick char *symtbl = "./restoresymtable"; 6011993Smckusick char name[MAXPATHLEN]; 614700Smckusic int (*signal())(); 6210312Smckusick extern int onintr(); 634610Smckusick 6410312Smckusick if (signal(SIGINT, onintr) == SIG_IGN) 6511438Smckusick (void) signal(SIGINT, SIG_IGN); 6610312Smckusick if (signal(SIGTERM, onintr) == SIG_IGN) 6711438Smckusick (void) signal(SIGTERM, SIG_IGN); 6811308Smckusick setlinebuf(stderr); 694610Smckusick if (argc < 2) { 704610Smckusick usage: 7111993Smckusick fprintf(stderr, "Usage:\n%s%s%s%s%s", 7211993Smckusick "\trestore tfhsvy [file file ...]\n", 7311993Smckusick "\trestore xfhmsvy [file file ...]\n", 7411993Smckusick "\trestore ifhmsvy\n", 7511993Smckusick "\trestore rfsvy\n", 7611993Smckusick "\trestore Rfsvy\n"); 774700Smckusic done(1); 784610Smckusick } 794610Smckusick argv++; 804610Smckusick argc -= 2; 8110202Smckusick command = '\0'; 824610Smckusick for (cp = *argv++; *cp; cp++) { 834610Smckusick switch (*cp) { 844610Smckusick case '-': 854610Smckusick break; 868302Smckusick case 'c': 878302Smckusick cvtflag++; 888302Smckusick break; 8910312Smckusick case 'd': 9010312Smckusick dflag++; 914610Smckusick break; 924610Smckusick case 'h': 9310202Smckusick hflag = 0; 944610Smckusick break; 954610Smckusick case 'm': 9610202Smckusick mflag = 0; 974610Smckusick break; 98*34269Smckusick case 'N': 99*34269Smckusick Nflag++; 100*34269Smckusick break; 1018374Smckusick case 'v': 1028374Smckusick vflag++; 1038374Smckusick break; 1048374Smckusick case 'y': 1058374Smckusick yflag++; 1068374Smckusick break; 10710312Smckusick case 'f': 10811400Smckusick if (argc < 1) { 10911400Smckusick fprintf(stderr, "missing device specifier\n"); 11011400Smckusick done(1); 11111400Smckusick } 11210312Smckusick inputdev = *argv++; 11310312Smckusick argc--; 11410312Smckusick break; 11517707Smckusick case 'b': 11617707Smckusick /* 11717707Smckusick * change default tape blocksize 11817707Smckusick */ 11918496Smckusick bflag++; 12017707Smckusick if (argc < 1) { 12117707Smckusick fprintf(stderr, "missing block size\n"); 12217707Smckusick done(1); 12317707Smckusick } 12417707Smckusick ntrec = atoi(*argv++); 12517707Smckusick if (ntrec <= 0) { 12617707Smckusick fprintf(stderr, "Block size must be a positive integer\n"); 12717707Smckusick done(1); 12817707Smckusick } 12917707Smckusick argc--; 13017707Smckusick break; 13110312Smckusick case 's': 13210312Smckusick /* 13310312Smckusick * dumpnum (skip to) for multifile dump tapes 13410312Smckusick */ 13511400Smckusick if (argc < 1) { 13611400Smckusick fprintf(stderr, "missing dump number\n"); 13711400Smckusick done(1); 13811400Smckusick } 13910312Smckusick dumpnum = atoi(*argv++); 14010312Smckusick if (dumpnum <= 0) { 14110312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 14210312Smckusick done(1); 14310312Smckusick } 14410312Smckusick argc--; 14510312Smckusick break; 1464610Smckusick case 't': 14710312Smckusick case 'R': 14810312Smckusick case 'r': 14910312Smckusick case 'x': 15011993Smckusick case 'i': 15110202Smckusick if (command != '\0') { 15210312Smckusick fprintf(stderr, 15311400Smckusick "%c and %c are mutually exclusive\n", 15411400Smckusick *cp, command); 15510202Smckusick goto usage; 15610202Smckusick } 15711400Smckusick command = *cp; 1584610Smckusick break; 1594610Smckusick default: 1604700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1614610Smckusick goto usage; 1624610Smckusick } 1634610Smckusick } 16410202Smckusick if (command == '\0') { 16511993Smckusick fprintf(stderr, "must specify i, t, r, R, or x\n"); 16610202Smckusick goto usage; 16710202Smckusick } 16810312Smckusick setinput(inputdev); 16910202Smckusick if (argc == 0) { 17010312Smckusick argc = 1; 17110202Smckusick *--argv = "."; 17210202Smckusick } 17310312Smckusick switch (command) { 17411993Smckusick /* 17511993Smckusick * Interactive mode. 17611993Smckusick */ 17711993Smckusick case 'i': 17810312Smckusick setup(); 17911993Smckusick extractdirs(1); 18011438Smckusick initsymtable((char *)0); 18111993Smckusick runcmdshell(); 18210312Smckusick done(0); 18311993Smckusick /* 18411993Smckusick * Incremental restoration of a file system. 18511993Smckusick */ 18610312Smckusick case 'r': 18710312Smckusick setup(); 18810312Smckusick if (dumptime > 0) { 18911438Smckusick /* 19011438Smckusick * This is an incremental dump tape. 19111438Smckusick */ 19211438Smckusick vprintf(stdout, "Begin incremental restore\n"); 19310312Smckusick initsymtable(symtbl); 19411993Smckusick extractdirs(1); 19511438Smckusick removeoldleaves(); 19611438Smckusick vprintf(stdout, "Calculate node updates.\n"); 19711438Smckusick treescan(".", ROOTINO, nodeupdates); 19811438Smckusick findunreflinks(); 19911438Smckusick removeoldnodes(); 20010312Smckusick } else { 20111438Smckusick /* 20211438Smckusick * This is a level zero dump tape. 20311438Smckusick */ 20411438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 20511438Smckusick initsymtable((char *)0); 20611993Smckusick extractdirs(1); 20711438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 20811438Smckusick treescan(".", ROOTINO, nodeupdates); 2094843Smckusic } 21010312Smckusick createleaves(symtbl); 21110312Smckusick createlinks(); 21211993Smckusick setdirmodes(); 21310312Smckusick checkrestore(); 21410312Smckusick if (dflag) { 21510312Smckusick vprintf(stdout, "Verify the directory structure\n"); 21610312Smckusick treescan(".", ROOTINO, verifyfile); 2174610Smckusick } 21810312Smckusick dumpsymtable(symtbl, (long)1); 21910312Smckusick done(0); 22011993Smckusick /* 22111993Smckusick * Resume an incremental file system restoration. 22211993Smckusick */ 22310312Smckusick case 'R': 22410312Smckusick initsymtable(symtbl); 22511320Smckusick skipmaps(); 22611320Smckusick skipdirs(); 22710312Smckusick createleaves(symtbl); 22810312Smckusick createlinks(); 22911993Smckusick setdirmodes(); 23010312Smckusick checkrestore(); 23110312Smckusick dumpsymtable(symtbl, (long)1); 23210312Smckusick done(0); 23311993Smckusick /* 23411993Smckusick * List contents of tape. 23511993Smckusick */ 23611993Smckusick case 't': 23711993Smckusick setup(); 23811993Smckusick extractdirs(0); 23927264Smckusick initsymtable((char *)0); 24011993Smckusick while (argc--) { 24111993Smckusick canon(*argv++, name); 24211993Smckusick ino = dirlookup(name); 24311993Smckusick if (ino == 0) 24411993Smckusick continue; 24511993Smckusick treescan(name, ino, listfile); 24611993Smckusick } 24711993Smckusick done(0); 24811993Smckusick /* 24911993Smckusick * Batch extraction of tape contents. 25011993Smckusick */ 25111993Smckusick case 'x': 25211993Smckusick setup(); 25311993Smckusick extractdirs(1); 25411993Smckusick initsymtable((char *)0); 25511993Smckusick while (argc--) { 25611993Smckusick canon(*argv++, name); 25711993Smckusick ino = dirlookup(name); 25811993Smckusick if (ino == 0) 25911993Smckusick continue; 26011993Smckusick if (mflag) 26111993Smckusick pathcheck(name); 26211993Smckusick treescan(name, ino, addfile); 26311993Smckusick } 26411993Smckusick createfiles(); 26511993Smckusick createlinks(); 26611993Smckusick setdirmodes(); 26711993Smckusick if (dflag) 26811993Smckusick checkrestore(); 26911993Smckusick done(0); 2704843Smckusic } 2714843Smckusic } 272