Annotation of MiNT/src/biosfs.c, revision 1.1.1.5

1.1       root        1: /*
                      2: 
1.1.1.4   root        3: Copyright 1991,1992 Eric R. Smith.
                      4: 
1.1.1.5 ! root        5: Copyright 1993,1994 Atari Corporation.
1.1.1.4   root        6: 
                      7: All rights reserved.
1.1       root        8: 
                      9:  */
                     10: 
                     11: 
                     12: 
                     13: /* simple biosfs.c */
                     14: 
                     15: 
                     16: 
                     17: #include "mint.h"
                     18: 
                     19: 
                     20: 
                     21: extern struct kerinfo kernelinfo;      /* see main.c */
                     22: 
                     23: 
                     24: 
1.1.1.2   root       25: static long    ARGS_ON_STACK bios_root P_((int drv, fcookie *fc));
1.1       root       26: 
1.1.1.2   root       27: static long    ARGS_ON_STACK bios_lookup       P_((fcookie *dir, const char *name, fcookie *fc));
1.1       root       28: 
1.1.1.2   root       29: static long    ARGS_ON_STACK bios_getxattr     P_((fcookie *fc, XATTR *xattr));
1.1       root       30: 
1.1.1.2   root       31: static long    ARGS_ON_STACK bios_chattr       P_((fcookie *fc, int attrib));
1.1       root       32: 
1.1.1.2   root       33: static long    ARGS_ON_STACK bios_chown        P_((fcookie *fc, int uid, int gid));
1.1       root       34: 
1.1.1.2   root       35: static long    ARGS_ON_STACK bios_chmode       P_((fcookie *fc, unsigned mode));
1.1       root       36: 
1.1.1.2   root       37: static long    ARGS_ON_STACK bios_rmdir        P_((fcookie *dir, const char *name));
1.1       root       38: 
1.1.1.2   root       39: static long    ARGS_ON_STACK bios_remove       P_((fcookie *dir, const char *name));
1.1       root       40: 
1.1.1.3   root       41: static long    ARGS_ON_STACK bios_getname      P_((fcookie *root, fcookie *dir, char *pathname, int size));
1.1       root       42: 
1.1.1.2   root       43: static long    ARGS_ON_STACK bios_rename       P_((fcookie *olddir, char *oldname,
1.1       root       44: 
                     45:                                    fcookie *newdir, const char *newname));
                     46: 
1.1.1.2   root       47: static long    ARGS_ON_STACK bios_opendir      P_((DIR *dirh, int flags));
1.1       root       48: 
1.1.1.2   root       49: static long    ARGS_ON_STACK bios_readdir      P_((DIR *dirh, char *nm, int nmlen, fcookie *fc));
1.1       root       50: 
1.1.1.2   root       51: static long    ARGS_ON_STACK bios_rewinddir    P_((DIR *dirh));
1.1       root       52: 
1.1.1.2   root       53: static long    ARGS_ON_STACK bios_closedir     P_((DIR *dirh));
1.1       root       54: 
1.1.1.2   root       55: static long    ARGS_ON_STACK bios_pathconf     P_((fcookie *dir, int which));
1.1       root       56: 
1.1.1.2   root       57: static long    ARGS_ON_STACK bios_dfree        P_((fcookie *dir, long *buf));
1.1       root       58: 
1.1.1.2   root       59: static DEVDRV *        ARGS_ON_STACK bios_getdev       P_((fcookie *fc, long *devspecial));
1.1       root       60: 
1.1.1.2   root       61: static long    ARGS_ON_STACK bios_fscntl       P_((fcookie *, const char *, int, long));
1.1       root       62: 
1.1.1.2   root       63: static long    ARGS_ON_STACK bios_symlink      P_((fcookie *, const char *, const char *));
1.1       root       64: 
1.1.1.2   root       65: static long    ARGS_ON_STACK bios_readlink     P_((fcookie *, char *, int));
1.1       root       66: 
                     67: 
                     68: 
1.1.1.2   root       69: static long    ARGS_ON_STACK bios_topen        P_((FILEPTR *f));
1.1       root       70: 
1.1.1.2   root       71: static long    ARGS_ON_STACK bios_twrite       P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       72: 
1.1.1.2   root       73: static long    ARGS_ON_STACK bios_tread        P_((FILEPTR *f, char *buf, long bytes));
1.1       root       74: 
1.1.1.2   root       75: static long    ARGS_ON_STACK bios_nwrite       P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       76: 
1.1.1.2   root       77: static long    ARGS_ON_STACK bios_nread        P_((FILEPTR *f, char *buf, long bytes));
1.1       root       78: 
1.1.1.2   root       79: static long    ARGS_ON_STACK bios_ioctl        P_((FILEPTR *f, int mode, void *buf));
1.1       root       80: 
1.1.1.2   root       81: static long    ARGS_ON_STACK bios_select       P_((FILEPTR *f, long p, int mode));
1.1       root       82: 
1.1.1.2   root       83: static void    ARGS_ON_STACK bios_unselect     P_((FILEPTR *f, long p, int mode));
1.1       root       84: 
1.1.1.2   root       85: static long    ARGS_ON_STACK bios_tseek        P_((FILEPTR *f, long where, int whence));
1.1       root       86: 
1.1.1.5 ! root       87: static long    ARGS_ON_STACK bios_close        P_((FILEPTR *f, int pid));
        !            88: 
1.1       root       89: 
                     90: 
1.1.1.2   root       91: long   ARGS_ON_STACK null_open P_((FILEPTR *f));
1.1       root       92: 
1.1.1.2   root       93: long   ARGS_ON_STACK null_write        P_((FILEPTR *f, const char *buf, long bytes));
1.1       root       94: 
1.1.1.2   root       95: long   ARGS_ON_STACK null_read P_((FILEPTR *f, char *buf, long bytes));
1.1       root       96: 
1.1.1.2   root       97: long   ARGS_ON_STACK null_lseek        P_((FILEPTR *f, long where, int whence));
1.1       root       98: 
1.1.1.2   root       99: long   ARGS_ON_STACK null_ioctl        P_((FILEPTR *f, int mode, void *buf));
1.1       root      100: 
1.1.1.2   root      101: long   ARGS_ON_STACK null_datime       P_((FILEPTR *f, short *time, int rwflag));
1.1       root      102: 
1.1.1.2   root      103: long   ARGS_ON_STACK null_close        P_((FILEPTR *f, int pid));
1.1       root      104: 
1.1.1.2   root      105: long   ARGS_ON_STACK null_select       P_((FILEPTR *f, long p, int mode));
1.1       root      106: 
1.1.1.2   root      107: void   ARGS_ON_STACK null_unselect     P_((FILEPTR *f, long p, int mode));
1.1       root      108: 
                    109: 
                    110: 
1.1.1.2   root      111: static long ARGS_ON_STACK mouse_open   P_((FILEPTR *f));
1.1       root      112: 
1.1.1.2   root      113: static long ARGS_ON_STACK mouse_read   P_((FILEPTR *f, char *buf, long nbytes));
1.1       root      114: 
1.1.1.2   root      115: static long ARGS_ON_STACK mouse_ioctl P_((FILEPTR *f, int mode, void *buf));
1.1       root      116: 
1.1.1.2   root      117: static long ARGS_ON_STACK mouse_close P_((FILEPTR *f, int pid));
1.1       root      118: 
1.1.1.2   root      119: static long ARGS_ON_STACK mouse_select P_((FILEPTR *f, long p, int mode));
1.1       root      120: 
1.1.1.2   root      121: static void ARGS_ON_STACK mouse_unselect P_((FILEPTR *f, long p, int mode));
1.1       root      122: 
                    123: 
                    124: 
                    125: /* device driver for BIOS terminals */
                    126: 
                    127: 
                    128: 
                    129: DEVDRV bios_tdevice = {
                    130: 
                    131:        bios_topen, bios_twrite, bios_tread, bios_tseek, bios_ioctl,
                    132: 
1.1.1.5 ! root      133:        null_datime, bios_close, bios_select, bios_unselect
1.1       root      134: 
                    135: };
                    136: 
                    137: 
                    138: 
                    139: /* device driver for BIOS devices that are not terminals */
                    140: 
                    141: 
                    142: 
                    143: DEVDRV bios_ndevice = {
                    144: 
                    145:        null_open, bios_nwrite, bios_nread, null_lseek, bios_ioctl,
                    146: 
1.1.1.5 ! root      147:        null_datime, bios_close, bios_select, bios_unselect
1.1       root      148: 
                    149: };
                    150: 
                    151: 
                    152: 
                    153: DEVDRV null_device = {
                    154: 
                    155:        null_open, null_write, null_read, null_lseek, null_ioctl,
                    156: 
                    157:        null_datime, null_close, null_select, null_unselect
                    158: 
                    159: };
                    160: 
                    161: 
                    162: 
                    163: DEVDRV mouse_device = {
                    164: 
                    165:        mouse_open, null_write, mouse_read, null_lseek, mouse_ioctl,
                    166: 
                    167:        null_datime, mouse_close, mouse_select, mouse_unselect
                    168: 
                    169: };
                    170: 
                    171: 
                    172: 
                    173: /* this special driver is checked for in dosfile.c, and indicates that
                    174: 
                    175:  * a dup operation is actually wanted rather than an open
                    176: 
                    177:  */
                    178: 
                    179: DEVDRV fakedev;
                    180: 
                    181: 
                    182: 
                    183: #ifdef FASTTEXT
                    184: 
                    185: extern DEVDRV screen_device;   /* see fasttext.c */
                    186: 
                    187: #endif
                    188: 
                    189: 
                    190: 
                    191: FILESYS bios_filesys = {
                    192: 
                    193:        (FILESYS *)0,
                    194: 
1.1.1.3   root      195:        FS_LONGPATH,
1.1       root      196: 
                    197:        bios_root,
                    198: 
                    199:        bios_lookup, nocreat, bios_getdev, bios_getxattr,
                    200: 
                    201:        bios_chattr, bios_chown, bios_chmode,
                    202: 
                    203:        nomkdir, bios_rmdir, bios_remove, bios_getname, bios_rename,
                    204: 
                    205:        bios_opendir, bios_readdir, bios_rewinddir, bios_closedir,
                    206: 
                    207:        bios_pathconf, bios_dfree, nowritelabel, noreadlabel,
                    208: 
                    209:        bios_symlink, bios_readlink, nohardlink, bios_fscntl, nodskchng
                    210: 
                    211: };
                    212: 
                    213: 
                    214: 
                    215: 
                    216: 
                    217: struct tty con_tty, aux_tty, midi_tty;
                    218: 
                    219: struct tty sccb_tty, scca_tty, ttmfp_tty;
                    220: 
                    221: 
                    222: 
                    223: struct bios_file BDEV[] = {
                    224: 
                    225: 
                    226: 
                    227: /* "real" bios devices present on all machines */
                    228: 
                    229:        {"centr", &bios_ndevice, 0, 0, 0, 0},
                    230: 
                    231:        {"console", &bios_tdevice, 2, O_TTY, &con_tty, 0},
                    232: 
                    233:        {"midi", &bios_tdevice, 3, O_TTY, &midi_tty, 0},
                    234: 
                    235:        {"kbd", &bios_ndevice, 4, 0, 0, 0},
                    236: 
                    237: /* devices that duplicate handles */
                    238: 
                    239:        {"prn", &fakedev, -3, 0, 0, 0}, /* handle -3 (printer) */
                    240: 
                    241:        {"aux", &fakedev, -2, 0, 0, 0}, /* handle -2 (aux. terminal) */
                    242: 
                    243:        {"con", &fakedev, -1, 0, 0, 0}, /* handle -1 (control terminal) */
                    244: 
                    245:        {"tty", &fakedev, -1, 0, 0, 0}, /* the Unix name for it */
                    246: 
                    247:        {"stdin", &fakedev, 0, 0, 0, 0},  /* handle 0 (stdin) */
                    248: 
                    249:        {"stdout", &fakedev, 1, 0, 0, 0}, /* handle 1 (stdout) */
                    250: 
                    251:        {"stderr", &fakedev, 2, 0, 0, 0}, /* handle 2 (stderr) */
                    252: 
1.1.1.5 ! root      253:        {"fd", &fakedev, S_IFDIR, 0, 0, 0}, /* file descriptor directory */
        !           254: 
1.1       root      255: 
                    256: 
                    257: /* other miscellaneous devices */
                    258: 
                    259:        {"mouse", &mouse_device, 0, 0, 0, 0},
                    260: 
                    261:        {"null", &null_device, 0, 0, 0, 0},
                    262: 
                    263: 
                    264: 
                    265: #ifdef FASTTEXT
                    266: 
                    267: /* alternate console driver */
                    268: 
                    269:        {"fasttext", &screen_device, 2, O_TTY, &con_tty, 0},
                    270: 
                    271: #endif
                    272: 
                    273: 
                    274: 
                    275: /* serial port things *must* come last, because not all of these
                    276: 
                    277:  * are present on all machines (except for modem1, which does however
                    278: 
                    279:  * have a different device number on TTs and STs)
                    280: 
                    281:  */
                    282: 
                    283:        {"modem1", &bios_tdevice, 6, O_TTY, &aux_tty, 0},
                    284: 
                    285:        {"modem2", &bios_tdevice, 7, O_TTY, &sccb_tty, 0},
                    286: 
                    287:        {"serial1", &bios_tdevice, 8, O_TTY, &ttmfp_tty, 0},
                    288: 
                    289:        {"serial2", &bios_tdevice, 9, O_TTY, &scca_tty, 0},
                    290: 
                    291:        {"", 0, 0, 0, 0, 0}
                    292: 
                    293: };
                    294: 
                    295: 
                    296: 
1.1.1.5 ! root      297: /* Does the fcookie fc refer to the \dev\fd directory? */
        !           298: 
        !           299: #define IS_FD_DIR(fc) ((fc)->aux == S_IFDIR)
        !           300: 
        !           301: /* Does the fcookie fc refer to a file in the \dev\fd directory? */
        !           302: 
        !           303: #define IS_FD_ENTRY(fc) ((fc)->index > 0 && (fc)->index <= MAX_OPEN-MIN_HANDLE)
        !           304: 
        !           305: 
        !           306: 
1.1       root      307: struct bios_file *broot, *bdevlast;
                    308: 
                    309: 
                    310: 
                    311: /* a file pointer for BIOS device 1, provided only for insurance
                    312: 
                    313:  * in case a Bconmap happens and we can't allocate a new FILEPTR;
                    314: 
                    315:  * in most cases, we'll want to build a FILEPTR in the usual
                    316: 
                    317:  * way.
                    318: 
                    319:  */
                    320: 
                    321: 
                    322: 
                    323: FILEPTR *defaultaux;
                    324: 
                    325: 
                    326: 
