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