Annotation of 43BSD/sys/stand/sys.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.