1.1.1.5 ! root      327: /* ts: a xattr field used for the root directory, 'cause there's no
        !           328: 
        !           329:  * bios_file structure for it.
        !           330: 
        !           331:  */
        !           332: 
        !           333: XATTR rxattr;
        !           334: 
        !           335: XATTR fdxattr;
        !           336: 
        !           337: 
        !           338: 
        !           339: /* ts: a small utility function to set up a xattr structure
        !           340: 
        !           341:  */
        !           342: 
        !           343: 
        !           344: 
        !           345: static void set_xattr P_((XATTR *xp, ushort mode, int rdev));
        !           346: 
        !           347: 
        !           348: 
        !           349: void set_xattr(xp, mode, rdev)
        !           350: 
        !           351:        XATTR *xp;
        !           352: 
        !           353:        ushort mode;
        !           354: 
        !           355:        int rdev;
        !           356: 
        !           357: {
        !           358: 
        !           359:        xp->mode = mode;
        !           360: 
        !           361:        xp->index = 0L;
        !           362: 
        !           363:        xp->dev = BIOSDRV;
        !           364: 
        !           365:        xp->rdev = rdev;
        !           366: 
        !           367:        xp->nlink = 1;
        !           368: 
        !           369:        xp->uid = curproc->euid;
        !           370: 
        !           371:        xp->gid = curproc->egid;
        !           372: 
        !           373:        xp->size = 0L;
        !           374: 
        !           375:        xp->blksize = 1L;
        !           376: 
        !           377:        xp->nblocks = 0L;
        !           378: 
        !           379: 
        !           380: 
        !           381:        xp->mtime = xp->atime = xp->ctime = timestamp;
        !           382: 
        !           383:        xp->mdate = xp->adate = xp->cdate = datestamp;
        !           384: 
        !           385: 
        !           386: 
        !           387: /* root directory only */
        !           388: 
        !           389:        if ((mode & S_IFMT) == S_IFDIR)
        !           390: 
        !           391:                xp->attr = FA_DIR;
        !           392: 
        !           393:        else
        !           394: 
        !           395:                xp->attr = 0;
        !           396: 
        !           397:        xp->reserved2 = 0;
        !           398: 
        !           399:        xp->reserved3[0] = 0L;
        !           400: 
        !           401:        xp->reserved3[1] = 0L;
        !           402: 
        !           403: }
        !           404: 
        !           405: 
        !           406: 
1.1       root      407: void
                    408: 
                    409: biosfs_init()
                    410: 
                    411: {
                    412: 
                    413:        struct bios_file *b;
                    414: 
1.1.1.5 ! root      415:        int majdev, mindev;
        !           416: 
1.1       root      417: 
                    418: 
                    419:        broot = BDEV;
                    420: 
                    421: 
                    422: 
                    423:        for (b = broot; b->name[0]; b++) {
                    424: 
                    425:                b->next = b+1;
                    426: 
                    427: 
                    428: 
                    429:        /* if not a TT or Mega STE, adjust the MODEM1 device to be BIOS
                    430: 
                    431:         * device 1
                    432: 
                    433:         * and ignore the remaining devices, since they're not present
                    434: 
                    435:         */
                    436: 
                    437:                if (!has_bconmap && b->private == 6) {
                    438: 
                    439:                        b->private = 1;
                    440: 
                    441:                        b->next = 0;
                    442: 
                    443:                        break;
                    444: 
                    445:                }
                    446: 
1.1.1.5 ! root      447:        /* SERIAL2 is not present on the Mega STe or Falcon */
1.1       root      448: 
1.1.1.5 ! root      449:                if (mch != TT && b->private == 8) {
1.1       root      450: 
                    451:                        b->next = 0;
                    452: 
                    453:                        break;
                    454: 
                    455:                }
                    456: 
                    457:                        
                    458: 
                    459:        }
                    460: 
                    461:        bdevlast = b;
                    462: 
                    463:        if (b->name[0] == 0) {
                    464: 
                    465:                --b;
                    466: 
                    467:                b->next = 0;
                    468: 
                    469:        }
                    470: 
                    471:        defaultaux = new_fileptr();
                    472: 
                    473:        defaultaux->links = 1;          /* so it never gets freed */
                    474: 
                    475:        defaultaux->flags = O_RDWR;
                    476: 
                    477:        defaultaux->pos = 0;
                    478: 
                    479:        defaultaux->devinfo = 0;
                    480: 
                    481:        defaultaux->fc.fs = &bios_filesys;
                    482: 
                    483:        defaultaux->fc.index = 0;
                    484: 
                    485:        defaultaux->fc.aux = 1;
                    486: 
                    487:        defaultaux->fc.dev = BIOSDRV;
                    488: 
                    489:        defaultaux->dev = &bios_ndevice;
                    490: 
1.1.1.5 ! root      491: 
        !           492: 
        !           493: /* set up XATTR fields */
        !           494: 
        !           495:        set_xattr(&rxattr, S_IFDIR|DEFAULT_DIRMODE, BIOSDRV);
        !           496: 
        !           497:        set_xattr(&fdxattr, S_IFDIR|DEFAULT_DIRMODE, BIOSDRV);
        !           498: 
        !           499: 
        !           500: 
        !           501:        for (b = BDEV; b; b = b->next) {
        !           502: 
        !           503:                if (b->device == &bios_ndevice || b->device == &bios_tdevice) {
        !           504: 
        !           505:                        majdev = BIOS_RDEV;
        !           506: 
        !           507:                        mindev = b->private;
        !           508: 
        !           509:                } else if (b->device == &fakedev) {
        !           510: 
        !           511:                        majdev = FAKE_RDEV;
        !           512: 
        !           513:                        mindev = b->private;
        !           514: 
        !           515:                } else {
        !           516: 
        !           517:                        majdev = UNK_RDEV;
        !           518: 
        !           519:                        mindev = b->private;
        !           520: 
        !           521:                }
        !           522: 
        !           523:                set_xattr(&b->xattr, S_IFCHR|DEFAULT_MODE,
        !           524: 
        !           525:                          majdev | (mindev & 0x00ff) );
        !           526: 
        !           527:        }
        !           528: 
1.1       root      529: }
                    530: 
                    531: 
                    532: 
1.1.1.2   root      533: static long ARGS_ON_STACK 
1.1       root      534: 
                    535: bios_root(drv, fc)
                    536: 
                    537:        int drv;
                    538: 
                    539:        fcookie *fc;
                    540: 
                    541: {
                    542: 
                    543:        if (drv == BIOSDRV) {
                    544: 
                    545:                fc->fs = &bios_filesys;
                    546: 
                    547:                fc->dev = drv;
                    548: 
                    549:                fc->index = 0L;
                    550: 
                    551:                return 0;
                    552: 
                    553:        }
                    554: 
                    555:        fc->fs = 0;
                    556: 
                    557:        return EINTRN;
                    558: 
                    559: }
                    560: 
                    561: 
                    562: 
1.1.1.2   root      563: static long ARGS_ON_STACK 
1.1       root      564: 
                    565: bios_lookup(dir, name, fc)
                    566: 
                    567:        fcookie *dir;
                    568: 
                    569:        const char *name;
                    570: 
                    571:        fcookie *fc;
                    572: 
                    573: {
                    574: 
                    575:        struct bios_file *b;
                    576: 
                    577: 
                    578: 
                    579:        if (dir->index != 0) {
                    580: 
1.1.1.5 ! root      581:        /* check for \dev\fd directory */
1.1       root      582: 
1.1.1.5 ! root      583:                if (!IS_FD_DIR(dir)) {
        !           584: 
        !           585:                        DEBUG(("bios_lookup: bad directory"));
        !           586: 
        !           587:                        return EPTHNF;
        !           588: 
        !           589:                }
        !           590: 
        !           591:                if (!*name || (name[0] == '.' && name[1] == 0)) {
        !           592: 
        !           593:                        *fc = *dir;
        !           594: 
        !           595:                        return 0;
        !           596: 
        !           597:                }
        !           598: 
        !           599:                if (!strcmp(name, "..")) {
        !           600: 
        !           601:                /* root directory */
        !           602: 
        !           603:                        fc->fs = &bios_filesys;
        !           604: 
        !           605:                        fc->dev = dir->dev;
        !           606: 
        !           607:                        fc->index = 0L;
        !           608: 
        !           609:                        return 0;
        !           610: 
        !           611:                }
        !           612: 
        !           613:                if (isdigit(*name) || *name == '-') {
        !           614: 
        !           615:                        int fd = (int) atol(name);
        !           616: 
        !           617:                        if (fd >= MIN_HANDLE && fd < MAX_OPEN) {
        !           618: 
        !           619:                                fc->fs = &bios_filesys;
        !           620: 
        !           621:                                fc->dev = dir->dev;
        !           622: 
        !           623:                                fc->aux = fd;
        !           624: 
        !           625:                                fc->index = fd - MIN_HANDLE + 1;
        !           626: 
        !           627:                                return 0;
        !           628: 
        !           629:                        }
        !           630: 
        !           631:                }
        !           632: 
        !           633:                DEBUG(("bios_lookup: name (%s) not found", name));
        !           634: 
        !           635:                return EFILNF;
1.1       root      636: 
                    637:        }
                    638: 
1.1.1.5 ! root      639: 
        !           640: 
1.1       root      641: /* special case: an empty name in a directory means that directory */
                    642: 
                    643: /* so does "." */
                    644: 
                    645:        if (!*name || (name[0] == '.' && name[1] == 0)) {
                    646: 
                    647:                *fc = *dir;
                    648: 
                    649:                return 0;
                    650: 
                    651:        }
                    652: 
                    653: 
                    654: 
                    655: /* another special case: ".." could be a mount point */
                    656: 
                    657:        if (!strcmp(name, "..")) {
                    658: 
                    659:                *fc = *dir;
                    660: 
                    661:                return EMOUNT;
                    662: 
                    663:        }
                    664: 
                    665: 
                    666: 
                    667:        for (b = broot; b; b = b->next) {
                    668: 
                    669:                if (!stricmp(b->name, name)) {
                    670: 
                    671:                        fc->fs = &bios_filesys;
                    672: 
                    673:                        fc->index = (long)b;
                    674: 
                    675:                        fc->aux = b->private;
                    676: 
                    677:                        fc->dev = dir->dev;
                    678: 
                    679:                        return 0;
                    680: 
                    681:                }
                    682: 
                    683:        }
                    684: 
1.1.1.2   root      685:        DEBUG(("bios_lookup: name(%s) not found", name));
1.1       root      686: 
                    687:        return EFILNF;
                    688: 
                    689: }
                    690: 
                    691: 
                    692: 
1.1.1.2   root      693: static long ARGS_ON_STACK 
1.1       root      694: 
                    695: bios_getxattr(fc, xattr)
                    696: 
                    697:        fcookie *fc;
                    698: 
                    699:        XATTR *xattr;
                    700: 
                    701: {
                    702: 
1.1.1.2   root      703:        FILEPTR *f;
                    704: 
1.1       root      705:        struct bios_file *b = (struct bios_file *)fc->index;
                    706: 
1.1.1.5 ! root      707:        long r;
        !           708: 
        !           709:        int majdev, mindev;
        !           710: 
        !           711: 
        !           712: 
        !           713:        majdev = UNK_RDEV;
        !           714: 
        !           715:        mindev = 0;
        !           716: 
        !           717: 
        !           718: 
        !           719:        if (fc->index == 0) {                   /* root directory? */
        !           720: 
        !           721:                *xattr = rxattr;
1.1       root      722: 
1.1.1.5 ! root      723:                xattr->index = fc->index;
1.1       root      724: 
1.1.1.5 ! root      725:                xattr->dev = fc->dev;
1.1       root      726: 
1.1.1.5 ! root      727:        } else if (IS_FD_DIR(fc)) {             /* fd directory? */
1.1       root      728: 
1.1.1.5 ! root      729:                *xattr = fdxattr;
1.1       root      730: 
1.1.1.5 ! root      731:                xattr->index = fc->index;
1.1       root      732: 
1.1.1.5 ! root      733:                xattr->dev = fc->dev;
1.1       root      734: 
1.1.1.5 ! root      735:        } else if (IS_FD_ENTRY(fc)) {
1.1       root      736: 
1.1.1.5 ! root      737:                /* u:\dev\fd\n */
1.1       root      738: 
1.1.1.5 ! root      739:                f = curproc->handle[(int)fc->aux];
1.1       root      740: 
1.1.1.5 ! root      741:                if (f) {
1.1       root      742: 
1.1.1.5 ! root      743:                        r = (*f->fc.fs->getxattr)(&f->fc, xattr);
1.1       root      744: 
1.1.1.5 ! root      745:                        if (r < 0)
1.1       root      746: 
1.1.1.5 ! root      747:                                return r;
1.1       root      748: 
1.1.1.5 ! root      749:                } else {
        !           750: 
        !           751:                        majdev = FAKE_RDEV;
        !           752: 
        !           753:                        mindev = ((int)fc->aux) & 0x00ff;
        !           754: 
        !           755:                        set_xattr(xattr, S_IFCHR | DEFAULT_MODE, majdev|mindev);
        !           756: 
        !           757:                }
        !           758: 
        !           759:        } else if (b->device == &fakedev) {
1.1       root      760: 
1.1.1.5 ! root      761:                if ((f = curproc->handle[b->private]) != 0) {
1.1.1.2   root      762: 
1.1.1.5 ! root      763:                    /* u:\dev\stdin, u:\dev\stdout, etc. */
1.1.1.2   root      764: 
1.1.1.5 ! root      765:                    r = (*f->fc.fs->getxattr) (&f->fc, xattr);
1.1       root      766: 
1.1.1.5 ! root      767:                    if (r < 0) return r;
1.1.1.2   root      768: 
1.1.1.5 ! root      769:                } else {
1.1.1.2   root      770: 
1.1.1.5 ! root      771:                        majdev = FAKE_RDEV;
1.1.1.2   root      772: 
1.1.1.5 ! root      773:                        mindev = ((int)b->private) & 0x00ff;
        !           774: 
        !           775:                        set_xattr(xattr, S_IFCHR|DEFAULT_MODE, majdev|mindev);
        !           776: 
        !           777:                }
1.1.1.2   root      778: 
                    779:        } else {
1.1       root      780: 
1.1.1.5 ! root      781:                *xattr = b->xattr;
        !           782: 
        !           783:                xattr->index = fc->index;
1.1       root      784: 
1.1.1.5 ! root      785:                xattr->dev = fc->dev;
1.1       root      786: 
                    787:        }
                    788: 
                    789:        return 0;
                    790: 
                    791: }
                    792: 
                    793: 
                    794: 
1.1.1.2   root      795: static long ARGS_ON_STACK 
1.1       root      796: 
                    797: bios_chattr(fc, attrib)
                    798: 
                    799:        fcookie *fc;
                    800: 
                    801:        int attrib;
                    802: 
                    803: {
                    804: 
1.1.1.2   root      805:        UNUSED(fc); UNUSED(attrib);
                    806: 
1.1       root      807:        return EACCDN;
                    808: 
                    809: }
                    810: 
                    811: 
                    812: 
