|
|
1.1 root 1: /*
2: * read a V7 PDP-11 filesystem
3: * quick hack: assumed to be on a VAX (byte order matters)
4: */
5:
6: /*
7: * miscellaneous filesystem definitions
8: * some are magic numbers here
9: */
10:
11: #include <sys/param.h>
12: #include <sys/filsys.h>
13: #include <sys/ino.h>
14: #include <sys/inode.h>
15: #include <sys/dir.h>
16:
17: #define BLSIZE 512
18:
19: #include "rf.h"
20: #include <errno.h>
21: #include <libc.h>
22:
23: int fserrno;
24: static int devfd;
25: static Rfile *root;
26:
27: typedef struct Fsfile {
28: daddr_t addr[NADDR];
29: } Fsfile;
30: #define fsp(f) ((Fsfile *)((f)->fs))
31:
32: /*
33: * init:
34: * open the device
35: */
36:
37: Rfile *
38: fsinit(argc, argv)
39: int argc;
40: char **argv;
41: {
42: register Rfile *f;
43:
44: if (argc <= 1)
45: rfpanic("no device specified\n");
46: if ((devfd = open(argv[0], 0)) < 0)
47: rfpanic("%s: cannot open\n", argv[1]);
48: /* never mind the super-block */
49: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL)
50: rfpanic("no mem for root\n");
51: if ((f->fs = malloc(sizeof(Fsfile))) == NULL)
52: rfpanic("no mem for root\n");
53: f->ino = ROOTINO;
54: fsstat(f);
55: root = f;
56: return (f);
57: }
58:
59: /*
60: * access a file
61: */
62:
63: Rfile *
64: fswalk(df, name)
65: register Rfile *df;
66: char *name;
67: {
68: register Rfile *f;
69: int ino;
70:
71: if ((ino = dsearch(df, name)) == 0) {
72: fserrno = ENOENT;
73: return (NULL);
74: }
75: if (df == root) { /* "." and ".." magic */
76: if (strcmp(name, ".") == 0)
77: return (df);
78: if (strcmp(name, "..") == 0) {
79: fserrno = 0; /* pseudo-error: popped out of root */
80: return (NULL);
81: }
82: }
83: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) {
84: fserrno = ENOMEM;
85: return (NULL);
86: }
87: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) {
88: free((char *)f);
89: fserrno = ENOMEM;
90: return (NULL);
91: }
92: f->ino = ino;
93: fsstat(f);
94: return (f);
95: }
96:
97: /*
98: * discard a file reference
99: */
100: int
101: fsdone(f)
102: Rfile *f;
103: {
104:
105: free(f->fs);
106: free((char *)f);
107: return (0);
108: }
109:
110: /*
111: * return file status
112: */
113: int
114: fsstat(f)
115: Rfile *f;
116: {
117:
118: getino(f);
119: return (0);
120: }
121:
122: /*
123: * read data
124: */
125: int
126: fsread(f, off, buf, len)
127: register Rfile *f;
128: long off;
129: char *buf;
130: int len;
131: {
132: char blk[BLSIZE];
133: int rest;
134: daddr_t bno;
135:
136: switch (f->mode & IFMT) {
137: case IFREG:
138: case IFDIR:
139: break;
140:
141: default:
142: return (0);
143: }
144: if (off >= f->size)
145: return (0);
146: if (off + len > f->size)
147: len = f->size - off;
148: bno = off / BLSIZE;
149: if (getlblk(f, bno, blk) == 0)
150: return (-1);
151: rest = (bno + 1)*BLSIZE - off;
152: if (len > rest)
153: len = rest;
154: memcpy(buf, blk + (off % BLSIZE), len);
155: return (len);
156: }
157:
158: /*
159: * read a piece of a directory
160: * -- cheap out for now: just return one
161: */
162: int
163: fsdirread(f, off, buf, len, offp)
164: register Rfile *f;
165: long off;
166: char *buf;
167: int len;
168: long *offp;
169: {
170: int stlen;
171: register struct direct *de;
172: char blk[BLSIZE];
173: char one[BLSIZE];
174: int n;
175:
176: if (off % sizeof(struct direct)) {
177: fserrno = EINVAL;
178: return (-1);
179: }
180: stlen = len;
181: de = (struct direct *)&blk[BLSIZE];
182: for (; off < f->size; de++, off += sizeof(struct direct)) {
183: if (de >= (struct direct *)&blk[BLSIZE]) {
184: if (getlblk(f, off/BLSIZE, blk) == 0)
185: break;
186: de = (struct direct *)&blk[off%BLSIZE];
187: }
188: if (de->d_ino == 0)
189: continue;
190: n = sprint(one, "%d\t%.14s", de->d_ino, de->d_name);
191: n++; /* need the NUL too */
192: if (n > len)
193: break;
194: memcpy(buf, one, n);
195: len -= n;
196: buf += n;
197: }
198: *offp = off;
199: return (stlen - len);
200: }
201:
202: /*
203: * fetch an i-node
204: * -- no sanity check for now
205: * -- magic inode-to-disk-block stuff here
206: */
207:
208: #define LINOPB (BLSIZE/sizeof(struct dinode))
209: int
210: getino(f)
211: register Rfile *f;
212: {
213: char buf[BLSIZE];
214: register struct dinode *dp;
215: register unsigned int ioff;
216:
217: ioff = f->ino - 1;
218: lseek(devfd, (long)BLSIZE*(ioff/LINOPB + SUPERB + 1), 0);
219: if (read(devfd, buf, BLSIZE) != BLSIZE) {
220: /* print error */
221: return (0);
222: }
223: dp = ((struct dinode *)buf) + (ioff%LINOPB);
224: switch (dp->di_mode & IFMT) {
225: case IFREG:
226: case IFDIR:
227: case IFBLK:
228: case IFCHR:
229: break;
230:
231: default:
232: return (0); /* unalloc or illegal */
233: }
234: l11tol(fsp(f)->addr, dp->di_addr, NADDR);
235: f->dev = 0;
236: f->rdev = fsp(f)->addr[0]; /* perhaps wrong; who cares? */
237: f->mode = dp->di_mode;
238: f->nlink = dp->di_nlink;
239: f->uid = dp->di_uid;
240: f->gid = dp->di_gid;
241: f->size = p11long(dp->di_size);
242: f->tm = p11long(dp->di_mtime);
243: f->ta = p11long(dp->di_atime);
244: f->tc = p11long(dp->di_ctime);
245: return (1);
246: }
247:
248: l11tol(l3, l, n)
249: register unsigned char *l3, *l;
250: register int n;
251: {
252: while (--n >= 0) {
253: *l++ = l3[2];
254: *l++ = l3[3];
255: *l++ = l3[1];
256: *l++ = 0;
257: l3 += 3;
258: }
259: }
260:
261: long
262: p11long(l)
263: long l;
264: {
265: return ((l<<16) | ((l>>16)&0xffff));
266: }
267:
268: /*
269: * look up a file
270: */
271:
272: #define LNDPB (BLSIZE/sizeof(struct direct))
273:
274: int
275: dsearch(f, name)
276: Rfile *f;
277: char *name;
278: {
279: struct direct dbuf[LNDPB];
280: register struct direct *de;
281: register int i;
282: register long b, size;
283:
284: for (b = 0, size = f->size; size > 0; b++, size -= BLSIZE) {
285: if (getlblk(f, b, (char *)dbuf) == 0)
286: continue;
287: for (i = 0, de = dbuf; i < LNDPB; i++, de++) {
288: if (de->d_ino == 0)
289: continue;
290: if (strncmp(de->d_name, name, DIRSIZ) == 0)
291: return (de->d_ino);
292: }
293: }
294: return (0);
295: }
296:
297: /*
298: * read a block from a file
299: */
300: daddr_t bmap();
301:
302: getlblk(f, bno, buf)
303: Rfile *f;
304: daddr_t bno;
305: char *buf;
306: {
307: daddr_t dbno;
308:
309: if ((dbno = bmap(f, bno)) == 0) {
310: memset(buf, 0, BLSIZE);
311: return (1);
312: }
313: lseek(devfd, dbno*BLSIZE, 0);
314: if (read(devfd, buf, BLSIZE) != BLSIZE) {
315: fserrno = errno;
316: return (0);
317: }
318: return (1);
319: }
320:
321: /*
322: * logical to physical block
323: * only singly-indirect files for now
324: */
325: #define LNINDIR (BLSIZE/sizeof(daddr_t))
326:
327: daddr_t
328: bmap(f, bno)
329: register Rfile *f;
330: daddr_t bno;
331: {
332: daddr_t indbuf[LNINDIR];
333:
334: if (bno < NADDR - 3)
335: return (fsp(f)->addr[bno]);
336: bno -= NADDR - 3;
337: if (bno >= LNINDIR)
338: return (0);
339: lseek(devfd, fsp(f)->addr[NADDR-3]*BLSIZE, 0);
340: if (read(devfd, (char *)indbuf, BLSIZE) != BLSIZE)
341: return (0);
342: return (indbuf[bno]);
343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.