|
|
1.1 root 1: /*
2: * face server, library style
3: */
4: #include <rf.h>
5: #include <ipc.h>
6: #include <signal.h>
7: #include "faceproto.h"
8:
9: #define NULL 0
10: char *malloc();
11:
12:
13: /*
14: * ignore permissions from server for now (who cares?)
15: * uid, gid always RFNOID
16: * permissions always read for everyone
17: */
18: #define FPERM ((RFPRD<<RFPOWNER)|(RFPRD<<RFPGROUP)|(RFPRD<<RFPOTHER))
19: #define DPERM (FPERM|(RFPDS<<RFPOWNER)|(RFPDS<<RFPGROUP)|(RFPDS<<RFPOTHER))
20:
21: char *server;
22: int commfd = -1;
23: static int ininit;
24:
25: #define TIMEOUT (2*60) /* disconnect if idle this long */
26:
27: /*
28: * init:
29: * we have to return something,
30: * but the server might not be running when we start
31: * so fake up a root for now
32: */
33:
34: Rfile *
35: fsinit(argc, argv)
36: int argc;
37: char **argv;
38: {
39: register Rfile *f;
40: int timeout();
41:
42: if (argc <= 1)
43: rfpanic("usage: a.out server\n");
44: server = argv[1];
45: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL)
46: rfpanic("no mem for root\n");
47: f->fs = "/";
48: f->ino = FROOT;
49: f->dev = 0;
50: f->type = RFTDIR;
51: f->mode = DPERM;
52: f->size = 512; /* something nonzero */
53: f->nlink = 1;
54: f->ta = f->tm = f->tc = 0;
55: signal(SIGALRM, timeout);
56: ininit = 1;
57: if (fsstat(f) < 0)
58: fserrno = 0; /* ignore error, use the fake data */
59: ininit = 0;
60: return (f);
61: }
62:
63: timeout(s)
64: int s;
65: {
66: signal(s, timeout);
67: if (rfdebug)
68: rflog("timeout\n");
69: callshutdown();
70: }
71:
72: /*
73: * cheap hack:
74: * if we've already checked the root,
75: * short-circuit namei calls for it,
76: * so status programs (like netb setup) won't make us
77: * keep a circuit open
78: */
79: Rfile *
80: fswalk(df, name)
81: Rfile *df;
82: char *name;
83: {
84: register Rfile *f;
85: char stbuf[FMAXDATA];
86: long rcode;
87: char *nname;
88:
89: if (df->ino == FROOT
90: && (name[0] == 0 || (name[0] == '.' && name[1] == 0)))
91: return (df);
92: if (df->ino == FROOT && strcmp(name, "..") == 0) {
93: fserrno = 0;
94: return (NULL);
95: }
96: if ((nname = malloc(FMAXPATH)) == NULL) {
97: rflog("no mem for name: %s/%s\n", df->fs, name);
98: fserrno = RFEINVAL;
99: return (NULL);
100: }
101: strcpy(nname, df->fs);
102: strcat(nname, "/");
103: strcat(nname, name);
104: if (facecall(nname, DOSTAT, 0L, 0L, stbuf, &rcode) < STLEN) {
105: /* call failed or network botch */
106: fserrno = RFEINVAL;
107: free(nname);
108: return (NULL);
109: }
110: if (rcode < 0) {
111: fserrno = RFENOENT;
112: free(nname);
113: return (NULL);
114: }
115: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) {
116: rflog("no mem for file: %s\n", nname);
117: fserrno = RFEINVAL;
118: free(nname);
119: return (NULL);
120: }
121: f->fs = nname;
122: stunpack(stbuf, f);
123: return (f);
124: }
125:
126: int
127: fsput(f)
128: Rfile *f;
129: {
130: free(f->fs);
131: free((char *)f);
132: return (0);
133: }
134:
135: int
136: fsstat(f)
137: Rfile *f;
138: {
139: char stbuf[FMAXDATA];
140: long rcode;
141:
142: if (f->ino == FROOT && ininit == 0)
143: return (0); /* and don't call */
144: if (facecall(f->fs, DOSTAT, 0L, 0L, stbuf, &rcode) < STLEN) {
145: fserrno = RFEINVAL;
146: return (-1);
147: }
148: if (rcode < 0) {
149: fserrno = RFEINVAL;
150: return (-1);
151: }
152: stunpack(stbuf, f);
153: return (0);
154: }
155:
156: /*
157: * read directories
158: */
159: int
160: fsdirread(f, off, buf, len, noffp)
161: Rfile *f;
162: long off;
163: char *buf;
164: int len;
165: long *noffp;
166: {
167: char dirbuf[FDLEN*32]; /* some even multiple */
168: char onebuf[FDLEN-FD_NAME + 10]; /* enough for one entry */
169: register unsigned char *dp;
170: register int nread, n;
171: register char *bp;
172:
173: if ((off%FDLEN) != 0) {
174: rflog("unaligned fsdirread: off %ld\n", off);
175: fserrno = RFEINVAL;
176: return (-1);
177: }
178: bp = buf;
179: while ((nread = fsread(f, off, dirbuf, sizeof(dirbuf))) > 0) {
180: dp = (unsigned char *)dirbuf;
181: while (nread >= FDLEN) {
182: /* should check ino==0 here */
183: sprintf(onebuf, "%d\t%.*s", frfshort(dp, FD_INO),
184: FDLEN - FD_NAME, dp + FD_NAME);
185: n = strlen(onebuf)+1; /* including NUL */
186: if ((len -= n) < 0)
187: goto out;
188: memcpy(bp, onebuf, n);
189: bp += n;
190: off += FDLEN;
191: dp += FDLEN;
192: nread -= FDLEN;
193: }
194: }
195: out:
196: *noffp = off;
197: if (bp != buf) /* if we read anything, return it */
198: return (bp - buf);
199: if (len < 0) { /* first entry too large */
200: fserrno = RFENOSPC;
201: return (-1);
202: }
203: return (nread); /* must be 0 or -1 */
204: }
205:
206: int
207: fsread(f, off, buf, len)
208: Rfile *f;
209: char *buf;
210: int len;
211: long off;
212: {
213: char data[FMAXDATA];
214: long rcode;
215:
216: if (facecall(f->fs, DOREAD, off, (long)len, data, &rcode) < 0) {
217: fserrno = RFEINVAL;
218: return (-1);
219: }
220: if (rcode < 0) {
221: fserrno = RFEIO;
222: return (-1);
223: }
224: if (rcode > len)
225: rfpanic("fsread wanted %d got %ld\n", len, rcode);
226: if (rcode)
227: memcpy(buf, data, (int)rcode);
228: return (rcode);
229: }
230:
231: /* need fsdirread too */
232:
233: /*
234: * one function call to the server
235: * interface is overly general and underused
236: * there are a filename, a function code, and two long parameters;
237: * some data is returned in result,
238: * and a long status code is returned in *codep
239: * the function return value is the length of the data;
240: * -1 means error
241: */
242: int
243: facecall(file, func, p1, p2, result, codep)
244: char *file;
245: int func;
246: long p1, p2;
247: char *result;
248: long *codep;
249: {
250: register unsigned char *p;
251: register char msg[F_DATA+FMAXDATA];
252: int len;
253:
254: alarm(0);
255: if (commfd < 0 && callsetup() < 0)
256: return (-1);
257: len = strlen(file) + 1;
258: if (len > FMAXDATA)
259: rfpanic("facecall: name too long\n");
260: p = (unsigned char *)msg;
261: p[F_TYPE] = func;
262: p[F_TYPE+1] = 0; /* safety for old servers */
263: tofshort(p, F_LEN, len);
264: toflong(p, F_P1, p1);
265: toflong(p, F_P2, p2);
266: memcpy(&p[F_DATA], file, len);
267: if (rfdebug)
268: rflog("facecall: %s: func %d p %ld %ld\n", file, func, p1, p2);
269: if (write(commfd, msg, len+F_DATA) != len+F_DATA) {
270: rflog("net write error\n");
271: callshutdown();
272: return (-1);
273: }
274: if (gread(commfd, msg, F_DATA, F_DATA) != F_DATA) {
275: rflog("net read error\n");
276: callshutdown();
277: return (-1);
278: }
279: len = frfshort(p, F_LEN);
280: if (len < 0 || len > FMAXDATA) {
281: rflog("net ill len %d\n", len);
282: callshutdown();
283: return (-1);
284: }
285: if (len > 0 && gread(commfd, result, len, len) != len) {
286: rflog("net read error (body)\n");
287: callshutdown();
288: return (-1);
289: }
290: *codep = frflong(p, F_P1);
291: if (rfdebug)
292: rflog("... len %d p1 %ld\n", len, *codep);
293: alarm(TIMEOUT);
294: return (len);
295: }
296:
297: /*
298: * call server
299: */
300: callsetup()
301: {
302: extern char *errstr;
303:
304: if (rfdebug)
305: rflog("call %s\n", server);
306: if ((commfd = ipcopen(ipcpath(server, "", ""), "")) < 0)
307: rflog("can't call %s: %s\n", server, errstr);
308: return (commfd);
309: }
310:
311: callshutdown()
312: {
313: close(commfd);
314: commfd = -1;
315: }
316:
317: /*
318: * unpack stat buffer into a file
319: */
320:
321: stunpack(buf, f)
322: char *buf;
323: register Rfile *f;
324: {
325: register unsigned char *p;
326:
327: p = (unsigned char *)buf;
328: f->ino = frfshort(p, ST_INO);
329: f->dev = 0;
330: if ((frfshort(p, ST_MODE) & STFMT) == STDIR) {
331: f->type = RFTDIR;
332: f->mode = DPERM;
333: } else {
334: f->type = RFTREG;
335: f->mode = FPERM;
336: }
337: f->nlink = frfshort(p, ST_NLINK);
338: f->uid = RFNOID;
339: f->gid = RFNOID;
340: f->size = frflong(p, ST_SIZE);
341: f->ta = frflong(p, ST_ATIME);
342: f->tm = frflong(p, ST_MTIME);
343: f->tc = frflong(p, ST_CTIME);
344: }
345:
346: /*
347: * gather data that may come in dribs and drabs:
348: * read size bytes into buf,
349: * but keep looking until at least minsize have arrived
350: */
351:
352: int
353: gread(fd, buf, size, minsize)
354: int fd;
355: char *buf;
356: int size;
357: register int minsize;
358: {
359: register int n, tot;
360:
361: tot = 0;
362: while (minsize > 0) {
363: if ((n = read(fd, buf, size)) <= 0)
364: break;
365: buf += n;
366: size -= n;
367: minsize -= n;
368: tot += n;
369: }
370: if (tot)
371: return (tot);
372: return (n);
373: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.