1.1.1.2   root      813: static long ARGS_ON_STACK 
1.1       root      814: 
                    815: bios_chown(fc, uid, gid)
                    816: 
                    817:        fcookie *fc;
                    818: 
                    819:        int uid, gid;
                    820: 
                    821: {
                    822: 
1.1.1.5 ! root      823:        struct bios_file *b = (struct bios_file *)fc->index;
1.1.1.2   root      824: 
                    825: 
1.1.1.5 ! root      826: 
        !           827:        if (!(curproc->euid)) {
        !           828: 
        !           829:                if (!b) {
        !           830: 
        !           831:                        /* a directory */
        !           832: 
        !           833:                        rxattr.uid = uid;
        !           834: 
        !           835:                        rxattr.gid = gid;
        !           836: 
        !           837:                } else if (IS_FD_DIR(fc)) {
        !           838: 
        !           839:                        fdxattr.uid = uid;
        !           840: 
        !           841:                        fdxattr.gid = gid;
        !           842: 
        !           843:                } else if (!IS_FD_ENTRY(fc)) {
        !           844: 
        !           845:                        /* any other entry */
        !           846: 
        !           847:                        b->xattr.uid = uid;
        !           848: 
        !           849:                        b->xattr.gid = gid;
        !           850: 
        !           851:                }
        !           852: 
        !           853:                return 0;
        !           854: 
        !           855:        }
        !           856: 
        !           857: 
        !           858: 
        !           859:        return EACCDN;
1.1       root      860: 
                    861: }
                    862: 
                    863: 
                    864: 
1.1.1.2   root      865: static long ARGS_ON_STACK 
1.1       root      866: 
                    867: bios_chmode(fc, mode)
                    868: 
                    869:        fcookie *fc;
                    870: 
                    871:        unsigned mode;
                    872: 
                    873: {
                    874: 
1.1.1.5 ! root      875:        struct bios_file *b = (struct bios_file *)fc->index;
1.1.1.2   root      876: 
1.1.1.5 ! root      877: 
        !           878: 
        !           879:        if (!b) {
        !           880: 
        !           881:                /* root directory */
        !           882: 
        !           883:                if (!curproc->euid || (curproc->euid == rxattr.uid)) {
        !           884: 
        !           885:                        rxattr.mode = (rxattr.mode & S_IFMT) | mode;
        !           886: 
        !           887:                        return 0;
        !           888: 
        !           889:                }
        !           890: 
        !           891:        } else if (IS_FD_DIR(fc)) {
        !           892: 
        !           893:                if (!curproc->euid || (curproc->euid == fdxattr.uid)) {
        !           894: 
        !           895:                        fdxattr.mode = (fdxattr.mode & S_IFMT) | mode;
        !           896: 
        !           897:                        return 0;
        !           898: 
        !           899:                }
        !           900: 
        !           901:        } else if (!IS_FD_ENTRY(fc)) {
        !           902: 
        !           903:                if (!curproc->euid && (curproc->euid == b->xattr.uid)) {
        !           904: 
        !           905:                        b->xattr.mode = (b->xattr.mode & S_IFMT) | mode;
        !           906: 
        !           907:                        return 0;
        !           908: 
        !           909:                }
        !           910: 
        !           911:        }
        !           912: 
        !           913: 
        !           914: 
        !           915:        return EACCDN;
1.1       root      916: 
                    917: }
                    918: 
                    919: 
                    920: 
1.1.1.2   root      921: long ARGS_ON_STACK 
1.1       root      922: 
                    923: nomkdir(dir, name, mode)
                    924: 
                    925:        fcookie *dir;
                    926: 
                    927:        const char *name;
                    928: 
                    929:        unsigned mode;
                    930: 
                    931: {
                    932: 
1.1.1.2   root      933:        UNUSED(dir); UNUSED(name);
                    934: 
                    935:        UNUSED(mode);
                    936: 
1.1       root      937:        return EACCDN;
                    938: 
                    939: }
                    940: 
                    941: 
                    942: 
1.1.1.2   root      943: static long ARGS_ON_STACK 
1.1       root      944: 
                    945: bios_rmdir(dir, name)
                    946: 
                    947:        fcookie *dir;
                    948: 
                    949:        const char *name;
                    950: 
                    951: {
                    952: 
                    953:        return bios_remove(dir, name);
                    954: 
                    955: }
                    956: 
                    957: 
                    958: 
                    959: /*
                    960: 
                    961:  * MAJOR BUG: we don't check here for removal of devices for which there
                    962: 
                    963:  * are still open files
                    964: 
                    965:  */
                    966: 
                    967: 
                    968: 
1.1.1.2   root      969: static long ARGS_ON_STACK 
1.1       root      970: 
                    971: bios_remove(dir, name)
                    972: 
                    973:        fcookie *dir;
                    974: 
                    975:        const char *name;
                    976: 
                    977: {
                    978: 
                    979:        struct bios_file *b, **lastb;
                    980: 
                    981: 
                    982: 
1.1.1.2   root      983:        UNUSED(dir);
                    984: 
1.1.1.5 ! root      985: 
        !           986: 
        !           987:        if (curproc->euid)
        !           988: 
        !           989:                return EACCDN;
        !           990: 
        !           991: 
        !           992: 
        !           993: /* don't allow removal in the fd directory */
        !           994: 
        !           995:        if (IS_FD_DIR(dir))
        !           996: 
        !           997:                return EACCDN;
        !           998: 
        !           999: 
        !          1000: 
1.1       root     1001:        lastb = &broot;
                   1002: 
                   1003:        for (b = broot; b; b = *(lastb = &b->next)) {
                   1004: 
                   1005:                if (!stricmp(b->name, name)) break;
                   1006: 
                   1007:        }
                   1008: 
                   1009:        if (!b) return EFILNF;
                   1010: 
                   1011: 
                   1012: 
1.1.1.5 ! root     1013: /* don't allow removal of the device if we don't own it */
        !          1014: 
        !          1015:        if (curproc->euid && (curproc->euid != b->xattr.uid)) {
        !          1016: 
        !          1017:                return EACCDN;
        !          1018: 
        !          1019:        }
        !          1020: 
        !          1021: 
        !          1022: 
1.1       root     1023: /* don't allow removal of the basic system devices */
                   1024: 
                   1025:        if (b >= BDEV && b <= bdevlast) {
                   1026: 
                   1027:                return EACCDN;
                   1028: 
                   1029:        }
                   1030: 
                   1031:        *lastb = b->next;
                   1032: 
                   1033: 
                   1034: 
                   1035:        if (b->device == 0 || b->device == &bios_tdevice)
                   1036: 
                   1037:                kfree(b->tty);
                   1038: 
                   1039: 
                   1040: 
                   1041:        kfree(b);
                   1042: 
                   1043:        return 0;
                   1044: 
                   1045: }
                   1046: 
                   1047: 
                   1048: 
1.1.1.2   root     1049: static long ARGS_ON_STACK 
1.1       root     1050: 
1.1.1.3   root     1051: bios_getname(root, dir, pathname, size)
1.1       root     1052: 
                   1053:        fcookie *root, *dir; char *pathname;
                   1054: 
1.1.1.3   root     1055:        int size;
                   1056: 
1.1       root     1057: {
                   1058: 
1.1.1.5 ! root     1059:        char *foo;
        !          1060: 
1.1.1.3   root     1061: 
                   1062: 
1.1.1.5 ! root     1063:        if (size == 0)
1.1.1.3   root     1064: 
1.1.1.5 ! root     1065:          return ERANGE;
1.1.1.2   root     1066: 
1.1.1.5 ! root     1067:        if (root->index == dir->index) {
1.1       root     1068: 
1.1.1.5 ! root     1069:            *pathname = 0;
1.1       root     1070: 
1.1.1.5 ! root     1071:            return 0;
        !          1072: 
        !          1073:        }
        !          1074: 
        !          1075:        /* DIR must point to the fd directory */
        !          1076: 
        !          1077:        if (!IS_FD_DIR (dir))
        !          1078: 
        !          1079:                return EINTRN;
        !          1080: 
        !          1081:        *pathname++ = '\\';
        !          1082: 
        !          1083:        size--;
        !          1084: 
        !          1085:        foo = ((struct bios_file *)dir->index)->name;
        !          1086: 
        !          1087:        if (strlen(foo) < size)
1.1.1.3   root     1088: 
                   1089:                strcpy(pathname, foo);
                   1090: 
1.1       root     1091:        else
                   1092: 
1.1.1.3   root     1093:                return ERANGE;
1.1       root     1094: 
                   1095:        return 0;
                   1096: 
                   1097: }
                   1098: 
                   1099: 
                   1100: 
1.1.1.2   root     1101: static long ARGS_ON_STACK 
1.1       root     1102: 
                   1103: bios_rename(olddir, oldname, newdir, newname)
                   1104: 
                   1105:        fcookie *olddir;
                   1106: 
                   1107:        char *oldname;
                   1108: 
                   1109:        fcookie *newdir;
                   1110: 
                   1111:        const char *newname;
                   1112: 
                   1113: {
                   1114: 
1.1.1.5 ! root     1115:        struct bios_file *b, *be = 0;
1.1       root     1116: 
                   1117: 
                   1118: 
1.1.1.2   root     1119:        UNUSED(olddir); UNUSED(newdir);
                   1120: 
                   1121: 
                   1122: 
1.1.1.5 ! root     1123:        if (curproc->euid)
        !          1124: 
        !          1125:                return EACCDN;
1.1       root     1126: 
                   1127: 
                   1128: 
                   1129:        for (b = broot; b; b = b->next) {
                   1130: 
1.1.1.5 ! root     1131:                if (!stricmp(b->name, newname)) {
1.1       root     1132: 
1.1.1.5 ! root     1133:                        return EACCDN;
1.1       root     1134: 
1.1.1.5 ! root     1135:                }
        !          1136: 
        !          1137:                if (!stricmp(b->name, oldname)) {
        !          1138: 
        !          1139:                        be = b;
1.1       root     1140: 
                   1141:                }
                   1142: 
                   1143:        }
                   1144: 
1.1.1.5 ! root     1145:        if (be) {
        !          1146: 
        !          1147:                strncpy(be->name, newname, BNAME_MAX);
        !          1148: 
        !          1149:                return 0;
        !          1150: 
        !          1151:        }
        !          1152: 
1.1       root     1153:        return EFILNF;
                   1154: 
                   1155: }
                   1156: 
                   1157: 
                   1158: 
1.1.1.2   root     1159: static long ARGS_ON_STACK 
1.1       root     1160: 
                   1161: bios_opendir(dirh, flags)
                   1162: 
                   1163:        DIR *dirh;
                   1164: 
                   1165:        int flags;
                   1166: 
                   1167: {
                   1168: 
1.1.1.2   root     1169:        UNUSED(flags);
                   1170: 
                   1171: 
                   1172: 
1.1.1.5 ! root     1173:        if (dirh->fc.index != 0 && !IS_FD_DIR(&dirh->fc)) {
1.1       root     1174: 
1.1.1.2   root     1175:                DEBUG(("bios_opendir: bad directory"));
1.1       root     1176: 
                   1177:                return EPTHNF;
                   1178: 
                   1179:        }
                   1180: 
                   1181:        return 0;
                   1182: 
                   1183: }
                   1184: 
                   1185: 
                   1186: 
1.1.1.2   root     1187: static long ARGS_ON_STACK 
1.1       root     1188: 
                   1189: bios_readdir(dirh, name, namelen, fc)
                   1190: 
                   1191:        DIR *dirh;
                   1192: 
                   1193:        char *name;
                   1194: 
                   1195:        int namelen;
                   1196: 
1.1.1.5 ! root     1197:        fcookie *fc;
        !          1198: 
        !          1199: {
        !          1200: 
        !          1201:        struct bios_file *b;
        !          1202: 
        !          1203:        int giveindex = dirh->flags == 0;
        !          1204: 
        !          1205:        int i;
        !          1206: 
        !          1207:        char buf[5];
        !          1208: 
        !          1209: 
        !          1210: 
        !          1211:        if (IS_FD_DIR(&dirh->fc)) {
        !          1212: 
        !          1213:                i = dirh->index++;
        !          1214: 
        !          1215:                if (i+MIN_HANDLE >= MAX_OPEN)
        !          1216: 
        !          1217:                        return ENMFIL;
        !          1218: 
        !          1219:                fc->fs = &bios_filesys;
        !          1220: 
        !          1221:                fc->index = i+1;
        !          1222: 
        !          1223:                fc->aux = i+MIN_HANDLE;
        !          1224: 
        !          1225:                fc->dev = dirh->fc.dev;
        !          1226: 
        !          1227:                if (giveindex) {
        !          1228: 
        !          1229:                        namelen -= (int)sizeof(long);
        !          1230: 
        !          1231:                        if (namelen <= 0)
        !          1232: 
        !          1233:                                return ERANGE;
        !          1234: 
        !          1235:                        *(long *)name = (long)i + 1;
        !          1236: 
        !          1237:                        name += sizeof(long);
        !          1238: 
        !          1239:                }
        !          1240: 
        !          1241:                ksprintf(buf, "%d", i+MIN_HANDLE);
        !          1242: 
        !          1243:                strncpy(name, buf, namelen - 1);
1.1       root     1244: 
1.1.1.5 ! root     1245:                if (strlen(buf) >= namelen)
1.1       root     1246: 
1.1.1.5 ! root     1247:                        return ENAMETOOLONG;
1.1       root     1248: 
1.1.1.5 ! root     1249:                return 0;
1.1       root     1250: 
1.1.1.5 ! root     1251:        }
1.1       root     1252: 
                   1253: 
                   1254: 
                   1255:        b = broot;
                   1256: 
                   1257:        i = dirh->index++;
                   1258: 
                   1259:        while(i-- > 0) {
                   1260: 
                   1261:                if (!b) break;
                   1262: 
                   1263:                b = b->next;
                   1264: 
                   1265:        }
                   1266: 
                   1267:        if (!b) {
                   1268: 
                   1269:                return ENMFIL;
                   1270: 
                   1271:        }
                   1272: 
                   1273:        fc->fs = &bios_filesys;
                   1274: 
                   1275:        fc->index = (long)b;
                   1276: 
                   1277:        fc->aux = b->private;
                   1278: 
                   1279:        fc->dev = dirh->fc.dev;
                   1280: 
                   1281:        if (giveindex) {
                   1282: 
1.1.1.2   root     1283:                namelen -= (int)sizeof(long);
1.1       root     1284: 
                   1285:                if (namelen <= 0)
                   1286: 
                   1287:                        return ERANGE;
                   1288: 
                   1289:                *((long *)name) = (long) b;
                   1290: 
                   1291:                name += sizeof(long);
                   1292: 
                   1293:        }
                   1294: 
                   1295:        strncpy(name, b->name, namelen-1);
                   1296: 
                   1297:        if (strlen(b->name) >= namelen)
                   1298: 
                   1299:                return ENAMETOOLONG;
                   1300: 
                   1301:        return 0;
                   1302: 
                   1303: }
                   1304: 
                   1305: 
                   1306: 
1.1.1.2   root     1307: static long ARGS_ON_STACK 
1.1       root     1308: 
                   1309: bios_rewinddir(dirh)
                   1310: 
                   1311:        DIR *dirh;
                   1312: 
                   1313: {
                   1314: 
                   1315:        dirh->index = 0;
                   1316: 
                   1317:        return 0;
                   1318: 
                   1319: }
                   1320: 
                   1321: 
                   1322: 
