|
|
1.1 root 1: #include <libc.h>
2: #include <cbt.h>
3: #undef nfree
4: #include "worm.h"
5: #include "sym.h"
6: #include <sys/types.h>
7: #include <sys/stat.h>
8:
9: static char *inonames;
10: static bfile *bf;
11: static dirlk(), wormdir();
12:
13: char *
14: cbtinit(s, blk, doinodes)
15: register Superblock *s;
16: long blk;
17: {
18: static char buf[64];
19: char name[256], buf1[256];
20:
21: if(s->magic != SMAGIC){
22: fprint(2, "bad Superblock at %ld\n", blk);
23: exit(1);
24: }
25: numinodes = s->ninodes;
26: if(doinodes){
27: inonames = malloc(s->blocksize*(int)NBLKS(s, s->ninochars));
28: if(inonames == 0){
29: sprint(buf, "cbtinit: can't malloc %d\n", s->blocksize*(int)NBLKS(s, s->ninochars));
30: return(buf);
31: }
32: if(dirlk(s) == 0)
33: wormdir(s);
34: } else
35: inonames = 0;
36: return((char *)0);
37: }
38:
39: static
40: dirlk(s)
41: register Superblock *s;
42: {
43: char name[256], buf1[256];
44: struct stat sbuf;
45: int fd;
46:
47: sprint(name, "/usr/worm/dirs/%s", s->vol_id);
48: sprint(buf1, "%s.I", name);
49: if(stat(buf1, &sbuf) < 0)
50: return(0);
51: if(sbuf.st_mtime < s->ctime)
52: return(0); /* worm is more recent than disk */
53: if((bf = bopen(name, 0)) == 0)
54: return(0);
55: sprint(buf1, "%s.I", name);
56: if((fd = open(buf1, 0)) < 0){
57: fprint(2, "%s: btree but no inodes\n", name);
58: return(0);
59: }
60: if(read(fd, inonames, (int)s->ninochars) != s->ninochars){
61: fprint(2, "%s: expected %d chars\n", buf1, s->ninochars);
62: close(fd);
63: return(0);
64: }
65: close(fd);
66: return(1);
67: }
68:
69: static
70: wormdir(s)
71: register Superblock *s;
72: {
73: char name[256], buf1[256];
74:
75: sprint(name, "/tmp/worm%d", getpid());
76: Seek(s, s->binodes);
77: sprint(buf1, "%s.F", name);
78: copyout(s, buf1, s->nF, 0, 0);
79: sprint(buf1, "%s.T", name);
80: copyout(s, buf1, s->nT, 0, 0);
81: if(Read(s, inonames, NBLKS(s, s->ninochars)))
82: return(0);
83: if((bf = bopen(name, 0)) == 0){
84: fprint(2, "can't bopen %s", name);
85: return(0);
86: }
87: sprint(buf1, "%s.F", name); unlink(buf1);
88: sprint(buf1, "%s.T", name); unlink(buf1);
89: return(1);
90: }
91:
92: copyout(s, name, len, overwrite, verbose)
93: register Superblock *s;
94: char *name;
95: long len;
96: {
97: int fd, l;
98: char *buf;
99:
100: if(access(name, 0) == 0){
101: if(!overwrite){
102: fprint(2, "%s already exists!\n", name);
103: exit(1);
104: }
105: if(verbose)
106: fprint(2, "overwriting %s\n", name);
107: }
108: if((fd = creat(name, 0666)) < 0){
109: perror(name);
110: exit(1);
111: }
112: if((buf = malloc(l = (BIGBLOCK/1024)*s->blocksize)) == 0){
113: fprint(2, "can't malloc %d\n", l);
114: exit(1);
115: }
116: if(verbose)
117: print("%s: %d bytes\n", name, len);
118: while(len >= l){
119: if(Read(s, buf, NBLKS(s, l)))
120: exit(1);
121: if(write(fd, buf, l) != l){
122: perror(name);
123: exit(2);
124: }
125: len -= l;
126: }
127: if(Read(s, buf, NBLKS(s, len)))
128: exit(2);
129: if(write(fd, buf, (int)len) != len){
130: perror(name);
131: exit(2);
132: }
133: free(buf);
134: }
135:
136: Inode *
137: binodefn(s)
138: char *s;
139: {
140: static Inode i;
141: mbuf key;
142:
143: if(inonames == 0)
144: return((Inode *)0);
145: key.mdata = s;
146: key.mlen = strlen(s);
147: if(bseek(bf, key) != 1)
148: return((Inode *)0);
149: key.mdata = (char *)&i;
150: if(bread(bf, (mbuf *)0, &key)){
151: perror("inode read");
152: return((Inode *)0);
153: }
154: i.name.n = i.name.o+inonames;
155: return(&i);
156: }
157:
158: void
159: btraverse(fn)
160: void (*fn)();
161: {
162: static Inode i;
163: mbuf key;
164:
165: if(inonames == 0)
166: return;
167: bfirst(bf);
168: key.mdata = (char *)&i;
169: while(bread(bf, (mbuf *)0, &key) == 0){
170: i.name.n = i.name.o+inonames;
171: (*fn)(&i);
172: }
173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.