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*27264Smckusick static char sccsid[] = "@(#)main.c 5.3 (Berkeley) 04/23/86"; 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; 4010312Smckusick int hflag = 1, mflag = 1; 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; 988374Smckusick case 'v': 998374Smckusick vflag++; 1008374Smckusick break; 1018374Smckusick case 'y': 1028374Smckusick yflag++; 1038374Smckusick break; 10410312Smckusick case 'f': 10511400Smckusick if (argc < 1) { 10611400Smckusick fprintf(stderr, "missing device specifier\n"); 10711400Smckusick done(1); 10811400Smckusick } 10910312Smckusick inputdev = *argv++; 11010312Smckusick argc--; 11110312Smckusick break; 11217707Smckusick case 'b': 11317707Smckusick /* 11417707Smckusick * change default tape blocksize 11517707Smckusick */ 11618496Smckusick bflag++; 11717707Smckusick if (argc < 1) { 11817707Smckusick fprintf(stderr, "missing block size\n"); 11917707Smckusick done(1); 12017707Smckusick } 12117707Smckusick ntrec = atoi(*argv++); 12217707Smckusick if (ntrec <= 0) { 12317707Smckusick fprintf(stderr, "Block size must be a positive integer\n"); 12417707Smckusick done(1); 12517707Smckusick } 12617707Smckusick argc--; 12717707Smckusick break; 12810312Smckusick case 's': 12910312Smckusick /* 13010312Smckusick * dumpnum (skip to) for multifile dump tapes 13110312Smckusick */ 13211400Smckusick if (argc < 1) { 13311400Smckusick fprintf(stderr, "missing dump number\n"); 13411400Smckusick done(1); 13511400Smckusick } 13610312Smckusick dumpnum = atoi(*argv++); 13710312Smckusick if (dumpnum <= 0) { 13810312Smckusick fprintf(stderr, "Dump number must be a positive integer\n"); 13910312Smckusick done(1); 14010312Smckusick } 14110312Smckusick argc--; 14210312Smckusick break; 1434610Smckusick case 't': 14410312Smckusick case 'R': 14510312Smckusick case 'r': 14610312Smckusick case 'x': 14711993Smckusick case 'i': 14810202Smckusick if (command != '\0') { 14910312Smckusick fprintf(stderr, 15011400Smckusick "%c and %c are mutually exclusive\n", 15111400Smckusick *cp, command); 15210202Smckusick goto usage; 15310202Smckusick } 15411400Smckusick command = *cp; 1554610Smckusick break; 1564610Smckusick default: 1574700Smckusic fprintf(stderr, "Bad key character %c\n", *cp); 1584610Smckusick goto usage; 1594610Smckusick } 1604610Smckusick } 16110202Smckusick if (command == '\0') { 16211993Smckusick fprintf(stderr, "must specify i, t, r, R, or x\n"); 16310202Smckusick goto usage; 16410202Smckusick } 16510312Smckusick setinput(inputdev); 16610202Smckusick if (argc == 0) { 16710312Smckusick argc = 1; 16810202Smckusick *--argv = "."; 16910202Smckusick } 17010312Smckusick switch (command) { 17111993Smckusick /* 17211993Smckusick * Interactive mode. 17311993Smckusick */ 17411993Smckusick case 'i': 17510312Smckusick setup(); 17611993Smckusick extractdirs(1); 17711438Smckusick initsymtable((char *)0); 17811993Smckusick runcmdshell(); 17910312Smckusick done(0); 18011993Smckusick /* 18111993Smckusick * Incremental restoration of a file system. 18211993Smckusick */ 18310312Smckusick case 'r': 18410312Smckusick setup(); 18510312Smckusick if (dumptime > 0) { 18611438Smckusick /* 18711438Smckusick * This is an incremental dump tape. 18811438Smckusick */ 18911438Smckusick vprintf(stdout, "Begin incremental restore\n"); 19010312Smckusick initsymtable(symtbl); 19111993Smckusick extractdirs(1); 19211438Smckusick removeoldleaves(); 19311438Smckusick vprintf(stdout, "Calculate node updates.\n"); 19411438Smckusick treescan(".", ROOTINO, nodeupdates); 19511438Smckusick findunreflinks(); 19611438Smckusick removeoldnodes(); 19710312Smckusick } else { 19811438Smckusick /* 19911438Smckusick * This is a level zero dump tape. 20011438Smckusick */ 20111438Smckusick vprintf(stdout, "Begin level 0 restore\n"); 20211438Smckusick initsymtable((char *)0); 20311993Smckusick extractdirs(1); 20411438Smckusick vprintf(stdout, "Calculate extraction list.\n"); 20511438Smckusick treescan(".", ROOTINO, nodeupdates); 2064843Smckusic } 20710312Smckusick createleaves(symtbl); 20810312Smckusick createlinks(); 20911993Smckusick setdirmodes(); 21010312Smckusick checkrestore(); 21110312Smckusick if (dflag) { 21210312Smckusick vprintf(stdout, "Verify the directory structure\n"); 21310312Smckusick treescan(".", ROOTINO, verifyfile); 2144610Smckusick } 21510312Smckusick dumpsymtable(symtbl, (long)1); 21610312Smckusick done(0); 21711993Smckusick /* 21811993Smckusick * Resume an incremental file system restoration. 21911993Smckusick */ 22010312Smckusick case 'R': 22110312Smckusick initsymtable(symtbl); 22211320Smckusick skipmaps(); 22311320Smckusick skipdirs(); 22410312Smckusick createleaves(symtbl); 22510312Smckusick createlinks(); 22611993Smckusick setdirmodes(); 22710312Smckusick checkrestore(); 22810312Smckusick dumpsymtable(symtbl, (long)1); 22910312Smckusick done(0); 23011993Smckusick /* 23111993Smckusick * List contents of tape. 23211993Smckusick */ 23311993Smckusick case 't': 23411993Smckusick setup(); 23511993Smckusick extractdirs(0); 236*27264Smckusick initsymtable((char *)0); 23711993Smckusick while (argc--) { 23811993Smckusick canon(*argv++, name); 23911993Smckusick ino = dirlookup(name); 24011993Smckusick if (ino == 0) 24111993Smckusick continue; 24211993Smckusick treescan(name, ino, listfile); 24311993Smckusick } 24411993Smckusick done(0); 24511993Smckusick /* 24611993Smckusick * Batch extraction of tape contents. 24711993Smckusick */ 24811993Smckusick case 'x': 24911993Smckusick setup(); 25011993Smckusick extractdirs(1); 25111993Smckusick initsymtable((char *)0); 25211993Smckusick while (argc--) { 25311993Smckusick canon(*argv++, name); 25411993Smckusick ino = dirlookup(name); 25511993Smckusick if (ino == 0) 25611993Smckusick continue; 25711993Smckusick if (mflag) 25811993Smckusick pathcheck(name); 25911993Smckusick treescan(name, ino, addfile); 26011993Smckusick } 26111993Smckusick createfiles(); 26211993Smckusick createlinks(); 26311993Smckusick setdirmodes(); 26411993Smckusick if (dflag) 26511993Smckusick checkrestore(); 26611993Smckusick done(0); 2674843Smckusic } 2684843Smckusic } 269