1.1.1.2   root     1323: static long ARGS_ON_STACK 
1.1       root     1324: 
                   1325: bios_closedir(dirh)
                   1326: 
                   1327:        DIR *dirh;
                   1328: 
                   1329: {
                   1330: 
1.1.1.2   root     1331:        UNUSED(dirh);
                   1332: 
1.1       root     1333:        return 0;
                   1334: 
                   1335: }
                   1336: 
                   1337: 
                   1338: 
1.1.1.2   root     1339: static long ARGS_ON_STACK 
1.1       root     1340: 
                   1341: bios_pathconf(dir, which)
                   1342: 
                   1343:        fcookie *dir;
                   1344: 
                   1345:        int which;
                   1346: 
                   1347: {
                   1348: 
1.1.1.2   root     1349:        UNUSED(dir);
                   1350: 
                   1351: 
                   1352: 
1.1       root     1353:        switch(which) {
                   1354: 
                   1355:        case -1:
                   1356: 
                   1357:                return DP_MAXREQ;
                   1358: 
                   1359:        case DP_IOPEN:
                   1360: 
                   1361:                return UNLIMITED;       /* no limit on BIOS file descriptors */
                   1362: 
                   1363:        case DP_MAXLINKS:
                   1364: 
                   1365:                return 1;               /* no hard links available */
                   1366: 
                   1367:        case DP_PATHMAX:
                   1368: 
                   1369:                return PATH_MAX;
                   1370: 
                   1371:        case DP_NAMEMAX:
                   1372: 
                   1373:                return BNAME_MAX;
                   1374: 
                   1375:        case DP_ATOMIC:
                   1376: 
                   1377:                return 1;               /* no atomic writes */
                   1378: 
                   1379:        case DP_TRUNC:
                   1380: 
                   1381:                return DP_AUTOTRUNC;    /* names are truncated */
                   1382: 
                   1383:        case DP_CASE:
                   1384: 
                   1385:                return DP_CASEINSENS;   /* not case sensitive */
                   1386: 
                   1387:        default:
                   1388: 
                   1389:                return EINVFN;
                   1390: 
                   1391:        }
                   1392: 
                   1393: }
                   1394: 
                   1395: 
                   1396: 
1.1.1.2   root     1397: static long ARGS_ON_STACK 
1.1       root     1398: 
                   1399: bios_dfree(dir, buf)
                   1400: 
                   1401:        fcookie *dir;
                   1402: 
                   1403:        long *buf;
                   1404: 
                   1405: {
                   1406: 
1.1.1.2   root     1407:        UNUSED(dir);
                   1408: 
                   1409: 
                   1410: 
1.1       root     1411:        buf[0] = 0;     /* number of free clusters */
                   1412: 
                   1413:        buf[1] = 0;     /* total number of clusters */
                   1414: 
                   1415:        buf[2] = 1;     /* sector size (bytes) */
                   1416: 
                   1417:        buf[3] = 1;     /* cluster size (sectors) */
                   1418: 
                   1419:        return 0;
                   1420: 
                   1421: }
                   1422: 
                   1423: 
                   1424: 
                   1425: /*
                   1426: 
                   1427:  * BIOS Dcntl() calls:
                   1428: 
                   1429:  * Dcntl(0xde02, "U:\DEV\FOO", &foo_descr): install a new device called
                   1430: 
                   1431:  *     "FOO", which is described by the dev_descr structure "foo_descr".
                   1432: 
                   1433:  *     this structure has the following fields:
                   1434: 
                   1435:  *         DEVDRV *driver              the device driver itself
                   1436: 
                   1437:  *        short  dinfo                 info for the device driver
                   1438: 
                   1439:  *        short  flags                 flags for the file (e.g. O_TTY)
                   1440: 
                   1441:  *        struct tty *tty              tty structure, if appropriate
                   1442: 
                   1443:  *
                   1444: 
                   1445:  * Dcntl(0xde00, "U:\DEV\BAR", n): install a new BIOS terminal device, with
                   1446: 
                   1447:  *     BIOS device number "n".
                   1448: 
                   1449:  * Dcntl(0xde01, "U:\DEV\BAR", n): install a new non-tty BIOS device, with
                   1450: 
                   1451:  *     BIOS device number "n".
                   1452: 
                   1453:  */
                   1454: 
                   1455: 
                   1456: 
1.1.1.2   root     1457: static long ARGS_ON_STACK 
1.1       root     1458: 
                   1459: bios_fscntl(dir, name, cmd, arg)
                   1460: 
                   1461:        fcookie *dir;
                   1462: 
                   1463:        const char *name;
                   1464: 
                   1465:        int cmd;
                   1466: 
                   1467:        long arg;
                   1468: 
                   1469: {
                   1470: 
                   1471:        struct bios_file *b;
                   1472: 
1.1.1.5 ! root     1473:        static int devindex = 0;
        !          1474: 
1.1       root     1475: 
                   1476: 
1.1.1.2   root     1477:        UNUSED(dir);
                   1478: 
1.1.1.5 ! root     1479: 
        !          1480: 
        !          1481:        if (curproc->euid) {
        !          1482: 
        !          1483:                DEBUG(("biosfs: Dcntl() by non-privileged process"));
        !          1484: 
        !          1485:                return ((unsigned)cmd == DEV_INSTALL) ? 0 : EACCDN;
        !          1486: 
        !          1487:        }
        !          1488: 
        !          1489: 
        !          1490: 
        !          1491:        if (IS_FD_DIR(dir))
        !          1492: 
        !          1493:                return EACCDN;
        !          1494: 
        !          1495: 
        !          1496: 
1.1.1.2   root     1497:        if ((unsigned)cmd == DEV_INSTALL) {
1.1       root     1498: 
                   1499:                struct dev_descr *d = (struct dev_descr *)arg;
                   1500: 
                   1501: 
                   1502: 
                   1503:                b = kmalloc(SIZEOF(struct bios_file));
                   1504: 
                   1505:                if (!b) return 0;
                   1506: 
                   1507:                strncpy(b->name, name, BNAME_MAX);
                   1508: 
                   1509:                b->name[BNAME_MAX] = 0;
                   1510: 
                   1511:                b->device = d->driver;
                   1512: 
                   1513:                b->private = d->dinfo;
                   1514: 
                   1515:                b->flags = d->flags;
                   1516: 
                   1517:                b->tty = d->tty;
                   1518: 
                   1519:                b->next = broot;
                   1520: 
                   1521:                broot = b;
                   1522: 
1.1.1.5 ! root     1523:                set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, UNK_RDEV|devindex);
        !          1524: 
        !          1525:                devindex = (devindex+1) & 0x00ff;
        !          1526: 
1.1       root     1527:                return (long)&kernelinfo;
                   1528: 
                   1529:        }
                   1530: 
1.1.1.2   root     1531:        if ((unsigned)cmd == DEV_NEWTTY) {
1.1       root     1532: 
                   1533:                b = kmalloc(SIZEOF(struct bios_file));
                   1534: 
                   1535:                if (!b) return ENSMEM;
                   1536: 
                   1537:                b->tty = kmalloc(SIZEOF(struct tty));
                   1538: 
                   1539:                if (!b->tty) {
                   1540: 
                   1541:                        kfree(b);
                   1542: 
                   1543:                        return ENSMEM;
                   1544: 
                   1545:                }
                   1546: 
                   1547:                strncpy(b->name, name, BNAME_MAX);
                   1548: 
                   1549:                b->name[BNAME_MAX] = 0;
                   1550: 
                   1551:                b->device = &bios_tdevice;
                   1552: 
                   1553:                b->private = arg;
                   1554: 
                   1555:                b->flags = O_TTY;
                   1556: 
                   1557:                *b->tty = default_tty;
                   1558: 
                   1559:                b->next = broot;
                   1560: 
                   1561:                broot = b;
                   1562: 
1.1.1.5 ! root     1563:                set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, BIOS_RDEV|(b->private&0x00ff));
        !          1564: 
1.1       root     1565:                return 0;
                   1566: 
                   1567:        }
                   1568: 
1.1.1.2   root     1569:        if ((unsigned)cmd == DEV_NEWBIOS) {
1.1       root     1570: 
                   1571:                b = kmalloc(SIZEOF(struct bios_file));
                   1572: 
                   1573:                if (!b) return ENSMEM;
                   1574: 
                   1575:                strncpy(b->name, name, BNAME_MAX);
                   1576: 
                   1577:                b->name[BNAME_MAX] = 0;
                   1578: 
                   1579:                b->tty = 0;
                   1580: 
                   1581:                b->device = &bios_ndevice;
                   1582: 
                   1583:                b->private = arg;
                   1584: 
                   1585:                b->flags = 0;
                   1586: 
                   1587:                b->next = broot;
                   1588: 
1.1.1.5 ! root     1589:                broot = b;
        !          1590: 
        !          1591:                set_xattr(&(b->xattr), S_IFCHR|DEFAULT_MODE, BIOS_RDEV|(b->private&0x00ff));
        !          1592: 
1.1       root     1593:                return 0;
                   1594: 
                   1595:        }
                   1596: 
                   1597:        return EINVFN;
                   1598: 
                   1599: }
                   1600: 
                   1601: 
                   1602: 
1.1.1.2   root     1603: static long ARGS_ON_STACK 
1.1       root     1604: 
                   1605: bios_symlink(dir, name, to)
                   1606: 
                   1607:        fcookie *dir;
                   1608: 
                   1609:        const char *name, *to;
                   1610: 
                   1611: {
                   1612: 
                   1613:        struct bios_file *b;
                   1614: 
                   1615:        long r;
                   1616: 
                   1617:        fcookie fc;
                   1618: 
                   1619: 
                   1620: 
1.1.1.5 ! root     1621:        if (curproc->euid)
        !          1622: 
        !          1623:                return EACCDN;
        !          1624: 
        !          1625: 
        !          1626: 
1.1       root     1627:        r = bios_lookup(dir, name, &fc);
                   1628: 
                   1629:        if (r == 0) return EACCDN;      /* file already exists */
                   1630: 
                   1631:        if (r != EFILNF) return r;      /* some other error */
                   1632: 
                   1633: 
                   1634: 
                   1635:        b = kmalloc(SIZEOF(struct bios_file));
                   1636: 
                   1637:        if (!b) return EACCDN;
                   1638: 
                   1639: 
                   1640: 
                   1641:        strncpy(b->name, name, BNAME_MAX);
                   1642: 
                   1643:        b->name[BNAME_MAX] = 0;
                   1644: 
                   1645:        b->device = 0;
                   1646: 
                   1647:        b->private = EINVFN;
                   1648: 
                   1649:        b->flags = 0;
                   1650: 
                   1651:        b->tty = kmalloc((long)strlen(to)+1);
                   1652: 
                   1653:        if (!b->tty) {
                   1654: 
                   1655:                kfree(b);
                   1656: 
                   1657:                return EACCDN;
                   1658: 
                   1659:        }
                   1660: 
                   1661:        strcpy((char *)b->tty, to);
                   1662: 
1.1.1.5 ! root     1663: 
        !          1664: 
        !          1665:        set_xattr(&b->xattr, S_IFLNK|DEFAULT_DIRMODE, BIOSDRV);
        !          1666: 
        !          1667:        b->xattr.size = strlen(to)+1;
        !          1668: 
        !          1669: 
        !          1670: 
1.1       root     1671:        b->next = broot;
                   1672: 
                   1673:        broot = b;
                   1674: 
                   1675:        return 0;
                   1676: 
                   1677: }
                   1678: 
                   1679: 
                   1680: 
1.1.1.2   root     1681: static long ARGS_ON_STACK 
1.1       root     1682: 
                   1683: bios_readlink(fc, buf, buflen)
                   1684: 
                   1685:        fcookie *fc;
                   1686: 
                   1687:        char *buf;
                   1688: 
                   1689:        int buflen;
                   1690: 
                   1691: {
                   1692: 
                   1693:        struct bios_file *b = (struct bios_file *)fc->index;
                   1694: 
                   1695: 
                   1696: 
1.1.1.5 ! root     1697:        if (IS_FD_DIR(fc) || IS_FD_ENTRY(fc))
        !          1698: 
        !          1699:                return EINVFN;
        !          1700: 
1.1       root     1701:        if (!b) return EINVFN;
                   1702: 
                   1703:        if (b->device) return EINVFN;
                   1704: 
                   1705: 
                   1706: 
                   1707:        strncpy(buf, (char *)b->tty, buflen);
                   1708: 
                   1709:        if (strlen((char *)b->tty) >= buflen)
                   1710: 
                   1711:                return ENAMETOOLONG;
                   1712: 
                   1713:        return 0;
                   1714: 
                   1715: }
                   1716: 
                   1717: 
                   1718: 
                   1719: 
                   1720: 
                   1721: /*
                   1722: 
                   1723:  * routines for file systems that don't support volume labels
                   1724: 
                   1725:  */
                   1726: 
                   1727: 
                   1728: 
1.1.1.2   root     1729: long ARGS_ON_STACK 
1.1       root     1730: 
                   1731: nowritelabel(dir, name)
                   1732: 
                   1733:        fcookie *dir;
                   1734: 
                   1735:        const char *name;
                   1736: 
                   1737: {
                   1738: 
1.1.1.2   root     1739:        UNUSED(dir);
                   1740: 
                   1741:        UNUSED(name);
                   1742: 
1.1       root     1743:        return EACCDN;
                   1744: 
                   1745: }
                   1746: 
                   1747: 
                   1748: 
1.1.1.2   root     1749: long ARGS_ON_STACK 
1.1       root     1750: 
                   1751: noreadlabel(dir, name, namelen)
                   1752: 
                   1753:        fcookie *dir;
                   1754: 
                   1755:        char *name;
                   1756: 
                   1757:        int namelen;
                   1758: 
                   1759: {
                   1760: 
1.1.1.2   root     1761:        UNUSED(dir);
                   1762: 
                   1763:        UNUSED(name);
                   1764: 
                   1765:        UNUSED(namelen);
                   1766: 
1.1       root     1767:        return EFILNF;
                   1768: 
                   1769: }
                   1770: 
                   1771: 
                   1772: 
                   1773: /*
                   1774: 
                   1775:  * routines for file systems that don't support links
                   1776: 
                   1777:  */
                   1778: 
                   1779: 
                   1780: 
1.1.1.2   root     1781: long ARGS_ON_STACK 
1.1       root     1782: 
                   1783: nosymlink(dir, name, to)
                   1784: 
                   1785:        fcookie *dir;
                   1786: 
                   1787:        const char *name, *to;
                   1788: 
                   1789: {
                   1790: 
1.1.1.2   root     1791:        UNUSED(dir); UNUSED(name);
                   1792: 
                   1793:        UNUSED(to);
                   1794: 
1.1       root     1795:        return EINVFN;
                   1796: 
                   1797: }
                   1798: 
                   1799: 
                   1800: 
