|
|
1.1 root 1: /* sys.c 4.4 81/03/22 */
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(io->i_blksz, itod(io->i_blksz, n)) + io->i_boff;
20: io->i_cc = BSIZE(io->i_blksz);
21: io->i_ma = io->i_buf;
22: devread(io);
23:
24: dp = (struct dinode *)io->i_buf;
25: dp = &dp[itoo(io->i_blksz, 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(io->i_blksz);
108: nb <<= NSHIFT(io->i_blksz);
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(io->i_blksz, nb) + io->i_boff;
133: io->i_ma = b[j];
134: io->i_cc = BSIZE(io->i_blksz);
135: devread(io);
136: bap = (daddr_t *)b[j];
137: blknos[j] = nb;
138: }
139: bap = (daddr_t *)b[j];
140: sh -= NSHIFT(io->i_blksz);
141: i = (bn>>sh) & NMASK(io->i_blksz);
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(io->i_blksz);
177: bn = (daddr_t)0;
178: while(n--) {
179: if (++dc >= BSIZE(io->i_blksz)/sizeof(struct direct)) {
180: io->i_bn = fsbtodb(io->i_blksz, sbmap(io, bn++)) + io->i_boff;
181: io->i_ma = io->i_buf;
182: io->i_cc = BSIZE(io->i_blksz);
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(io->i_blksz, addr/BSIZE(io->i_blksz)) + 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_blksz,
249: io->i_offset/(off_t)BSIZE(io->i_blksz));
250: if (io->i_flgs&F_FILE)
251: io->i_bn = fsbtodb(io->i_blksz,
252: sbmap(io, dbtofsb(io->i_blksz, io->i_bn))) + io->i_boff;
253: io->i_ma = io->i_buf;
254: io->i_cc = BSIZE(io->i_blksz);
255: devread(io);
256: if (io->i_flgs&F_FILE) {
257: off = io->i_offset % (off_t)BSIZE(io->i_blksz);
258: if (io->i_offset+(BSIZE(io->i_blksz)-off) >= io->i_ino.i_size)
259: io->i_cc = io->i_ino.i_size - io->i_offset + off;
260: io->i_cc -= off;
261: if (io->i_cc <= 0)
262: return(-1);
263: } else
264: off = 0;
265: p = &io->i_buf[off];
266: }
267: io->i_cc--;
268: io->i_offset++;
269: c = (unsigned)*p++;
270: io->i_ma = p;
271: return(c);
272: }
273: /* does this port?
274: getw(fdesc)
275: int fdesc;
276: {
277: register w,i;
278: register char *cp;
279: int val;
280:
281: for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
282: w = getc(fdesc);
283: if (w < 0) {
284: if (i == 0)
285: return(-1);
286: else
287: return(val);
288: }
289: *cp++ = w;
290: }
291: return(val);
292: }
293: */
294:
295: read(fdesc, buf, count)
296: int fdesc;
297: char *buf;
298: int count;
299: {
300: register i;
301: register struct iob *file;
302:
303: if (fdesc >= 0 & fdesc <= 2) {
304: i = count;
305: do {
306: *buf = getchar();
307: } while (--i && *buf++ != '\n');
308: return(count - i);
309: }
310: fdesc -= 3;
311: if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
312: return(-1);
313: if ((file->i_flgs&F_READ) == 0)
314: return(-1);
315: if ((file->i_flgs&F_FILE) == 0) {
316: file->i_cc = count;
317: file->i_ma = buf;
318: i = devread(file);
319: file->i_bn += CLSIZE;
320: return(i);
321: }
322: else {
323: if (file->i_offset+count > file->i_ino.i_size)
324: count = file->i_ino.i_size - file->i_offset;
325: if ((i = count) <= 0)
326: return(0);
327: do {
328: *buf++ = getc(fdesc+3);
329: } while (--i);
330: return(count);
331: }
332: }
333:
334: write(fdesc, buf, count)
335: int fdesc;
336: char *buf;
337: int count;
338: {
339: register i;
340: register struct iob *file;
341:
342: if (fdesc >= 0 && fdesc <= 2) {
343: i = count;
344: while (i--)
345: putchar(*buf++);
346: return(count);
347: }
348: fdesc -= 3;
349: if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
350: return(-1);
351: if ((file->i_flgs&F_WRITE) == 0)
352: return(-1);
353: file->i_cc = count;
354: file->i_ma = buf;
355: i = devwrite(file);
356: file->i_bn += CLSIZE;
357: return(i);
358: }
359:
360: int openfirst = 1;
361:
362: open(str, how)
363: char *str;
364: int how;
365: {
366: register char *cp;
367: int i;
368: register struct iob *file;
369: register struct devsw *dp;
370: int fdesc;
371: long atol();
372:
373: if (openfirst) {
374: for (i = 0; i < NFILES; i++)
375: iob[i].i_flgs = 0;
376: openfirst = 0;
377: }
378:
379: for (fdesc = 0; fdesc < NFILES; fdesc++)
380: if (iob[fdesc].i_flgs == 0)
381: goto gotfile;
382: _stop("No more file slots");
383: gotfile:
384: (file = &iob[fdesc])->i_flgs |= F_ALLOC;
385:
386: for (cp = str; *cp && *cp != '('; cp++)
387: ;
388: if (*cp != '(') {
389: printf("Bad device\n");
390: file->i_flgs = 0;
391: return(-1);
392: }
393: *cp++ = '\0';
394: for (dp = devsw; dp->dv_name; dp++) {
395: if (match(str, dp->dv_name))
396: goto gotdev;
397: }
398: printf("Unknown device\n");
399: file->i_flgs = 0;
400: return(-1);
401: gotdev:
402: *(cp-1) = '(';
403: file->i_ino.i_dev = dp-devsw;
404: file->i_blksz = devsw[file->i_ino.i_dev].dv_size;
405: file->i_unit = *cp++ - '0';
406: if (*cp >= '0' && *cp <= '9')
407: file->i_unit = file->i_unit * 10 + *cp++ - '0';
408: if (file->i_unit < 0 || file->i_unit > 31) {
409: printf("Bad unit specifier\n");
410: file->i_flgs = 0;
411: return(-1);
412: }
413: if (*cp++ != ',') {
414: badoff:
415: printf("Missing offset specification\n");
416: file->i_flgs = 0;
417: return(-1);
418: }
419: file->i_boff = atol(cp);
420: for (;;) {
421: if (*cp == ')')
422: break;
423: if (*cp++)
424: continue;
425: goto badoff;
426: }
427: devopen(file);
428: if (*++cp == '\0') {
429: file->i_flgs |= how+1;
430: file->i_cc = 0;
431: file->i_offset = 0;
432: return(fdesc+3);
433: }
434: if ((i = find(cp, file)) == 0) {
435: file->i_flgs = 0;
436: return(-1);
437: }
438: if (how != 0) {
439: printf("Can't write files yet.. Sorry\n");
440: file->i_flgs = 0;
441: return(-1);
442: }
443: openi(i, file);
444: file->i_offset = 0;
445: file->i_cc = 0;
446: file->i_flgs |= F_FILE | (how+1);
447: return(fdesc+3);
448: }
449:
450: close(fdesc)
451: int fdesc;
452: {
453: struct iob *file;
454:
455: fdesc -= 3;
456: if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
457: return(-1);
458: #if NOTDEF /* ntw */
459: if ((file->i_flgs&F_FILE) == 0)
460: #endif
461: devclose(file);
462: file->i_flgs = 0;
463: return(0);
464: }
465:
466: exit()
467: {
468: _stop("Exit called");
469: }
470:
471: _stop(s)
472: char *s;
473: {
474: int i;
475:
476: for (i = 0; i < NFILES; i++)
477: if (iob[i].i_flgs != 0)
478: close(i);
479: printf("%s\n", s);
480: _rtt();
481: }
482:
483: trap(ps)
484: int ps;
485: {
486: printf("Trap %o\n", ps);
487: for (;;)
488: ;
489: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.