|
|
1.1 root 1: #include <libc.h>
2: #include "worm.h"
3:
4: static Inode *inodebase;
5: static char *namebase;
6: static long nnames, ninodes;
7: static char *expanded;
8: static readinodes;
9: static ifd;
10:
11: static Inode *diskinode();
12:
13: static Inode *
14: finode(s)
15: char *s;
16: {
17: register lo, hi, m;
18: register Inode *i;
19:
20: if(readinodes == 0)
21: return(diskinode(s));
22: #define EXPAND(in) (i = inodebase+(in), expanded[in]?0:(i->name.n=i->name.o+namebase, expanded[in]=1))
23: #define CMP(str, in) (EXPAND(in), strcmp(str, i->name.n))
24:
25: if(CMP(s, lo = 0) < 0)
26: return(0);
27: if(CMP(s, (hi = ninodes)-1) > 0)
28: return(0);
29: while(lo < hi-1){
30: m = (lo+hi)/2;
31: if(CMP(s, m) < 0)
32: hi = m;
33: else
34: lo = m;
35: }
36: if(CMP(s, lo) == 0)
37: return(inodebase+lo);
38: else
39: return(0);
40: }
41:
42: static void
43: ftraverse(fn)
44: void (*fn)();
45: {
46: register Inode *i;
47: register n;
48:
49: if(readinodes == 0){
50: readinodes = 1;
51: lseek(ifd, 8L, 0);
52: read(ifd, (char *)inodebase, (int)ninodes*sizeof(Inode));
53: }
54: for(n = 0; n < ninodes; n++){
55: EXPAND(n);
56: (*fn)(i);
57: }
58: }
59:
60: fastlink(s, msg, ifn, tfn)
61: Superblock *s;
62: char **msg;
63: Inode *(**ifn)();
64: void (**tfn)();
65: {
66: int n;
67: long t;
68: static char buf[256];
69:
70: *msg = 0;
71: *ifn = finode;
72: *tfn = ftraverse;
73: sprint(buf, "/usr/worm/tmp/%s", s->vol_id);
74: if((ifd = open(buf, 0)) < 0)
75: return(0);
76: read(ifd, (char *)&t, 4);
77: if(t != s->ctime)
78: return(0);
79: read(ifd, (char *)&ninodes, 4);
80: inodebase = (Inode *)malloc(n = ninodes*sizeof(Inode));
81: expanded = malloc((int)ninodes);
82: memset(expanded, 0, (int)ninodes);
83: lseek(ifd, (long)n, 1);
84: readinodes = 0;
85: read(ifd, (char *)&nnames, 4);
86: namebase = malloc((int)nnames);
87: read(ifd, namebase, (int)nnames);
88: numinodes = ninodes;
89: numnamechars = nnames;
90: return(1);
91: }
92:
93: static
94: readi(ino, ip)
95: Inode *ip;
96: {
97: static myino = -1;
98: static Inode myi;
99:
100: if(ino != myino){
101: myino = ino;
102: lseek(ifd, 8L+myino*sizeof(Inode), 0);
103: read(ifd, (char *)&myi, sizeof myi);
104: myi.name.n = myi.name.o+namebase;
105: }
106: *ip = myi;
107: }
108:
109: static Inode *
110: diskinode(s)
111: char *s;
112: {
113: register lo, hi, m;
114: static Inode ii;
115: register Inode *i = ⅈ
116:
117: #define READ(in) readi(in, i)
118: #undef CMP
119: #define CMP(str, in) (READ(in), strcmp(str, i->name.n))
120:
121: if(ninodes <= 0)
122: return(0);
123: if(CMP(s, lo = 0) < 0)
124: return(0);
125: if(CMP(s, (hi = ninodes)-1) > 0)
126: return(0);
127: while(lo < hi-1){
128: m = (lo+hi)/2;
129: if(CMP(s, m) < 0)
130: hi = m;
131: else
132: lo = m;
133: }
134: if(CMP(s, lo) == 0)
135: return(i);
136: else
137: return(0);
138: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.