1.1.1.2   root     1801: long ARGS_ON_STACK 
1.1       root     1802: 
                   1803: noreadlink(dir, buf, buflen)
                   1804: 
                   1805:        fcookie *dir;
                   1806: 
                   1807:        char *buf;
                   1808: 
                   1809:        int buflen;
                   1810: 
                   1811: {
                   1812: 
1.1.1.2   root     1813:        UNUSED(dir); UNUSED(buf);
                   1814: 
                   1815:        UNUSED(buflen);
                   1816: 
1.1       root     1817:        return EINVFN;
                   1818: 
                   1819: }
                   1820: 
                   1821: 
                   1822: 
1.1.1.2   root     1823: long ARGS_ON_STACK 
1.1       root     1824: 
                   1825: nohardlink(fromdir, fromname, todir, toname)
                   1826: 
                   1827:        fcookie *fromdir, *todir;
                   1828: 
                   1829:        const char *fromname, *toname;
                   1830: 
                   1831: {
                   1832: 
1.1.1.2   root     1833:        UNUSED(fromdir); UNUSED(todir);
                   1834: 
                   1835:        UNUSED(fromname); UNUSED(toname);
                   1836: 
1.1       root     1837:        return EINVFN;
                   1838: 
                   1839: }
                   1840: 
                   1841: 
                   1842: 
                   1843: /* dummy routine for file systems with no Fscntl commands */
                   1844: 
                   1845: 
                   1846: 
1.1.1.2   root     1847: long ARGS_ON_STACK 
1.1       root     1848: 
                   1849: nofscntl(dir, name, cmd, arg)
                   1850: 
                   1851:        fcookie *dir;
                   1852: 
                   1853:        const char *name;
                   1854: 
                   1855:        int cmd;
                   1856: 
                   1857:        long arg;
                   1858: 
                   1859: {
                   1860: 
1.1.1.2   root     1861:        UNUSED(dir); UNUSED(name);
                   1862: 
                   1863:        UNUSED(cmd); UNUSED(arg);
                   1864: 
1.1       root     1865:        return EINVFN;
                   1866: 
                   1867: }
                   1868: 
                   1869: 
                   1870: 
                   1871: /*
                   1872: 
                   1873:  * Did the disk change? Not on this drive!
                   1874: 
                   1875:  * However, we have to do Getbpb anyways, because someone has decided
                   1876: 
                   1877:  * to force a media change on our (non-existent) drive.
                   1878: 
                   1879:  */
                   1880: 
1.1.1.2   root     1881: long ARGS_ON_STACK 
1.1       root     1882: 
                   1883: nodskchng(drv)
                   1884: 
                   1885:        int drv;
                   1886: 
                   1887: {
                   1888: 
                   1889:        (void)getbpb(drv);
                   1890: 
                   1891:        return 0;
                   1892: 
                   1893: }
                   1894: 
                   1895: 
                   1896: 
1.1.1.2   root     1897: long ARGS_ON_STACK 
1.1       root     1898: 
                   1899: nocreat(dir, name, mode, attrib, fc)
                   1900: 
                   1901:        fcookie *dir, *fc;
                   1902: 
                   1903:        const char *name;
                   1904: 
                   1905:        unsigned mode;
                   1906: 
                   1907:        int attrib;
                   1908: 
                   1909: {
                   1910: 
1.1.1.2   root     1911:        UNUSED(dir); UNUSED(fc);
                   1912: 
                   1913:        UNUSED(name); UNUSED(mode);
                   1914: 
                   1915:        UNUSED(attrib);
                   1916: 
1.1       root     1917:        return EACCDN;
                   1918: 
                   1919: }
                   1920: 
                   1921: 
                   1922: 
1.1.1.2   root     1923: static DEVDRV * ARGS_ON_STACK 
1.1       root     1924: 
                   1925: bios_getdev(fc, devsp)
                   1926: 
                   1927:        fcookie *fc;
                   1928: 
                   1929:        long *devsp;
                   1930: 
                   1931: {
                   1932: 
                   1933:        struct bios_file *b;
                   1934: 
                   1935: 
                   1936: 
1.1.1.5 ! root     1937:        /* Check for \dev\fd\... */
        !          1938: 
        !          1939:        if (IS_FD_ENTRY(fc)) {
        !          1940: 
        !          1941:            *devsp = (int) fc->aux;
        !          1942: 
        !          1943:            return &fakedev;
        !          1944: 
        !          1945:        }
        !          1946: 
        !          1947: 
        !          1948: 
1.1       root     1949:        b = (struct bios_file *)fc->index;
                   1950: 
                   1951: 
                   1952: 
                   1953:        if (b->device && b->device != &fakedev)
                   1954: 
                   1955:                *devsp = (long)b->tty;
                   1956: 
                   1957:        else
                   1958: 
                   1959:                *devsp = b->private;
                   1960: 
                   1961: 
                   1962: 
                   1963:        return b->device;       /* return the device driver */
                   1964: 
                   1965: }
                   1966: 
                   1967: 
                   1968: 
                   1969: /*
                   1970: 
                   1971:  * NULL device driver
                   1972: 
                   1973:  */
                   1974: 
                   1975: 
                   1976: 
1.1.1.2   root     1977: long ARGS_ON_STACK 
1.1       root     1978: 
                   1979: null_open(f)
                   1980: 
                   1981:        FILEPTR *f;
                   1982: 
                   1983: {
                   1984: 
1.1.1.2   root     1985:        UNUSED(f);
                   1986: 
1.1       root     1987:        return 0;
                   1988: 
                   1989: }
                   1990: 
                   1991: 
                   1992: 
1.1.1.2   root     1993: long ARGS_ON_STACK 
1.1       root     1994: 
                   1995: null_write(f, buf, bytes)
                   1996: 
                   1997:        FILEPTR *f; const char *buf; long bytes;
                   1998: 
                   1999: {
                   2000: 
1.1.1.2   root     2001:        UNUSED(f); UNUSED(buf);
                   2002: 
1.1       root     2003:        return bytes;
                   2004: 
                   2005: }
                   2006: 
                   2007: 
                   2008: 
1.1.1.2   root     2009: long ARGS_ON_STACK 
1.1       root     2010: 
                   2011: null_read(f, buf, bytes)
                   2012: 
                   2013:        FILEPTR *f; char *buf; long bytes;
                   2014: 
                   2015: {
                   2016: 
1.1.1.2   root     2017:        UNUSED(f); UNUSED(buf);
                   2018: 
                   2019:        UNUSED(bytes);
                   2020: 
1.1       root     2021:        return 0;
                   2022: 
                   2023: }
                   2024: 
                   2025: 
                   2026: 
1.1.1.2   root     2027: long ARGS_ON_STACK 
1.1       root     2028: 
                   2029: null_lseek(f, where, whence)
                   2030: 
                   2031:        FILEPTR *f; long where; int whence;
                   2032: 
                   2033: {
                   2034: 
1.1.1.2   root     2035:        UNUSED(f); UNUSED(whence);
                   2036: 
1.1       root     2037:        return (where == 0) ? 0 : ERANGE;
                   2038: 
                   2039: }
                   2040: 
                   2041: 
                   2042: 
1.1.1.2   root     2043: long ARGS_ON_STACK 
1.1       root     2044: 
                   2045: null_ioctl(f, mode, buf)
                   2046: 
                   2047:        FILEPTR *f; int mode; void *buf;
                   2048: 
                   2049: {
                   2050: 
1.1.1.2   root     2051:        UNUSED(f);
                   2052: 
1.1       root     2053:        if (mode == FIONREAD) {
                   2054: 
                   2055:                *((long *)buf) = 0;
                   2056: 
                   2057:        }
                   2058: 
                   2059:        else if (mode == FIONWRITE)
                   2060: 
                   2061:                *((long *)buf) = 1;
                   2062: 
                   2063:        else
                   2064: 
                   2065:                return EINVFN;
                   2066: 
                   2067:        return 0;
                   2068: 
                   2069: }
                   2070: 
                   2071: 
                   2072: 
1.1.1.2   root     2073: long ARGS_ON_STACK 
1.1       root     2074: 
                   2075: null_datime(f, timeptr, rwflag)
                   2076: 
                   2077:        FILEPTR *f;
                   2078: 
                   2079:        short *timeptr;
                   2080: 
                   2081:        int rwflag;
                   2082: 
                   2083: {
                   2084: 
1.1.1.2   root     2085:        UNUSED(f);
                   2086: 
1.1       root     2087:        if (rwflag)
                   2088: 
                   2089:                return EACCDN;
                   2090: 
                   2091:        *timeptr++ = timestamp;
                   2092: 
                   2093:        *timeptr = datestamp;
                   2094: 
                   2095:        return 0;
                   2096: 
                   2097: }
                   2098: 
                   2099: 
                   2100: 
1.1.1.2   root     2101: long ARGS_ON_STACK 
1.1       root     2102: 
                   2103: null_close(f, pid)
                   2104: 
                   2105:        FILEPTR *f;
                   2106: 
                   2107:        int pid;
                   2108: 
                   2109: {
                   2110: 
1.1.1.2   root     2111:        UNUSED(f);
                   2112: 
                   2113:        UNUSED(pid);
                   2114: 
1.1       root     2115:        return 0;
                   2116: 
                   2117: }
                   2118: 
                   2119: 
                   2120: 
1.1.1.2   root     2121: long ARGS_ON_STACK 
1.1       root     2122: 
                   2123: null_select(f, p, mode)
                   2124: 
                   2125:        FILEPTR *f; long p;
                   2126: 
                   2127:        int mode;
                   2128: 
                   2129: {
                   2130: 
1.1.1.2   root     2131:        UNUSED(f); UNUSED(p);
                   2132: 
                   2133:        UNUSED(mode);
                   2134: 
1.1       root     2135:        return 1;       /* we're always ready to read/write */
                   2136: 
                   2137: }
                   2138: 
                   2139: 
                   2140: 
1.1.1.2   root     2141: void ARGS_ON_STACK 
1.1       root     2142: 
                   2143: null_unselect(f, p, mode)
                   2144: 
                   2145:        FILEPTR *f;
                   2146: 
                   2147:        long p;
                   2148: 
                   2149:        int mode;
                   2150: 
                   2151: {
                   2152: 
1.1.1.2   root     2153:        UNUSED(f); UNUSED(p);
                   2154: 
                   2155:        UNUSED(mode);
                   2156: 
1.1       root     2157:        /* nothing to do */
                   2158: 
                   2159: }
                   2160: 
                   2161: 
                   2162: 
                   2163: /*
                   2164: 
                   2165:  * BIOS terminal device driver
                   2166: 
                   2167:  */
                   2168: 
                   2169: 
                   2170: 
1.1.1.2   root     2171: static long ARGS_ON_STACK 
1.1       root     2172: 
                   2173: bios_topen(f)
                   2174: 
                   2175:        FILEPTR *f;
                   2176: 
                   2177: {
                   2178: 
                   2179:        f->flags |= O_TTY;
                   2180: 
                   2181:        return 0;
                   2182: 
                   2183: }
                   2184: 
                   2185: 
                   2186: 
                   2187: /*
                   2188: 
                   2189:  * Note: when a BIOS device is a terminal (i.e. has the O_TTY flag
                   2190: 
                   2191:  * set), bios_read and bios_write will only ever be called indirectly, via
                   2192: 
                   2193:  * tty_read and tty_write. That's why we can afford to play a bit fast and
                   2194: 
                   2195:  * loose with the pointers ("buf" is really going to point to a long) and
                   2196: 
                   2197:  * why we know that "bytes" is divisible by 4.
                   2198: 
                   2199:  */
                   2200: 
                   2201: 
                   2202: 
1.1.1.2   root     2203: static long ARGS_ON_STACK 
1.1       root     2204: 
                   2205: bios_twrite(f, buf, bytes)
                   2206: 
                   2207:        FILEPTR *f; const char *buf; long bytes;
                   2208: 
                   2209: {
                   2210: 
                   2211:        long *r;
                   2212: 
                   2213:        long ret = 0;
                   2214: 
                   2215:        int bdev = f->fc.aux;
                   2216: 
1.1.1.5 ! root     2217:        struct bios_file *b = (struct bios_file *)f->fc.index;
        !          2218: 
1.1       root     2219: 
                   2220: 
                   2221:        r = (long *)buf;
                   2222: 
1.1.1.3   root     2223: 
                   2224: 
                   2225: /* Check for control characters on any newline output.
                   2226: 
                   2227:  * Note that newlines are always output through tty_putchar,
                   2228: 
                   2229:  * so they'll always be the first thing in the buffer (at least,
                   2230: 
                   2231:  * for cooked TTY output they will, which is the only sort that
                   2232: 
                   2233:  * control characters affect anyways).
                   2234: 
                   2235:  */
                   2236: 
                   2237:        if (bytes > 0 && (*r & 0x000000ffL) == '\n')
                   2238: 
                   2239:                (void) checkkeys();
                   2240: 
                   2241: 
                   2242: 
1.1.1.2   root     2243:        if (f->flags & O_NDELAY) {
1.1       root     2244: 
1.1.1.2   root     2245:                while (bytes > 0) {
                   2246: 
                   2247:                    if (!bcostat(bdev)) break;
                   2248: 
                   2249:                    if (bconout(bdev, (int)*r) == 0)
1.1       root     2250: 
                   2251:                        break;
                   2252: 
1.1.1.2   root     2253:                    r++; bytes -= 4; ret+= 4;
                   2254: 
                   2255:                }
                   2256: 
                   2257:        } else {
1.1       root     2258: 
1.1.1.2   root     2259:                while (bytes > 0) {
1.1       root     2260: 
1.1.1.2   root     2261:                    if (bconout(bdev, (int)*r) == 0)
1.1       root     2262: 
                   2263:                        break;
                   2264: 
1.1.1.2   root     2265:                    r++; bytes -= 4; ret+= 4;
1.1       root     2266: 
1.1.1.2   root     2267:                }
1.1       root     2268: 
                   2269:        }
                   2270: 
1.1.1.2   root     2271: 
1.1       root     2272: 
1.1.1.5 ! root     2273:        if (ret > 0) {
        !          2274: 
        !          2275:                b->xattr.mtime = b->xattr.atime = timestamp;
        !          2276: 
        !          2277:                b->xattr.mdate = b->xattr.adate = datestamp;
        !          2278: 
        !          2279:        }
1.1.1.2   root     2280: 
1.1       root     2281:        return ret;
                   2282: 
                   2283: }
                   2284: 
                   2285: 
                   2286: 
