|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)sys.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: #include "../h/param.h"
10: #include "../h/inode.h"
11: #include "../h/fs.h"
12: #include "../h/dir.h"
13: #include "saio.h"
14:
15: ino_t dlook();
16:
17: struct dirstuff {
18: int loc;
19: struct iob *io;
20: };
21:
22: static
23: openi(n, io)
24: register struct iob *io;
25: {
26: register struct dinode *dp;
27: int cc;
28:
29: io->i_offset = 0;
30: io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
31: io->i_cc = io->i_fs.fs_bsize;
32: io->i_ma = io->i_buf;
33: cc = devread(io);
34: dp = (struct dinode *)io->i_buf;
35: io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
36: return (cc);
37: }
38:
39: static
40: find(path, file)
41: register char *path;
42: struct iob *file;
43: {
44: register char *q;
45: char c;
46: int n;
47:
48: if (path==NULL || *path=='\0') {
49: printf("null path\n");
50: return (0);
51: }
52:
53: if (openi((ino_t) ROOTINO, file) < 0) {
54: printf("can't read root inode\n");
55: return (0);
56: }
57: while (*path) {
58: while (*path == '/')
59: path++;
60: q = path;
61: while(*q != '/' && *q != '\0')
62: q++;
63: c = *q;
64: *q = '\0';
65: if (q == path) path = "." ; /* "/" means "/." */
66:
67: if ((n = dlook(path, file)) != 0) {
68: if (c == '\0')
69: break;
70: if (openi(n, file) < 0)
71: return (0);
72: *q = c;
73: path = q;
74: continue;
75: } else {
76: printf("%s: not found\n", path);
77: return (0);
78: }
79: }
80: return (n);
81: }
82:
83: static daddr_t
84: sbmap(io, bn)
85: register struct iob *io;
86: daddr_t bn;
87: {
88: register struct inode *ip;
89: int i, j, sh;
90: daddr_t nb, *bap;
91:
92: ip = &io->i_ino;
93: if (bn < 0) {
94: printf("bn negative\n");
95: return ((daddr_t)0);
96: }
97:
98: /*
99: * blocks 0..NDADDR are direct blocks
100: */
101: if(bn < NDADDR) {
102: nb = ip->i_db[bn];
103: return (nb);
104: }
105:
106: /*
107: * addresses NIADDR have single and double indirect blocks.
108: * the first step is to determine how many levels of indirection.
109: */
110: sh = 1;
111: bn -= NDADDR;
112: for (j = NIADDR; j > 0; j--) {
113: sh *= NINDIR(&io->i_fs);
114: if (bn < sh)
115: break;
116: bn -= sh;
117: }
118: if (j == 0) {
119: printf("bn ovf %D\n", bn);
120: return ((daddr_t)0);
121: }
122:
123: /*
124: * fetch the first indirect block address from the inode
125: */
126: nb = ip->i_ib[NIADDR - j];
127: if (nb == 0) {
128: printf("bn void %D\n",bn);
129: return ((daddr_t)0);
130: }
131:
132: /*
133: * fetch through the indirect blocks
134: */
135: for (; j <= NIADDR; j++) {
136: if (blknos[j] != nb) {
137: io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
138: io->i_ma = b[j];
139: io->i_cc = io->i_fs.fs_bsize;
140: if (devread(io) != io->i_fs.fs_bsize) {
141: if (io->i_error)
142: errno = io->i_error;
143: printf("bn %D: read error\n", io->i_bn);
144: return ((daddr_t)0);
145: }
146: blknos[j] = nb;
147: }
148: bap = (daddr_t *)b[j];
149: sh /= NINDIR(&io->i_fs);
150: i = (bn / sh) % NINDIR(&io->i_fs);
151: nb = bap[i];
152: if(nb == 0) {
153: printf("bn void %D\n",bn);
154: return ((daddr_t)0);
155: }
156: }
157: return (nb);
158: }
159:
160: static ino_t
161: dlook(s, io)
162: char *s;
163: register struct iob *io;
164: {
165: register struct direct *dp;
166: register struct inode *ip;
167: struct dirstuff dirp;
168: int len;
169:
170: if (s == NULL || *s == '\0')
171: return (0);
172: ip = &io->i_ino;
173: if ((ip->i_mode&IFMT) != IFDIR) {
174: printf("not a directory\n");
175: printf("%s: not a directory\n", s);
176: return (0);
177: }
178: if (ip->i_size == 0) {
179: printf("%s: zero length directory\n", s);
180: return (0);
181: }
182: len = strlen(s);
183: dirp.loc = 0;
184: dirp.io = io;
185: for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
186: if(dp->d_ino == 0)
187: continue;
188: if (dp->d_namlen == len && !strcmp(s, dp->d_name))
189: return (dp->d_ino);
190: }
191: return (0);
192: }
193:
194: /*
195: * get next entry in a directory.
196: */
197: struct direct *
198: readdir(dirp)
199: register struct dirstuff *dirp;
200: {
201: register struct direct *dp;
202: register struct iob *io;
203: daddr_t lbn, d;
204: int off;
205:
206: io = dirp->io;
207: for(;;) {
208: if (dirp->loc >= io->i_ino.i_size)
209: return (NULL);
210: off = blkoff(&io->i_fs, dirp->loc);
211: if (off == 0) {
212: lbn = lblkno(&io->i_fs, dirp->loc);
213: d = sbmap(io, lbn);
214: if(d == 0)
215: return NULL;
216: io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
217: io->i_ma = io->i_buf;
218: io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
219: if (devread(io) < 0) {
220: errno = io->i_error;
221: printf("bn %D: directory read error\n",
222: io->i_bn);
223: return (NULL);
224: }
225: }
226: dp = (struct direct *)(io->i_buf + off);
227: dirp->loc += dp->d_reclen;
228: if (dp->d_ino == 0)
229: continue;
230: return (dp);
231: }
232: }
233:
234: lseek(fdesc, addr, ptr)
235: int fdesc, ptr;
236: off_t addr;
237: {
238: register struct iob *io;
239:
240: #ifndef SMALL
241: if (ptr != 0) {
242: printf("Seek not from beginning of file\n");
243: errno = EOFFSET;
244: return (-1);
245: }
246: #endif SMALL
247: fdesc -= 3;
248: if (fdesc < 0 || fdesc >= NFILES ||
249: ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
250: errno = EBADF;
251: return (-1);
252: }
253: io->i_offset = addr;
254: io->i_bn = addr / DEV_BSIZE;
255: io->i_cc = 0;
256: return (0);
257: }
258:
259: getc(fdesc)
260: int fdesc;
261: {
262: register struct iob *io;
263: register struct fs *fs;
264: register char *p;
265: int c, lbn, off, size, diff;
266:
267:
268: if (fdesc >= 0 && fdesc <= 2)
269: return (getchar());
270: fdesc -= 3;
271: if (fdesc < 0 || fdesc >= NFILES ||
272: ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
273: errno = EBADF;
274: return (-1);
275: }
276: p = io->i_ma;
277: if (io->i_cc <= 0) {
278: if ((io->i_flgs & F_FILE) != 0) {
279: diff = io->i_ino.i_size - io->i_offset;
280: if (diff <= 0)
281: return (-1);
282: fs = &io->i_fs;
283: lbn = lblkno(fs, io->i_offset);
284: io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
285: off = blkoff(fs, io->i_offset);
286: size = blksize(fs, &io->i_ino, lbn);
287: } else {
288: io->i_bn = io->i_offset / DEV_BSIZE;
289: off = 0;
290: size = DEV_BSIZE;
291: }
292: io->i_ma = io->i_buf;
293: io->i_cc = size;
294: if (devread(io) < 0) {
295: errno = io->i_error;
296: return (-1);
297: }
298: if ((io->i_flgs & F_FILE) != 0) {
299: if (io->i_offset - off + size >= io->i_ino.i_size)
300: io->i_cc = diff + off;
301: io->i_cc -= off;
302: }
303: p = &io->i_buf[off];
304: }
305: io->i_cc--;
306: io->i_offset++;
307: c = (unsigned)*p++;
308: io->i_ma = p;
309: return (c);
310: }
311:
312: int errno;
313:
314: read(fdesc, buf, count)
315: int fdesc, count;
316: char *buf;
317: {
318: register i, size;
319: register struct iob *file;
320: register struct fs *fs;
321: int lbn, off;
322:
323: errno = 0;
324: if (fdesc >= 0 & fdesc <= 2) {
325: i = count;
326: do {
327: *buf = getchar();
328: } while (--i && *buf++ != '\n');
329: return (count - i);
330: }
331: fdesc -= 3;
332: if (fdesc < 0 || fdesc >= NFILES ||
333: ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
334: errno = EBADF;
335: return (-1);
336: }
337: if ((file->i_flgs&F_READ) == 0) {
338: errno = EBADF;
339: return (-1);
340: }
341: #ifndef SMALL
342: if ((file->i_flgs & F_FILE) == 0) {
343: file->i_cc = count;
344: file->i_ma = buf;
345: file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
346: i = devread(file);
347: file->i_offset += count;
348: if (i < 0)
349: errno = file->i_error;
350: return (i);
351: }
352: #endif SMALL
353: if (file->i_offset+count > file->i_ino.i_size)
354: count = file->i_ino.i_size - file->i_offset;
355: if ((i = count) <= 0)
356: return (0);
357: /*
358: * While reading full blocks, do I/O into user buffer.
359: * Anything else uses getc().
360: */
361: fs = &file->i_fs;
362: while (i) {
363: off = blkoff(fs, file->i_offset);
364: lbn = lblkno(fs, file->i_offset);
365: size = blksize(fs, &file->i_ino, lbn);
366: if (off == 0 && size <= i) {
367: file->i_bn = fsbtodb(fs, sbmap(file, lbn)) +
368: file->i_boff;
369: file->i_cc = size;
370: file->i_ma = buf;
371: if (devread(file) < 0) {
372: errno = file->i_error;
373: return (-1);
374: }
375: file->i_offset += size;
376: file->i_cc = 0;
377: buf += size;
378: i -= size;
379: } else {
380: size -= off;
381: if (size > i)
382: size = i;
383: i -= size;
384: do {
385: *buf++ = getc(fdesc+3);
386: } while (--size);
387: }
388: }
389: return (count);
390: }
391:
392: #ifndef SMALL
393: write(fdesc, buf, count)
394: int fdesc, count;
395: char *buf;
396: {
397: register i;
398: register struct iob *file;
399:
400: errno = 0;
401: if (fdesc >= 0 && fdesc <= 2) {
402: i = count;
403: while (i--)
404: putchar(*buf++);
405: return (count);
406: }
407: fdesc -= 3;
408: if (fdesc < 0 || fdesc >= NFILES ||
409: ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
410: errno = EBADF;
411: return (-1);
412: }
413: if ((file->i_flgs&F_WRITE) == 0) {
414: errno = EBADF;
415: return (-1);
416: }
417: file->i_cc = count;
418: file->i_ma = buf;
419: file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
420: i = devwrite(file);
421: file->i_offset += count;
422: if (i < 0)
423: errno = file->i_error;
424: return (i);
425: }
426: #endif SMALL
427:
428: int openfirst = 1;
429: #ifdef notyet
430: int opendev; /* last device opened; for boot to set bootdev */
431: extern int bootdev;
432: #endif notyet
433:
434: open(str, how)
435: char *str;
436: int how;
437: {
438: register char *cp;
439: int i;
440: register struct iob *file;
441: register struct devsw *dp;
442: int fdesc;
443: long atol();
444:
445: if (openfirst) {
446: for (i = 0; i < NFILES; i++)
447: iob[i].i_flgs = 0;
448: openfirst = 0;
449: }
450:
451: for (fdesc = 0; fdesc < NFILES; fdesc++)
452: if (iob[fdesc].i_flgs == 0)
453: goto gotfile;
454: _stop("No more file slots");
455: gotfile:
456: (file = &iob[fdesc])->i_flgs |= F_ALLOC;
457:
458: #ifdef notyet
459: for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++)
460: ;
461: if (*cp != ':') {
462: /* default bootstrap unit and device */
463: file->i_ino.i_dev = bootdev;
464: cp = str;
465: } else {
466: # define isdigit(n) ((n>='0') && (n<='9'))
467: /*
468: * syntax for possible device name:
469: * <alpha-string><digit-string><letter>:
470: */
471: for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
472: ;
473: for (dp = devsw; dp->dv_name; dp++) {
474: if (!strncmp(str, dp->dv_name,cp-str))
475: goto gotdev;
476: }
477: printf("unknown device\n");
478: file->i_flgs = 0;
479: errno = EDEV;
480: return (-1);
481: gotdev:
482: i = 0;
483: while (*cp >= '0' && *cp <= '9')
484: i = i * 10 + *cp++ - '0';
485: if (i < 0 || i > 255) {
486: printf("minor device number out of range (0-255)\n");
487: file->i_flgs = 0;
488: errno = EUNIT;
489: return (-1);
490: }
491: if (*cp >= 'a' && *cp <= 'h') {
492: if (i > 31) {
493: printf("unit number out of range (0-31)\n");
494: file->i_flgs = 0;
495: errno = EUNIT;
496: return (-1);
497: }
498: i = make_minor(i, *cp++ - 'a');
499: }
500:
501: if (*cp++ != ':') {
502: printf("incorrect device specification\n");
503: file->i_flgs = 0;
504: errno = EOFFSET;
505: return (-1);
506: }
507: opendev = file->i_ino.i_dev = makedev(dp-devsw, i);
508: }
509: file->i_boff = 0;
510: devopen(file);
511: if (cp != str && *cp == '\0') {
512: file->i_flgs |= how+1;
513: file->i_cc = 0;
514: file->i_offset = 0;
515: return (fdesc+3);
516: }
517: #else notyet
518: for (cp = str; *cp && *cp != '('; cp++)
519: ;
520: if (*cp != '(') {
521: printf("Bad device\n");
522: file->i_flgs = 0;
523: errno = EDEV;
524: return (-1);
525: }
526: *cp++ = '\0';
527: for (dp = devsw; dp->dv_name; dp++) {
528: if (!strcmp(str, dp->dv_name))
529: goto gotdev;
530: }
531: printf("Unknown device\n");
532: file->i_flgs = 0;
533: errno = ENXIO;
534: return (-1);
535: gotdev:
536: *(cp-1) = '(';
537: file->i_ino.i_dev = dp-devsw;
538: file->i_unit = *cp++ - '0';
539: if (*cp >= '0' && *cp <= '9')
540: file->i_unit = file->i_unit * 10 + *cp++ - '0';
541: if (file->i_unit < 0 || file->i_unit > 63) {
542: printf("Bad unit specifier\n");
543: file->i_flgs = 0;
544: errno = EUNIT;
545: return (-1);
546: }
547: if (*cp++ != ',') {
548: badoff:
549: printf("Missing offset specification\n");
550: file->i_flgs = 0;
551: errno = EOFFSET;
552: return (-1);
553: }
554: file->i_boff = atol(cp);
555: for (;;) {
556: if (*cp == ')')
557: break;
558: if (*cp++)
559: continue;
560: goto badoff;
561: }
562: devopen(file);
563: if (*++cp == '\0') {
564: file->i_flgs |= how+1;
565: file->i_cc = 0;
566: file->i_offset = 0;
567: return (fdesc+3);
568: }
569: #endif notyet
570: file->i_ma = (char *)(&file->i_fs);
571: file->i_cc = SBSIZE;
572: file->i_bn = SBLOCK + file->i_boff;
573: file->i_offset = 0;
574: if (devread(file) < 0) {
575: errno = file->i_error;
576: printf("super block read error\n");
577: return (-1);
578: }
579: if ((i = find(cp, file)) == 0) {
580: file->i_flgs = 0;
581: errno = ESRCH;
582: return (-1);
583: }
584: #ifndef SMALL
585: if (how != 0) {
586: printf("Can't write files yet.. Sorry\n");
587: file->i_flgs = 0;
588: errno = EIO;
589: return (-1);
590: }
591: #endif SMALL
592: if (openi(i, file) < 0) {
593: errno = file->i_error;
594: return (-1);
595: }
596: file->i_offset = 0;
597: file->i_cc = 0;
598: file->i_flgs |= F_FILE | (how+1);
599: return (fdesc+3);
600: }
601:
602: close(fdesc)
603: int fdesc;
604: {
605: struct iob *file;
606:
607: fdesc -= 3;
608: if (fdesc < 0 || fdesc >= NFILES ||
609: ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
610: errno = EBADF;
611: return (-1);
612: }
613: if ((file->i_flgs&F_FILE) == 0)
614: devclose(file);
615: file->i_flgs = 0;
616: return (0);
617: }
618:
619: #ifndef SMALL
620: ioctl(fdesc, cmd, arg)
621: int fdesc, cmd;
622: char *arg;
623: {
624: register struct iob *file;
625: int error = 0;
626:
627: fdesc -= 3;
628: if (fdesc < 0 || fdesc >= NFILES ||
629: ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
630: errno = EBADF;
631: return (-1);
632: }
633: switch (cmd) {
634:
635: case SAIOHDR:
636: file->i_flgs |= F_HDR;
637: break;
638:
639: case SAIOCHECK:
640: file->i_flgs |= F_CHECK;
641: break;
642:
643: case SAIOHCHECK:
644: file->i_flgs |= F_HCHECK;
645: break;
646:
647: case SAIONOBAD:
648: file->i_flgs |= F_NBSF;
649: break;
650:
651: case SAIODOBAD:
652: file->i_flgs &= ~F_NBSF;
653: break;
654:
655: default:
656: error = devioctl(file, cmd, arg);
657: break;
658: }
659: if (error < 0)
660: errno = file->i_error;
661: return (error);
662: }
663: #endif SMALL
664:
665: exit()
666: {
667: _stop("Exit called");
668: }
669:
670: _stop(s)
671: char *s;
672: {
673: int i;
674:
675: for (i = 0; i < NFILES; i++)
676: if (iob[i].i_flgs != 0)
677: close(i);
678: printf("%s\n", s);
679: _rtt();
680: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.