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