Annotation of MiNT/src/unifs.c, revision 1.1

1.1     ! root        1: /*
        !             2: 
        !             3: Copyright 1991,1992 Eric R. Smith. All rights reserved.
        !             4: 
        !             5:  */
        !             6: 
        !             7: 
        !             8: 
        !             9: /* a simple unified file system */
        !            10: 
        !            11: 
        !            12: 
        !            13: #include "mint.h"
        !            14: 
        !            15: 
        !            16: 
        !            17: 
        !            18: 
        !            19: extern FILESYS bios_filesys, proc_filesys, pipe_filesys, shm_filesys;
        !            20: 
        !            21: 
        !            22: 
        !            23: static long    uni_root        P_((int drv, fcookie *fc));
        !            24: 
        !            25: static long    uni_lookup      P_((fcookie *dir, const char *name, fcookie *fc));
        !            26: 
        !            27: static long    uni_getxattr    P_((fcookie *fc, XATTR *xattr));
        !            28: 
        !            29: static long    uni_chattr      P_((fcookie *fc, int attrib));
        !            30: 
        !            31: static long    uni_chown       P_((fcookie *fc, int uid, int gid));
        !            32: 
        !            33: static long    uni_chmode      P_((fcookie *fc, unsigned mode));
        !            34: 
        !            35: static long    uni_rmdir       P_((fcookie *dir, const char *name));
        !            36: 
        !            37: static long    uni_remove      P_((fcookie *dir, const char *name));
        !            38: 
        !            39: static long    uni_getname     P_((fcookie *root, fcookie *dir, char *pathname));
        !            40: 
        !            41: static long    uni_rename      P_((fcookie *olddir, char *oldname,
        !            42: 
        !            43:                                    fcookie *newdir, const char *newname));
        !            44: 
        !            45: static long    uni_opendir     P_((DIR *dirh, int flags));
        !            46: 
        !            47: static long    uni_readdir     P_((DIR *dirh, char *nm, int nmlen, fcookie *));
        !            48: 
        !            49: static long    uni_rewinddir   P_((DIR *dirh));
        !            50: 
        !            51: static long    uni_closedir    P_((DIR *dirh));
        !            52: 
        !            53: static long    uni_pathconf    P_((fcookie *dir, int which));
        !            54: 
        !            55: static long    uni_dfree       P_((fcookie *dir, long *buf));
        !            56: 
        !            57: static DEVDRV *        uni_getdev      P_((fcookie *fc, long *devsp));
        !            58: 
        !            59: static long    uni_symlink     P_((fcookie *dir, const char *name, const char *to));
        !            60: 
        !            61: static long    uni_readlink    P_((fcookie *fc, char *buf, int buflen));
        !            62: 
        !            63: 
        !            64: 
        !            65: FILESYS uni_filesys = {
        !            66: 
        !            67:        (FILESYS *)0,
        !            68: 
        !            69:        0,
        !            70: 
        !            71:        uni_root,
        !            72: 
        !            73:        uni_lookup, nocreat, uni_getdev, uni_getxattr,
        !            74: 
        !            75:        uni_chattr, uni_chown, uni_chmode,
        !            76: 
        !            77:        nomkdir, uni_rmdir, uni_remove, uni_getname, uni_rename,
        !            78: 
        !            79:        uni_opendir, uni_readdir, uni_rewinddir, uni_closedir,
        !            80: 
        !            81:        uni_pathconf, uni_dfree, nowritelabel, noreadlabel,
        !            82: 
        !            83:        uni_symlink, uni_readlink, nohardlink, nofscntl, nodskchng
        !            84: 
        !            85: };
        !            86: 
        !            87: 
        !            88: 
        !            89: /*
        !            90: 
        !            91:  * structure that holds files
        !            92: 
        !            93:  * if (mode & S_IFMT == S_IFDIR), then this is an alias for a drive:
        !            94: 
        !            95:  *     "dev" holds the appropriate BIOS device number, and
        !            96: 
        !            97:  *     "data" is meaningless
        !            98: 
        !            99:  * if (mode & S_IFMT == S_IFLNK), then this is a symbolic link:
        !           100: 
        !           101:  *     "dev" holds the user id of the owner, and
        !           102: 
        !           103:  *     "data" points to the actual link data
        !           104: 
        !           105:  */
        !           106: 
        !           107: 
        !           108: 
        !           109: typedef struct unifile {
        !           110: 
        !           111:        char name[NAME_MAX+1];
        !           112: 
        !           113:        short mode;
        !           114: 
        !           115:        ushort dev;
        !           116: 
        !           117:        FILESYS *fs;
        !           118: 
        !           119:        void *data;
        !           120: 
        !           121:        struct unifile *next;
        !           122: 
        !           123: } UNIFILE;
        !           124: 
        !           125: 
        !           126: 
        !           127: /* the "+1" is for shared memory, which has no BIOS drive */
        !           128: 
        !           129: #define UNI_DIRS NUM_DRIVES+1
        !           130: 
        !           131: static UNIFILE u_drvs[UNI_DIRS];
        !           132: 
        !           133: static UNIFILE *u_root = 0;
        !           134: 
        !           135: 
        !           136: 
        !           137: void
        !           138: 
        !           139: unifs_init()
        !           140: 
        !           141: {
        !           142: 
        !           143:        UNIFILE *u = u_drvs;
        !           144: 
        !           145:        int i;
        !           146: 
        !           147: 
        !           148: 
        !           149:        u_root = u;
        !           150: 
        !           151:        for (i = 0; i < NUM_DRIVES; i++,u++) {
        !           152: 
        !           153:                u->next = u+1;
        !           154: 
        !           155:                u->mode = S_IFDIR|DEFAULT_DIRMODE;
        !           156: 
        !           157:                u->dev = i;
        !           158: 
        !           159:                u->fs = 0;
        !           160: 
        !           161:                if (i == PROCDRV)
        !           162: 
        !           163:                        strcpy(u->name, "proc");
        !           164: 
        !           165:                else if (i == PIPEDRV)
        !           166: 
        !           167:                        strcpy(u->name, "pipe");
        !           168: 
        !           169:                else if (i == BIOSDRV)
        !           170: 
        !           171:                        strcpy(u->name, "dev");
        !           172: 
        !           173:                else if (i == UNIDRV) {
        !           174: 
        !           175:                        (u-1)->next = u->next;  /* skip this drive */
        !           176: 
        !           177:                } else {
        !           178: 
        !           179:                        u->name[0] = i + 'a';
        !           180: 
        !           181:                        u->name[1] = 0;
        !           182: 
        !           183:                }
        !           184: 
        !           185:        }
        !           186: 
        !           187:        u->next = 0;
        !           188: 
        !           189:        u->mode = S_IFDIR|DEFAULT_DIRMODE;
        !           190: 
        !           191:        u->dev = SHMDEVICE;
        !           192: 
        !           193:        u->fs = &shm_filesys;
        !           194: 
        !           195:        strcpy(u->name, "shm");
        !           196: 
        !           197: }
        !           198: 
        !           199: 
        !           200: 
        !           201: static long
        !           202: 
        !           203: uni_root(drv, fc)
        !           204: 
        !           205:        int drv;
        !           206: 
        !           207:        fcookie *fc;
        !           208: 
        !           209: {
        !           210: 
        !           211:        if (drv == UNIDRV) {
        !           212: 
        !           213:                fc->fs = &uni_filesys;
        !           214: 
        !           215:                fc->dev = drv;
        !           216: 
        !           217:                fc->index = 0L;
        !           218: 
        !           219:                return 0;
        !           220: 
        !           221:        }
        !           222: 
        !           223:        fc->fs = 0;
        !           224: 
        !           225:        return EINTRN;
        !           226: 
        !           227: }
        !           228: 
        !           229: 
        !           230: 
        !           231: static long
        !           232: 
        !           233: uni_lookup(dir, name, fc)
        !           234: 
        !           235:        fcookie *dir;
        !           236: 
        !           237:        const char *name;
        !           238: 
        !           239:        fcookie *fc;
        !           240: 
        !           241: {
        !           242: 
        !           243:        UNIFILE *u;
        !           244: 
        !           245:        long drvs;
        !           246: 
        !           247:        FILESYS *fs;
        !           248: 
        !           249:        extern long dosdrvs;
        !           250: 
        !           251: 
        !           252: 
        !           253:        TRACE("uni_lookup(%s)", name);
        !           254: 
        !           255: 
        !           256: 
        !           257:        if (dir->index != 0) {
        !           258: 
        !           259:                DEBUG("uni_lookup: bad directory");
        !           260: 
        !           261:                return EPTHNF;
        !           262: 
        !           263:        }
        !           264: 
        !           265: /* special case: an empty name in a directory means that directory */
        !           266: 
        !           267: /* so do "." and ".." */
        !           268: 
        !           269: 
        !           270: 
        !           271:        if (!*name || !strcmp(name, ".") || !strcmp(name, "..")) {
        !           272: 
        !           273:                *fc = *dir;
        !           274: 
        !           275:                return 0;
        !           276: 
        !           277:        }
        !           278: 
        !           279:        drvs = drvmap() | dosdrvs | PSEUDODRVS;
        !           280: 
        !           281: /*
        !           282: 
        !           283:  * OK, check the list of aliases and special directories
        !           284: 
        !           285:  */
        !           286: 
        !           287:        for (u = u_root; u; u = u->next) {
        !           288: 
        !           289:                if (!stricmp(name, u->name)) {
        !           290: 
        !           291:                        if ( (u->mode & S_IFMT) == S_IFDIR ) {
        !           292: 
        !           293:                                if (u->dev >= NUM_DRIVES) {
        !           294: 
        !           295:                                        fs = u->fs;
        !           296: 
        !           297:                                        return (*fs->root)(u->dev,fc);
        !           298: 
        !           299:                                }
        !           300: 
        !           301:                                if ((drvs & (1L << u->dev)) == 0)
        !           302: 
        !           303:                                        return EPTHNF;
        !           304: 
        !           305:                                *fc = curproc->root[u->dev];
        !           306: 
        !           307:                                if (!fc->fs) {          /* drive changed? */
        !           308: 
        !           309:                                        changedrv(fc->dev);
        !           310: 
        !           311:                                        *fc = curproc->root[u->dev];
        !           312: 
        !           313:                                        if (!fc->fs)
        !           314: 
        !           315:                                                return EPTHNF;
        !           316: 
        !           317:                                }
        !           318: 
        !           319:                        } else {                /* a symbolic link */
        !           320: 
        !           321:                                fc->fs = &uni_filesys;
        !           322: 
        !           323:                                fc->dev = UNIDRV;
        !           324: 
        !           325:                                fc->index = (long)u;
        !           326: 
        !           327:                        }
        !           328: 
        !           329:                        return 0;
        !           330: 
        !           331:                }
        !           332: 
        !           333:        }
        !           334: 
        !           335:        DEBUG("uni_lookup: name (%s) not found", name);
        !           336: 
        !           337:        return EFILNF;
        !           338: 
        !           339: }
        !           340: 
        !           341: 
        !           342: 
        !           343: static long
        !           344: 
        !           345: uni_getxattr(fc, xattr)
        !           346: 
        !           347:        fcookie *fc;
        !           348: 
        !           349:        XATTR *xattr;
        !           350: 
        !           351: {
        !           352: 
        !           353:        UNIFILE *u = (UNIFILE *)fc->index;
        !           354: 
        !           355: 
        !           356: 
        !           357:        if (fc->fs != &uni_filesys) {
        !           358: 
        !           359:                ALERT("ERROR: wrong file system getxattr called");
        !           360: 
        !           361:                return EINTRN;
        !           362: 
        !           363:        }
        !           364: 
        !           365: 
        !           366: 
        !           367:        xattr->index = fc->index;
        !           368: 
        !           369:        xattr->dev = fc->dev;
        !           370: 
        !           371:        xattr->nlink = 1;
        !           372: 
        !           373:        xattr->blksize = 1;
        !           374: 
        !           375: 
        !           376: 
        !           377: /* If "u" is null, then we have the root directory, otherwise
        !           378: 
        !           379:  * we use the UNIFILE structure to get the info about it
        !           380: 
        !           381:  */
        !           382: 
        !           383:        if (!u || ( (u->mode & S_IFMT) == S_IFDIR )) {
        !           384: 
        !           385:                xattr->uid = xattr->gid = 0;
        !           386: 
        !           387:                xattr->size = xattr->nblocks = 0;
        !           388: 
        !           389:                xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
        !           390: 
        !           391:                xattr->attr = FA_DIR;
        !           392: 
        !           393:        } else {
        !           394: 
        !           395:                xattr->uid = u->dev;
        !           396: 
        !           397:                xattr->gid = 0;
        !           398: 
        !           399:                xattr->size = xattr->nblocks = strlen(u->data) + 1;
        !           400: 
        !           401:                xattr->mode = u->mode;
        !           402: 
        !           403:                xattr->attr = 0;
        !           404: 
        !           405:        }
        !           406: 
        !           407:        xattr->mtime = xattr->atime = xattr->ctime = 0;
        !           408: 
        !           409:        xattr->mdate = xattr->adate = xattr->cdate = 0;
        !           410: 
        !           411:        return 0;
        !           412: 
        !           413: }
        !           414: 
        !           415: 
        !           416: 
        !           417: static long
        !           418: 
        !           419: uni_chattr(dir, attrib)
        !           420: 
        !           421:        fcookie *dir;
        !           422: 
        !           423:        int attrib;
        !           424: 
        !           425: {
        !           426: 
        !           427:        return EACCDN;
        !           428: 
        !           429: }
        !           430: 
        !           431: 
        !           432: 
        !           433: static long
        !           434: 
        !           435: uni_chown(dir, uid, gid)
        !           436: 
        !           437:        fcookie *dir;
        !           438: 
        !           439:        int uid, gid;
        !           440: 
        !           441: {
        !           442: 
        !           443:        return EINVFN;
        !           444: 
        !           445: }
        !           446: 
        !           447: 
        !           448: 
        !           449: static long
        !           450: 
        !           451: uni_chmode(dir, mode)
        !           452: 
        !           453:        fcookie *dir;
        !           454: 
        !           455:        unsigned mode;
        !           456: 
        !           457: {
        !           458: 
        !           459:        return EINVFN;
        !           460: 
        !           461: }
        !           462: 
        !           463: 
        !           464: 
        !           465: static long
        !           466: 
        !           467: uni_rmdir(dir, name)
        !           468: 
        !           469:        fcookie *dir;
        !           470: 
        !           471:        const char *name;
        !           472: 
        !           473: {
        !           474: 
        !           475:        long r;
        !           476: 
        !           477: 
        !           478: 
        !           479:        r = uni_remove(dir, name);
        !           480: 
        !           481:        if (r == EFILNF) r = EPTHNF;
        !           482: 
        !           483:        return r;
        !           484: 
        !           485: }
        !           486: 
        !           487: 
        !           488: 
        !           489: static long
        !           490: 
        !           491: uni_remove(dir, name)
        !           492: 
        !           493:        fcookie *dir;
        !           494: 
        !           495:        const char *name;
        !           496: 
        !           497: {
        !           498: 
        !           499:        UNIFILE *u, *lastu;
        !           500: 
        !           501: 
        !           502: 
        !           503:        lastu = 0;
        !           504: 
        !           505:        u = u_root;
        !           506: 
        !           507:        while (u) {
        !           508: 
        !           509:                if (!strncmp(u->name, name, NAME_MAX)) {
        !           510: 
        !           511:                        if ( (u->mode & S_IFMT) != S_IFLNK ) return EFILNF;
        !           512: 
        !           513:                        kfree(u->data);
        !           514: 
        !           515:                        if (lastu)
        !           516: 
        !           517:                                lastu->next = u->next;
        !           518: 
        !           519:                        else
        !           520: 
        !           521:                                u_root = u->next;
        !           522: 
        !           523:                        kfree(u);
        !           524: 
        !           525:                        return 0;
        !           526: 
        !           527:                }
        !           528: 
        !           529:                lastu = u;
        !           530: 
        !           531:                u = u->next;
        !           532: 
        !           533:        }
        !           534: 
        !           535:        return EFILNF;
        !           536: 
        !           537: }
        !           538: 
        !           539: 
        !           540: 
        !           541: static long
        !           542: 
        !           543: uni_getname(root, dir, pathname)
        !           544: 
        !           545:        fcookie *root, *dir; char *pathname;
        !           546: 
        !           547: {
        !           548: 
        !           549:        FILESYS *fs;
        !           550: 
        !           551:        UNIFILE *u;
        !           552: 
        !           553:        char *n;
        !           554: 
        !           555:        fcookie relto;
        !           556: 
        !           557: 
        !           558: 
        !           559:        fs = dir->fs;
        !           560: 
        !           561:        if (dir->dev == UNIDRV) {
        !           562: 
        !           563:                *pathname = 0;
        !           564: 
        !           565:                return 0;
        !           566: 
        !           567:        }
        !           568: 
        !           569: 
        !           570: 
        !           571:        for (u = u_root; u; u = u->next) {
        !           572: 
        !           573:                if (dir->dev == u->dev && (u->mode & S_IFMT) == S_IFDIR) {
        !           574: 
        !           575:                        *pathname++ = '\\';
        !           576: 
        !           577:                        for (n = u->name; *n; )
        !           578: 
        !           579:                                *pathname++ = *n++;
        !           580: 
        !           581:                        break;
        !           582: 
        !           583:                }
        !           584: 
        !           585:        }
        !           586: 
        !           587: 
        !           588: 
        !           589:        if (!u) {
        !           590: 
        !           591:                ALERT("unifs: couldn't match a drive with a directory");
        !           592: 
        !           593:                return EPTHNF;
        !           594: 
        !           595:        }
        !           596: 
        !           597: 
        !           598: 
        !           599:        if (dir->dev >= NUM_DRIVES) {
        !           600: 
        !           601:                if ((*fs->root)(dir->dev, &relto) == 0) {
        !           602: 
        !           603:                        return (*fs->getname)(&relto, dir, pathname);
        !           604: 
        !           605:                } else {
        !           606: 
        !           607:                        *pathname++ = 0;
        !           608: 
        !           609:                        return EINTRN;
        !           610: 
        !           611:                }
        !           612: 
        !           613:        }
        !           614: 
        !           615: 
        !           616: 
        !           617:        if (curproc->root[dir->dev].fs != fs) {
        !           618: 
        !           619:                ALERT("unifs: drive's file system doesn't match directory's");
        !           620: 
        !           621:                return EINTRN;
        !           622: 
        !           623:        }
        !           624: 
        !           625: 
        !           626: 
        !           627:        return (*fs->getname)(&curproc->root[dir->dev], dir, pathname);
        !           628: 
        !           629: }
        !           630: 
        !           631: 
        !           632: 
        !           633: static long
        !           634: 
        !           635: uni_rename(olddir, oldname, newdir, newname)
        !           636: 
        !           637:        fcookie *olddir;
        !           638: 
        !           639:        char *oldname;
        !           640: 
        !           641:        fcookie *newdir;
        !           642: 
        !           643:        const char *newname;
        !           644: 
        !           645: {
        !           646: 
        !           647:        UNIFILE *u = 0;
        !           648: 
        !           649:        fcookie fc;
        !           650: 
        !           651:        long r;
        !           652: 
        !           653: 
        !           654: 
        !           655:        for (u = u_root; u; u = u->next) {
        !           656: 
        !           657:                if (!stricmp(u->name, oldname))
        !           658: 
        !           659:                        break;
        !           660: 
        !           661:        }
        !           662: 
        !           663: 
        !           664: 
        !           665:        if (!u) {
        !           666: 
        !           667:                DEBUG("uni_rename: old file not found");
        !           668: 
        !           669:                return EFILNF;
        !           670: 
        !           671:        }
        !           672: 
        !           673: 
        !           674: 
        !           675: /* the new name is not allowed to exist! */
        !           676: 
        !           677:        r = uni_lookup(newdir, newname, &fc);
        !           678: 
        !           679:        if (r != EFILNF) {
        !           680: 
        !           681:                DEBUG("uni_rename: error %ld", r);
        !           682: 
        !           683:                return (r == 0) ? EACCDN : r;
        !           684: 
        !           685:        }
        !           686: 
        !           687: 
        !           688: 
        !           689:        (void)strncpy(u->name, newname, NAME_MAX);
        !           690: 
        !           691:        return 0;
        !           692: 
        !           693: }
        !           694: 
        !           695: 
        !           696: 
        !           697: static long
        !           698: 
        !           699: uni_opendir(dirh, flags)
        !           700: 
        !           701:        DIR *dirh;
        !           702: 
        !           703:        int flags;
        !           704: 
        !           705: {
        !           706: 
        !           707:        if (dirh->fc.index != 0) {
        !           708: 
        !           709:                DEBUG("uni_opendir: bad directory");
        !           710: 
        !           711:                return EPTHNF;
        !           712: 
        !           713:        }
        !           714: 
        !           715:        dirh->index = 0;
        !           716: 
        !           717:        return 0;
        !           718: 
        !           719: }
        !           720: 
        !           721: 
        !           722: 
        !           723: 
        !           724: 
        !           725: static long
        !           726: 
        !           727: uni_readdir(dirh, name, namelen, fc)
        !           728: 
        !           729:        DIR *dirh;
        !           730: 
        !           731:        char *name;
        !           732: 
        !           733:        int namelen;
        !           734: 
        !           735:        fcookie *fc;
        !           736: 
        !           737: {
        !           738: 
        !           739:        long map;
        !           740: 
        !           741:        char *dirname;
        !           742: 
        !           743:        int i;
        !           744: 
        !           745:        int giveindex = (dirh->flags == 0);
        !           746: 
        !           747:        UNIFILE *u;
        !           748: 
        !           749:        long index;
        !           750: 
        !           751:        extern long dosdrvs;
        !           752: 
        !           753:        long r;
        !           754: 
        !           755: 
        !           756: 
        !           757:        map = dosdrvs | drvmap() | PSEUDODRVS;
        !           758: 
        !           759:        i = dirh->index++;
        !           760: 
        !           761:        u = u_root;
        !           762: 
        !           763:        while (i > 0) {
        !           764: 
        !           765:                --i;
        !           766: 
        !           767:                u = u->next;
        !           768: 
        !           769:                if (!u)
        !           770: 
        !           771:                        break;
        !           772: 
        !           773:        }
        !           774: 
        !           775: tryagain:
        !           776: 
        !           777:        if (!u) return ENMFIL;
        !           778: 
        !           779: 
        !           780: 
        !           781:        dirname = u->name;
        !           782: 
        !           783:        index = (long)u;
        !           784: 
        !           785:        if ( (u->mode & S_IFMT) == S_IFDIR ) {
        !           786: 
        !           787: /* make sure the drive really exists */
        !           788: 
        !           789:                if ( u->dev >= NUM_DRIVES) {
        !           790: 
        !           791:                    r = (*u->fs->root)(u->dev,fc);
        !           792: 
        !           793:                    if (r) {
        !           794: 
        !           795:                        fc->fs = &uni_filesys;
        !           796: 
        !           797:                        fc->index = 0;
        !           798: 
        !           799:                        fc->dev = u->dev;
        !           800: 
        !           801:                    }
        !           802: 
        !           803:                } else {
        !           804: 
        !           805:                    if ((map & (1L << u->dev)) == 0 ) {
        !           806: 
        !           807:                        dirh->index++;
        !           808: 
        !           809:                        u = u->next;
        !           810: 
        !           811:                        goto tryagain;
        !           812: 
        !           813:                    }
        !           814: 
        !           815:                    *fc = curproc->root[u->dev];
        !           816: 
        !           817:                    if (!fc->fs) {      /* drive not yet initialized */
        !           818: 
        !           819:                /* use default attributes */
        !           820: 
        !           821:                        fc->fs = &uni_filesys;
        !           822: 
        !           823:                        fc->index = 0;
        !           824: 
        !           825:                        fc->dev = u->dev;
        !           826: 
        !           827:                    }
        !           828: 
        !           829:                }
        !           830: 
        !           831:        } else {                /* a symbolic link */
        !           832: 
        !           833:                fc->fs = &uni_filesys;
        !           834: 
        !           835:                fc->dev = UNIDRV;
        !           836: 
        !           837:                fc->index = (long)u;
        !           838: 
        !           839:        }
        !           840: 
        !           841: 
        !           842: 
        !           843:        if (giveindex) {
        !           844: 
        !           845:                namelen -= sizeof(long);
        !           846: 
        !           847:                if (namelen <= 0) return ERANGE;
        !           848: 
        !           849:                *((long *)name) = index;
        !           850: 
        !           851:                name += sizeof(long);
        !           852: 
        !           853:        }
        !           854: 
        !           855:        strncpy(name, dirname, namelen-1);
        !           856: 
        !           857:        if (strlen(name) < strlen(dirname))
        !           858: 
        !           859:                return ENAMETOOLONG;
        !           860: 
        !           861:        return 0;
        !           862: 
        !           863: }
        !           864: 
        !           865: 
        !           866: 
        !           867: static long
        !           868: 
        !           869: uni_rewinddir(dirh)
        !           870: 
        !           871:        DIR *dirh;
        !           872: 
        !           873: {
        !           874: 
        !           875:        dirh->index = 0;
        !           876: 
        !           877:        return 0;
        !           878: 
        !           879: }
        !           880: 
        !           881: 
        !           882: 
        !           883: static long
        !           884: 
        !           885: uni_closedir(dirh)
        !           886: 
        !           887:        DIR *dirh;
        !           888: 
        !           889: {
        !           890: 
        !           891:        return 0;
        !           892: 
        !           893: }
        !           894: 
        !           895: 
        !           896: 
        !           897: static long
        !           898: 
        !           899: uni_pathconf(dir, which)
        !           900: 
        !           901:        fcookie *dir;
        !           902: 
        !           903:        int which;
        !           904: 
        !           905: {
        !           906: 
        !           907:        switch(which) {
        !           908: 
        !           909:        case -1:
        !           910: 
        !           911:                return DP_MAXREQ;
        !           912: 
        !           913:        case DP_IOPEN:
        !           914: 
        !           915:                return 0;               /* no files to open */
        !           916: 
        !           917:        case DP_MAXLINKS:
        !           918: 
        !           919:                return 1;               /* no hard links available */
        !           920: 
        !           921:        case DP_PATHMAX:
        !           922: 
        !           923:                return PATH_MAX;
        !           924: 
        !           925:        case DP_NAMEMAX:
        !           926: 
        !           927:                return NAME_MAX;
        !           928: 
        !           929:        case DP_ATOMIC:
        !           930: 
        !           931:                return 1;               /* no atomic writes */
        !           932: 
        !           933:        case DP_TRUNC:
        !           934: 
        !           935:                return DP_AUTOTRUNC;
        !           936: 
        !           937:        case DP_CASE:
        !           938: 
        !           939:                return DP_CASEINSENS;
        !           940: 
        !           941:        default:
        !           942: 
        !           943:                return EINVFN;
        !           944: 
        !           945:        }
        !           946: 
        !           947: }
        !           948: 
        !           949: 
        !           950: 
        !           951: static long
        !           952: 
        !           953: uni_dfree(dir, buf)
        !           954: 
        !           955:        fcookie *dir;
        !           956: 
        !           957:        long *buf;
        !           958: 
        !           959: {
        !           960: 
        !           961:        buf[0] = 0;     /* number of free clusters */
        !           962: 
        !           963:        buf[1] = 0;     /* total number of clusters */
        !           964: 
        !           965:        buf[2] = 1;     /* sector size (bytes) */
        !           966: 
        !           967:        buf[3] = 1;     /* cluster size (sectors) */
        !           968: 
        !           969:        return 0;
        !           970: 
        !           971: }
        !           972: 
        !           973: 
        !           974: 
        !           975: static DEVDRV *
        !           976: 
        !           977: uni_getdev(fc, devsp)
        !           978: 
        !           979:        fcookie *fc;
        !           980: 
        !           981:        long *devsp;
        !           982: 
        !           983: {
        !           984: 
        !           985:        *devsp = EACCDN;
        !           986: 
        !           987:        return 0;
        !           988: 
        !           989: }
        !           990: 
        !           991: 
        !           992: 
        !           993: static long
        !           994: 
        !           995: uni_symlink(dir, name, to)
        !           996: 
        !           997:        fcookie *dir;
        !           998: 
        !           999:        const char *name;
        !          1000: 
        !          1001:        const char *to;
        !          1002: 
        !          1003: {
        !          1004: 
        !          1005:        UNIFILE *u;
        !          1006: 
        !          1007:        fcookie fc;
        !          1008: 
        !          1009:        long r;
        !          1010: 
        !          1011: 
        !          1012: 
        !          1013:        r = uni_lookup(dir, name, &fc);
        !          1014: 
        !          1015:        if (r == 0) return EACCDN;      /* file already exists */
        !          1016: 
        !          1017:        if (r != EFILNF) return r;      /* some other error */
        !          1018: 
        !          1019: 
        !          1020: 
        !          1021:        u = kmalloc(SIZEOF(UNIFILE));
        !          1022: 
        !          1023:        if (!u) return EACCDN;
        !          1024: 
        !          1025: 
        !          1026: 
        !          1027:        strncpy(u->name, name, NAME_MAX);
        !          1028: 
        !          1029:        u->name[NAME_MAX] = 0;
        !          1030: 
        !          1031: 
        !          1032: 
        !          1033:        u->data = kmalloc((long)strlen(to)+1);
        !          1034: 
        !          1035:        if (!u->data) {
        !          1036: 
        !          1037:                kfree(u);
        !          1038: 
        !          1039:                return EACCDN;
        !          1040: 
        !          1041:        }
        !          1042: 
        !          1043:        strcpy(u->data, to);
        !          1044: 
        !          1045:        u->mode = S_IFLNK | DEFAULT_DIRMODE;
        !          1046: 
        !          1047:        u->dev = curproc->ruid;
        !          1048: 
        !          1049:        u->next = u_root;
        !          1050: 
        !          1051:        u->fs = &uni_filesys;
        !          1052: 
        !          1053:        u_root = u;
        !          1054: 
        !          1055:        return 0;
        !          1056: 
        !          1057: }
        !          1058: 
        !          1059: 
        !          1060: 
        !          1061: static long
        !          1062: 
        !          1063: uni_readlink(fc, buf, buflen)
        !          1064: 
        !          1065:        fcookie *fc;
        !          1066: 
        !          1067:        char *buf;
        !          1068: 
        !          1069:        int buflen;
        !          1070: 
        !          1071: {
        !          1072: 
        !          1073:        UNIFILE *u;
        !          1074: 
        !          1075: 
        !          1076: 
        !          1077:        u = (UNIFILE *)fc->index;
        !          1078: 
        !          1079:        assert(u);
        !          1080: 
        !          1081:        assert((u->mode & S_IFMT) == S_IFLNK);
        !          1082: 
        !          1083:        assert(u->data);
        !          1084: 
        !          1085:        strncpy(buf, u->data, buflen);
        !          1086: 
        !          1087:        if (strlen(u->data) >= buflen)
        !          1088: 
        !          1089:                return ENAMETOOLONG;
        !          1090: 
        !          1091:        return 0;
        !          1092: 
        !          1093: }
        !          1094: 

unix.superglobalmegacorp.com

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