1.1.1.2   root     2287: static long ARGS_ON_STACK 
1.1       root     2288: 
                   2289: bios_tread(f, buf, bytes)
                   2290: 
                   2291:        FILEPTR *f; char *buf; long bytes;
                   2292: 
                   2293: {
                   2294: 
                   2295:        long *r, ret = 0;
                   2296: 
                   2297:        int bdev = f->fc.aux;
                   2298: 
1.1.1.5 ! root     2299:        struct  bios_file *b = (struct bios_file *)f->fc.index;
        !          2300: 
1.1       root     2301: 
                   2302: 
                   2303:        r = (long *)buf;
                   2304: 
                   2305: 
                   2306: 
1.1.1.2   root     2307:        if ((f->flags & O_NDELAY)) {
1.1       root     2308: 
1.1.1.2   root     2309:                while (bytes > 0) {
                   2310: 
                   2311:                    if ( !bconstat(bdev) )
1.1       root     2312: 
                   2313:                        break;
                   2314: 
1.1.1.2   root     2315:                    *r++ = bconin(bdev) & 0x7fffffffL;
                   2316: 
                   2317:                    bytes -= 4; ret += 4;
                   2318: 
                   2319:                }
                   2320: 
                   2321:        } else {
1.1       root     2322: 
1.1.1.2   root     2323:                while (bytes > 0) {
                   2324: 
                   2325:                    *r++ = bconin(bdev) & 0x7fffffffL;
                   2326: 
                   2327:                    bytes -= 4; ret += 4;
                   2328: 
                   2329:                }
1.1       root     2330: 
                   2331:        }
                   2332: 
1.1.1.5 ! root     2333:        if (ret > 0) {
        !          2334: 
        !          2335:                b->xattr.atime = timestamp;
        !          2336: 
        !          2337:                b->xattr.adate = datestamp;
        !          2338: 
        !          2339:        }
        !          2340: 
1.1       root     2341:        return ret;
                   2342: 
                   2343: }
                   2344: 
                   2345: 
                   2346: 
                   2347: /*
                   2348: 
                   2349:  * read/write routines for BIOS devices that aren't terminals (like the
                   2350: 
                   2351:  * printer & IKBD devices)
                   2352: 
                   2353:  */
                   2354: 
                   2355: 
                   2356: 
1.1.1.2   root     2357: static long ARGS_ON_STACK 
1.1       root     2358: 
                   2359: bios_nwrite(f, buf, bytes)
                   2360: 
                   2361:        FILEPTR *f; const char *buf; long bytes;
                   2362: 
                   2363: {
                   2364: 
                   2365:        long ret = 0;
                   2366: 
                   2367:        int bdev = f->fc.aux;
                   2368: 
                   2369:        int c;
                   2370: 
1.1.1.5 ! root     2371:        struct bios_file *b = (struct bios_file *)f->fc.index;
        !          2372: 
1.1       root     2373: 
                   2374: 
                   2375:        while (bytes > 0) {
                   2376: 
                   2377:                if ( (f->flags & O_NDELAY) && !bcostat(bdev) )
                   2378: 
                   2379:                        break;
                   2380: 
                   2381: 
                   2382: 
                   2383:                c = *buf++ & 0x00ff;
                   2384: 
                   2385: 
                   2386: 
                   2387:                if (bconout(bdev, c) == 0)
                   2388: 
                   2389:                        break;
                   2390: 
                   2391: 
                   2392: 
                   2393:                bytes--; ret++;
                   2394: 
                   2395:        }
                   2396: 
1.1.1.5 ! root     2397:        if (ret > 0) {
        !          2398: 
        !          2399:                b->xattr.mtime = b->xattr.atime = timestamp;
        !          2400: 
        !          2401:                b->xattr.mdate = b->xattr.adate = datestamp;
        !          2402: 
        !          2403:        }
        !          2404: 
1.1       root     2405:        return ret;
                   2406: 
                   2407: }
                   2408: 
                   2409: 
                   2410: 
1.1.1.2   root     2411: static long ARGS_ON_STACK 
1.1       root     2412: 
                   2413: bios_nread(f, buf, bytes)
                   2414: 
                   2415:        FILEPTR *f; char *buf; long bytes;
                   2416: 
                   2417: {
                   2418: 
                   2419:        long ret = 0;
                   2420: 
                   2421:        int bdev = f->fc.aux;
                   2422: 
1.1.1.5 ! root     2423:        struct bios_file *b = (struct bios_file *)f->fc.index;
        !          2424: 
1.1       root     2425: 
                   2426: 
                   2427:        while (bytes > 0) {
                   2428: 
                   2429:                if ( (f->flags & O_NDELAY) && !bconstat(bdev) )
                   2430: 
                   2431:                        break;
                   2432: 
                   2433:                *buf++ = bconin(bdev) & 0xff;
                   2434: 
                   2435:                bytes--; ret++;
                   2436: 
                   2437:        }
                   2438: 
1.1.1.5 ! root     2439:        if (ret > 0) {
        !          2440: 
        !          2441:                b->xattr.atime = timestamp;
        !          2442: 
        !          2443:                b->xattr.adate = datestamp;
        !          2444: 
        !          2445:        }
        !          2446: 
1.1       root     2447:        return ret;
                   2448: 
                   2449: }
                   2450: 
                   2451: 
                   2452: 
                   2453: /*
                   2454: 
                   2455:  * BIOS terminal seek code -- this has to match the documented
                   2456: 
                   2457:  * way to do isatty()
                   2458: 
                   2459:  */
                   2460: 
                   2461: 
                   2462: 
1.1.1.2   root     2463: static long ARGS_ON_STACK 
1.1       root     2464: 
                   2465: bios_tseek(f, where, whence)
                   2466: 
                   2467:        FILEPTR *f;
                   2468: 
                   2469:        long where;
                   2470: 
                   2471:        int whence;
                   2472: 
                   2473: {
                   2474: 
1.1.1.2   root     2475:        UNUSED(f); UNUSED(where);
                   2476: 
                   2477:        UNUSED(whence);
                   2478: 
1.1       root     2479: /* terminals always are at position 0 */
                   2480: 
                   2481:        return 0;
                   2482: 
                   2483: }
                   2484: 
                   2485: 
                   2486: 
                   2487: #define MAXBAUD 16
                   2488: 
                   2489: 
                   2490: 
1.1.1.2   root     2491: /* keep these sorted in descending order */
                   2492: 
1.1       root     2493: static long baudmap[MAXBAUD] = {
                   2494: 
                   2495: 19200L, 9600L, 4800L, 3600L, 2400L, 2000L, 1800L, 1200L,
                   2496: 
                   2497: 600L, 300L, 200L, 150L, 134L, 110L, 75L, 50L
                   2498: 
                   2499: };
                   2500: 
                   2501: 
                   2502: 
