|
|
1.1 root 1: /*
2: * read a 512-byte VAX-ordered Unix filesystem
3: * quick, cheap hack
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[1], 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: l3tol(fsp(f)->addr, dp->di_addr, NADDR);
235: f->dev = 0;
236: f->rdev = fsp(f)->addr[0];
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 = dp->di_size;
242: f->tm = dp->di_mtime;
243: f->ta = dp->di_atime;
244: f->tc = dp->di_ctime;
245: return (1);
246: }
247:
248: /*
249: * look up a file
250: */
251:
252: #define LNDPB (BLSIZE/sizeof(struct direct))
253:
254: int
255: dsearch(f, name)
256: Rfile *f;
257: char *name;
258: {
259: struct direct dbuf[LNDPB];
260: register struct direct *de;
261: register int i;
262: register long b, size;
263:
264: for (b = 0, size = f->size; size > 0; b++, size -= BLSIZE) {
265: if (getlblk(f, b, (char *)dbuf) == 0)
266: continue;
267: for (i = 0, de = dbuf; i < LNDPB; i++, de++) {
268: if (de->d_ino == 0)
269: continue;
270: if (strncmp(de->d_name, name, DIRSIZ) == 0)
271: return (de->d_ino);
272: }
273: }
274: return (0);
275: }
276:
277: /*
278: * read a block from a file
279: */
280: daddr_t bmap();
281:
282: getlblk(f, bno, buf)
283: Rfile *f;
284: daddr_t bno;
285: char *buf;
286: {
287: daddr_t dbno;
288:
289: if ((dbno = bmap(f, bno)) == 0) {
290: memset(buf, 0, BLSIZE);
291: return (1);
292: }
293: lseek(devfd, dbno*BLSIZE, 0);
294: if (read(devfd, buf, BLSIZE) != BLSIZE) {
295: fserrno = errno;
296: return (0);
297: }
298: return (1);
299: }
300:
301: /*
302: * logical to physical block
303: * only singly-indirect files for now
304: */
305: #define LNINDIR (BLSIZE/sizeof(daddr_t))
306:
307: daddr_t
308: bmap(f, bno)
309: register Rfile *f;
310: daddr_t bno;
311: {
312: daddr_t indbuf[LNINDIR];
313:
314: if (bno < NADDR - 3)
315: return (fsp(f)->addr[bno]);
316: bno -= NADDR - 3;
317: if (bno >= LNINDIR)
318: return (0);
319: lseek(devfd, fsp(f)->addr[NADDR-3]*BLSIZE, 0);
320: if (read(devfd, (char *)indbuf, BLSIZE) != BLSIZE)
321: return (0);
322: return (indbuf[bno]);
323: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.