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