|
|
1.1 root 1: #define NI 16
2: #define DIRPB (BSIZE/sizeof(struct direct))
3:
4: #include <stdio.h>
5: #include <sys/param.h>
6: #include <sys/inode.h>
7: #include <sys/ino.h>
8: #include <sys/fblk.h>
9: #include <sys/filsys.h>
10: #include <sys/dir.h>
11: #include <dumprestor.h>
12:
13: #define MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
14: #define MBIT(i) (1<<((unsigned)(i-1)%MLEN))
15: #define BIS(i,w) (MWORD(w,i) |= MBIT(i))
16: #define BIC(i,w) (MWORD(w,i) &= ~MBIT(i))
17: #define BIT(i,w) (MWORD(w,i) & MBIT(i))
18:
19: struct filsys sblock;
20: struct dinode itab[INOPB*NI];
21: short clrmap[MSIZ];
22: short dirmap[MSIZ];
23: short nodmap[MSIZ];
24:
25: char *disk;
26: char *tape;
27: char *increm;
28: char incno;
29: int uflag;
30: int fi;
31: int to;
32: ino_t ino;
33: int nsubdir;
34: int ntape;
35: int nadded;
36: int dadded;
37: int density = 160;
38:
39: char *ctime();
40: char *prdate();
41: long atol();
42: int fi;
43: long tsize;
44: long esize;
45: long asize;
46: int mark();
47: int add();
48: int dump();
49: int tapsrec();
50: int dmpspc();
51: int dsrch();
52: int nullf();
53:
54: #define HOUR (60L*60L)
55: #define DAY (24L*HOUR)
56: #define YEAR (365L*DAY)
57:
58: main(argc, argv)
59: char *argv[];
60: {
61: char *arg;
62: register i;
63:
64: time(&spcl.c_date);
65:
66: tsize = 2300L*12L*10L;
67: tape = "/dev/rmt1";
68: disk = "/dev/rrp1g";
69: increm = "/etc/ddate";
70: incno = '9';
71: uflag = 0;
72: arg = "u";
73: if(argc > 1) {
74: argv++;
75: argc--;
76: arg = *argv;
77: }
78: while(*arg)
79: switch (*arg++) {
80:
81: case 'f':
82: if(argc > 1) {
83: argv++;
84: argc--;
85: tape = *argv;
86: }
87: break;
88:
89: case 'd':
90: if (argc > 1) {
91: argv++;
92: argc--;
93: density = atoi(*argv);
94: }
95: break;
96:
97: case 's':
98: if(argc > 1) {
99: argv++;
100: argc--;
101: tsize = atol(*argv);
102: tsize *= 12L*10L;
103: }
104: break;
105:
106: case '0':
107: case '1':
108: case '2':
109: case '3':
110: case '4':
111: case '5':
112: case '6':
113: case '7':
114: case '8':
115: case '9':
116: incno = arg[-1];
117: break;
118:
119: case 'u':
120: uflag++;
121: break;
122:
123: default:
124: printf("bad key '%c%'\n", arg[-1]);
125: exit(1);
126: }
127: if(argc > 1) {
128: argv++;
129: argc--;
130: disk = *argv;
131: }
132:
133: getitime();
134: printf(" date = %s\n", prdate(spcl.c_date));
135: printf("dump date = %s\n", prdate(spcl.c_ddate));
136: printf("dumping %s to %s\n", disk, tape);
137: fi = open(disk, 0);
138: if(fi < 0) {
139: printf("dump: cannot open %s\n", disk);
140: exit(1);
141: }
142: otape();
143: printf("I\n");
144: esize = 0;
145: CLR(clrmap);
146: CLR(dirmap);
147: CLR(nodmap);
148:
149: pass(mark, (short *)NULL);
150: do {
151: printf("II\n");
152: nadded = 0;
153: pass(add, dirmap);
154: } while(nadded);
155:
156: bmapest(clrmap);
157: bmapest(nodmap);
158: printf("estimated %ld tape blocks on %d tape(s)\n",
159: esize, 0);
160:
161: printf("III\n");
162: bitmap(clrmap, TS_CLRI);
163: pass(dump, dirmap);
164: printf("IV\n");
165: pass(dump, nodmap);
166: putitime();
167: printf("DONE\n");
168: spcl.c_type = TS_END;
169: for(i=0; i<NTREC; i++)
170: spclrec();
171: printf("%ld tape blocks on %d tape(s)\n",
172: spcl.c_tapea, spcl.c_volume);
173: }
174:
175: pass(fn, map)
176: int (*fn)();
177: short *map;
178: {
179: register i, j;
180: int bits;
181: ino_t mino;
182: daddr_t d;
183:
184: sync();
185: bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
186: mino = (sblock.s_isize-2) * INOPB;
187: ino = 0;
188: for(i=2;; i+=NI) {
189: if(ino >= mino)
190: break;
191: d = (unsigned)i;
192: for(j=0; j<INOPB*NI; j++) {
193: if(ino >= mino)
194: break;
195: if((ino % MLEN) == 0) {
196: bits = ~0;
197: if(map != NULL)
198: bits = *map++;
199: }
200: ino++;
201: if(bits & 1) {
202: if(d != 0) {
203: bread(d, (char *)itab, sizeof(itab));
204: d = 0;
205: }
206: (*fn)(&itab[j]);
207: }
208: bits >>= 1;
209: }
210: }
211: }
212:
213: icat(ip, fn1, fn2)
214: struct dinode *ip;
215: int (*fn1)(), (*fn2)();
216: {
217: register i;
218: daddr_t d[NADDR];
219:
220: l3tol(&d[0], &ip->di_addr[0], NADDR);
221: (*fn2)(d, NADDR-3);
222: for(i=0; i<NADDR; i++) {
223: if(d[i] != 0) {
224: if(i < NADDR-3)
225: (*fn1)(d[i]); else
226: indir(d[i], fn1, fn2, i-(NADDR-3));
227: }
228: }
229: }
230:
231: indir(d, fn1, fn2, n)
232: daddr_t d;
233: int (*fn1)(), (*fn2)();
234: {
235: register i;
236: daddr_t idblk[NINDIR];
237:
238: bread(d, (char *)idblk, sizeof(idblk));
239: if(n <= 0) {
240: spcl.c_type = TS_ADDR;
241: (*fn2)(idblk, NINDIR);
242: for(i=0; i<NINDIR; i++) {
243: d = idblk[i];
244: if(d != 0)
245: (*fn1)(d);
246: }
247: } else {
248: n--;
249: for(i=0; i<NINDIR; i++) {
250: d = idblk[i];
251: if(d != 0)
252: indir(d, fn1, fn2, n);
253: }
254: }
255: }
256:
257: mark(ip)
258: struct dinode *ip;
259: {
260: register f;
261:
262: f = ip->di_mode & IFMT;
263: if(f == 0)
264: return;
265: BIS(ino, clrmap);
266: if(f == IFDIR)
267: BIS(ino, dirmap);
268: if(ip->di_mtime >= spcl.c_ddate ||
269: ip->di_ctime >= spcl.c_ddate) {
270: BIS(ino, nodmap);
271: if (f != IFREG)
272: return;
273: est(ip);
274: }
275: }
276:
277: add(ip)
278: struct dinode *ip;
279: {
280:
281: if(BIT(ino, nodmap))
282: return;
283: nsubdir = 0;
284: dadded = 0;
285: icat(ip, dsrch, nullf);
286: if(dadded) {
287: BIS(ino, nodmap);
288: est(ip);
289: nadded++;
290: }
291: if(nsubdir == 0)
292: if(!BIT(ino, nodmap))
293: BIC(ino, dirmap);
294: }
295:
296: dump(ip)
297: struct dinode *ip;
298: {
299: register i;
300:
301: if(ntape) {
302: ntape = 0;
303: bitmap(nodmap, TS_BITS);
304: }
305: BIC(ino, nodmap);
306: spcl.c_dinode = *ip;
307: spcl.c_type = TS_INODE;
308: spcl.c_count = 0;
309: i = ip->di_mode & IFMT;
310: if(i != IFDIR && i != IFREG) {
311: spclrec();
312: return;
313: }
314: icat(ip, tapsrec, dmpspc);
315: }
316:
317: dmpspc(dp, n)
318: daddr_t *dp;
319: {
320: register i, t;
321:
322: spcl.c_count = n;
323: for(i=0; i<n; i++) {
324: t = 0;
325: if(dp[i] != 0)
326: t++;
327: spcl.c_addr[i] = t;
328: }
329: spclrec();
330: }
331:
332: bitmap(map, typ)
333: short *map;
334: {
335: register i, n;
336: char *cp;
337:
338: n = -1;
339: for(i=0; i<MSIZ; i++)
340: if(map[i])
341: n = i;
342: if(n < 0)
343: return;
344: spcl.c_type = typ;
345: spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
346: spclrec();
347: cp = (char *)map;
348: for(i=0; i<spcl.c_count; i++) {
349: taprec(cp);
350: cp += BSIZE;
351: }
352: }
353:
354: spclrec()
355: {
356: register i, *ip, s;
357:
358: spcl.c_inumber = ino;
359: spcl.c_magic = MAGIC;
360: spcl.c_checksum = 0;
361: ip = (int *)&spcl;
362: s = 0;
363: for(i=0; i<BSIZE/sizeof(*ip); i++)
364: s += *ip++;
365: spcl.c_checksum = CHECKSUM - s;
366: taprec((char *)&spcl);
367: }
368:
369: dsrch(d)
370: daddr_t d;
371: {
372: register char *cp;
373: register i;
374: register ino_t in;
375: struct direct dblk[DIRPB];
376:
377: if(dadded)
378: return;
379: bread(d, (char *)dblk, sizeof(dblk));
380: for(i=0; i<DIRPB; i++) {
381: in = dblk[i].d_ino;
382: if(in == 0)
383: continue;
384: cp = dblk[i].d_name;
385: if(cp[0] == '.') {
386: if(cp[1] == '\0')
387: continue;
388: if(cp[1] == '.' && cp[2] == '\0')
389: continue;
390: }
391: if(BIT(in, nodmap)) {
392: dadded++;
393: return;
394: }
395: if(BIT(in, dirmap))
396: nsubdir++;
397: }
398: }
399:
400: nullf()
401: {
402: }
403:
404: bread(da, ba, c)
405: daddr_t da;
406: char *ba;
407: {
408: register n;
409:
410: lseek(fi, da*BSIZE, 0);
411: n = read(fi, ba, c);
412: if(n != c)
413: printf("asked %d; got %d\n", c, n);
414: }
415:
416: CLR(map)
417: register short *map;
418: {
419: register n;
420:
421: n = MSIZ;
422: do
423: *map++ = 0;
424: while(--n);
425: }
426:
427:
428: char tblock[NTREC][BSIZE];
429: daddr_t tdaddr[NTREC];
430: int trecno;
431:
432: taprec(dp)
433: char *dp;
434: {
435: register i;
436:
437: for(i=0; i<BSIZE; i++)
438: tblock[trecno][i] = *dp++;
439: tdaddr[trecno] = 0;
440: trecno++;
441: spcl.c_tapea++;
442: if(trecno >= NTREC)
443: flusht();
444: }
445:
446: tapsrec(d)
447: daddr_t d;
448: {
449:
450: if(d == 0)
451: return;
452: tdaddr[trecno] = d;
453: trecno++;
454: spcl.c_tapea++;
455: if(trecno >= NTREC)
456: flusht();
457: }
458:
459: flusht()
460: {
461: char place[100];
462: register i, si;
463: daddr_t d;
464:
465: while(trecno < NTREC)
466: tdaddr[trecno++] = 1;
467:
468: loop:
469: d = 0;
470: for(i=0; i<NTREC; i++)
471: if(tdaddr[i] != 0)
472: if(d == 0 || tdaddr[i] < d) {
473: si = i;
474: d = tdaddr[i];
475: }
476: if(d != 0) {
477: bread(d, tblock[si], BSIZE);
478: tdaddr[si] = 0;
479: goto loop;
480: }
481: trecno = 0;
482: write(to, tblock[0], sizeof(tblock));
483: asize += sizeof(tblock)/density;
484: asize += 7;
485: if(asize > tsize) {
486: close(to);
487: printf("change tapes\n");
488: read(0, place, sizeof(place));
489: otape();
490: }
491: }
492:
493: otape()
494: {
495: to = creat(tape, 0666);
496: if(to < 0) {
497: printf("dump: cannot create %s\n", tape);
498: exit(1);
499: }
500: asize = 0;
501: ntape++;
502: spcl.c_volume++;
503: spcl.c_type = TS_TAPE;
504: spclrec();
505: }
506:
507: char *
508: prdate(d)
509: time_t d;
510: {
511: char *p;
512:
513: if(d == 0)
514: return("the epoch");
515: p = ctime(&d);
516: p[24] = 0;
517: return(p);
518: }
519:
520: getitime()
521: {
522: register i, df;
523: struct idates idbuf;
524: char *fname;
525:
526: fname = disk;
527: l1:
528: for(i=0; fname[i]; i++)
529: if(fname[i] == '/') {
530: fname += i+1;
531: goto l1;
532: }
533:
534: spcl.c_ddate = 0;
535: df = open(increm, 0);
536: if(df < 0) {
537: printf("cannot open %s\n", increm);
538: exit(1);
539: }
540:
541: l2:
542: i = read(df, (char *)&idbuf, sizeof(idbuf));
543: if(i != sizeof(idbuf)) {
544: close(df);
545: return;
546: }
547: for(i=0;; i++) {
548: if(fname[i] != idbuf.id_name[i])
549: goto l2;
550: if(fname[i] == '\0')
551: break;
552: }
553: if(idbuf.id_incno >= incno)
554: goto l2;
555: if(idbuf.id_ddate <= spcl.c_ddate)
556: goto l2;
557: spcl.c_ddate = idbuf.id_ddate;
558: goto l2;
559: }
560:
561: putitime()
562: {
563: register i, n, df;
564: struct idates idbuf;
565: char *fname;
566:
567: if(uflag == 0)
568: return;
569: fname = disk;
570: l1:
571: for(i=0; fname[i]; i++)
572: if(fname[i] == '/') {
573: fname += i+1;
574: goto l1;
575: }
576:
577: spcl.c_ddate = 0;
578: df = open(increm, 2);
579: if(df < 0) {
580: printf("cannot open %s\n", increm);
581: exit(1);
582: }
583: n = 0;
584: l2:
585: i = read(df, (char *)&idbuf, sizeof(idbuf));
586: if(i != sizeof(idbuf))
587: goto l3;
588: n++;
589: for(i=0;; i++) {
590: if(fname[i] != idbuf.id_name[i])
591: goto l2;
592: if(fname[i] == '\0')
593: break;
594: }
595: if(idbuf.id_incno != incno)
596: goto l2;
597: l3:
598: lseek(df, (long)n*sizeof(idbuf), 0);
599: for(i=0;; i++) {
600: idbuf.id_name[i] = fname[i];
601: if(fname[i] == '\0')
602: break;
603: }
604: idbuf.id_incno = incno;
605: idbuf.id_ddate = spcl.c_date;
606: write(df, (char *)&idbuf, sizeof(idbuf));
607: close(df);
608: printf("level %c dump on %s\n", incno, prdate(spcl.c_date));
609: }
610:
611: est(ip)
612: struct dinode *ip;
613: {
614: long s;
615:
616: esize++;
617: s = (ip->di_size + BSIZE-1) / BSIZE;
618: esize += s;
619: if(s > NADDR-3) {
620: s -= NADDR-3;
621: s = (s + (BSIZE/sizeof(daddr_t))-1) / (BSIZE/sizeof(daddr_t));
622: esize += s;
623: }
624: }
625:
626: bmapest(map)
627: short *map;
628: {
629: register i, n;
630:
631: n = -1;
632: for(i=0; i<MSIZ; i++)
633: if(map[i])
634: n = i;
635: if(n < 0)
636: return;
637: esize++;
638: esize += (n + (BSIZE/sizeof(short))-1) / (BSIZE/sizeof(short));
639: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.