|
|
1.1 root 1: /*
2: * file service routines for FILES-11 ODS-1
3: * in its modern instance, with subdirectories
4: */
5:
6: #include <rf.h>
7: #include "files11.h"
8: #include "f11.h"
9:
10: #define NULL 0
11: #define HUGE 0x7fffffff
12:
13: int diskfd;
14: struct homeblock home;
15: Fsfile indexf;
16: unsigned short dirtyp;
17:
18: static htorf();
19: static char *itoa();
20: static int binchk();
21: char *r50toa();
22: char *malloc();
23:
24: /*
25: * permission hacks
26: */
27: #define UXOTHER 1
28: static Idmap gmap[] = { "other", UXOTHER, 0 };
29:
30: /*
31: * init:
32: * install the root
33: *
34: * argv[1] == the file containing our filesystem
35: */
36: Rfile *
37: fsinit(argc, argv)
38: int argc;
39: char **argv;
40: {
41: register Rfile *f;
42: register long firsthdr;
43: char *p;
44:
45: p = "dir";
46: dirtyp = ator50(&p);
47: if (argc <= 1)
48: rfpanic("no files-11 filesystem specified\n");
49: if ((diskfd = open(argv[1], 0)) < 0) /* readonly for now */
50: rfpanic("%s: cannot open\n", argv[1]);
51: if (lseek(diskfd, (long)HOMEBLK * BLKSIZ, 0) < 0)
52: rfpanic("can't seek for home block\n");
53: if (read(diskfd, (char *)&home, sizeof(home)) != sizeof(home))
54: rfpanic("can't read homeblock\n");
55: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL
56: || (f->fs = malloc(sizeof(Fsfile))) == NULL)
57: rfpanic("no mem for root\n");
58: firsthdr = plong(home.H_iblb)+home.H_ibsz;
59: lseek(diskfd, (firsthdr + fidtob(FINDEX)) * BLKSIZ, 0);
60: if (read(diskfd, (char *)&indexf.h, sizeof(indexf.h)) != sizeof(indexf.h))
61: rfpanic("can't read index header\n");
62: indexf.lbase = HUGE;
63: if (gethdr(FROOT, &fsp(f)->h) == 0)
64: rfpanic("can't read root header\n");
65: htorf(f, &fsp(f)->h);
66: fsp(f)->parent = FROOT;
67: fsp(f)->lbase = HUGE;
68: fsp(f)->flags = FBIN;
69: fsp(f)->tboff = fsp(f)->tbno = fsp(f)->tuoff = 0;
70: rfgidmap = gmap;
71: return (f);
72: }
73:
74: /*
75: * access a file
76: */
77: Rfile *
78: fswalk(df, name)
79: Rfile *df;
80: char *name;
81: {
82: register Rfile *f;
83: unsigned short fid;
84: int binary;
85:
86: binary = binchk(name);
87: if (strcmp(name, ".") == 0)
88: return (df);
89: else if (strcmp(name, "..") == 0) {
90: if (df->ino == FROOT) {
91: fserrno = 0; /* magic: popped out */
92: return (NULL);
93: }
94: fid = fsp(df)->parent;
95: } else if ((fid = f11walk(df, name)) == 0)
96: return (NULL);
97: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) {
98: rflog("no mem\n");
99: fserrno = RFEINVAL;
100: return (NULL);
101: }
102: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) {
103: free((char *)f);
104: rflog("no mem\n");
105: fserrno = RFEINVAL;
106: return (NULL);
107: }
108: fsp(f)->lbase = HUGE;
109: if (gethdr(fid, &fsp(f)->h) == 0) {
110: free((char *)f);
111: fserrno = RFEIO;
112: return (NULL);
113: }
114: if (fsp(f)->h.h_ident.i_fnam.f_typ == dirtyp)
115: fsp(f)->parent = fsp(df)->h.h_fnum;
116: htorf(f, &fsp(f)->h);
117: fsp(f)->tboff = fsp(f)->tbno = fsp(f)->tuoff = 0;
118: if (binary)
119: fsp(f)->flags = FBIN;
120: else if (fsp(f)->h.h_fcs.f_rtyp == RTVAR && fsp(f)->h.h_fcs.f_ratt & RTCR)
121: fsp(f)->flags = 0;
122: else
123: fsp(f)->flags = FBIN;
124: return (f);
125: }
126:
127: /*
128: * see if filename is `binary': trailing % in name
129: * stamp it out if so
130: */
131: static
132: binchk(name)
133: register char *name;
134: {
135: name += strlen(name);
136: if (*--name == '%') {
137: *name = 0;
138: return (1);
139: }
140: return (0);
141: }
142:
143: /*
144: * discard a file reference
145: */
146: int
147: fsdone(f)
148: Rfile *f;
149: {
150:
151: free(f->fs);
152: free((char *)f);
153: return (0);
154: }
155:
156: /*
157: * return file status
158: */
159: fsstat(f)
160: register Rfile *f;
161: {
162:
163: if (gethdr(fsp(f)->h.h_fnum, &fsp(f)->h) == 0) {
164: fserrno = RFEINVAL;
165: return (-1);
166: }
167: htorf(f, &fsp(f)->h);
168: return (0);
169: }
170:
171: /*
172: * read
173: */
174: int
175: fsread(f, off, buf, len)
176: Rfile *f;
177: long off;
178: char *buf;
179: int len;
180: {
181:
182: if (fsp(f)->flags & FBIN)
183: return (binread(f, off, buf, len));
184: else
185: return (textread(f, off, buf, len));
186: }
187:
188: int
189: binread(f, off, buf, len)
190: Rfile *f;
191: long off;
192: char *buf;
193: int len;
194: {
195: char bbuf[BLKSIZ];
196: int boff;
197: long bno;
198: int nread, r;
199: int ncpy;
200:
201: nread = 0;
202: bno = off / BLKSIZ;
203: boff = off % BLKSIZ;
204: /*
205: * contract this loop later
206: */
207: r = 0;
208: while (len > 0) {
209: if ((r = f11rblk(f, bno, bbuf)) <= 0)
210: break;
211: ncpy = BLKSIZ - boff;
212: ncpy = (len > ncpy) ? ncpy : len;
213: memcpy(buf, bbuf+boff, ncpy);
214: len -= ncpy;
215: buf += ncpy;
216: nread += ncpy;
217: boff = 0;
218: bno++;
219: }
220: if (nread || r >= 0)
221: return (nread);
222: fserrno = RFEIO;
223: return (-1);
224: }
225:
226: int
227: textread(f, off, buf, len)
228: Rfile *f;
229: long off;
230: char *buf;
231: int len;
232: {
233: unsigned char bbuf[BLKSIZ];
234: int boff;
235: long bno;
236: int nread, r;
237: int ncpy;
238: int rlen;
239: unsigned char *p;
240:
241: nread = 0;
242: if (off == fsp(f)->tuoff) {
243: bno = fsp(f)->tbno;
244: boff = fsp(f)->tboff;
245: } else if (off == 0) {
246: bno = 0;
247: boff = 0;
248: } else { /* wrong, but so what? */
249: bno = off / BLKSIZ;
250: boff = off % BLKSIZ;
251: }
252: if ((r = f11rblk(f, bno, bbuf)) <= 0)
253: goto out;
254: p = bbuf + boff;
255: while (len > 0) {
256: if (boff & 01) {
257: p++;
258: boff++;
259: }
260: if ((bno * BLKSIZ) + boff >= f->size)
261: break;
262: rlen = p[0] + (p[1]<<8);
263: if (rlen == -1) { /* skip to next block */
264: if ((r = f11rblk(f, ++bno, bbuf)) <= 0)
265: goto out;
266: p = bbuf;
267: boff = 0;
268: continue;
269: }
270: if (rlen + 1 > len) /* +1 for newline */
271: /* set a particular error here? */
272: break;
273: p += 2;
274: for (; rlen > 0; rlen -= ncpy) {
275: ncpy = &bbuf[BLKSIZ] - p;
276: if (ncpy > rlen)
277: ncpy = rlen;
278: memcpy(buf, p, ncpy);
279: p += ncpy;
280: boff = p - bbuf;
281: nread += ncpy;
282: buf += ncpy;
283: len -= ncpy;
284: if (ncpy < rlen) { /* next block */
285: if ((r = f11rblk(f, ++bno, bbuf)) <= 0)
286: goto out;
287: p = bbuf;
288: boff = 0;
289: }
290: }
291: *buf++ = '\n';
292: nread++;
293: len--;
294: if (boff > BLKSIZ - 2) { /* about to need new block */
295: if ((r = f11rblk(f, ++bno, bbuf)) <= 0)
296: goto out;
297: p = bbuf;
298: boff = 0;
299: }
300: }
301: out:
302: if (boff == BLKSIZ) {
303: boff = 0;
304: bno++;
305: }
306: if (nread) {
307: fsp(f)->tuoff = off + nread;
308: fsp(f)->tbno = bno;
309: fsp(f)->tboff = boff;
310: }
311: if (nread || r >= 0)
312: return (nread);
313: fserrno = RFEIO;
314: return (-1);
315: }
316:
317: /*
318: * read directory --
319: * return ascii records: decimal `i-number', tab, filename, NUL
320: * filename is filname.typ.ver
321: * *offp gets new file offset for directory
322: */
323: #define DENTSIZE (6+9+4+6+1) /* max len of a directory record */
324:
325: int
326: fsdirread(f, off, buf, len, offp)
327: Rfile *f;
328: long off;
329: char *buf;
330: int len;
331: long *offp;
332: {
333: char bbuf[BLKSIZ];
334: register char *p;
335: register struct directory *dp;
336: struct directory *dend;
337: char *op;
338: int r;
339: long bno;
340: int boff;
341:
342: bno = off / BLKSIZ;
343: if ((r = f11rblk(f, bno, bbuf)) <= 0) {
344: fserrno = RFEIO;
345: return (r);
346: }
347: boff = off % BLKSIZ;
348: dp = (struct directory *)bbuf + (boff/sizeof(struct directory));
349: dend = (struct directory *)&bbuf[BLKSIZ];
350: p = buf;
351: while (len >= DENTSIZE) {
352: while (dp < dend && dp->d_fid.f_num == 0)
353: dp++;
354: if (dp >= dend) {
355: bno++;
356: dp = (struct directory *)bbuf;
357: if ((r = f11rblk(f, bno, bbuf)) <= 0)
358: break;
359: }
360: op = p;
361: p = itoa(p, dp->d_fid.f_num);
362: *p++ = '\t';
363: p = r50toa(p, dp->d_fname.f_nam[0]);
364: p = r50toa(p, dp->d_fname.f_nam[1]);
365: p = r50toa(p, dp->d_fname.f_nam[2]);
366: while (p[-1] == ' ')
367: --p;
368: *p++ = '.';
369: p = r50toa(p, dp->d_fname.f_typ);
370: while (p[-1] == ' ')
371: --p;
372: *p++ = '.';
373: p = itoa(p, dp->d_fname.f_ver);
374: *p++ = 0;
375: len -= p - op;
376: dp++;
377: }
378: if (p == buf && r < 0) {
379: fserrno = RFEIO;
380: return (-1);
381: }
382: *offp = (bno * BLKSIZ) + (char *)dp - bbuf;
383: return (p - buf);
384: }
385:
386: /*
387: * f11 to rf file attributes
388: * -- temporary permission hack:
389: * turn apparent f11 other to asserted unix other group
390: */
391: #define F11OTHER (-1)
392:
393: static
394: htorf(f, h)
395: register Rfile *f;
396: register struct header *h;
397: {
398: f->ino = h->h_fnum;
399: f->dev = 0;
400: f->mode = htouperm(h->h_fpro);
401: if (h->h_ident.i_fnam.f_typ != dirtyp)
402: f->type = RFTREG;
403: else {
404: f->mode |= (f->mode & 0444)>>2; /* copy `read' into `execute' */
405: f->type = RFTDIR;
406: }
407: f->nlink = 1;
408: f->uid = h->h_fown.u_prog;
409: f->gid = h->h_fown.u_proj;
410: if (f->gid == F11OTHER)
411: f->gid = UXOTHER;
412: f->rdev = 0;
413: f->size = hfilesize(h);
414: f->ta = 0;
415: f->tm = htoutime(h->h_ident.i_rvdt);
416: f->tc = htoutime(h->h_ident.i_crdt); /* wrong, but let it stand */
417: if (f->tm == 0)
418: f->tm = f->tc;
419: }
420:
421: /*
422: * number to string
423: */
424:
425: static char digits[] = "0123456789";
426:
427: static char *
428: itoa(s, n)
429: register char *s;
430: register unsigned int n;
431: {
432: register int d;
433:
434: if ((d = n / 10) == 0)
435: *s++ = digits[n];
436: else {
437: s = itoa(s, d);
438: *s++ = digits[n % 10];
439: }
440: return (s);
441: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.