1 /* 2 * Copyright (c) 1983 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)main.c 5.8 (Berkeley) 06/01/90"; 16 #endif /* not lint */ 17 18 /* 19 * Modified to recursively extract all files within a subtree 20 * (supressed by the h option) and recreate the heirarchical 21 * structure of that subtree and move extracted files to their 22 * proper homes (supressed by the m option). 23 * Includes the s (skip files) option for use with multiple 24 * dumps on a single tape. 25 * 8/29/80 by Mike Litzkow 26 * 27 * Modified to work on the new file system and to recover from 28 * tape read errors. 29 * 1/19/82 by Kirk McKusick 30 * 31 * Full incremental restore running entirely in user code and 32 * interactive tape browser. 33 * 1/19/83 by Kirk McKusick 34 */ 35 36 #include "restore.h" 37 #include <protocols/dumprestore.h> 38 #include <sys/signal.h> 39 #include "pathnames.h" 40 41 int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; 42 int hflag = 1, mflag = 1, Nflag = 0; 43 char command = '\0'; 44 long dumpnum = 1; 45 long volno = 0; 46 long ntrec; 47 char *dumpmap; 48 char *clrimap; 49 ino_t maxino; 50 time_t dumptime; 51 time_t dumpdate; 52 FILE *terminal; 53 54 main(argc, argv) 55 int argc; 56 char *argv[]; 57 { 58 register char *cp; 59 ino_t ino; 60 char *inputdev = _PATH_DEFTAPE; 61 char *symtbl = "./restoresymtable"; 62 char name[MAXPATHLEN]; 63 void onintr(); 64 65 if (signal(SIGINT, onintr) == SIG_IGN) 66 (void) signal(SIGINT, SIG_IGN); 67 if (signal(SIGTERM, onintr) == SIG_IGN) 68 (void) signal(SIGTERM, SIG_IGN); 69 setlinebuf(stderr); 70 if (argc < 2) { 71 usage: 72 fprintf(stderr, "Usage:\n%s%s%s%s%s", 73 "\trestore tfhsvy [file file ...]\n", 74 "\trestore xfhmsvy [file file ...]\n", 75 "\trestore ifhmsvy\n", 76 "\trestore rfsvy\n", 77 "\trestore Rfsvy\n"); 78 done(1); 79 } 80 argv++; 81 argc -= 2; 82 command = '\0'; 83 for (cp = *argv++; *cp; cp++) { 84 switch (*cp) { 85 case '-': 86 break; 87 case 'c': 88 cvtflag++; 89 break; 90 case 'd': 91 dflag++; 92 break; 93 case 'h': 94 hflag = 0; 95 break; 96 case 'm': 97 mflag = 0; 98 break; 99 case 'N': 100 Nflag++; 101 break; 102 case 'v': 103 vflag++; 104 break; 105 case 'y': 106 yflag++; 107 break; 108 case 'f': 109 if (argc < 1) { 110 fprintf(stderr, "missing device specifier\n"); 111 done(1); 112 } 113 inputdev = *argv++; 114 argc--; 115 break; 116 case 'b': 117 /* 118 * change default tape blocksize 119 */ 120 bflag++; 121 if (argc < 1) { 122 fprintf(stderr, "missing block size\n"); 123 done(1); 124 } 125 ntrec = atoi(*argv++); 126 if (ntrec <= 0) { 127 fprintf(stderr, "Block size must be a positive integer\n"); 128 done(1); 129 } 130 argc--; 131 break; 132 case 's': 133 /* 134 * dumpnum (skip to) for multifile dump tapes 135 */ 136 if (argc < 1) { 137 fprintf(stderr, "missing dump number\n"); 138 done(1); 139 } 140 dumpnum = atoi(*argv++); 141 if (dumpnum <= 0) { 142 fprintf(stderr, "Dump number must be a positive integer\n"); 143 done(1); 144 } 145 argc--; 146 break; 147 case 't': 148 case 'R': 149 case 'r': 150 case 'x': 151 case 'i': 152 if (command != '\0') { 153 fprintf(stderr, 154 "%c and %c are mutually exclusive\n", 155 *cp, command); 156 goto usage; 157 } 158 command = *cp; 159 break; 160 default: 161 fprintf(stderr, "Bad key character %c\n", *cp); 162 goto usage; 163 } 164 } 165 if (command == '\0') { 166 fprintf(stderr, "must specify i, t, r, R, or x\n"); 167 goto usage; 168 } 169 setinput(inputdev); 170 if (argc == 0) { 171 argc = 1; 172 *--argv = "."; 173 } 174 switch (command) { 175 /* 176 * Interactive mode. 177 */ 178 case 'i': 179 setup(); 180 extractdirs(1); 181 initsymtable((char *)0); 182 runcmdshell(); 183 done(0); 184 /* 185 * Incremental restoration of a file system. 186 */ 187 case 'r': 188 setup(); 189 if (dumptime > 0) { 190 /* 191 * This is an incremental dump tape. 192 */ 193 vprintf(stdout, "Begin incremental restore\n"); 194 initsymtable(symtbl); 195 extractdirs(1); 196 removeoldleaves(); 197 vprintf(stdout, "Calculate node updates.\n"); 198 treescan(".", ROOTINO, nodeupdates); 199 findunreflinks(); 200 removeoldnodes(); 201 } else { 202 /* 203 * This is a level zero dump tape. 204 */ 205 vprintf(stdout, "Begin level 0 restore\n"); 206 initsymtable((char *)0); 207 extractdirs(1); 208 vprintf(stdout, "Calculate extraction list.\n"); 209 treescan(".", ROOTINO, nodeupdates); 210 } 211 createleaves(symtbl); 212 createlinks(); 213 setdirmodes(); 214 checkrestore(); 215 if (dflag) { 216 vprintf(stdout, "Verify the directory structure\n"); 217 treescan(".", ROOTINO, verifyfile); 218 } 219 dumpsymtable(symtbl, (long)1); 220 done(0); 221 /* 222 * Resume an incremental file system restoration. 223 */ 224 case 'R': 225 initsymtable(symtbl); 226 skipmaps(); 227 skipdirs(); 228 createleaves(symtbl); 229 createlinks(); 230 setdirmodes(); 231 checkrestore(); 232 dumpsymtable(symtbl, (long)1); 233 done(0); 234 /* 235 * List contents of tape. 236 */ 237 case 't': 238 setup(); 239 extractdirs(0); 240 initsymtable((char *)0); 241 while (argc--) { 242 canon(*argv++, name); 243 ino = dirlookup(name); 244 if (ino == 0) 245 continue; 246 treescan(name, ino, listfile); 247 } 248 done(0); 249 /* 250 * Batch extraction of tape contents. 251 */ 252 case 'x': 253 setup(); 254 extractdirs(1); 255 initsymtable((char *)0); 256 while (argc--) { 257 canon(*argv++, name); 258 ino = dirlookup(name); 259 if (ino == 0) 260 continue; 261 if (mflag) 262 pathcheck(name); 263 treescan(name, ino, addfile); 264 } 265 createfiles(); 266 createlinks(); 267 setdirmodes(); 268 if (dflag) 269 checkrestore(); 270 done(0); 271 } 272 } 273