|
|
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 "saio.h"
8:
9: ino_t dlook();
10:
11: struct dirstuff {
12: int loc;
13: struct iob *io;
14: };
15:
16: static
17: openi(n, io)
18: register struct iob *io;
19: {
20: register struct dinode *dp;
21: int cc;
22:
23: io->i_offset = 0;
24: io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
25: io->i_cc = io->i_fs.fs_bsize;
26: io->i_ma = io->i_buf;
27: cc = devread(io);
28: dp = (struct dinode *)io->i_buf;
29: io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
30: return (cc);
31: }
32:
33: static
34: find(path, file)
35: register char *path;
36: struct iob *file;
37: {
38: register char *q;
39: char c;
40: int n;
41:
42: if (path==NULL || *path=='\0') {
43: printf("null path\n");
44: return (0);
45: }
46:
47: if (openi((ino_t) ROOTINO, file) < 0) {
48: printf("can't read root inode\n");
49: return (0);
50: }
51: while (*path) {
52: while (*path == '/')
53: path++;
54: q = path;
55: while(*q != '/' && *q != '\0')
56: q++;
57: c = *q;
58: *q = '\0';
59:
60: if ((n = dlook(path, file)) != 0) {
61: if (c == '\0')
62: break;
63: if (openi(n, file) < 0)
64: return (0);
65: *q = c;
66: path = q;
67: continue;
68: } else {
69: printf("%s not found\n", path);
70: return (0);
71: }
72: }
73: return (n);
74: }
75:
76: static daddr_t
77: sbmap(io, bn)
78: register struct iob *io;
79: daddr_t bn;
80: {
81: register struct inode *ip;
82: int i, j, sh;
83: daddr_t nb, *bap;
84:
85: ip = &io->i_ino;
86: if (bn < 0) {
87: printf("bn negative\n");
88: return ((daddr_t)0);
89: }
90:
91: /*
92: * blocks 0..NDADDR are direct blocks
93: */
94: if(bn < NDADDR) {
95: nb = ip->i_db[bn];
96: return (nb);
97: }
98:
99: /*
100: * addresses NIADDR have single and double indirect blocks.
101: * the first step is to determine how many levels of indirection.
102: */
103: sh = 1;
104: bn -= NDADDR;
105: for (j = NIADDR; j > 0; j--) {
106: sh *= NINDIR(&io->i_fs);
107: if (bn < sh)
108: break;
109: bn -= sh;
110: }
111: if (j == 0) {
112: printf("bn ovf %D\n", bn);
113: return ((daddr_t)0);
114: }
115:
116: /*
117: * fetch the first indirect block address from the inode
118: */
119: nb = ip->i_ib[NIADDR - 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 <= NIADDR; j++) {
129: if (blknos[j] != nb) {
130: io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
131: io->i_ma = b[j];
132: io->i_cc = io->i_fs.fs_bsize;
133: if (devread(io) != io->i_fs.fs_bsize) {
134: if (io->i_error)
135: errno = io->i_error;
136: printf("bn %D: read error\n", io->i_bn);
137: return ((daddr_t)0);
138: }
139: blknos[j] = nb;
140: }
141: bap = (daddr_t *)b[j];
142: sh /= NINDIR(&io->i_fs);
143: i = (bn / sh) % NINDIR(&io->i_fs);
144: nb = bap[i];
145: if(nb == 0) {
146: printf("bn void %D\n",bn);
147: return ((daddr_t)0);
148: }
149: }
150: return (nb);
151: }
152:
153: static ino_t
154: dlook(s, io)
155: char *s;
156: register struct iob *io;
157: {
158: register struct direct *dp;
159: register struct inode *ip;
160: struct dirstuff dirp;
161: int len;
162:
163: if (s == NULL || *s == '\0')
164: return (0);
165: ip = &io->i_ino;
166: if ((ip->i_mode&IFMT) != IFDIR) {
167: printf("not a directory\n");
168: return (0);
169: }
170: if (ip->i_size == 0) {
171: printf("zero length directory\n");
172: return (0);
173: }
174: len = strlen(s);
175: dirp.loc = 0;
176: dirp.io = io;
177: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
178: if(dp->d_ino == 0)
179: continue;
180: if (dp->d_namlen == len && !strcmp(s, dp->d_name))
181: return (dp->d_ino);
182: }
183: return (0);
184: }
185:
186: /*
187: * get next entry in a directory.
188: */
189: struct direct *
190: readdir(dirp)
191: register struct dirstuff *dirp;
192: {
193: register struct direct *dp;
194: register struct iob *io;
195: daddr_t lbn, d;
196: int off;
197:
198: io = dirp->io;
199: for(;;) {
200: if (dirp->loc >= io->i_ino.i_size)
201: return (NULL);
202: off = blkoff(&io->i_fs, dirp->loc);
203: if (off == 0) {
204: lbn = lblkno(&io->i_fs, dirp->loc);
205: d = sbmap(io, lbn);
206: if(d == 0)
207: return NULL;
208: io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
209: io->i_ma = io->i_buf;
210: io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
211: if (devread(io) < 0) {
212: errno = io->i_error;
213: printf("bn %D: read error\n", io->i_bn);
214: return (NULL);
215: }
216: }
217: dp = (struct direct *)(io->i_buf + off);
218: dirp->loc += dp->d_reclen;
219: if (dp->d_ino == 0)
220: continue;
221: return (dp);
222: }
223: }
224:
225: lseek(fdesc, addr, ptr)
226: int fdesc, ptr;
227: off_t addr;
228: {
229: register struct iob *io;
230:
231: if (ptr != 0) {
232: printf("Seek not from beginning of file\n");
233: errno = EOFFSET;
234: return (-1);
235: }
236: fdesc -= 3;
237: if (fdesc < 0 || fdesc >= NFILES ||
238: ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
239: errno = EBADF;
240: return (-1);
241: }
242: io->i_offset = addr;
243: io->i_bn = addr / DEV_BSIZE;
244: io->i_cc = 0;
245: return (0);
246: }
247:
248: getc(fdesc)
249: int fdesc;
250: {
251: register struct iob *io;
252: register struct fs *fs;
253: register char *p;
254: int c, lbn, off, size, diff;
255:
256:
257: if (fdesc >= 0 && fdesc <= 2)
258: return (getchar());
259: fdesc -= 3;
260: if (fdesc < 0 || fdesc >= NFILES ||
261: ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
262: errno = EBADF;
263: return (-1);
264: }
265: p = io->i_ma;
266: if (io->i_cc <= 0) {
267: if ((io->i_flgs & F_FILE) != 0) {
268: diff = io->i_ino.i_size - io->i_offset;
269: if (diff <= 0)
270: return (-1);
271: fs = &io->i_fs;
272: lbn = lblkno(fs, io->i_offset);
273: io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
274: off = blkoff(fs, io->i_offset);
275: size = blksize(fs, &io->i_ino, lbn);
276: } else {
277: io->i_bn = io->i_offset / DEV_BSIZE;
278: off = 0;
279: size = DEV_BSIZE;
280: }
281: io->i_ma = io->i_buf;
282: io->i_cc = size;
283: if (devread(io) < 0) {
284: errno = io->i_error;
285: return (-1);
286: }
287: if ((io->i_flgs & F_FILE) != 0) {
288: if (io->i_offset - off + size >= io->i_ino.i_size)
289: io->i_cc = diff + off;
290: io->i_cc -= off;
291: }
292: p = &io->i_buf[off];
293: }
294: io->i_cc--;
295: io->i_offset++;
296: c = (unsigned)*p++;
297: io->i_ma = p;
298: return (c);
299: }
300:
301: /* does this port?
302: getw(fdesc)
303: int fdesc;
304: {
305: register w,i;
306: register char *cp;
307: int val;
308:
309: for (i = 0, val = 0, cp = &val; 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: *cp++ = w;
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 > 31) {
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: devopen(file);
475: if (*++cp == '\0') {
476: file->i_flgs |= how+1;
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: return (-1);
489: }
490: if ((i = find(cp, file)) == 0) {
491: file->i_flgs = 0;
492: errno = ESRCH;
493: return (-1);
494: }
495: if (how != 0) {
496: printf("Can't write files yet.. Sorry\n");
497: file->i_flgs = 0;
498: errno = EIO;
499: return (-1);
500: }
501: if (openi(i, file) < 0) {
502: errno = file->i_error;
503: return (-1);
504: }
505: file->i_offset = 0;
506: file->i_cc = 0;
507: file->i_flgs |= F_FILE | (how+1);
508: return (fdesc+3);
509: }
510:
511: close(fdesc)
512: int fdesc;
513: {
514: struct iob *file;
515:
516: fdesc -= 3;
517: if (fdesc < 0 || fdesc >= NFILES ||
518: ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
519: errno = EBADF;
520: return (-1);
521: }
522: if ((file->i_flgs&F_FILE) == 0)
523: devclose(file);
524: file->i_flgs = 0;
525: return (0);
526: }
527:
528: ioctl(fdesc, cmd, arg)
529: int fdesc, cmd;
530: char *arg;
531: {
532: register struct iob *file;
533: int error = 0;
534:
535: fdesc -= 3;
536: if (fdesc < 0 || fdesc >= NFILES ||
537: ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
538: errno = EBADF;
539: return (-1);
540: }
541: switch (cmd) {
542:
543: case SAIOHDR:
544: file->i_flgs |= F_HDR;
545: break;
546:
547: case SAIOCHECK:
548: file->i_flgs |= F_CHECK;
549: break;
550:
551: case SAIOHCHECK:
552: file->i_flgs |= F_HCHECK;
553: break;
554:
555: case SAIONOBAD:
556: file->i_flgs |= F_NBSF;
557: break;
558:
559: case SAIODOBAD:
560: file->i_flgs &= ~F_NBSF;
561: break;
562:
563: case SAIOECCLIM:
564: file->i_flgs |= F_ECCLM;
565: break;
566:
567: case SAIOECCUNL:
568: file->i_flgs &= ~F_ECCLM;
569: break;
570:
571: case SAIOSEVRE:
572: file->i_flgs |= F_SEVRE;
573: break;
574:
575: case SAIONSEVRE:
576: file->i_flgs &= ~F_SEVRE;
577: break;
578:
579: default:
580: error = devioctl(file, cmd, arg);
581: break;
582: }
583: if (error < 0)
584: errno = file->i_error;
585: return (error);
586: }
587:
588: exit()
589: {
590: _stop("Exit called");
591: }
592:
593: _stop(s)
594: char *s;
595: {
596: int i;
597:
598: for (i = 0; i < NFILES; i++)
599: if (iob[i].i_flgs != 0)
600: close(i);
601: printf("%s\n", s);
602: _rtt();
603: }
604:
605: trap(ps)
606: int ps;
607: {
608: printf("Trap %o\n", ps);
609: for (;;)
610: ;
611: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.