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