|
|
1.1 root 1: #include "fserv.h"
2: #include "errno.h"
3: #include "sys/neta.h"
4:
5: extern char *realloc();
6: /* temporary static alloc of devtab */
7:
8: struct tdev devtab[NDEV];
9: struct stat rootstat;
10: int ndev, dev;
11: extern int alive;
12: char *cmdnames[] = {"0?", "stat", "wrt", "read", "free", "trunc", "updat",
13: "get", "nami", "put", "10?"};
14: char *buf, *nbuf;
15: int buflen, nbuflen;
16:
17: #define NF 100
18: /* temporary static alloc of netftab */
19: netf netftab[NF];
20: int nnetf;
21:
22: #define MASK 0x0
23:
24: ourdev(n)
25: { int i;
26: for(i = 0; i < ndev; i++)
27: if(devtab[i].his == n)
28: return(devtab[i].ours);
29: return(-1);
30: }
31:
32: hisdev(n)
33: { int i;
34: for(i = 0; i < ndev; i++)
35: if(devtab[i].ours == n)
36: return(devtab[i].his);
37: return(-1);
38: }
39:
40: newdev(n)
41: { struct tdev *p;
42: p = devtab + ndev++;
43: p->ours = n;
44: p->his = dev++;
45: debug1("\tnewdev %d %d", p->ours, p->his);
46: }
47:
48: netf *
49: gettag(n)
50: long n;
51: { int i;
52: for(i = 0; i < nnetf; i++)
53: if(netftab[i].tag == n)
54: return(netftab + i);
55: errno = ENOENT;
56: return(0);
57: }
58:
59: netf *
60: getnetf(d, i) /* either root of netfs, or in the table */
61: { int j;
62: netf *p;
63: if(i == 0) {
64: errno = ENOENT;
65: return(0);
66: }
67: for(j = 0; j < nnetf; j++)
68: if(netftab[j].ino == i && netftab[j].dev == d)
69: return(netftab + j);
70: debug2("\tgetnetf(%d,%d)", d, i);
71: for(p = netftab, j = 0; j < nnetf; j++, p++) {
72: debug2("\t%d %d %d %s", p->tag, p->dev, p->ino, p->name?p->name:"");
73: }
74: return(0);
75: }
76: netf *
77: oldnetf(s) /* special case for nami/NDEL */
78: char *s;
79: { netf *p;
80: struct stat stb;
81: if(xstat(s, &stb) < 0)
82: return(0);
83: if(p = getnetf(hisdev(stb.st_dev), stb.st_ino)) {
84: p->statb = stb;
85: return(p);
86: }
87: return(0);
88: }
89:
90: netf *
91: newnetf(s, fd, how)
92: char *s;
93: { int i;
94: netf *p;
95: struct stat stb;
96: if(xstat(s, &stb) < 0)
97: return(0);
98: if(p = getnetf(hisdev(stb.st_dev), stb.st_ino)) {
99: p->statb = stb;
100: return(p);
101: }
102: for(i = 0; i < nnetf; i++)
103: if(netftab[i].ino == 0)
104: goto found;
105: i = nnetf++;
106: if(nnetf > NF) {
107: errno = ENOMEM;
108: return(0);
109: }
110: found:
111: alive++;
112: p = netftab + i;
113: p->name = malloc(strlen(s) + 1);
114: strcpy(p->name, s);
115: p->statb = stb;
116: if(fd < 0) {
117: if(ftype(p) != S_IFLNK && ftype(p) != S_IFCHR && ftype(p) != S_IFBLK)
118: p->fd = open(p->name, 0); /* this better work */
119: else
120: p->fd = -1;
121: p->how = 0;
122: }
123: else {
124: p->fd = fd;
125: p->how = how;
126: }
127: p->dev = hisdev(p->statb.st_dev);
128: if(p->dev == -1) {
129: newdev(p->statb.st_dev);
130: p->dev = hisdev(p->statb.st_dev);
131: }
132: p->ino = p->statb.st_ino;
133: p->tag = (p->dev << 16) ^ p->ino ^ MASK;
134: debug2("\tnew %d %d %s", p->dev, p->ino, p->name);
135: debug2("\tnew 0%o %d %d", p->statb.st_mode, p->statb.st_uid, p->statb.st_gid);
136: debug2("\tnew %d", nnetf);
137: return(p);
138: }
139:
140: clrnetf(n)
141: { netf *p;
142: p = gettag(n);
143: if(p == 0) {
144: debug("\tclr net got 0 (x%x)", n);
145: dumpstate();
146: leave(8); /* shut it down */
147: return;
148: }
149: if(p->ino == 2 && p->dev == devtab[0].his)
150: return; /* hold on to the root */
151: if(p->tag != n) {
152: debug("\tclr weird %d %d", n, p->tag);
153: errno = EIO;
154: dumpstate();
155: return;
156: }
157: debug1("\tclear %d %s", p->tag, p->name);
158: if(p->fd != -1) {
159: close(p->fd);
160: p->fd = -1;
161: p->how = 0;
162: }
163: p->tag = p->dev = p->ino = 0;
164: if(p->name)
165: free(p->name);
166: p->name = 0;
167: alive--;
168: }
169:
170: opennf(p, fl) /* fl: 0-read, 1-write, 2-trunc */
171: netf *p;
172: { int i;
173: if(p->fd != -1 && p->how == fl)
174: return(0);
175: if(fl == 2) {
176: errno = EPERM;
177: return(1);
178: }
179: i = open(p->name, fl);
180: if(p->fd != -1)
181: close(p->fd);
182: p->fd = i;
183: debug1("\topennf %s %d", p->name, p->fd);
184: if(p->fd == -1)
185: return(1);
186: p->how = fl;
187: return(0);
188: }
189:
190: truncnf(n)
191: long n;
192: { netf *p;
193: int fd;
194: p = gettag(n);
195: if(p == 0) {
196: debug("\ttrunc %d", n);
197: errno = EIO;
198: dumpstate();
199: return;
200: }
201: if(p->fd != -1)
202: close(p->fd);
203: fd = creat(p->name, 0);
204: p->fd = fd;
205: p->how = 1;
206: }
207:
208: isroot(p)
209: netf *p;
210: {
211: debug2("\tisroot(dev=%d ino=%d), ourde=%d", p->dev, p->ino, ourdev(p->dev));
212: return(p->ino == rootstat.st_ino && ourdev(p->dev) == rootstat.st_dev);
213: }
214:
215: prcmd(x)
216: struct senda *x;
217: {
218: debug1("got %s %d %d %d", cmdnames[x->cmd], major(x->dev), minor(x->dev), x->ino);
219: }
220:
221: getbuf(n)
222: {
223: if(n < buflen)
224: return;
225: if(buflen == 0)
226: buf = malloc(buflen = n);
227: else
228: buf = realloc(buf, buflen = n);
229: if(buf)
230: return;
231: debug("getbuf failed");
232: leave(6);
233: }
234:
235: getnbuf(n)
236: long n;
237: {
238: if(n < nbuflen)
239: return;
240: if(nbuflen == 0)
241: nbuf = malloc(nbuflen = n);
242: else
243: nbuf = realloc(nbuf, nbuflen = n);
244: if(nbuf)
245: return;
246: debug("nbuf failed");
247: leave(7);
248: }
249: /* the current name is a full path name, buf contains another component */
250: fixnbuf(name, count, buf, flag)
251: char *name, *buf;
252: { int i, n;
253: for(i = 0; i < count && buf[i]; i++)
254: ;
255: count = i;
256: n = strlen(name);
257: getnbuf(n + count + 2);
258: strcpy(nbuf, name);
259: if(count > 2 || flag == NLINK || flag == NDEL) {
260: ok:
261: nbuf[n++] = '/';
262: for(i = 0; i < count; i++)
263: nbuf[n++] = *buf++;
264: nbuf[n] = 0;
265: return;
266: }
267: if(count == 0)
268: return;
269: if(count == 1)
270: if(buf[0] == '.')
271: return; /* do we know that name is a directory? */
272: else
273: goto ok;
274: if(buf[0] != '.' || buf[1] != '.')
275: goto ok;
276: while(n > 0 && nbuf[n] != '/')
277: n--;
278: nbuf[n] = 0;
279: if(nbuf[0] != '/')
280: strcpy(nbuf, "/..");
281: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.