Annotation of coherent/b/STREAMS/coh.386/sys5.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * coh.386/sys5.c
        !             3:  *
        !             4:  * System calls introduced when going from COH 286 to COH 386.
        !             5:  *
        !             6:  * Revised: Mon Jul 12 12:27:55 1993 CDT
        !             7:  */ 
        !             8: #include <sys/coherent.h>
        !             9: #include <sys/buf.h>
        !            10: #include <sys/errno.h>
        !            11: #include <canon.h>
        !            12: #include <sys/con.h>
        !            13: #include <fcntl.h>
        !            14: #include <sys/fd.h>
        !            15: #include <sys/filsys.h>
        !            16: #include <sys/ino.h>
        !            17: #include <sys/inode.h>
        !            18: #include <sys/io.h>
        !            19: #include <sys/mount.h>
        !            20: #include <sys/stat.h>
        !            21: #include <dirent.h>
        !            22: #include <sys/utsname.h>
        !            23: #include <sys/mount.h>
        !            24: #include <ustat.h>
        !            25: #include <sys/statfs.h>
        !            26: #include <sys/sysi86.h>
        !            27: #include <sys/file.h>
        !            28: #include <ulimit.h>
        !            29: 
        !            30: 
        !            31: utime(tp)
        !            32: long *tp;
        !            33: {
        !            34:        return timer.t_time;
        !            35: }
        !            36: 
        !            37: /*
        !            38:  * Return an unique number.
        !            39:  */
        !            40: usysi86(f, arg1)
        !            41: {
        !            42:        register MOUNT *mp;
        !            43:        register struct filsys *fsp;
        !            44:        extern void (*ndpEmFn)();
        !            45:        int fpval;
        !            46:        extern short ndpType;
        !            47: 
        !            48:        switch (f) {
        !            49:        case SYI86UNEEK:
        !            50:                if ((mp = getment (rootdev, 1)) == NULL)
        !            51:                        return;
        !            52:                fsp = & mp->m_super;
        !            53:                fsp->s_fmod = 1;
        !            54:                return ++ fsp->s_unique;
        !            55: 
        !            56:        case SI86FPHW:
        !            57:                /* 
        !            58:                 * 2's bit: floating point ndp is present (80287/80387/80486dx)
        !            59:                 * 1's bit (when 2's bit = 1): 80387/486dx is present
        !            60:                 */
        !            61: 
        !            62:                if (! useracc (arg1, sizeof (int), 1)) {
        !            63:                        SET_U_ERROR (EFAULT, "sysi386:SI86FPHW");
        !            64:                        return;
        !            65:                }
        !            66:                if (ndpType <= 1) { /* no ndp */
        !            67:                        fpval = (ndpEmFn) ? FP_SW : FP_NO;
        !            68:                } else
        !            69:                        fpval = (ndpType > 2) ? FP_387 : FP_287;
        !            70: 
        !            71:                putuwd (arg1, fpval);
        !            72:                return 0;
        !            73: 
        !            74:        }
        !            75: }
        !            76: 
        !            77: ushmsys(func, arg1, arg2, arg3)
        !            78: int func, arg1, arg2, arg3;
        !            79: {
        !            80:        switch(func){
        !            81:        case 0: return ushmat(arg1, arg2, arg3);
        !            82:        case 1: return ushmctl(arg1, arg2, arg3);
        !            83:        case 2: return ushmdt(arg1);
        !            84:        case 3: return ushmget(arg1, arg2, arg3);
        !            85:        default: u.u_error = EINVAL;
        !            86:        }
        !            87: }
        !            88: 
        !            89: usemsys(func, arg1, arg2, arg3, arg4)
        !            90: int func, arg1, arg2, arg3, arg4;
        !            91: {
        !            92:        switch(func){
        !            93:        case 0: return usemctl(arg1, arg2, arg3, arg4);
        !            94:        case 1: return usemget(arg1, arg2, arg3);
        !            95:        case 2: return usemop(arg1, arg2, arg3);
        !            96:        default: u.u_error = EINVAL;
        !            97:        }
        !            98: }
        !            99: 
        !           100: /*
        !           101:  * uname and ustat system calls.
        !           102:  *
        !           103:  * int uname(struct utsname *name)
        !           104:  * Before lcall instruction 4(%esp) contains name, 8(%esp) contains
        !           105:  * an unspecified value, and 12(%esp) contains the value 0.
        !           106:  *
        !           107:  * int ustat(int dev, struct ustat *buf)
        !           108:  * Before lcall instruction 4(%esp) contains buf (REVERSE order of argument)
        !           109:  * 8(%esp) contains dev, and 12(%esp) contains the value 2.
        !           110:  */
        !           111: 
        !           112: uutssys(arg1, arg2, func)
        !           113: {
        !           114:        switch(func) {  
        !           115:        case 0: return uname(arg1);
        !           116:        case 2: return u_ustat(arg2, arg1);
        !           117:        default:u.u_error = EINVAL;
        !           118:        }
        !           119: }
        !           120: 
        !           121: /*
        !           122:  * uname - get name of the current operating system.
        !           123:  */
        !           124: extern char    version[];      /* Defined in main.c */
        !           125: extern char    release[];      /* Defined in main.c */
        !           126: 
        !           127: uname(name)
        !           128: struct utsname *name;
        !           129: {
        !           130:        register char   *rcp;                   /**/
        !           131:        register int    i;                      /* Counter, loop index */
        !           132:        register INODE  *ip;                    /* /etc/uucpname inode */
        !           133:        BUF             *bp;                    /* Read buffer */
        !           134:        char            namebuf[SYS_NMLN];      /* System name */
        !           135:        int             fl;                     /* File length*/
        !           136: 
        !           137:        /* Check if *name is an available user area */
        !           138:        if (! useracc ((char *) name, sizeof (struct utsname), 1)) {
        !           139:                u.u_error = EFAULT;
        !           140:                return 0;
        !           141:        }
        !           142:        /* Find the size of the version number */
        !           143:        for (rcp = version, i = 0; *rcp != '\0' && i < SYS_NMLN; i++, rcp++)
        !           144:                /* DO NOTHING */ ;
        !           145: 
        !           146:        /* Write version number to user area */
        !           147:        if (! kucopy (version, name->version, i))
        !           148:                return 0;
        !           149: 
        !           150:        /* Find the size of the release number */
        !           151:        for (rcp = release, i = 0 ; * rcp != '\0' && i < SYS_NMLN ;
        !           152:             i ++, rcp ++)
        !           153:                /* DO NOTHING */ ;
        !           154: 
        !           155:        /* Write release number to user area */
        !           156:        if (! kucopy (release, name->release, i))
        !           157:                return;
        !           158: 
        !           159:        /* Write "machine" to user area */
        !           160:        if (! kucopy ("i386", name->machine, 4))
        !           161:                return;
        !           162:        /*
        !           163:         * We supposed that system name and nodename are in /etc/uucpname
        !           164:         * NIGEL: Set the global io segment to IOSYS so that ftoi () will use
        !           165:         * the right method of getting at the argument passed to it.
        !           166:         */
        !           167: 
        !           168:        {
        !           169:                IO              io;
        !           170:                struct direct   dir;
        !           171: 
        !           172:                io.io_seg = IOSYS;
        !           173:                if (ftoi ("/etc/uucpname", 'r', & io, & dir) != 0)
        !           174:                        return sys_unknown (name);
        !           175:        }
        !           176: 
        !           177:        ip = u.u_cdiri;
        !           178:        if ((fl = ip->i_size) == 0) {
        !           179:                idetach (ip);
        !           180:                return sys_unknown (name);
        !           181:        }
        !           182: 
        !           183:        if (iaccess (ip, IPR) == 0) {
        !           184:                idetach (ip);
        !           185:                return;
        !           186:        }
        !           187:        if ((bp = vread (ip, (daddr_t) 0)) == NULL) {
        !           188:                brelease (bp);
        !           189:                idetach (ip);
        !           190:                return;
        !           191:        }
        !           192: 
        !           193:        /* namebuf should be not more than SYS_NMLN - 1 characters long */
        !           194:        fl = fl > SYS_NMLN ? SYS_NMLN : fl;
        !           195:        memcpy (namebuf, bp->b_vaddr, fl);
        !           196: 
        !           197:        brelease (bp);
        !           198:        idetach (ip);
        !           199: 
        !           200:        if (fl == 1 && namebuf [0] == '\n')
        !           201:                return sys_unknown (name);
        !           202: 
        !           203:        for (rcp = namebuf, i = 0 ; i < fl ; rcp ++) {
        !           204:                i ++;
        !           205:                if (* rcp == '\n') {
        !           206:                        * rcp = '\0';
        !           207:                        break;
        !           208:                }
        !           209:        }
        !           210:        namebuf[i - 1] = '\0';
        !           211: 
        !           212:        /* Write system name to user area */
        !           213:        if (! kucopy (namebuf, name->sysname, i))
        !           214:                return 0;
        !           215: 
        !           216:        /* Write system name to user area */
        !           217:        if (! kucopy (namebuf, name->nodename, i))
        !           218:                return 0;
        !           219:        return 0;
        !           220: }
        !           221: 
        !           222: /*
        !           223:  * sys_unknown - write name unknown to utsname struct
        !           224:  */
        !           225: char   unknown[] = "UNKNOWN";
        !           226: sys_unknown(name)
        !           227: struct utsname *name;
        !           228: {
        !           229:        if (! kucopy (unknown, name->sysname, sizeof (unknown)))
        !           230:                return;
        !           231:        if (! kucopy (unknown, name->nodename, sizeof (unknown)))
        !           232:                return;
        !           233: }
        !           234: 
        !           235: /* 
        !           236:  * u_ustat - get file system statistics. (Name ustat in use for stat s.c.)
        !           237:  */
        !           238: 
        !           239: u_ustat(dev, buf)
        !           240: dev_t  dev;
        !           241: struct ustat   *buf;
        !           242: {
        !           243:        register MOUNT  *mp;
        !           244: 
        !           245:        /* Check if buf is an available user area. */
        !           246:        /* B_READ | B_WRITE is not implemented yet. */
        !           247:        if (! useracc ((char *) buf, sizeof (struct ustat), 1)) {
        !           248:                u.u_error = EFAULT;
        !           249:                return;
        !           250:        }
        !           251: 
        !           252:        /* Take mount filesystem, check if dev is mounted device */
        !           253:        for (mp = mountp ; mp != NULL ; mp = mp->m_next)
        !           254:                if (mp->m_dev == dev)
        !           255:                        break;
        !           256: 
        !           257:        if (mp == NULL) {
        !           258:                u.u_error = EINVAL;
        !           259:                return;
        !           260:        }
        !           261: 
        !           262:        /* Pickup information from superblock */
        !           263:        /* Number of free blocks */
        !           264:        if (! kucopy (& mp->m_super.s_tfree, & buf->f_tfree,
        !           265:                     sizeof (mp->m_super.s_tfree)))
        !           266:                return;
        !           267: 
        !           268:        /* Number of free inodes */
        !           269:        if (! kucopy (& mp->m_super.s_tinode, & buf->f_tinode,
        !           270:                      sizeof (mp->m_super.s_tinode)))
        !           271:                return;
        !           272: 
        !           273:        /* File system name */
        !           274:        if (! kucopy (mp->m_super.s_fname, buf->f_fname,  
        !           275:                      sizeof (mp->m_super.s_fname)))
        !           276:                return;
        !           277: 
        !           278:        /* File system pack name */
        !           279:        if (! kucopy (mp->m_super.s_fpack, buf->f_fpack,  
        !           280:                      sizeof (mp->m_super.s_fpack)))
        !           281:                return;
        !           282: }
        !           283: 
        !           284: umsgsys(func, arg1, arg2, arg3, arg4, arg5)
        !           285: {
        !           286:        switch (func) {
        !           287:        case 0: return umsgget (arg1, arg2);
        !           288:        case 1: return umsgctl (arg1, arg2, arg3);
        !           289:        case 2: return umsgrcv (arg1, arg2, arg3, arg4, arg5);
        !           290:        case 3: return umsgsnd (arg1, arg2, arg3, arg4);
        !           291:        default:u.u_error = EINVAL;
        !           292:        }
        !           293: }
        !           294: 
        !           295: /* Don't tell user process about last remaining 64k of RAM */
        !           296: #define BRK_CUSHION    16
        !           297: 
        !           298: uulimit(cmd, newlimit)
        !           299: {
        !           300:        int freeClicks;
        !           301: 
        !           302:        switch (cmd) {
        !           303:        case UL_GETFSIZE:       /* Get max # of 512-byte blocks per file. */
        !           304:                return u.u_bpfmax;
        !           305:                break;
        !           306: 
        !           307:        case UL_SETFSIZE: /* Set max # of 512-byte blocks per file. */
        !           308:                /* (only superuser may increase this) */
        !           309:                if (newlimit <= u.u_bpfmax || super ()) {
        !           310:                        u.u_bpfmax = newlimit;
        !           311:                        return 0;
        !           312:                }
        !           313:                /* else super() will have set u.u_error to EPERM */
        !           314:                break;
        !           315: 
        !           316:        case UL_GMEMLIM: /* Get max break value. */
        !           317:                /* return (current brk value) + (amount of free space) */
        !           318:                /* Don't report all free clicks - leave a cushion. */
        !           319:                freeClicks = allocno () - BRK_CUSHION;
        !           320:                if (freeClicks < 0)
        !           321:                        freeClicks = 0;
        !           322:                return u.u_segl [SIPDATA].sr_base +
        !           323:                        SELF->p_segp [SIPDATA]->s_size + NBPC * freeClicks;
        !           324: 
        !           325:        case UL_GDESLIM:
        !           326:                /* Return configured number of open files per process. */
        !           327:                return NOFILE;
        !           328:                break;
        !           329: 
        !           330:        default:
        !           331:                u.u_error = EINVAL;
        !           332:        }
        !           333: }
        !           334: 
        !           335: /*
        !           336:  *  Change the size of a file.
        !           337:  */
        !           338: uchsize(fd, size)
        !           339: int fd;
        !           340: register long size;
        !           341: {
        !           342:        FD *fdp;
        !           343:        register INODE *ip;
        !           344: 
        !           345:        if (size < 0) {
        !           346:                u.u_error = EINVAL;
        !           347:                return -1;
        !           348:        }
        !           349:        if ((fdp = fdget (fd))==NULL || (fdp->f_flag & IPW) == 0) {
        !           350:                u.u_error = EBADF;
        !           351:                return -1;
        !           352:        }
        !           353: 
        !           354:        ip = fdp->f_ip;
        !           355:        switch (ip->i_mode & IFMT) {
        !           356:        case IFREG:
        !           357:                if (size > (long) u.u_bpfmax * BSIZE) {
        !           358:                        u.u_error = EFBIG;
        !           359:                        return -1;
        !           360:                }
        !           361:                if (size == ip->i_size)
        !           362:                        break;
        !           363:                ilock (ip);
        !           364:                if (size < ip->i_size)
        !           365:                        blclear (ip, __DIVIDE_ROUNDUP (ip->i_size, BSIZE));
        !           366:                ip->i_size = size;
        !           367:                imod (ip);
        !           368:                icrt (ip);
        !           369:                iunlock (ip);
        !           370:                break;
        !           371: 
        !           372:        case IFPIPE:
        !           373:                if (size > PIPSIZE) {
        !           374:                        u.u_error = EFBIG;
        !           375:                        return -1;
        !           376:                }
        !           377: 
        !           378:                ilock(ip);
        !           379: 
        !           380:                if (! ip->i_par && ! ip->i_psr) {
        !           381:                        u.u_error = EPIPE;
        !           382:                        sendsig (SIGPIPE, SELF);
        !           383:                        iunlock (ip);
        !           384:                        return -1;
        !           385:                }
        !           386:                ip->i_pwx += (size - ip->i_pnc);
        !           387:                if (size > ip->i_pnc) {
        !           388:                        if (ip->i_pwx >= PIPSIZE)
        !           389:                                ip->i_pwx -= PIPSIZE;
        !           390:                } else if (size < ip->i_pnc) {
        !           391:                        if (ip->i_pwx < 0)
        !           392:                                ip->i_pwx += PIPSIZE;
        !           393:                }
        !           394: 
        !           395:                ip->i_pnc = size;
        !           396:                imod (ip);
        !           397:                icrt (ip);
        !           398: 
        !           399:                if (size > 0)
        !           400:                        pwake (ip, 2);  /* 2==IFWFW, see pipe.c */
        !           401:                if (size < PIPSIZE)
        !           402:                        pwake (ip, 1);  /* 1==IFWFR, see pipe.c */
        !           403:                iunlock (ip);
        !           404:                break;
        !           405: 
        !           406:        default:
        !           407:                u.u_error = EBADF;
        !           408:                return -1;
        !           409:        }
        !           410:        return 0;
        !           411: }
        !           412: 
        !           413: /*
        !           414:  * Remove a directory.
        !           415:  */
        !           416: 
        !           417: urmdir(path)
        !           418: char   *path;
        !           419: {
        !           420:        register INODE  *ip;
        !           421:        int             iPathLen;       /* Size of the string */
        !           422:        int             isdirempty();
        !           423:        extern int      strUserAcc();
        !           424:        IO              io;
        !           425:        struct direct   dir;
        !           426:        
        !           427:        /* Check if path points to a valid user buffer.*/
        !           428:        if ((iPathLen = strUserAcc (path, 0)) < 0) {
        !           429:                u.u_error = EFAULT;
        !           430:                return;
        !           431:        }
        !           432: 
        !           433:        io.io_seg = IOUSR;
        !           434:        if (ftoi (path, 'r', & io, & dir) != 0)
        !           435:                return;
        !           436: 
        !           437:        ip = u.u_cdiri;
        !           438: 
        !           439:        /* Check if path is a directory */
        !           440:        if ((ip->i_mode & IFMT) != IFDIR) {
        !           441:                SET_U_ERROR(ENOTDIR, "rmdir: no such directory");
        !           442:                idetach (ip);
        !           443:                return;
        !           444:        }
        !           445: 
        !           446:        /* We have to check if directory is empty */
        !           447:        if (! isdirempty (ip)) {
        !           448:                SET_U_ERROR (EEXIST, "rmdir: directory is not empty");
        !           449:                idetach (ip);
        !           450:                return;
        !           451:        }
        !           452:        idetach (ip);
        !           453:        removedir (path, iPathLen);
        !           454:        return 0;
        !           455: }
        !           456: 
        !           457: /*
        !           458:  * Remove a directory.
        !           459:  * path is a pointer to user area.
        !           460:  */
        !           461: 
        !           462: removedir(path, iPathLen)
        !           463: char   *path;  /* Directory name */
        !           464: int    iPathLen;       /* Path length */
        !           465: {
        !           466:        char            *buf;
        !           467:        char            *cpbuf,         /* internal file_name buffer */
        !           468:                        *cppath;        /* user file_name buffer */
        !           469: 
        !           470:        /*
        !           471:         * Allocate kernel buffer. We need extra space for '/', '.', '..' 
        !           472:         * and '\0'
        !           473:         */
        !           474: 
        !           475:        if ((buf = kalloc (iPathLen + 4)) == NULL) {
        !           476:                SET_U_ERROR (ENOSPC, "rmdir: out of kernel space");
        !           477:                return;
        !           478:        }
        !           479:        cpbuf = buf;
        !           480:        cppath = path;
        !           481: 
        !           482:        /* Copy path to the kernel buffer. */
        !           483:        while ((* cpbuf = getubd (cppath)) != '\0') {
        !           484:                cppath ++;
        !           485:                cpbuf ++;
        !           486:        }
        !           487:        * cpbuf++ = '/';
        !           488:        * cpbuf++ = '.';
        !           489:        * cpbuf = '\0';
        !           490: 
        !           491:        dunlink (buf);
        !           492:        if (u.u_error) {
        !           493:                kfree (buf);
        !           494:                return;
        !           495:        }
        !           496: 
        !           497:        * cpbuf ++ = '.';
        !           498:        * cpbuf = '\0';
        !           499: 
        !           500:        dunlink (buf);
        !           501:        if (u.u_error) {
        !           502:                /* We have to link '.' back here. */
        !           503:                kfree (buf);
        !           504:                return;
        !           505:        }
        !           506: 
        !           507:        buf [iPathLen] = '\0';
        !           508: 
        !           509:        dunlink (buf);
        !           510:        if (u.u_error) {
        !           511:                /* We have to link '.' and '..' back here. */
        !           512:                kfree (buf);
        !           513:                return;
        !           514:        }
        !           515:        kfree(buf);
        !           516:        return;
        !           517: }
        !           518: 
        !           519: 
        !           520: /*
        !           521:  * Unlink the given directory.
        !           522:  */
        !           523: 
        !           524: dunlink (np)
        !           525: char *np;
        !           526: {
        !           527:        register INODE *ip;
        !           528:        register dev_t dev;
        !           529:        IO              io;
        !           530:        struct direct   dir;
        !           531: 
        !           532:        io.io_seg = IOSYS;
        !           533:        if (file_to_inode (np, 'u', 1, & io, & dir) != 0)
        !           534:                return;
        !           535:  
        !           536:        ip = u.u_pdiri;
        !           537:        if (iaccess (ip, IPW) == 0)
        !           538:                goto err;
        !           539: 
        !           540:        dev = ip->i_dev;
        !           541:        if (diucheck (dev, u.u_cdirn) == 0)
        !           542:                goto err;
        !           543: 
        !           544:        idirent (0, & io, & dir);
        !           545:        idetach (ip);
        !           546: 
        !           547:        if ((ip = iattach (dev, u.u_cdirn)) == NULL)
        !           548:                return;
        !           549: 
        !           550:        if (ip->i_nlink > 0)
        !           551:                -- ip->i_nlink;
        !           552:        icrt (ip);      /* unlink - ctime */
        !           553: 
        !           554: err:
        !           555:        idetach (ip);
        !           556:        return;
        !           557: }
        !           558: 
        !           559: /*
        !           560:  * This is a copy of iucheck. The only one difference is that that allows
        !           561:  * to remove a directory to a regular user.
        !           562:  */
        !           563: 
        !           564: diucheck (dev, ino)
        !           565: register dev_t dev;
        !           566: register ino_t ino;
        !           567: {
        !           568:        register INODE *ip;
        !           569:        INODE inode;
        !           570: 
        !           571:        for (ip = & inodep [NINODE - 1] ; ip >= inodep ; -- ip) {
        !           572:                if (ip->i_ino == ino && ip->i_dev == dev)
        !           573:                        break;
        !           574:        }
        !           575: 
        !           576:        if (ip < inodep) {
        !           577:                ip = & inode;
        !           578:                ip->i_dev = dev;
        !           579:                ip->i_ino = ino;
        !           580:                if (icopydm (ip) == 0)
        !           581:                        return 0;
        !           582:        }
        !           583:        return 1;
        !           584: }
        !           585: 
        !           586: /* 
        !           587:  * Check if directory is empty.
        !           588:  */
        !           589: int isdirempty (ip)
        !           590: register INODE *ip;
        !           591: {
        !           592:        register char   *cp;
        !           593:        int             count;
        !           594:        BUF             *bp;
        !           595: 
        !           596:        for (count = 0 ; count < ip->i_size ; count += 512) {
        !           597:                if ((bp = vread (ip, count)) == NULL) 
        !           598:                        break;
        !           599: 
        !           600:                for (cp = (char *) bp->b_vaddr ; 
        !           601:                     cp < (char *) bp->b_vaddr + BSIZE ; cp += 16) {
        !           602: 
        !           603:                        if (cp == '\0' && cp [1] == '\0') 
        !           604:                                continue;
        !           605:                        if (cp [2] != '.')
        !           606:                                goto bad;
        !           607:                        if (cp [3] == '\0')
        !           608:                                continue;
        !           609:                        if (cp [3] != '.' || cp [4] != '\0')
        !           610:                                goto bad;
        !           611:                }
        !           612: 
        !           613:                brelease (bp);
        !           614:        }
        !           615:        return 1;
        !           616: 
        !           617: bad:
        !           618:        brelease (bp);
        !           619:        return 0;
        !           620: }
        !           621: 
        !           622: /*
        !           623:  * SysV compatible mkdir() system call.
        !           624:  *
        !           625:  *     Create a directory of the given "path" and "mode", if possible.
        !           626:  *     Creating the directory is straight forward.  Trying to clean
        !           627:  *     up in case we run out of inodes or freee blocks in the process 
        !           628:  *     is not trivial.
        !           629:  *     This system call was implemented in very press time.
        !           630:  *     Vlad 6-04-92
        !           631:  */
        !           632: 
        !           633: umkdir(path, mode)
        !           634: char   *path;
        !           635: int    mode;
        !           636: {
        !           637:        INODE           *dmknod();              /* make directory node */
        !           638:        register INODE  *pip;                   /* parent inode pointer */
        !           639:        register char   *cp_path, 
        !           640:                        *cpb_path, 
        !           641:                        *cp_dot, 
        !           642:                        *cp_dotdot,
        !           643:                        *cp_parent;
        !           644:        char            bufpath[512],
        !           645:                        bufdot[512],            
        !           646:                        bufdotdot[512],
        !           647:                        bufparent[512];
        !           648:        int             uid;
        !           649: 
        !           650:        /* Check if path points to a valid user buffer.*/
        !           651:        if (strUserAcc (path, 0) < 0) {
        !           652:                u.u_error = EFAULT;
        !           653:                return;
        !           654:        }
        !           655: 
        !           656:        /*
        !           657:         * Create a local copies of "path" which we can use to build up
        !           658:         * the required directory links:
        !           659:         *      path/. -- bufdot
        !           660:         *      path/..-- bufdotdot
        !           661:         * Verify that the given path is not too long.
        !           662:         */
        !           663:        cp_path = path;
        !           664:        cpb_path = bufpath;
        !           665:        cp_dot = bufdot;
        !           666:        cp_dotdot = bufdotdot;
        !           667:        cp_parent = bufparent;
        !           668: 
        !           669:        while ((* cpb_path = getubd (cp_path)) != '\0') {
        !           670:                * cp_dot ++ = * cp_dotdot ++ = * cp_parent ++ = * cpb_path;
        !           671:                ++ cp_path;
        !           672:                if (++ cpb_path >= & bufpath [sizeof (bufpath) - 3]) {
        !           673:                        SET_U_ERROR (ENOENT, "sys5: mkdir: path too long");
        !           674:                        return;
        !           675:                }
        !           676:        }
        !           677: 
        !           678:        while (-- cp_parent >= bufparent) {
        !           679:                if (* cp_parent == '/') {
        !           680:                        * ++ cp_parent = '\0';
        !           681:                        break;
        !           682:                }
        !           683:        }
        !           684: 
        !           685:        if (cp_parent < bufparent) {
        !           686:                * ++ cp_parent = '.';
        !           687:                * ++ cp_parent = '\0';
        !           688:        }
        !           689:        
        !           690:        * cp_dotdot ++ = * cp_dot++ = '/';
        !           691:        * cp_dotdot ++ = * cp_dot++ = '.';
        !           692:        * cp_dotdot ++ = '.';
        !           693:        * cp_dotdot = * cp_dot = '\0';
        !           694: 
        !           695:        if ((pip = dmknod (path, mode, IOUSR)) == NULL)
        !           696:                return;
        !           697: 
        !           698:        /*
        !           699:         * Now we can switch our id to root. It allows to use existing
        !           700:          * functions.
        !           701:         */
        !           702: 
        !           703:        uid = u.u_uid;
        !           704:        u.u_uid = 0;
        !           705: 
        !           706:        do_link (bufpath, bufdot, IOSYS);
        !           707: 
        !           708:        if (u.u_error) {
        !           709:                u.u_error = do_unlink (bufpath, IOSYS);
        !           710: 
        !           711:                u.u_uid = uid;
        !           712:                return;
        !           713:        }
        !           714: 
        !           715:        do_link (bufparent, bufdotdot, IOSYS);
        !           716: 
        !           717:        if (u.u_error) {
        !           718:                u.u_error = do_unlink (bufdot, IOSYS);
        !           719:                u.u_error = do_unlink (bufpath, IOSYS);
        !           720:        }
        !           721: 
        !           722:        u.u_uid = uid;
        !           723:        return 0;
        !           724: }
        !           725: 
        !           726: 
        !           727: /*
        !           728:  * Create a directory.
        !           729:  *
        !           730:  * We cannot use original ulink because it makes the directories only
        !           731:  * for superuser.
        !           732:  */
        !           733: 
        !           734: INODE *
        !           735: dmknod (np, mode, space)
        !           736: char   *np;    /* Direcotory name */
        !           737: int    mode;
        !           738: int            space;
        !           739: {
        !           740:        register INODE *ip, *pip;
        !           741:        register int type;
        !           742:        IO              io;
        !           743:        struct direct   dir;
        !           744: 
        !           745:        type = (mode & ~IFMT);
        !           746:        type |= S_IFDIR;
        !           747: 
        !           748:        /* If ftoi returns nonzero, u.u_error has been set. */
        !           749:        io.io_seg = space;
        !           750:        if (ftoi (np, 'c', & io, & dir) != 0)
        !           751:                return NULL;
        !           752: 
        !           753:        if ((ip = u.u_cdiri) != NULL) {
        !           754:                SET_U_ERROR (EEXIST, "dmknod: path already exists");
        !           755:                idetach (ip);
        !           756:                return NULL;
        !           757:        }
        !           758:        if ((ip = imake (type, (dev_t) 0, & io, & dir)) != NULL)
        !           759:                idetach (ip);
        !           760:        pip = u.u_pdiri;        /* grab ptr to parent inode */
        !           761:        return pip;
        !           762: }
        !           763: 
        !           764: 
        !           765: /*
        !           766:  * Get directory entry in file system independent format.
        !           767:  */
        !           768: 
        !           769: ugetdents(fd, bp, n)
        !           770: int            fd;     /* File descriptor to an open directory */
        !           771: char           *bp;    /* Buffer where entries should be read */
        !           772: unsigned       n;      /* Number of bytes to be read */
        !           773: {
        !           774:        struct direct   r_dir;  
        !           775:        unsigned        bytes;  /* Number of bytes */
        !           776:        struct dirent   sd;
        !           777:        ino_t           inode;  /* Inode number */
        !           778:        unsigned short  ofnm;   /* Offset to file name in dirent */
        !           779:        char            *cw, 
        !           780:                        *cr;
        !           781:        int             minbuf; /* Minimum possible size of the bp */
        !           782:        int             i, mod;
        !           783:        int             entry;
        !           784:        char            ends[3] = "";
        !           785:        int             total = 0;
        !           786: 
        !           787:        cw = bp;
        !           788: 
        !           789:        ofnm = sizeof (sd.d_ino) + sizeof (sd.d_off) + sizeof (sd.d_reclen);
        !           790: 
        !           791:        /*
        !           792:         * Find minimum possible size of bp. It should be enough to contain
        !           793:         * the header of dirent, file name + '\0', and be on a sizeof(long)
        !           794:         * boundary.
        !           795:         */
        !           796: 
        !           797:        entry = ofnm + DIRSIZ + 1;
        !           798:        mod = entry % sizeof(long);
        !           799:        minbuf = entry + (mod ? sizeof(long) - mod : 0); 
        !           800: 
        !           801:        /* Is user buffer available? */
        !           802:        if (! useracc (bp, n, 1) || n < minbuf) {
        !           803:                u.u_error = EFAULT;
        !           804:                return 0;
        !           805:        }
        !           806: 
        !           807:        while(n - (cw - bp) >= minbuf) {
        !           808:                /*
        !           809:                 * Read next entry from the directory. 
        !           810:                 * inode == 0 for rm(ed) entries 
        !           811:                 */
        !           812: 
        !           813:                do {
        !           814:                        if ((bytes = dirio (fd, & r_dir,
        !           815:                                            sizeof (struct direct), 
        !           816:                                            & sd.d_off)) == 0)
        !           817:                                return total;
        !           818: 
        !           819:                        inode = r_dir.d_ino;
        !           820:                } while (! inode);
        !           821: 
        !           822:                /* Find the size of file name */
        !           823:                for (cr = r_dir.d_name, i = 0 ; * cr != '\0' && i < DIRSIZ ; 
        !           824:                     i ++, cr ++)
        !           825:                        /* DO NOTHING */ ;
        !           826: 
        !           827:                /* Copy file name */
        !           828:                if (! kucopy (r_dir.d_name, cw + ofnm, i))
        !           829:                        return 0;
        !           830: 
        !           831:                /* Write '\0' */
        !           832:                putubd (cw + ofnm + i ++, '\0');
        !           833: 
        !           834:                /* Round up to long boundary */
        !           835:                if (mod = (ofnm + i) % sizeof(long))
        !           836:                        if (! kucopy (ends, cw + ofnm + i, sizeof
        !           837:                                      (long) - mod))
        !           838:                                return 0;
        !           839: 
        !           840:                sd.d_ino = r_dir.d_ino;
        !           841:                sd.d_reclen = ofnm + i;         /* Size of directory entry */
        !           842:                if (mod)
        !           843:                        sd.d_reclen += sizeof (long) - mod;
        !           844: 
        !           845:                if (! kucopy(& sd, cw, ofnm))
        !           846:                        return 0;
        !           847: 
        !           848:                total += sd.d_reclen;
        !           849:                cw += sd.d_reclen;
        !           850:        }
        !           851:        return total;
        !           852: }
        !           853: 
        !           854: /*
        !           855:  * Read `n' bytes from the directory `fd' using the buffer `bp'.
        !           856:  */
        !           857: 
        !           858: dirio(fd, bp, n, offset)
        !           859: struct direct  *bp;
        !           860: unsigned       n;
        !           861: off_t          *offset;
        !           862: {
        !           863:        register FD *fdp;
        !           864:        register INODE *ip;
        !           865:        IO              io;
        !           866: 
        !           867:        /* Check file descriptor */
        !           868:        if ((fdp = fdget (fd)) == NULL)
        !           869:                return 0;
        !           870: 
        !           871:        if ((fdp->f_flag & IPR) == 0) {
        !           872:                u.u_error = EBADF;
        !           873:                return 0;
        !           874:        }
        !           875: 
        !           876:        ip = fdp->f_ip;
        !           877:        if ((ip->i_mode & IFMT) != IFDIR) {
        !           878:                u.u_error = EBADF;
        !           879:                return 0;
        !           880:        }
        !           881: 
        !           882:        ilock (ip);     /* We do not want file changes during the read */
        !           883: 
        !           884:        io.io_seg = IOSYS;
        !           885:        io.io_seek = fdp->f_seek;
        !           886:        io.io.vbase = bp;
        !           887:        io.io_ioc  = n;
        !           888:        io.io_flag = 0;
        !           889: 
        !           890:        if ((fdp->f_flag & IPNDLY) != 0)
        !           891:                io.io_flag |= IONDLY;
        !           892: 
        !           893:        if ((fdp->f_flag & IPNONBLOCK) != 0)
        !           894:                io.io_flag |= IONONBLOCK;
        !           895: 
        !           896:        iread (ip, & io);
        !           897:        iacc (ip);              /* read - atime */
        !           898: 
        !           899:        n -= io.io_ioc;
        !           900:        * offset = fdp->f_seek;
        !           901:        fdp->f_seek += n;
        !           902: 
        !           903:        iunlock (ip);
        !           904:        return n;
        !           905: }
        !           906: 
        !           907: /* 
        !           908:  * Get file system information by file name.
        !           909:  */
        !           910: ustatfs(path, stfs, len, fstyp)
        !           911: char           *path;  /* File name */
        !           912: struct statfs  *stfs;  /* Pointer to a user structure */
        !           913: int            len;    /* Size of the structure */
        !           914: int            fstyp;  /* File system type */
        !           915: {
        !           916:        struct filsys   *statmount();   /* Get mp for mounted device */
        !           917:        struct filsys   *statunmount(); /* Get mp for unmounted device */
        !           918:        struct filsys   *sb;            /* Pointer to superblock */
        !           919:        int             count = 0;      /* Number of copied bytes */
        !           920:        short           systype = 1;    /* System type */
        !           921:        long            bsize = BSIZE;  /* Block size */
        !           922:        long            frsize = 0;     /* Fragment size */
        !           923: 
        !           924:        /* Check if stfs is an available user area. */
        !           925:        if (! useracc ((char *) stfs, len, 1)) {
        !           926:                SET_U_ERROR (EFAULT, "ustatfs 0");
        !           927:                return;
        !           928:        }
        !           929: 
        !           930:        /* Filesystem type is 1 for 512 bytes blocks. */
        !           931:        count += sizeof (systype);
        !           932:        if (count > len) {
        !           933:                SET_U_ERROR (EFAULT, "ustatfs 1");
        !           934:                return;
        !           935:        }
        !           936:        if (! kucopy (& systype, & stfs->f_fstyp, sizeof (systype)))
        !           937:                return;
        !           938:        
        !           939:        /* Block size */
        !           940:        count += sizeof (bsize);
        !           941:        if (count > len) {
        !           942:                SET_U_ERROR (EFAULT, "ustatfs 2");
        !           943:                return;
        !           944:        }
        !           945:        if (! kucopy (& bsize, & stfs->f_bsize, sizeof (bsize)))
        !           946:                return;
        !           947: 
        !           948:        /* Fragment size. */
        !           949:        count += sizeof (int);
        !           950:        if (count > len) {
        !           951:                SET_U_ERROR (EFAULT, "ustatfs 3");
        !           952:                return;
        !           953:        }
        !           954:        if (! kucopy (& frsize, & stfs->f_frsize, sizeof (frsize)))
        !           955:                return;
        !           956: 
        !           957:        if (! fstyp) {
        !           958:                if ((sb = statmount (-1, path)) == NULL)
        !           959:                        return;
        !           960:                devinfo (sb, stfs, len, & count);
        !           961:        } else {
        !           962:                if ((sb = statunmount (-1, path)) == NULL)
        !           963:                        return;
        !           964:                devinfo (sb, stfs, len, & count);
        !           965:                kfree (sb);
        !           966:        }
        !           967:        return 0;
        !           968: }
        !           969: 
        !           970: /*
        !           971:  * statmount - get superblock for mounted file system.
        !           972:  * fd - file descriptor or -1, path -  file name or NULL.
        !           973:  */
        !           974: struct filsys *statmount(fd, path)
        !           975: int    fd;
        !           976: char   *path;
        !           977: {      
        !           978:        register INODE  *ip;            /* Structure inode */
        !           979:        register FD     *fdp;
        !           980:        register MOUNT  *mp;            /* Pointer to device */
        !           981:        dev_t           device;         /* Mounted device */
        !           982: 
        !           983:        /* Find the device */
        !           984:        if (path) {     /* Find ip by file name */
        !           985:                IO              io;
        !           986:                struct direct   dir;
        !           987: 
        !           988:                io.io_seg = IOUSR;
        !           989:                if (ftoi (path, 'r', & io, & dir)) {
        !           990:                        /* If ftoi returned nonzero, it also set u.u_error. */
        !           991:                        return NULL;
        !           992:                }
        !           993:                ip = u.u_cdiri;
        !           994:                device = ip->i_dev;
        !           995:                idetach(ip);
        !           996:        } else {                /* Find ip by file descriptor */
        !           997:                if ((fdp = fdget (fd)) == NULL)
        !           998:                        return NULL;
        !           999:                if ((fdp->f_flag & IPR) == 0) {
        !          1000:                        SET_U_ERROR (EBADF, "statmount 1");
        !          1001:                        return NULL;
        !          1002:                }
        !          1003:                ip = fdp->f_ip;
        !          1004:                device = ip->i_dev;
        !          1005:        }       
        !          1006: 
        !          1007:        /* Take mount filesystem, check if dev is mounted device */
        !          1008:        for (mp = mountp; mp != NULL; mp = mp->m_next)
        !          1009:                if (mp->m_dev == device)
        !          1010:                        break;
        !          1011: 
        !          1012:        if (mp == NULL) {
        !          1013:                u.u_error = EINVAL;
        !          1014:                return NULL;
        !          1015:        }
        !          1016:        return & mp->m_super;
        !          1017: }
        !          1018: 
        !          1019: /*
        !          1020:  * devinfo() write system information to user area
        !          1021:  */
        !          1022: devinfo(sb, stfs, len, count)
        !          1023: struct filsys  *sb;    /* File name */
        !          1024: struct statfs  *stfs;  /* Pointer to a user structure */
        !          1025: int            len;    /* Size of the structure */
        !          1026: int            *count;
        !          1027: {
        !          1028:        long            inode;
        !          1029: 
        !          1030:        /* Total number of blocks */
        !          1031:        * count += sizeof (sb->s_fsize);
        !          1032:        if (* count > len)
        !          1033:                return;
        !          1034: 
        !          1035:        if (! kucopy (& sb->s_fsize, & stfs->f_blocks, sizeof (sb->s_fsize)))
        !          1036:                return;
        !          1037: 
        !          1038:        /* Count of free blocks */
        !          1039:        * count += sizeof (sb->s_tfree);
        !          1040:        if (* count > len)
        !          1041:                return;
        !          1042:        if (! kucopy (& sb->s_tfree, & stfs->f_bfree, sizeof (sb->s_tfree)))
        !          1043:                return;
        !          1044: 
        !          1045:        /* Total number of file inodes */
        !          1046:        * count += sizeof (inode);
        !          1047:        if (* count > len)
        !          1048:                return;
        !          1049: 
        !          1050:        inode = (long) (sb->s_isize - INODEI) * INOPB;
        !          1051:        if (! kucopy (& inode, & stfs->f_files, sizeof (inode)))
        !          1052:                return;
        !          1053: 
        !          1054:        /* Number of free inodes */
        !          1055:        * count += sizeof(inode);
        !          1056:        if (* count > len)
        !          1057:                return;
        !          1058:        inode = sb->s_tinode;
        !          1059:        if (! kucopy (& inode, & stfs->f_ffree, sizeof (inode)))
        !          1060:                return;
        !          1061: 
        !          1062:        /* Volume name */
        !          1063:        * count += sizeof (sb->s_fname);
        !          1064:        if (* count > len)
        !          1065:                return;
        !          1066:        if (! kucopy (sb->s_fname, stfs->f_fname, sizeof (sb->s_fpack)))
        !          1067:                return;
        !          1068: 
        !          1069:        /* Pack name */
        !          1070:        * count += sizeof(sb->s_fpack);
        !          1071:        if (* count > len)
        !          1072:                return;
        !          1073:        if (! kucopy (sb->s_fpack, stfs->f_fpack, sizeof (sb->s_fpack)))
        !          1074:                return;
        !          1075: }
        !          1076: 
        !          1077: /*
        !          1078:  * statunmount - get superblock for unmounted file system.
        !          1079:  * fd - file descriptor or -1, path -  file name or NULL.
        !          1080:  */
        !          1081: struct filsys *statunmount(fd, path)
        !          1082: int    fd;     /* File descriptor */
        !          1083: char   *path;  /* File name */
        !          1084: {
        !          1085:        register INODE  *ip;
        !          1086:        register MOUNT  *mp;
        !          1087:        register dev_t  rdev;
        !          1088:        FD              *fdp;
        !          1089:        int             mode;
        !          1090:        BUF             *bp;
        !          1091:        struct filsys   *sb;
        !          1092: 
        !          1093:        /* Find the device */
        !          1094:        if (path) {     /* Find ip by file name */
        !          1095:                IO              io;
        !          1096:                struct direct   dir;
        !          1097: 
        !          1098:                if (ftoi (path, 'r', & io, & dir)) 
        !          1099:                        return NULL;
        !          1100:                ip = u.u_cdiri;
        !          1101:                mode = ip->i_mode;
        !          1102:                rdev = ip->i_a.i_rdev;
        !          1103:                idetach (ip);
        !          1104:        } else {                /* Find ip by file descriptor */
        !          1105:                if ((fdp = fdget(fd)) == NULL)
        !          1106:                        return NULL;
        !          1107:                if ((fdp->f_flag & IPR) == 0) {
        !          1108:                        u.u_error = EBADF;
        !          1109:                        return NULL;
        !          1110:                }
        !          1111:                ip = fdp->f_ip;
        !          1112:                ilock (ip);
        !          1113:                mode = ip->i_mode;
        !          1114:                rdev = ip->i_a.i_rdev;
        !          1115:                iunlock (ip);
        !          1116:        }       
        !          1117: 
        !          1118:        /* Check for block special device */
        !          1119:        if ((mode & IFMT) != IFBLK) {
        !          1120:                u.u_error = ENOTBLK;
        !          1121:                return NULL;
        !          1122:        }
        !          1123: 
        !          1124:        /* Check if device is mounted device */
        !          1125:        for (mp = mountp; mp != NULL; mp = mp->m_next) {
        !          1126:                if (mp->m_dev == rdev) {
        !          1127:                        u.u_error = EBUSY;
        !          1128:                        return NULL;
        !          1129:                }
        !          1130:        }
        !          1131: 
        !          1132:        dopen (rdev, IPR, DFBLK);
        !          1133:        if (u.u_error) 
        !          1134:                return NULL;
        !          1135:        
        !          1136:        /*
        !          1137:         * NIGEL: Modified for new dclose ().
        !          1138:         */
        !          1139: 
        !          1140:        bp = bread (rdev, (daddr_t) SUPERI, BUF_SYNC);
        !          1141:        dclose (rdev, IPR, DFBLK);
        !          1142: 
        !          1143:        if (bp == NULL)
        !          1144:                return NULL;
        !          1145: 
        !          1146:        if ((sb = kalloc (sizeof (struct filsys))) == NULL)
        !          1147:                return NULL;
        !          1148: 
        !          1149:        memcpy (sb, bp->b_vaddr, sizeof (struct filsys));
        !          1150:        brelease (bp);
        !          1151: 
        !          1152:        cansuper (sb);          /* canonicalize superblock */
        !          1153:        if (tstf (sb) == 0) {   /* check for consistency */
        !          1154:                kfree (sb);
        !          1155:                u.u_error = EINVAL;
        !          1156:                return NULL;
        !          1157:        }
        !          1158:        return sb;
        !          1159: }
        !          1160: 
        !          1161: /* 
        !          1162:  * Get file system information by file descriptor
        !          1163:  */
        !          1164: ufstatfs(fildes, stfs, len, fstyp)
        !          1165: int            fildes; /* File descriptor */
        !          1166: struct statfs  *stfs;  /* Pointer to a user structure */
        !          1167: int            len;    /* Size of the structure */
        !          1168: int            fstyp;  /* File system type */
        !          1169: {      
        !          1170:        struct filsys   *statmount();   /* Get mp for mounted device */
        !          1171:        struct filsys   *statunmount(); /* Get mp for unmounted device */
        !          1172:        struct filsys   *sb;            /* Pointer to superblock */
        !          1173:        int             count = 0;      /* Number of copied bytes */
        !          1174:        short           systype = 1;    /* System type */
        !          1175:        long            bsize = BSIZE;  /* Block size */
        !          1176:        long            frsize = 0;     /* Fragment size */
        !          1177: 
        !          1178:        /* Check if stfs is an available user area. */
        !          1179:        if (! useracc ((char *) stfs, len)) {
        !          1180:                u.u_error = EFAULT;
        !          1181:                return;
        !          1182:        }
        !          1183: 
        !          1184:        /* Filesystem type is 1 for 512 bytes blocks. */
        !          1185:        count += sizeof (systype);
        !          1186:        if (count > len) {
        !          1187:                SET_U_ERROR (EFAULT, "ufstatfs 0");
        !          1188:                return;
        !          1189:        }
        !          1190:        if (! kucopy (& systype, & stfs->f_fstyp, sizeof (systype)))
        !          1191:                return;
        !          1192:        
        !          1193:        /* Block size */
        !          1194:        count += sizeof (bsize);
        !          1195:        if (count > len) {
        !          1196:                SET_U_ERROR (EFAULT, "ufstatfs 1");
        !          1197:                return;
        !          1198:        }
        !          1199:        if (! kucopy (& bsize, & stfs->f_bsize, sizeof (bsize)))
        !          1200:                return;
        !          1201: 
        !          1202:        /* Fragment size. */
        !          1203:        count += sizeof (int);
        !          1204:        if (count > len) {
        !          1205:                SET_U_ERROR (EFAULT, "ufstatfs 2");
        !          1206:                return;
        !          1207:        }
        !          1208:        if (! kucopy (& frsize, & stfs->f_frsize, sizeof (frsize)))
        !          1209:                return;
        !          1210: 
        !          1211:        if (! fstyp) {
        !          1212:                if ((sb = statmount (fildes, NULL)) == NULL)
        !          1213:                        return;
        !          1214:                devinfo (sb, stfs, len, & count);
        !          1215:        } else {
        !          1216:                if ((sb = statunmount (fildes, NULL)) == NULL)
        !          1217:                        return;
        !          1218:                devinfo (sb, stfs, len, & count);
        !          1219:                kfree (sb);
        !          1220:        }
        !          1221:        return 0;
        !          1222: }
        !          1223: 
        !          1224: /*
        !          1225:  * Check superblock for consistency.
        !          1226:  */
        !          1227: 
        !          1228: tstf(fp)
        !          1229: register struct filsys *fp;
        !          1230: {
        !          1231:        register daddr_t *dp;
        !          1232:        register ino_t *ip;
        !          1233:        register ino_t maxinode;
        !          1234: 
        !          1235:        maxinode = (fp->s_isize - INODEI) * INOPB + 1;
        !          1236:        if (fp->s_isize >= fp->s_fsize)
        !          1237:                return 0;
        !          1238:        if (fp->s_tfree < fp->s_nfree ||
        !          1239:            fp->s_tfree >= fp->s_fsize - fp->s_isize + 1)
        !          1240:                return 0;
        !          1241:        if (fp->s_tinode < fp->s_ninode || fp->s_tinode >= maxinode - 1)
        !          1242:                return 0;
        !          1243: 
        !          1244:        for (dp = fp->s_free ; dp < fp->s_free + fp->s_nfree ; dp += 1)
        !          1245:                if (* dp < fp->s_isize || * dp >= fp->s_fsize)
        !          1246:                        return 0;
        !          1247: 
        !          1248:        for (ip = fp->s_inode ; ip < fp->s_inode + fp->s_ninode ; ip += 1)
        !          1249:                if (* ip < 1 || * ip > maxinode)
        !          1250:                        return 0;
        !          1251:        return 1;
        !          1252: }
        !          1253: 
        !          1254: /* the following calls are not in the BCS */
        !          1255: 
        !          1256: uadmin()
        !          1257: {
        !          1258:        u.u_error = EINVAL;
        !          1259: }

unix.superglobalmegacorp.com

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