|
|
1.1 root 1: /*
2: * read an old (V6 and before) PDP-11 Unix filesystem
3: * quick, cheap hack; runs only on VAXes
4: */
5:
6: /*
7: * miscellaneous filesystem definitions
8: * some are magic numbers here
9: */
10:
11: #include <stdio.h>
12: #include <sys/types.h>
13: #include <sys/inode.h>
14: #include <sys/dir.h> /* hack: pdp11 dirs == vax dirs */
15:
16: #define BLSIZE 512
17:
18: /*
19: * v6 disk inode
20: */
21: #define V6NADDR 8
22:
23: struct v6dinode {
24: short flags;
25: unsigned char nlinks;
26: unsigned char uid;
27: unsigned char gid;
28: unsigned char hisize;
29: unsigned short losize;
30: unsigned short addr[V6NADDR];
31: unsigned short atime[2]; /* pdp-11 order */
32: unsigned short mtime[2]; /* pdp-11 order */
33: };
34:
35: /*
36: * type part of mode
37: */
38: #define V6FMT 0160000
39: #define V6IFREG 0100000
40: #define V6IFDIR 0140000
41: #define V6IFCHR 0120000
42: #define V6IFBLK 0160000
43: #define V6MODE 07777
44: #define V6LARGE 010000
45:
46: #define V6SUPERB 1
47: #define V6ROOT 1 /* root inode */
48:
49: /*
50: * local file data
51: */
52: typedef struct Fsfile {
53: long addr[V6NADDR];
54: int large;
55: } Fsfile;
56:
57: #define fsp(f) ((Fsfile *)((f)->fs))
58:
59: #include "rf.h"
60: #include <errno.h>
61: #include <libc.h>
62:
63: int fserrno;
64: static int devfd;
65: static Rfile *root;
66:
67: /*
68: * init:
69: * open the device
70: */
71:
72: Rfile *
73: fsinit(argc, argv)
74: int argc;
75: char **argv;
76: {
77: register Rfile *f;
78: char *passwd, *group;
79:
80: if (argc <= 1)
81: rfpanic("no device specified\n");
82: if ((devfd = open(argv[1], 0)) < 0)
83: rfpanic("%s: cannot open\n", argv[1]);
84: if (argc > 2)
85: passwd = argv[2];
86: else
87: passwd = "/etc/passwd";
88: if (argc > 3)
89: group = argv[3];
90: else
91: group = "/etc/group";
92: rfuidmap = rfmkidmap(passwd, (Namemap *)0);
93: rfgidmap = rfmkidmap(group, (Namemap *)0);
94: /* never mind the super-block */
95: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL)
96: rfpanic("no mem for root\n");
97: if ((f->fs = malloc(sizeof(Fsfile))) == NULL)
98: rfpanic("no mem for root\n");
99: f->ino = V6ROOT;
100: fsstat(f);
101: root = f;
102: return (f);
103: }
104:
105: /*
106: * access a file
107: */
108:
109: Rfile *
110: fswalk(df, name)
111: Rfile *df;
112: char *name;
113: {
114: register Rfile *f;
115: int ino;
116:
117: if ((ino = dsearch(df, name)) == 0) {
118: fserrno = ENOENT;
119: return (NULL);
120: }
121: if (df == root) { /* "." and ".." magic */
122: if (strcmp(name, ".") == 0)
123: return (df);
124: if (strcmp(name, "..") == 0) {
125: fserrno = 0; /* pseudo-error: popped out of root */
126: return (NULL);
127: }
128: }
129: if ((f = (Rfile *)malloc(sizeof(Rfile))) == NULL) {
130: fserrno = ENOMEM;
131: return (NULL);
132: }
133: if ((f->fs = malloc(sizeof(Fsfile))) == NULL) {
134: free((char *)f);
135: fserrno = ENOMEM;
136: return (NULL);
137: }
138: f->ino = ino;
139: fsstat(f);
140: return (f);
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: int
160: fsstat(f)
161: Rfile *f;
162: {
163:
164: getino(f);
165: return (0);
166: }
167:
168: /*
169: * read data
170: */
171: int
172: fsread(f, off, buf, len)
173: register Rfile *f;
174: long off;
175: char *buf;
176: int len;
177: {
178: char blk[BLSIZE];
179: int rest;
180: daddr_t bno;
181:
182: switch (f->mode & IFMT) {
183: case IFREG:
184: case IFDIR:
185: break;
186:
187: default:
188: return (0);
189: }
190: if (off >= f->size)
191: return (0);
192: if (off + len > f->size)
193: len = f->size - off;
194: bno = off / BLSIZE;
195: if (getlblk(f, bno, blk) == 0)
196: return (-1);
197: rest = (bno + 1)*BLSIZE - off;
198: if (len > rest)
199: len = rest;
200: memcpy(buf, blk + (off % BLSIZE), len);
201: return (len);
202: }
203:
204: /*
205: * read a piece of a directory
206: * -- cheap out for now: just return one
207: */
208: int
209: fsdirread(f, off, buf, len, offp)
210: register Rfile *f;
211: long off;
212: char *buf;
213: int len;
214: long *offp;
215: {
216: int stlen;
217: register struct direct *de;
218: char blk[BLSIZE];
219: char one[BLSIZE];
220: int n;
221:
222: if (off % sizeof(struct direct)) {
223: fserrno = EINVAL;
224: return (-1);
225: }
226: stlen = len;
227: de = (struct direct *)&blk[BLSIZE];
228: for (; off < f->size; de++, off += sizeof(struct direct)) {
229: if (de >= (struct direct *)&blk[BLSIZE]) {
230: if (getlblk(f, off/BLSIZE, blk) == 0)
231: break;
232: de = (struct direct *)&blk[off%BLSIZE];
233: }
234: if (de->d_ino == 0)
235: continue;
236: n = sprintf(one, "%d\t%.14s", de->d_ino, de->d_name);
237: n++; /* need the NUL too */
238: if (n > len)
239: break;
240: memcpy(buf, one, n);
241: len -= n;
242: buf += n;
243: }
244: *offp = off;
245: return (stlen - len);
246: }
247:
248: /*
249: * fetch an i-node
250: * -- no sanity check for now
251: * -- magic inode-to-disk-block stuff here
252: */
253:
254: #define LINOPB (BLSIZE/sizeof(struct v6dinode))
255: int
256: getino(f)
257: register Rfile *f;
258: {
259: char buf[BLSIZE];
260: register struct v6dinode *dp;
261: register int ioff;
262: register int i;
263: int mode;
264:
265: ioff = f->ino - 1;
266: lseek(devfd, (long)BLSIZE*(ioff/LINOPB + V6SUPERB + 1), 0);
267: if (read(devfd, buf, BLSIZE) != BLSIZE) {
268: /* print error */
269: return (0);
270: }
271: dp = ((struct v6dinode *)buf) + (ioff%LINOPB);
272: switch (dp->flags & V6FMT) {
273: case V6IFREG:
274: mode = IFREG;
275: break;
276:
277: case V6IFDIR:
278: mode = IFDIR;
279: break;
280:
281: case V6IFCHR:
282: mode = IFCHR;
283: break;
284:
285: case V6IFBLK:
286: mode = IFBLK;
287: break;
288:
289: default:
290: return (0); /* unalloc or illegal */
291: }
292: for (i = 0; i < V6NADDR; i++)
293: fsp(f)->addr[i] = dp->addr[i];
294: f->dev = 0; /* all the same device */
295: f->rdev = fsp(f)->addr[0];
296: f->mode = mode | (dp->flags & V6MODE);
297: fsp(f)->large = (dp->flags & V6LARGE) != 0;
298: f->nlink = dp->nlinks;
299: f->uid = dp->uid;
300: f->gid = dp->gid;
301: f->size = (dp->hisize << 16) + dp->losize;
302: f->tm = (dp->mtime[0]<<16) + dp->mtime[1];
303: f->ta = (dp->atime[0]<<16) + dp->atime[1];
304: f->tc = f->tm;
305: return (1);
306: }
307:
308: /*
309: * look up a file
310: */
311:
312: #define LNDPB (BLSIZE/sizeof(struct direct))
313:
314: int
315: dsearch(f, name)
316: Rfile *f;
317: char *name;
318: {
319: struct direct dbuf[LNDPB];
320: register struct direct *de;
321: register int i;
322: register long b, size;
323:
324: for (b = 0, size = f->size; size > 0; b++, size -= BLSIZE) {
325: if (getlblk(f, b, (char *)dbuf) == 0)
326: continue;
327: for (i = 0, de = dbuf; i < LNDPB; i++, de++) {
328: if (de->d_ino == 0)
329: continue;
330: if (strncmp(de->d_name, name, DIRSIZ) == 0)
331: return (de->d_ino);
332: }
333: }
334: return (0);
335: }
336:
337: /*
338: * read a block from a file
339: */
340: daddr_t bmap();
341:
342: getlblk(f, bno, buf)
343: Rfile *f;
344: daddr_t bno;
345: char *buf;
346: {
347: daddr_t dbno;
348:
349: if ((dbno = bmap(f, bno)) == 0) {
350: memset(buf, 0, BLSIZE);
351: return (1);
352: }
353: lseek(devfd, dbno*BLSIZE, 0);
354: if (read(devfd, buf, BLSIZE) != BLSIZE) {
355: fserrno = errno;
356: return (0);
357: }
358: return (1);
359: }
360:
361: /*
362: * logical to physical block
363: * only singly-indirect files for now
364: */
365: #define LNINDIR (BLSIZE/sizeof(unsigned short))
366:
367: daddr_t
368: bmap(f, bno)
369: register Rfile *f;
370: daddr_t bno;
371: {
372: unsigned short indbuf[LNINDIR];
373:
374: if (fsp(f)->large == 0) {
375: if (bno < V6NADDR)
376: return (fsp(f)->addr[bno]);
377: return (0);
378: }
379: if (bno < V6NADDR*LNINDIR) {
380: lseek(devfd, fsp(f)->addr[bno/LNINDIR]*BLSIZE, 0);
381: if (read(devfd, (char *)indbuf, BLSIZE) != BLSIZE)
382: return (0);
383: return (indbuf[bno%LNINDIR]);
384: }
385: return (0);
386: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.