|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)main.c 3.12 (Berkeley) 83/08/11";
3: #endif
4:
5: /* Copyright (c) 1983 Regents of the University of California */
6:
7: /*
8: * Modified to recursively extract all files within a subtree
9: * (supressed by the h option) and recreate the heirarchical
10: * structure of that subtree and move extracted files to their
11: * proper homes (supressed by the m option).
12: * Includes the s (skip files) option for use with multiple
13: * dumps on a single tape.
14: * 8/29/80 by Mike Litzkow
15: *
16: * Modified to work on the new file system and to recover from
17: * tape read errors.
18: * 1/19/82 by Kirk McKusick
19: *
20: * Full incremental restore running entirely in user code and
21: * interactive tape browser.
22: * 1/19/83 by Kirk McKusick
23: */
24:
25: #include "restore.h"
26: #include <signal.h>
27:
28: int cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
29: int hflag = 1, mflag = 1;
30: char command = '\0';
31: long dumpnum = 1;
32: long volno = 0;
33: char *dumpmap;
34: char *clrimap;
35: ino_t maxino;
36: time_t dumptime;
37: time_t dumpdate;
38: FILE *terminal;
39:
40: main(argc, argv)
41: int argc;
42: char *argv[];
43: {
44: register char *cp;
45: ino_t ino;
46: char *inputdev = "/dev/rmt8";
47: char *symtbl = "./restoresymtable";
48: char name[MAXPATHLEN];
49: int (*signal())();
50: extern int onintr();
51:
52: if (signal(SIGINT, onintr) == SIG_IGN)
53: (void) signal(SIGINT, SIG_IGN);
54: if (signal(SIGTERM, onintr) == SIG_IGN)
55: (void) signal(SIGTERM, SIG_IGN);
56: setlinebuf(stderr);
57: if (argc < 2) {
58: usage:
59: fprintf(stderr, "Usage:\n%s%s%s%s%s",
60: "\trestore tfhsvy [file file ...]\n",
61: "\trestore xfhmsvy [file file ...]\n",
62: "\trestore ifhmsvy\n",
63: "\trestore rfsvy\n",
64: "\trestore Rfsvy\n");
65: done(1);
66: }
67: argv++;
68: argc -= 2;
69: command = '\0';
70: for (cp = *argv++; *cp; cp++) {
71: switch (*cp) {
72: case '-':
73: break;
74: case 'c':
75: cvtflag++;
76: break;
77: case 'd':
78: dflag++;
79: break;
80: case 'h':
81: hflag = 0;
82: break;
83: case 'm':
84: mflag = 0;
85: break;
86: case 'v':
87: vflag++;
88: break;
89: case 'y':
90: yflag++;
91: break;
92: case 'f':
93: if (argc < 1) {
94: fprintf(stderr, "missing device specifier\n");
95: done(1);
96: }
97: inputdev = *argv++;
98: argc--;
99: break;
100: case 's':
101: /*
102: * dumpnum (skip to) for multifile dump tapes
103: */
104: if (argc < 1) {
105: fprintf(stderr, "missing dump number\n");
106: done(1);
107: }
108: dumpnum = atoi(*argv++);
109: if (dumpnum <= 0) {
110: fprintf(stderr, "Dump number must be a positive integer\n");
111: done(1);
112: }
113: argc--;
114: break;
115: case 't':
116: case 'R':
117: case 'r':
118: case 'x':
119: case 'i':
120: if (command != '\0') {
121: fprintf(stderr,
122: "%c and %c are mutually exclusive\n",
123: *cp, command);
124: goto usage;
125: }
126: command = *cp;
127: break;
128: default:
129: fprintf(stderr, "Bad key character %c\n", *cp);
130: goto usage;
131: }
132: }
133: if (command == '\0') {
134: fprintf(stderr, "must specify i, t, r, R, or x\n");
135: goto usage;
136: }
137: setinput(inputdev);
138: if (argc == 0) {
139: argc = 1;
140: *--argv = ".";
141: }
142: switch (command) {
143: /*
144: * Interactive mode.
145: */
146: case 'i':
147: setup();
148: extractdirs(1);
149: initsymtable((char *)0);
150: runcmdshell();
151: done(0);
152: /*
153: * Incremental restoration of a file system.
154: */
155: case 'r':
156: setup();
157: if (dumptime > 0) {
158: /*
159: * This is an incremental dump tape.
160: */
161: vprintf(stdout, "Begin incremental restore\n");
162: initsymtable(symtbl);
163: extractdirs(1);
164: removeoldleaves();
165: vprintf(stdout, "Calculate node updates.\n");
166: treescan(".", ROOTINO, nodeupdates);
167: findunreflinks();
168: removeoldnodes();
169: } else {
170: /*
171: * This is a level zero dump tape.
172: */
173: vprintf(stdout, "Begin level 0 restore\n");
174: initsymtable((char *)0);
175: extractdirs(1);
176: vprintf(stdout, "Calculate extraction list.\n");
177: treescan(".", ROOTINO, nodeupdates);
178: }
179: createleaves(symtbl);
180: createlinks();
181: setdirmodes();
182: checkrestore();
183: if (dflag) {
184: vprintf(stdout, "Verify the directory structure\n");
185: treescan(".", ROOTINO, verifyfile);
186: }
187: dumpsymtable(symtbl, (long)1);
188: done(0);
189: /*
190: * Resume an incremental file system restoration.
191: */
192: case 'R':
193: initsymtable(symtbl);
194: skipmaps();
195: skipdirs();
196: createleaves(symtbl);
197: createlinks();
198: setdirmodes();
199: checkrestore();
200: dumpsymtable(symtbl, (long)1);
201: done(0);
202: /*
203: * List contents of tape.
204: */
205: case 't':
206: setup();
207: extractdirs(0);
208: while (argc--) {
209: canon(*argv++, name);
210: ino = dirlookup(name);
211: if (ino == 0)
212: continue;
213: treescan(name, ino, listfile);
214: }
215: done(0);
216: /*
217: * Batch extraction of tape contents.
218: */
219: case 'x':
220: setup();
221: extractdirs(1);
222: initsymtable((char *)0);
223: while (argc--) {
224: canon(*argv++, name);
225: ino = dirlookup(name);
226: if (ino == 0)
227: continue;
228: if (mflag)
229: pathcheck(name);
230: treescan(name, ino, addfile);
231: }
232: createfiles();
233: createlinks();
234: setdirmodes();
235: if (dflag)
236: checkrestore();
237: done(0);
238: }
239: }
240:
241: /*
242: * Read and execute commands from the terminal.
243: */
244: runcmdshell()
245: {
246: register struct entry *np;
247: ino_t ino;
248: char curdir[MAXPATHLEN];
249: char name[MAXPATHLEN];
250: char cmd[BUFSIZ];
251:
252: canon("/", curdir);
253: loop:
254: getcmd(curdir, cmd, name);
255: switch (cmd[0]) {
256: /*
257: * Add elements to the extraction list.
258: */
259: case 'a':
260: ino = dirlookup(name);
261: if (ino == 0)
262: break;
263: if (mflag)
264: pathcheck(name);
265: treescan(name, ino, addfile);
266: break;
267: /*
268: * Change working directory.
269: */
270: case 'c':
271: ino = dirlookup(name);
272: if (ino == 0)
273: break;
274: if (inodetype(ino) == LEAF) {
275: fprintf(stderr, "%s: not a directory\n", name);
276: break;
277: }
278: (void) strcpy(curdir, name);
279: break;
280: /*
281: * Delete elements from the extraction list.
282: */
283: case 'd':
284: np = lookupname(name);
285: if (np == NIL || (np->e_flags & NEW) == 0) {
286: fprintf(stderr, "%s: not on extraction list\n", name);
287: break;
288: }
289: treescan(name, np->e_ino, deletefile);
290: break;
291: /*
292: * Extract the requested list.
293: */
294: case 'e':
295: createfiles();
296: createlinks();
297: setdirmodes();
298: if (dflag)
299: checkrestore();
300: volno = 0;
301: break;
302: /*
303: * List available commands.
304: */
305: case 'h':
306: case '?':
307: fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
308: "Available commands are:\n",
309: "\tls [arg] - list directory\n",
310: "\tcd arg - change directory\n",
311: "\tpwd - print current directory\n",
312: "\tadd [arg] - add `arg' to list of",
313: " files to be extracted\n",
314: "\tdelete [arg] - delete `arg' from",
315: " list of files to be extracted\n",
316: "\textract - extract requested files\n",
317: "\tquit - immediately exit program\n",
318: "\tverbose - toggle verbose flag",
319: " (useful with ``ls'')\n",
320: "\thelp or `?' - print this list\n",
321: "If no `arg' is supplied, the current",
322: " directory is used\n");
323: break;
324: /*
325: * List a directory.
326: */
327: case 'l':
328: ino = dirlookup(name);
329: if (ino == 0)
330: break;
331: printlist(name, ino);
332: break;
333: /*
334: * Print current directory.
335: */
336: case 'p':
337: if (curdir[1] == '\0')
338: fprintf(stderr, "/\n");
339: else
340: fprintf(stderr, "%s\n", &curdir[1]);
341: break;
342: /*
343: * Quit.
344: */
345: case 'q':
346: case 'x':
347: return;
348: /*
349: * Toggle verbose mode.
350: */
351: case 'v':
352: if (vflag) {
353: fprintf(stderr, "verbose mode off\n");
354: vflag = 0;
355: break;
356: }
357: fprintf(stderr, "verbose mode on\n");
358: vflag++;
359: break;
360: /*
361: * Turn on debugging.
362: */
363: case 'D':
364: if (dflag) {
365: fprintf(stderr, "debugging mode off\n");
366: dflag = 0;
367: break;
368: }
369: fprintf(stderr, "debugging mode on\n");
370: dflag++;
371: break;
372: /*
373: * Unknown command.
374: */
375: default:
376: fprintf(stderr, "%s: unknown command; type ? for help\n", cmd);
377: break;
378: }
379: goto loop;
380: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.