|
|
1.1 root 1: #include <sys/param.h>
2: #include <sys/ino.h>
3: #include <sys/inode.h>
4: #include <sys/filsys.h>
5: #include <sys/dir.h>
6: #include "saio.h"
7:
8: ino_t dlook();
9:
10: static
11: openi(n,io)
12: register struct iob *io;
13: {
14: register struct dinode *dp;
15:
16: io->i_offset = 0;
17: io->i_bn = fsbtodb(itod(n)) + io->i_boff;
18: io->i_cc = BSIZE;
19: io->i_ma = io->i_buf;
20: devread(io);
21:
22: dp = (struct dinode *)io->i_buf;
23: dp = &dp[itoo(n)];
24: io->i_ino.i_number = n;
25: io->i_ino.i_mode = dp->di_mode;
26: io->i_ino.i_size = dp->di_size;
27: l3tol((char *)io->i_ino.i_un.i_addr, (char *)dp->di_addr, NADDR);
28: }
29:
30: static
31: find(path, file)
32: register char *path;
33: struct iob *file;
34: {
35: register char *q;
36: char c;
37: int n;
38:
39: if (path==NULL || *path=='\0') {
40: printf("null path\n");
41: return(0);
42: }
43:
44: openi((ino_t) ROOTINO, file);
45: while (*path) {
46: while (*path == '/')
47: path++;
48: q = path;
49: while(*q != '/' && *q != '\0')
50: q++;
51: c = *q;
52: *q = '\0';
53:
54: if ((n=dlook(path, file))!=0) {
55: if (c=='\0')
56: break;
57: openi(n, file);
58: *q = c;
59: path = q;
60: continue;
61: } else {
62: printf("%s not found\n",path);
63: return(0);
64: }
65: }
66: return(n);
67: }
68:
69: static daddr_t
70: sbmap(io, bn)
71: register struct iob *io;
72: daddr_t bn;
73: {
74: register i;
75: register struct inode *ip;
76: int j, sh;
77: daddr_t nb, *bap;
78: int ibn = bn;
79:
80: ip = &io->i_ino;
81: if(bn < 0) {
82: printf("bn negative\n");
83: return((daddr_t)0);
84: }
85:
86: /*
87: * blocks 0..NADDR-4 are direct blocks
88: */
89: if(bn < NADDR-3) {
90: i = bn;
91: nb = ip->i_un.i_addr[i];
92: return(nb);
93: }
94:
95: /*
96: * addresses NADDR-3, NADDR-2, and NADDR-1
97: * have single, double, triple indirect blocks.
98: * the first step is to determine
99: * how many levels of indirection.
100: */
101: sh = 0;
102: nb = 1;
103: bn -= NADDR-3;
104: for(j=3; j>0; j--) {
105: sh += NSHIFT;
106: nb <<= NSHIFT;
107: if(bn < nb)
108: break;
109: bn -= nb;
110: }
111: if(j == 0) {
112: printf("bn ovf %D\n",bn);
113: return((daddr_t)0);
114: }
115:
116: /*
117: * fetch the address from the inode
118: */
119: nb = ip->i_un.i_addr[NADDR-j];
120: if(nb == 0) {
121: printf("bn void %D\n",bn);
122: return((daddr_t)0);
123: }
124:
125: /*
126: * fetch through the indirect blocks
127: */
128: for(; j<=3; j++) {
129: if (blknos[j] != nb) {
130: io->i_bn = fsbtodb(nb) + io->i_boff;
131: io->i_ma = b[j];
132: io->i_cc = BSIZE;
133: devread(io);
134: bap = (daddr_t *)b[j];
135: blknos[j] = nb;
136: }
137: bap = (daddr_t *)b[j];
138: sh -= NSHIFT;
139: i = (bn>>sh) & NMASK;
140: nb = bap[i];
141: if(nb == 0) {
142: printf("bn void %D\n",bn);
143: return((daddr_t)0);
144: }
145: }
146: return(nb);
147: }
148:
149: static ino_t
150: dlook(s, io)
151: char *s;
152: register struct iob *io;
153: {
154: register struct direct *dp;
155: register struct inode *ip;
156: daddr_t bn;
157: int n,dc;
158:
159: if (s==NULL || *s=='\0')
160: return(0);
161: ip = &io->i_ino;
162: if ((ip->i_mode&IFMT)!=IFDIR) {
163: printf("not a directory\n");
164: return(0);
165: }
166:
167: n = ip->i_size/sizeof(struct direct);
168:
169: if (n==0) {
170: printf("zero length directory\n");
171: return(0);
172: }
173:
174: dc = BSIZE;
175: bn = (daddr_t)0;
176: while(n--) {
177: if (++dc >= BSIZE/sizeof(struct direct)) {
178: io->i_bn = fsbtodb(sbmap(io, bn++)) + io->i_boff;
179: io->i_ma = io->i_buf;
180: io->i_cc = BSIZE;
181: devread(io);
182: dp = (struct direct *)io->i_buf;
183: dc = 0;
184: }
185:
186: if (match(s, dp->d_name))
187: return(dp->d_ino);
188: dp++;
189: }
190: return(0);
191: }
192:
193: static
194: match(s1,s2)
195: register char *s1,*s2;
196: {
197: register cc;
198:
199: cc = DIRSIZ;
200: while (cc--) {
201: if (*s1 != *s2)
202: return(0);
203: if (*s1++ && *s2++)
204: continue; else
205: return(1);
206: }
207: return(1);
208: }
209:
210: lseek(fdesc, addr, ptr)
211: int fdesc;
212: off_t addr;
213: int ptr;
214: {
215: register struct iob *io;
216:
217: if (ptr != 0) {
218: printf("Seek not from beginning of file\n");
219: return(-1);
220: }
221: fdesc -= 3;
222: if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
223: return(-1);
224: io->i_offset = addr;
225: io->i_bn = fsbtodb(addr/BSIZE) + io->i_boff;
226: io->i_cc = 0;
227: return(0);
228: }
229:
230: getc(fdesc)
231: int fdesc;
232: {
233: register struct iob *io;
234: register char *p;
235: register c;
236: int off;
237:
238:
239: if (fdesc >= 0 && fdesc <= 2)
240: return(getchar());
241: fdesc -= 3;
242: if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
243: return(-1);
244: p = io->i_ma;
245: if (io->i_cc <= 0) {
246: io->i_bn = fsbtodb(io->i_offset/(off_t)BSIZE);
247: if (io->i_flgs&F_FILE)
248: io->i_bn = fsbtodb(sbmap(io, dbtofsb(io->i_bn))) + io->i_boff;
249: io->i_ma = io->i_buf;
250: io->i_cc = BSIZE;
251: devread(io);
252: if (io->i_flgs&F_FILE) {
253: off = io->i_offset % (off_t)BSIZE;
254: if (io->i_offset+(BSIZE-off) >= io->i_ino.i_size)
255: io->i_cc = io->i_ino.i_size - io->i_offset + off;
256: io->i_cc -= off;
257: if (io->i_cc <= 0)
258: return(-1);
259: } else
260: off = 0;
261: p = &io->i_buf[off];
262: }
263: io->i_cc--;
264: io->i_offset++;
265: c = (unsigned)*p++;
266: io->i_ma = p;
267: return(c);
268: }
269: /* does this port?
270: getw(fdesc)
271: int fdesc;
272: {
273: register w,i;
274: register char *cp;
275: int val;
276:
277: for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
278: w = getc(fdesc);
279: if (w < 0) {
280: if (i == 0)
281: return(-1);
282: else
283: return(val);
284: }
285: *cp++ = w;
286: }
287: return(val);
288: }
289: */
290:
291: read(fdesc, buf, count)
292: int fdesc;
293: char *buf;
294: int count;
295: {
296: register i;
297: register struct iob *file;
298:
299: if (fdesc >= 0 & fdesc <= 2) {
300: i = count;
301: do {
302: *buf = getchar();
303: } while (--i && *buf++ != '\n');
304: return(count - i);
305: }
306: fdesc -= 3;
307: if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
308: return(-1);
309: if ((file->i_flgs&F_READ) == 0)
310: return(-1);
311: if ((file->i_flgs&F_FILE) == 0) {
312: file->i_cc = count;
313: file->i_ma = buf;
314: i = devread(file);
315: file->i_bn += CLSIZE;
316: return(i);
317: }
318: else {
319: if (file->i_offset+count > file->i_ino.i_size)
320: count = file->i_ino.i_size - file->i_offset;
321: if ((i = count) <= 0)
322: return(0);
323: do {
324: *buf++ = getc(fdesc+3);
325: } while (--i);
326: return(count);
327: }
328: }
329:
330: write(fdesc, buf, count)
331: int fdesc;
332: char *buf;
333: int count;
334: {
335: register i;
336: register struct iob *file;
337:
338: if (fdesc >= 0 && fdesc <= 2) {
339: i = count;
340: while (i--)
341: putchar(*buf++);
342: return(count);
343: }
344: fdesc -= 3;
345: if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
346: return(-1);
347: if ((file->i_flgs&F_WRITE) == 0)
348: return(-1);
349: file->i_cc = count;
350: file->i_ma = buf;
351: i = devwrite(file);
352: file->i_bn += CLSIZE;
353: return(i);
354: }
355:
356: open(str, how)
357: char *str;
358: int how;
359: {
360: register char *cp;
361: int i;
362: register struct iob *file;
363: register struct devsw *dp;
364: int fdesc;
365: static first = 1;
366: long atol();
367:
368: if (first) {
369: for (i = 0; i < NFILES; i++)
370: iob[i].i_flgs = 0;
371: first = 0;
372: }
373:
374: for (fdesc = 0; fdesc < NFILES; fdesc++)
375: if (iob[fdesc].i_flgs == 0)
376: goto gotfile;
377: _stop("No more file slots");
378: gotfile:
379: (file = &iob[fdesc])->i_flgs |= F_ALLOC;
380:
381: for (cp = str; *cp && *cp != '('; cp++)
382: ;
383: if (*cp != '(') {
384: printf("Bad device\n");
385: file->i_flgs = 0;
386: return(-1);
387: }
388: *cp++ = '\0';
389: for (dp = devsw; dp->dv_name; dp++) {
390: if (match(str, dp->dv_name))
391: goto gotdev;
392: }
393: printf("Unknown device\n");
394: file->i_flgs = 0;
395: return(-1);
396: gotdev:
397: *(cp-1) = '(';
398: file->i_ino.i_dev = dp-devsw;
399: file->i_unit = *cp++ - '0';
400: if (file->i_unit < 0 || file->i_unit > 7) {
401: printf("Bad unit specifier\n");
402: file->i_flgs = 0;
403: return(-1);
404: }
405: if (*cp++ != ',') {
406: badoff:
407: printf("Missing offset specification\n");
408: file->i_flgs = 0;
409: return(-1);
410: }
411: file->i_boff = atol(cp);
412: for (;;) {
413: if (*cp == ')')
414: break;
415: if (*cp++)
416: continue;
417: goto badoff;
418: }
419: devopen(file);
420: if (*++cp == '\0') {
421: file->i_flgs |= how+1;
422: file->i_cc = 0;
423: file->i_offset = 0;
424: return(fdesc+3);
425: }
426: if ((i = find(cp, file)) == 0) {
427: file->i_flgs = 0;
428: return(-1);
429: }
430: if (how != 0) {
431: printf("Can't write files yet.. Sorry\n");
432: file->i_flgs = 0;
433: return(-1);
434: }
435: openi(i, file);
436: file->i_offset = 0;
437: file->i_cc = 0;
438: file->i_flgs |= F_FILE | (how+1);
439: return(fdesc+3);
440: }
441:
442: close(fdesc)
443: int fdesc;
444: {
445: struct iob *file;
446:
447: fdesc -= 3;
448: if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
449: return(-1);
450: if ((file->i_flgs&F_FILE) == 0)
451: devclose(file);
452: file->i_flgs = 0;
453: return(0);
454: }
455:
456: exit()
457: {
458: _stop("Exit called");
459: }
460:
461: _stop(s)
462: char *s;
463: {
464: printf("%s\n", s);
465: _rtt();
466: }
467:
468: trap(ps)
469: int ps;
470: {
471: printf("Trap %o\n", ps);
472: for (;;)
473: ;
474: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.