1.1.1.2   root     2503: static long ARGS_ON_STACK 
1.1       root     2504: 
                   2505: bios_ioctl(f, mode, buf)
                   2506: 
                   2507:        FILEPTR *f; int mode; void *buf;
                   2508: 
                   2509: {
                   2510: 
                   2511:        long *r = (long *)buf;
                   2512: 
                   2513:        struct winsize *ws;
                   2514: 
                   2515:        char *aline;
                   2516: 
                   2517:        short dev;
                   2518: 
                   2519:        int i;
                   2520: 
1.1.1.5 ! root     2521:        struct bios_file *b;
        !          2522: 
1.1       root     2523: 
                   2524: 
                   2525:        if (mode == FIONREAD) {
                   2526: 
                   2527:                if (bconstat(f->fc.aux))
                   2528: 
                   2529:                        *r = 1;
                   2530: 
                   2531:                else
                   2532: 
                   2533:                        *r = 0;
                   2534: 
                   2535:        }
                   2536: 
                   2537:        else if (mode == FIONWRITE) {
                   2538: 
                   2539:                if (bcostat(f->fc.aux))
                   2540: 
                   2541:                        *r = 1;
                   2542: 
                   2543:                else
                   2544: 
                   2545:                        *r = 0;
                   2546: 
                   2547:        }
                   2548: 
                   2549:        else if (mode == TIOCFLUSH) {
                   2550: 
1.1.1.5 ! root     2551:                int oldmap;
        !          2552: 
        !          2553:                IOREC_T *ior;
        !          2554: 
        !          2555:                int flushtype;
        !          2556: 
        !          2557:                short sr;
        !          2558: 
        !          2559: 
        !          2560: 
        !          2561:                dev = f->fc.aux;
        !          2562: 
        !          2563: 
        !          2564: 
        !          2565:                if ((!r) || (!(*r & 3))) {
        !          2566: 
        !          2567:                        flushtype = 3;
        !          2568: 
        !          2569:                } else {
        !          2570: 
        !          2571:                        flushtype = (int) *r;
        !          2572: 
        !          2573:                }
        !          2574: 
        !          2575:                if (dev == 1 || dev >= 6) {
        !          2576: 
        !          2577: /* trick uiorec into setting the correct port (it uses curproc->bconmap) */
        !          2578: 
        !          2579:                        oldmap = curproc->bconmap;
        !          2580: 
        !          2581:                        if (has_bconmap)
        !          2582: 
        !          2583:                                curproc->bconmap = (dev == 1)
        !          2584: 
        !          2585:                                                ? curproc->bconmap
        !          2586: 
        !          2587:                                                : dev;
        !          2588: 
        !          2589:                        ior = (IOREC_T *) uiorec(0);
        !          2590: 
        !          2591:                        if (flushtype & 1) {
        !          2592: 
        !          2593:                                sr = spl7();
        !          2594: 
        !          2595:                                ior->head = ior->tail = 0;
        !          2596: 
        !          2597:                                spl(sr);
        !          2598: 
        !          2599:                        }
        !          2600: 
        !          2601:                        if (flushtype & 2) {
        !          2602: 
        !          2603:                                ior++; /* output record */
        !          2604: 
        !          2605:                                sr = spl7();
        !          2606: 
        !          2607:                                ior->head = ior->tail = 0;
        !          2608: 
        !          2609:                                spl(sr);
        !          2610: 
        !          2611:                        }
        !          2612: 
        !          2613:                        curproc->bconmap = oldmap;
        !          2614: 
        !          2615:                } else if (dev == 3 || dev == 2 || dev == 5) {
        !          2616: 
        !          2617:                        if (dev == 3) {
        !          2618: 
        !          2619:                                /* midi */
        !          2620: 
        !          2621:                                ior = (IOREC_T *) uiorec(2);
        !          2622: 
        !          2623:                        } else {
        !          2624: 
        !          2625:                                /* ikbd */
        !          2626: 
        !          2627:                                ior = (IOREC_T *) uiorec(1);
        !          2628: 
        !          2629:                        }
        !          2630: 
        !          2631:                        if (flushtype & 1) {
        !          2632: 
        !          2633:                                sr = spl7();
        !          2634: 
        !          2635:                                ior->head = ior->tail = 0;
        !          2636: 
        !          2637:                                spl(sr);
        !          2638: 
        !          2639:                        }
        !          2640: 
        !          2641:                }
        !          2642: 
        !          2643:                return 0;
        !          2644: 
        !          2645:        }
        !          2646: 
        !          2647:        else if (mode == TIOCOUTQ) {
        !          2648: 
        !          2649:                int oldmap;
        !          2650: 
        !          2651:                IOREC_T *ior;
        !          2652: 
        !          2653: 
        !          2654: 
        !          2655:                dev = f->fc.aux;
        !          2656: 
        !          2657: 
        !          2658: 
        !          2659:                if (dev == 1 || dev >= 6) {
        !          2660: 
        !          2661: /* trick uiorec into setting the correct port (it uses curproc->bconmap) */
        !          2662: 
        !          2663:                        oldmap = curproc->bconmap;
        !          2664: 
        !          2665:                        if (has_bconmap)
        !          2666: 
        !          2667:                                curproc->bconmap = (dev == 1)
        !          2668: 
        !          2669:                                                ? curproc->bconmap
        !          2670: 
        !          2671:                                                : dev;
        !          2672: 
        !          2673:                        ior = (IOREC_T *) uiorec(0) + 1;
        !          2674: 
        !          2675:                        *r = ior->tail - ior->head;
        !          2676: 
        !          2677:                        if (*r < 0)
        !          2678: 
        !          2679:                                *r += ior->buflen;
        !          2680: 
        !          2681:                        curproc->bconmap = oldmap;
        !          2682: 
        !          2683:                }
        !          2684: 
        !          2685:                else
        !          2686: 
        !          2687:                        *r = 0;
1.1       root     2688: 
                   2689:                return 0;
                   2690: 
                   2691:        }
                   2692: 
                   2693:        else if (mode == TIOCGWINSZ && f->fc.aux == 2) {
                   2694: 
                   2695:                aline = lineA0();
                   2696: 
                   2697:                ws = (struct winsize *)buf;
                   2698: 
                   2699:                ws->ws_row = *((short *)(aline - 42)) + 1;
                   2700: 
                   2701:                ws->ws_col = *((short *)(aline - 44)) + 1;
                   2702: 
                   2703:        } else if (mode == TIOCIBAUD || mode == TIOCOBAUD) {
                   2704: 
                   2705:                long oldbaud, newbaud;
                   2706: 
1.1.1.4   root     2707:                int oldmap;
                   2708: 
                   2709: 
                   2710: 
1.1       root     2711:                dev = f->fc.aux;
                   2712: 
                   2713: 
                   2714: 
                   2715:                newbaud = *r;
                   2716: 
                   2717:                if (dev == 1 || dev >= 6) {
                   2718: 
1.1.1.4   root     2719: /* trick rsconf into setting the correct port (it uses curproc->bconmap) */
                   2720: 
                   2721:                        oldmap = curproc->bconmap;
                   2722: 
1.1       root     2723:                        if (has_bconmap)
                   2724: 
1.1.1.4   root     2725:                                curproc->bconmap = 
                   2726: 
                   2727:                                        (dev == 1) ? curproc->bconmap : dev;
1.1       root     2728: 
1.1.1.2   root     2729:                        i = (int)rsconf(-2, -1, -1, -1, -1, -1);
1.1       root     2730: 
1.1.1.4   root     2731: 
                   2732: 
1.1       root     2733:                        if (i < 0 || i >= MAXBAUD)
                   2734: 
                   2735:                                oldbaud = -1L;
                   2736: 
                   2737:                        else
                   2738: 
                   2739:                                oldbaud = baudmap[i];
                   2740: 
                   2741:                        *r = oldbaud;
                   2742: 
1.1.1.5 ! root     2743:                        if (newbaud > 0) {
1.1       root     2744: 
1.1.1.2   root     2745:        /* BUG: assert DTR works only on modem1 */
                   2746: 
                   2747:                                if (dev == 1 || dev == 6) {
                   2748: 
                   2749:                                        Offgibit(0xef);
                   2750: 
                   2751:                                }
                   2752: 
1.1.1.5 ! root     2753:                                if (newbaud == oldbaud) {
        !          2754: 
        !          2755:                                        curproc->bconmap = oldmap;
        !          2756: 
        !          2757:                                        return 0;
        !          2758: 
        !          2759:                                }
        !          2760: 
1.1       root     2761:                                for (i = 0; i < MAXBAUD; i++) {
                   2762: 
                   2763:                                        if (baudmap[i] == newbaud) {
                   2764: 
                   2765:                                                rsconf(i, -1, -1, -1, -1, -1);
                   2766: 
1.1.1.4   root     2767:                                                curproc->bconmap = oldmap;
                   2768: 
1.1       root     2769:                                                return 0;
                   2770: 
1.1.1.2   root     2771:                                        } else if (baudmap[i] < newbaud) {
                   2772: 
                   2773:                                                *r = baudmap[i];
                   2774: 
1.1.1.4   root     2775:                                                curproc->bconmap = oldmap;
                   2776: 
1.1.1.2   root     2777:                                                break;
                   2778: 
1.1       root     2779:                                        }
                   2780: 
                   2781:                                }
                   2782: 
1.1.1.4   root     2783:                                curproc->bconmap = oldmap;
                   2784: 
1.1       root     2785:                                return ERANGE;
                   2786: 
                   2787:                        } else if (newbaud == 0L) {
                   2788: 
1.1.1.2   root     2789:        /* BUG: drop DTR: works only on modem1 */
1.1       root     2790: 
                   2791:                                if (dev == 1 || dev == 6) {
                   2792: 
                   2793:                                        Ongibit(0x10);
                   2794: 
                   2795:                                }
                   2796: 
                   2797:                        }
                   2798: 
1.1.1.4   root     2799:                        curproc->bconmap = oldmap;
                   2800: 
1.1       root     2801:                        return 0;
                   2802: 
                   2803:                } else if (dev == 2 || dev == 5) {
                   2804: 
                   2805:                        /* screen: assume 9600 baud */
                   2806: 
                   2807:                        oldbaud = 9600L;
                   2808: 
                   2809:                } else if (dev == 3) {
                   2810: 
                   2811:                        /* midi */
                   2812: 
                   2813:                        oldbaud = 31250L;
                   2814: 
                   2815:                } else {
                   2816: 
                   2817:                        oldbaud = -1L;  /* unknown speed */
                   2818: 
                   2819:                }
                   2820: 
                   2821:                *r = oldbaud;
                   2822: 
                   2823:                if (newbaud > 0 && newbaud != oldbaud)
                   2824: 
                   2825:                        return ERANGE;
                   2826: 
                   2827:                return 0;
                   2828: 
                   2829:        } else if (mode == TIOCCBRK || mode == TIOCSBRK) {
                   2830: 
                   2831:                unsigned long bits;
                   2832: 
                   2833: 
                   2834: 
                   2835:                dev = f->fc.aux;
                   2836: 
                   2837:                if (dev == 1 || dev >= 6) {
                   2838: 
                   2839:                        if (has_bconmap)
                   2840: 
                   2841:                                mapin((dev == 1) ? curproc->bconmap : dev);
                   2842: 
                   2843:                } else {
                   2844: 
                   2845:                        return EINVFN;
                   2846: 
                   2847:                }
                   2848: 
                   2849:                bits = rsconf(-1, -1, -1, -1, -1, -1);  /* get settings */
                   2850: 
                   2851:                bits = (bits >> 8) & 0x0ff;             /* isolate TSR byte */
                   2852: 
                   2853:                if (mode == TIOCCBRK)
                   2854: 
                   2855:                        bits &= ~8;
                   2856: 
                   2857:                else
                   2858: 
                   2859:                        bits |= 8;
                   2860: 
                   2861:                (void)rsconf(-1, -1, -1, -1, (int)bits, -1);
                   2862: 
                   2863:        } else if (mode == TIOCGFLAGS || mode == TIOCSFLAGS) {
                   2864: 
1.1.1.5 ! root     2865:                unsigned short oflags, flags, *sgflags;
1.1       root     2866: 
                   2867:                unsigned long bits;
                   2868: 
                   2869:                unsigned char ucr;
                   2870: 
                   2871:                short flow;
                   2872: 
                   2873: 
                   2874: 
                   2875:                dev = f->fc.aux;
                   2876: 
                   2877:                if (dev == 1 || dev >= 6) {
                   2878: 
1.1.1.5 ! root     2879:                        sgflags = &((struct tty *)f->devinfo)->sg.sg_flags;
1.1       root     2880: 
1.1.1.5 ! root     2881:                        oflags = *sgflags & (T_TANDEM|T_RTSCTS);
1.1       root     2882: 
                   2883:                        if (has_bconmap)
                   2884: 
                   2885:                                mapin((dev == 1) ? curproc->bconmap : dev);
                   2886: 
                   2887:                        bits = rsconf(-1, -1, -1, -1, -1, -1);  /* get settings */
                   2888: 
                   2889:                        ucr = (bits >> 24L) & 0x0ff;            /* isolate UCR byte */
                   2890: 
                   2891:                        oflags |= (ucr >> 3) & (TF_STOPBITS|TF_CHARBITS);
                   2892: 
                   2893:                        if (ucr & 0x4) {                        /* parity on? */
                   2894: 
                   2895:                                oflags |= (ucr & 0x2) ? T_EVENP : T_ODDP;
                   2896: 
                   2897:                        }
                   2898: 
                   2899:                        if (mode == TIOCSFLAGS) {
                   2900: 
                   2901:                                flags = (*(unsigned short *)buf);
                   2902: 
1.1.1.5 ! root     2903:                                *sgflags &= ~(T_RTSCTS|T_TANDEM);
        !          2904: 
        !          2905:                                *sgflags |= flags & (T_RTSCTS|T_TANDEM);
        !          2906: 
1.1       root     2907:                                if (flags & T_EVENP) {
                   2908: 
                   2909:                                        ucr |= 0x6;
                   2910: 
                   2911:                                } else if (flags & T_ODDP) {
                   2912: 
                   2913:                                        ucr &= ~2;
                   2914: 
                   2915:                                        ucr |= 0x4;
                   2916: 
                   2917:                                } else {
                   2918: 
                   2919:                                        ucr &= ~6;
                   2920: 
                   2921:                                }
                   2922: 
                   2923:                                if (flags & TF_STOPBITS) {
                   2924: 
                   2925:                                        ucr &= ~(0x18);
                   2926: 
                   2927:                                        ucr |= (flags & TF_STOPBITS) << 3;
                   2928: 
                   2929:                                }
                   2930: 
                   2931:                                ucr &= ~(0x60);
                   2932: 
                   2933:                                ucr |= (flags & TF_CHARBITS) << 3;
                   2934: 
                   2935:                                flow = (flags & (T_RTSCTS|T_TANDEM)) >> 12L;
                   2936: 
                   2937:                                rsconf(-1, flow, ucr, -1, -1, -1);
                   2938: 
                   2939:                        } else {
                   2940: 
                   2941:                                *((unsigned short *)buf) = oflags;
                   2942: 
                   2943:                        }
                   2944: 
                   2945:                } else {
                   2946: 
                   2947:                        return EINVFN;
                   2948: 
                   2949:                }
                   2950: 
1.1.1.4   root     2951:        } else if ((mode >= TCURSOFF && mode <= TCURSSTEADY) && (f->fc.aux == 2)) {
                   2952: 
                   2953:                return Cursconf(mode - TCURSOFF, 0);
                   2954: 
                   2955:        } else if ((mode >= TCURSSRATE && mode <= TCURSGRATE) && (f->fc.aux == 2)) {
                   2956: 
                   2957:                long r;
                   2958: 
                   2959: 
                   2960: 
                   2961:                r = Cursconf(mode - TCURSOFF, *((short *)buf));
                   2962: 
                   2963:                if (r >= 0) {
                   2964: 
                   2965:                        *(short *)buf = r;
                   2966: 
                   2967:                        r = 0;
                   2968: 
                   2969:                }
1.1       root     2970: 
1.1.1.4   root     2971:                return r;
1.1       root     2972: 
1.1.1.5 ! root     2973:        } else if (mode == F_SETLK || mode == F_SETLKW) {
        !          2974: 
        !          2975:                struct flock *lck = (struct flock *)buf;
        !          2976: 
        !          2977: 
        !          2978: 
        !          2979:                b = (struct bios_file *)f->fc.index;
        !          2980: 
        !          2981:                while (b->lockpid && b->lockpid != curproc->pid) {
        !          2982: 
        !          2983:                        if (mode == F_SETLKW && lck->l_type != F_UNLCK)
        !          2984: 
        !          2985:                                sleep(IO_Q, (long)b);
        !          2986: 
        !          2987:                        else
        !          2988: 
        !          2989:                                return ELOCKED;
        !          2990: 
        !          2991:                }
        !          2992: 
        !          2993:                if (lck->l_type == F_UNLCK) {
        !          2994: 
        !          2995:                        if (!(f->flags & O_LOCK)) {
        !          2996: 
        !          2997:                                DEBUG(("bios_ioctl: wrong file descriptor for UNLCK"));
        !          2998: 
        !          2999:                                return ENSLOCK;
        !          3000: 
        !          3001:                        }
        !          3002: 
        !          3003:                        if (b->lockpid != curproc->pid)
        !          3004: 
        !          3005:                                return ENSLOCK;
        !          3006: 
        !          3007:                        b->lockpid = 0;
        !          3008: 
        !          3009:                        f->flags &= ~O_LOCK;
        !          3010: 
        !          3011:                        wake(IO_Q, (long)b);    /* wake anyone waiting for this lock */
        !          3012: 
        !          3013:                } else {
        !          3014: 
        !          3015:                        b->lockpid = curproc->pid;
        !          3016: 
        !          3017:                        f->flags |= O_LOCK;
        !          3018: 
        !          3019:                }
        !          3020: 
        !          3021:        } else if (mode == F_GETLK) {
        !          3022: 
        !          3023:                struct flock *lck = (struct flock *)buf;
        !          3024: 
        !          3025: 
        !          3026: 
        !          3027:                b = (struct bios_file *)f->fc.index;
        !          3028: 
        !          3029:                if (b->lockpid) {
        !          3030: 
        !          3031:                        lck->l_type = F_WRLCK;
        !          3032: 
        !          3033:                        lck->l_start = lck->l_len = 0;
        !          3034: 
        !          3035:                        lck->l_pid = b->lockpid;
        !          3036: 
        !          3037:                } else {
        !          3038: 
        !          3039:                        lck->l_type = F_UNLCK;
        !          3040: 
        !          3041:                }
        !          3042: 
1.1       root     3043:        } else {
                   3044: 
                   3045:        /* Fcntl will automatically call tty_ioctl to handle
                   3046: 
                   3047:         * terminal calls that we didn't deal with
                   3048: 
                   3049:         */
                   3050: 
                   3051:                return EINVFN;
                   3052: 
                   3053:        }
                   3054: 
                   3055:        return 0;
                   3056: 
                   3057: }
                   3058: 
                   3059: 
                   3060: 
1.1.1.2   root     3061: static long ARGS_ON_STACK 
1.1       root     3062: 
                   3063: bios_select(f, p, mode)
                   3064: 
                   3065:        FILEPTR *f; long p; int mode;
                   3066: 
                   3067: {
                   3068: 
                   3069:        struct tty *tty = (struct tty *)f->devinfo;
                   3070: 
                   3071:        int dev = f->fc.aux;
                   3072: 
                   3073: 
                   3074: 
                   3075:        if (mode == O_RDONLY) {
                   3076: 
                   3077:                if (bconstat(dev)) {
                   3078: 
1.1.1.2   root     3079:                        TRACE(("bios_select: data present for device %d", dev));
1.1       root     3080: 
                   3081:                        return 1;
                   3082: 
                   3083:                }
                   3084: 
                   3085:                if (tty) {
                   3086: 
                   3087:                /* avoid collisions with other processes */
                   3088: 
                   3089:                        if (!tty->rsel)
                   3090: 
1.1.1.5 ! root     3091:                                return 2;       /* collision */
        !          3092: 
        !          3093:                        tty->rsel = p;
1.1       root     3094: 
                   3095:                }
                   3096: 
                   3097:                return 0;
                   3098: 
                   3099:        } else if (mode == O_WRONLY) {
                   3100: 
                   3101:                if (bcostat(dev)) {
                   3102: 
1.1.1.2   root     3103:                        TRACE(("bios_select: ready to output on %d", dev));
1.1       root     3104: 
                   3105:                        return 1;
                   3106: 
                   3107:                }
                   3108: 
                   3109:                if (tty) {
                   3110: 
                   3111:                        if (!tty->wsel)
                   3112: 
1.1.1.5 ! root     3113:                                return 2;       /* collision */
        !          3114: 
        !          3115:                        tty->wsel = p;
1.1       root     3116: 
                   3117:                }
                   3118: 
                   3119:                return 0;
                   3120: 
                   3121:        }
                   3122: 
                   3123:        /* default -- we don't know this mode, return 0 */
                   3124: 
                   3125:        return 0;
                   3126: 
                   3127: }
                   3128: 
                   3129: 
                   3130: 
1.1.1.2   root     3131: static void ARGS_ON_STACK 
1.1       root     3132: 
                   3133: bios_unselect(f, p, mode)
                   3134: 
                   3135:        FILEPTR *f;
                   3136: 
                   3137:        long p;
                   3138: 
                   3139:        int mode;
                   3140: 
                   3141: {
                   3142: 
                   3143:        struct tty *tty = (struct tty *)f->devinfo;
                   3144: 
                   3145: 
                   3146: 
                   3147:        if (tty) {
                   3148: 
                   3149:                if (mode == O_RDONLY && tty->rsel == p)
                   3150: 
                   3151:                        tty->rsel = 0;
                   3152: 
                   3153:                else if (mode == O_WRONLY && tty->wsel == p)
                   3154: 
                   3155:                        tty->wsel = 0;
                   3156: 
                   3157:        }
                   3158: 
                   3159: }
                   3160: 
                   3161: 
                   3162: 
1.1.1.5 ! root     3163: static long ARGS_ON_STACK 
        !          3164: 
        !          3165: bios_close(f, pid)
        !          3166: 
        !          3167:        FILEPTR *f;
        !          3168: 
        !          3169:        int pid;
        !          3170: 
        !          3171: {
        !          3172: 
        !          3173:        struct bios_file *b;
        !          3174: 
        !          3175: 
        !          3176: 
        !          3177:        b = (struct bios_file *)f->fc.index;
        !          3178: 
        !          3179:        if ((f->flags & O_LOCK) && (b->lockpid == pid)) {
        !          3180: 
        !          3181:                b->lockpid = 0;
        !          3182: 
        !          3183:        }
        !          3184: 
        !          3185:        return 0;
        !          3186: 
        !          3187: }
        !          3188: 
        !          3189: 
        !          3190: 
1.1       root     3191: /*
                   3192: 
                   3193:  * mouse device driver
                   3194: 
                   3195:  */
                   3196: 
                   3197: 
                   3198: 
                   3199: #define MOUSESIZ 128*3
                   3200: 
                   3201: static unsigned char mousebuf[MOUSESIZ];
                   3202: 
                   3203: static int mousehead, mousetail;
                   3204: 
                   3205: 
                   3206: 
                   3207: long mousersel;        /* is someone calling select() on the mouse? */
                   3208: 
                   3209: 
                   3210: 
                   3211: char mshift;           /* shift key status; set by checkkeys() in bios.c */
                   3212: 
                   3213: short *gcurx = 0,
                   3214: 
                   3215:       *gcury = 0;      /* mouse pos. variables; used by big screen emulators */
                   3216: 
                   3217: 
                   3218: 
