Commit | Line | Data |
---|---|---|
f2563105 KT |
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/rrp3"; | |
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)/10; | |
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*512, 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 | } |