|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.