new copyright notice
[unix-history] / usr / src / sbin / restore / main.c
... / ...
CommitLineData
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
9char 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
15static char sccsid[] = "@(#)main.c 5.8 (Berkeley) %G%";
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
41int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
42int hflag = 1, mflag = 1, Nflag = 0;
43char command = '\0';
44long dumpnum = 1;
45long volno = 0;
46long ntrec;
47char *dumpmap;
48char *clrimap;
49ino_t maxino;
50time_t dumptime;
51time_t dumpdate;
52FILE *terminal;
53
54main(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) {
71usage:
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}