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