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

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

unix.superglobalmegacorp.com

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