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