|
|
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/rcy0s";
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 'T':
117: case 'R':
118: case 'r':
119: case 'x':
120: case 'X':
121: case 'i':
122: if (command != '\0') {
123: fprintf(stderr,
124: "%c and %c are mutually exclusive\n",
125: *cp, command);
126: goto usage;
127: }
128: command = *cp;
129: break;
130: default:
131: fprintf(stderr, "Bad key character %c\n", *cp);
132: goto usage;
133: }
134: }
135: if (command == '\0') {
136: fprintf(stderr, "must specify i, T, r, R, or x\n");
137: goto usage;
138: }
139: setinput(inputdev);
140: if (argc == 0) {
141: argc = 1;
142: *--argv = ".";
143: }
144: switch (command) {
145: /*
146: * Interactive mode.
147: */
148: case 'i':
149: setup();
150: extractdirs(1);
151: initsymtable((char *)0);
152: runcmdshell();
153: done(0);
154: /*
155: * Incremental restoration of a file system.
156: */
157: case 'r':
158: setup();
159: if (dumptime > 0) {
160: /*
161: * This is an incremental dump tape.
162: */
163: vprintf(stdout, "Begin incremental restore\n");
164: initsymtable(symtbl);
165: extractdirs(1);
166: removeoldleaves();
167: vprintf(stdout, "Calculate node updates.\n");
168: treescan(".", ROOTINO, nodeupdates);
169: findunreflinks();
170: removeoldnodes();
171: } else {
172: /*
173: * This is a level zero dump tape.
174: */
175: vprintf(stdout, "Begin level 0 restore\n");
176: initsymtable((char *)0);
177: extractdirs(1);
178: vprintf(stdout, "Calculate extraction list.\n");
179: treescan(".", ROOTINO, nodeupdates);
180: }
181: createleaves(symtbl);
182: createlinks();
183: setdirmodes();
184: checkrestore();
185: if (dflag) {
186: vprintf(stdout, "Verify the directory structure\n");
187: treescan(".", ROOTINO, verifyfile);
188: }
189: dumpsymtable(symtbl, (long)1);
190: done(0);
191: /*
192: * Resume an incremental file system restoration.
193: */
194: case 'R':
195: initsymtable(symtbl);
196: skipmaps();
197: skipdirs();
198: createleaves(symtbl);
199: createlinks();
200: setdirmodes();
201: checkrestore();
202: dumpsymtable(symtbl, (long)1);
203: done(0);
204: /*
205: * Give dump dates of tape.
206: */
207: case 'T':
208: setup();
209: done(0);
210: /*
211: * List contents of tape.
212: */
213: case 't':
214: setup();
215: extractdirs(0);
216: while (argc--) {
217: canon(*argv++, name);
218: ino = dirlookup(name);
219: if (ino == 0)
220: continue;
221: treescan(name, ino, listfile);
222: }
223: done(0);
224: /*
225: * Batch extraction of tape contents.
226: */
227: case 'x':
228: case 'X':
229: setup();
230: extractdirs(1);
231: initsymtable((char *)0);
232: while (argc--) {
233: canon(*argv++, name);
234: ino = dirlookup(name);
235: if (ino == 0)
236: continue;
237: if (mflag)
238: pathcheck(name);
239: treescan(name, ino, addfile);
240: }
241: createfiles();
242: createlinks();
243: setdirmodes();
244: if (dflag)
245: checkrestore();
246: done(0);
247: }
248: }
249:
250: /*
251: * Read and execute commands from the terminal.
252: */
253: runcmdshell()
254: {
255: register struct entry *np;
256: ino_t ino;
257: char curdir[MAXPATHLEN];
258: char name[MAXPATHLEN];
259: char cmd[BUFSIZ];
260:
261: canon("/", curdir);
262: loop:
263: getcmd(curdir, cmd, name);
264: switch (cmd[0]) {
265: /*
266: * Add elements to the extraction list.
267: */
268: case 'a':
269: ino = dirlookup(name);
270: if (ino == 0)
271: break;
272: if (mflag)
273: pathcheck(name);
274: treescan(name, ino, addfile);
275: break;
276: /*
277: * Change working directory.
278: */
279: case 'c':
280: ino = dirlookup(name);
281: if (ino == 0)
282: break;
283: if (inodetype(ino) == LEAF) {
284: fprintf(stderr, "%s: not a directory\n", name);
285: break;
286: }
287: (void) strcpy(curdir, name);
288: break;
289: /*
290: * Delete elements from the extraction list.
291: */
292: case 'd':
293: np = lookupname(name);
294: if (np == NIL || (np->e_flags & NEW) == 0) {
295: fprintf(stderr, "%s: not on extraction list\n", name);
296: break;
297: }
298: treescan(name, np->e_ino, deletefile);
299: break;
300: /*
301: * Extract the requested list.
302: */
303: case 'e':
304: createfiles();
305: createlinks();
306: setdirmodes();
307: if (dflag)
308: checkrestore();
309: volno = 0;
310: break;
311: /*
312: * List available commands.
313: */
314: case 'h':
315: case '?':
316: fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
317: "Available commands are:\n",
318: "\tls [arg] - list directory\n",
319: "\tcd arg - change directory\n",
320: "\tpwd - print current directory\n",
321: "\tadd [arg] - add `arg' to list of",
322: " files to be extracted\n",
323: "\tdelete [arg] - delete `arg' from",
324: " list of files to be extracted\n",
325: "\textract - extract requested files\n",
326: "\tquit - immediately exit program\n",
327: "\tverbose - toggle verbose flag",
328: " (useful with ``ls'')\n",
329: "\thelp or `?' - print this list\n",
330: "If no `arg' is supplied, the current",
331: " directory is used\n");
332: break;
333: /*
334: * List a directory.
335: */
336: case 'l':
337: ino = dirlookup(name);
338: if (ino == 0)
339: break;
340: printlist(name, ino);
341: break;
342: /*
343: * Print current directory.
344: */
345: case 'p':
346: if (curdir[1] == '\0')
347: fprintf(stderr, "/\n");
348: else
349: fprintf(stderr, "%s\n", &curdir[1]);
350: break;
351: /*
352: * Quit.
353: */
354: case 'q':
355: case 'x':
356: return;
357: /*
358: * Toggle verbose mode.
359: */
360: case 'v':
361: if (vflag) {
362: fprintf(stderr, "verbose mode off\n");
363: vflag = 0;
364: break;
365: }
366: fprintf(stderr, "verbose mode on\n");
367: vflag++;
368: break;
369: /*
370: * Turn on debugging.
371: */
372: case 'D':
373: if (dflag) {
374: fprintf(stderr, "debugging mode off\n");
375: dflag = 0;
376: break;
377: }
378: fprintf(stderr, "debugging mode on\n");
379: dflag++;
380: break;
381: /*
382: * Unknown command.
383: */
384: default:
385: fprintf(stderr, "%s: unknown command; type ? for help\n", cmd);
386: break;
387: }
388: goto loop;
389: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.