1.1.1.2   root     3219: void ARGS_ON_STACK 
1.1       root     3220: 
                   3221: mouse_handler(buf)
                   3222: 
                   3223:        const char *buf;        /* must be a *signed* character */
                   3224: 
                   3225: {
                   3226: 
                   3227:        unsigned char *mbuf, buttons;
                   3228: 
                   3229:        int newmtail;
                   3230: 
                   3231:        short dx, dy;
                   3232: 
                   3233: 
                   3234: 
                   3235: /* the Sun mouse driver has 0=down, 1=up, while the atari hardware gives
                   3236: 
                   3237:    us the reverse. also, we have the "middle" button and the "left"
                   3238: 
                   3239:    button reversed; so we use this table to convert (and also to add the
                   3240: 
                   3241:    0x80 to indicate a mouse packet)
                   3242: 
                   3243:  */
                   3244: 
                   3245:        static int _cnvrt[8] = {
                   3246: 
                   3247:                0x87, 0x86, 0x83, 0x82, 0x85, 0x84, 0x81, 0x80
                   3248: 
                   3249:        };
                   3250: 
                   3251: 
                   3252: 
                   3253:        mbuf = &mousebuf[mousetail];
                   3254: 
                   3255:        newmtail = mousetail + 3;
                   3256: 
                   3257:        if (newmtail >= MOUSESIZ)
                   3258: 
                   3259:                newmtail = 0;
                   3260: 
                   3261:        if (newmtail == mousehead)
                   3262: 
                   3263:                return;                 /* buffer full */
                   3264: 
                   3265: 
                   3266: 
                   3267:        buttons = *buf++ & 0x7;         /* convert to SUN format */
                   3268: 
                   3269:        if (mshift & 0x3) {             /* a shift key held down? */
                   3270: 
                   3271:        /* if so, convert shift+button to a "middle" button */
                   3272: 
                   3273:                if (buttons == 0x1 || buttons == 0x2)
                   3274: 
                   3275:                        buttons = 0x4;
                   3276: 
                   3277:                else if (buttons == 0x3)
                   3278: 
                   3279:                        buttons = 0x7;
                   3280: 
                   3281:        }
                   3282: 
                   3283:        *mbuf++ = _cnvrt[buttons];      /* convert to Sun format */
                   3284: 
                   3285:        dx = *buf++;
                   3286: 
                   3287:        *mbuf++ = dx;                   /* copy X delta */
                   3288: 
1.1.1.2   root     3289:        dy = *buf;
1.1       root     3290: 
1.1.1.2   root     3291:        *mbuf = -dy;                    /* invert Y delta for Sun format */
1.1       root     3292: 
                   3293:        mousetail = newmtail;
                   3294: 
                   3295:        *gcurx += dx;                   /* update line A variables */
                   3296: 
                   3297:        *gcury += dy;
                   3298: 
                   3299: /*
                   3300: 
                   3301:  * if someone has called select() waiting for mouse input, wake them
                   3302: 
                   3303:  * up
                   3304: 
                   3305:  */
                   3306: 
                   3307:        if (mousersel) {
                   3308: 
                   3309:                wakeselect(mousersel);
                   3310: 
                   3311:        }
                   3312: 
                   3313: }
                   3314: 
                   3315: 
                   3316: 
1.1.1.2   root     3317: extern void newmvec(), newjvec();      /* in intr.s */
1.1       root     3318: 
                   3319: static long oldvec = 0;
                   3320: 
1.1.1.2   root     3321: long oldjvec = 0;
                   3322: 
1.1       root     3323: 
                   3324: 
1.1.1.2   root     3325: static long ARGS_ON_STACK 
1.1       root     3326: 
                   3327: mouse_open(f)
                   3328: 
                   3329:        FILEPTR *f;
                   3330: 
                   3331: {
                   3332: 
                   3333:        char *aline;
                   3334: 
                   3335: 
                   3336: 
                   3337:        static char parameters[] = {
                   3338: 
                   3339:                0,              /* Y=0 in lower corner */
                   3340: 
                   3341:                0,              /* normal button handling */
                   3342: 
                   3343:                1, 1            /* X, Y scaling factors */
                   3344: 
                   3345:        };
                   3346: 
                   3347: 
                   3348: 
1.1.1.2   root     3349:        UNUSED(f);
                   3350: 
                   3351: 
                   3352: 
1.1       root     3353:        if (oldvec)             /* mouse in use */
                   3354: 
                   3355:                return EACCDN;
                   3356: 
                   3357: 
                   3358: 
                   3359: /* initialize pointers to line A variables */
                   3360: 
                   3361:        if (!gcurx) {
                   3362: 
                   3363:                aline = lineA0();
                   3364: 
                   3365:                if (aline == 0) {       /* should never happen */
                   3366: 
                   3367:                        ALERT("unable to read line A variables");
                   3368: 
                   3369:                        return -1;
                   3370: 
                   3371:                }
                   3372: 
                   3373:                gcurx = (short *)(aline - 0x25a);
                   3374: 
                   3375:                gcury = (short *)(aline - 0x258);
                   3376: 
                   3377:                *gcurx = *gcury = 32;   /* magic number -- what MGR uses */
                   3378: 
                   3379:        }
                   3380: 
                   3381: 
                   3382: 
                   3383:        oldvec = syskey->mousevec;
                   3384: 
1.1.1.2   root     3385:        oldjvec = syskey->joyvec;       /* jr: save old joystick vector */
                   3386: 
1.1       root     3387:        Initmous(1, parameters, newmvec);
                   3388: 
1.1.1.2   root     3389:        syskey->joyvec = (long)newjvec; /* jr: set up new joystick handler */
                   3390: 
1.1       root     3391:        mousehead = mousetail = 0;
                   3392: 
                   3393:        return 0;
                   3394: 
                   3395: }
                   3396: 
                   3397: 
                   3398: 
1.1.1.2   root     3399: static long ARGS_ON_STACK 
1.1       root     3400: 
                   3401: mouse_close(f, pid)
                   3402: 
                   3403:        FILEPTR *f;
                   3404: 
                   3405:        int pid;
                   3406: 
                   3407: {
                   3408: 
                   3409:        static char parameters[] = {
                   3410: 
                   3411:                0,              /* Y=0 in lower corner */
                   3412: 
                   3413:                0,              /* normal button handling */
                   3414: 
                   3415:                1, 1            /* X, Y scaling factors */
                   3416: 
                   3417:        };
                   3418: 
                   3419: 
                   3420: 
1.1.1.2   root     3421:        UNUSED(pid);
                   3422: 
1.1       root     3423:        if (!f) return EIHNDL;
                   3424: 
                   3425:        if (f->links <= 0) {
                   3426: 
                   3427:                if (!oldvec) {
                   3428: 
1.1.1.2   root     3429:                        DEBUG(("Mouse not open!!"));
1.1       root     3430: 
                   3431:                        return -1;
                   3432: 
                   3433:                }
                   3434: 
                   3435:                Initmous(1, parameters, (void *)oldvec);        /* gratuitous (void *) for Lattice */
                   3436: 
1.1.1.2   root     3437:                syskey->joyvec = oldjvec;       /* jr: restore old joystick handler */
                   3438: 
1.1       root     3439:                oldvec = 0;
                   3440: 
                   3441:        }
                   3442: 
                   3443:        return 0;
                   3444: 
                   3445: }
                   3446: 
                   3447: 
                   3448: 
1.1.1.2   root     3449: static long ARGS_ON_STACK 
1.1       root     3450: 
                   3451: mouse_read(f, buf, nbytes)
                   3452: 
                   3453:        FILEPTR *f;
                   3454: 
                   3455:        char *buf;
                   3456: 
                   3457:        long nbytes;
                   3458: 
                   3459: {
                   3460: 
                   3461:        long count = 0;
                   3462: 
                   3463:        int mhead;
                   3464: 
                   3465:        unsigned char *foo;
                   3466: 
1.1.1.5 ! root     3467:        struct bios_file *b = (struct bios_file *)f->fc.index;
        !          3468: 
1.1       root     3469: 
                   3470: 
                   3471:        mhead = mousehead;
                   3472: 
                   3473:        foo = &mousebuf[mhead];
                   3474: 
                   3475: 
                   3476: 
                   3477:        if (mhead == mousetail) {
                   3478: 
                   3479:                if (f->flags & O_NDELAY)
                   3480: 
                   3481:                        return 0;
                   3482: 
                   3483:                do {
                   3484: 
                   3485:                        yield();
                   3486: 
                   3487:                } while (mhead == mousetail);
                   3488: 
                   3489:        }
                   3490: 
                   3491: 
                   3492: 
                   3493:        while ( (mhead != mousetail) && (nbytes > 0)) {
                   3494: 
                   3495:                *buf++ = *foo++;
                   3496: 
                   3497:                mhead++;
                   3498: 
                   3499:                if (mhead >= MOUSESIZ) {
                   3500: 
                   3501:                        mhead = 0;
                   3502: 
                   3503:                        foo = mousebuf;
                   3504: 
                   3505:                }
                   3506: 
                   3507:                count++;
                   3508: 
                   3509:                --nbytes;
                   3510: 
                   3511:        }
                   3512: 
                   3513:        mousehead = mhead;
                   3514: 
1.1.1.5 ! root     3515:        if (count > 0) {
        !          3516: 
        !          3517:                b->xattr.atime = timestamp;
        !          3518: 
        !          3519:                b->xattr.adate = datestamp;
        !          3520: 
        !          3521:        }
        !          3522: 
1.1       root     3523:        return count;
                   3524: 
                   3525: }
                   3526: 
                   3527: 
                   3528: 
1.1.1.2   root     3529: static long ARGS_ON_STACK 
1.1       root     3530: 
                   3531: mouse_ioctl(f, mode, buf)
                   3532: 
                   3533:        FILEPTR *f;
                   3534: 
                   3535:        int mode;
                   3536: 
                   3537:        void *buf;
                   3538: 
                   3539: {
                   3540: 
                   3541:        long r;
                   3542: 
                   3543: 
                   3544: 
1.1.1.2   root     3545:        UNUSED(f);
                   3546: 
1.1       root     3547:        if (mode == FIONREAD) {
                   3548: 
                   3549:                r = mousetail - mousehead;
                   3550: 
                   3551:                if (r < 0) r += MOUSESIZ;
                   3552: 
                   3553:                *((long *)buf) = r;
                   3554: 
                   3555:        }
                   3556: 
                   3557:        else
                   3558: 
                   3559:                return EINVFN;
                   3560: 
                   3561:        return 0;
                   3562: 
                   3563: }
                   3564: 
                   3565: 
                   3566: 
1.1.1.2   root     3567: static long ARGS_ON_STACK 
1.1       root     3568: 
                   3569: mouse_select(f, p, mode)
                   3570: 
                   3571:        FILEPTR *f;
                   3572: 
                   3573:        long p;
                   3574: 
                   3575:        int mode;
                   3576: 
                   3577: {
                   3578: 
1.1.1.2   root     3579:        UNUSED(f);
                   3580: 
                   3581: 
                   3582: 
1.1       root     3583:        if (mode != O_RDONLY)
                   3584: 
                   3585:                return 1;       /* we can always take output :-) */
                   3586: 
                   3587: 
                   3588: 
                   3589:        if (mousetail - mousehead)
                   3590: 
                   3591:                return 1;       /* input waiting already */
                   3592: 
                   3593: 
                   3594: 
1.1.1.5 ! root     3595:        if (mousersel)
        !          3596: 
        !          3597:                return 2;       /* collision */
1.1       root     3598: 
1.1.1.5 ! root     3599:        mousersel = p;
1.1       root     3600: 
                   3601:        return 0;
                   3602: 
                   3603: }
                   3604: 
                   3605: 
                   3606: 
1.1.1.2   root     3607: static void ARGS_ON_STACK 
1.1       root     3608: 
                   3609: mouse_unselect(f, p, mode)
                   3610: 
                   3611:        FILEPTR *f;
                   3612: 
                   3613:        long p;
                   3614: 
                   3615:        int mode;
                   3616: 
                   3617: {
                   3618: 
1.1.1.2   root     3619:        UNUSED(f);
                   3620: 
                   3621: 
                   3622: 
1.1       root     3623:        if (mode == O_RDONLY && mousersel == p)
                   3624: 
                   3625:                mousersel = 0;
                   3626: 
                   3627: }
                   3628: 
                   3629: 
                   3630: 
                   3631: 
                   3632: 
                   3633: /*
                   3634: 
                   3635:  * UTILITY ROUTINE called by Bconmap() in xbios.c:
                   3636: 
                   3637:  * this sets handle -1 of process p to a file handle
                   3638: 
                   3639:  * that has BIOS device "dev". Returns 0 on failure,
                   3640: 
                   3641:  * non-zero on success.
                   3642: 
                   3643:  */
                   3644: 
                   3645: 
                   3646: 
                   3647: int
                   3648: 
                   3649: set_auxhandle(p, dev)
                   3650: 
                   3651:        PROC *p;
                   3652: 
                   3653:        int dev;
                   3654: 
                   3655: {
                   3656: 
                   3657:        FILEPTR *f;
                   3658: 
                   3659:        struct bios_file *b;
                   3660: 
                   3661: 
                   3662: 
                   3663:        f = new_fileptr();
                   3664: 
                   3665:        if (f) {
                   3666: 
                   3667:                f->links = 1;
                   3668: 
                   3669:                f->flags = O_RDWR;
                   3670: 
                   3671:                f->pos = 0;
                   3672: 
                   3673:                f->devinfo = 0;
                   3674: 
                   3675:                f->fc.fs = &bios_filesys;
                   3676: 
                   3677:                f->fc.aux = dev;
                   3678: 
                   3679:                f->fc.dev = BIOSDRV;
                   3680: 
                   3681:                for (b = broot; b; b = b->next) {
                   3682: 
                   3683:                        if (b->private == dev &&
                   3684: 
                   3685:                            (b->device == &bios_tdevice ||
                   3686: 
                   3687:                             b->device == &bios_ndevice)) {
                   3688: 
                   3689:                                f->fc.index = (long)b;
                   3690: 
                   3691:                                f->dev = b->device;
                   3692: 
                   3693:                                if (b->device != &fakedev)
                   3694: 
                   3695:                                        f->devinfo = (long)b->tty;
                   3696: 
                   3697:                                goto found_device;
                   3698: 
                   3699:                        }
                   3700: 
                   3701:                }
                   3702: 
                   3703:                f->fc.index = 0;
                   3704: 
                   3705:                f->dev = &bios_ndevice;
                   3706: 
                   3707: found_device:
                   3708: 
                   3709:                if ((*f->dev->open)(f) < 0) {
                   3710: 
                   3711:                        f->links = 0;
                   3712: 
                   3713:                        dispose_fileptr(f);
                   3714: 
                   3715:                        return 0;
                   3716: 
                   3717:                }
                   3718: 
                   3719:        } else {
                   3720: 
                   3721: /* no memory! use the fake FILEPTR we
                   3722: 
                   3723:  * set up in biosfs_init
                   3724: 
                   3725:  */
                   3726: 
                   3727:                f = defaultaux;
                   3728: 
                   3729:                f->links++;
                   3730: 
                   3731:        }
                   3732: 
                   3733: 
                   3734: 
                   3735:        (void)do_pclose(p, p->aux);
                   3736: 
                   3737:        p->aux = f;
                   3738: 
                   3739: 
                   3740: 
                   3741:        return 1;
                   3742: 
                   3743: }
                   3744: 

unix.superglobalmegacorp.com

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