source: buchla-68k/libcio/filesys.c@ 109c83b

Last change on this file since 109c83b was 109c83b, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Compiled full ROM in Hatari.

  • Property mode set to 100644
File size: 24.3 KB
Line 
1/*
2 =============================================================================
3 filesys.c -- file system support functions
4 Version 44 -- 1987-11-15 -- D.N. Lynx Crowe
5
6 These functions support a {MS,GEM}DOS|TOS-like file system.
7 Only 12 bit FAT entries are supported.
8 Subdirectories are not supported in this version.
9 =============================================================================
10*/
11
12#define DEBUGIT 0
13
14#define _FS_DEF_ /* to avoid unnecessary externals */
15
16#include "stddefs.h"
17#include "biosdefs.h"
18#include "errno.h"
19#include "memory.h"
20#include "io.h"
21#include "fcntl.h"
22
23#define FAT_EOF 0x0FF8
24
25#define IO_ERR -1
26#define IO_OK 0
27#define IO_EOF 1
28
29#define DE_NULL ((struct dirent *)0L)
30
31extern unsigned micons();
32extern long miconl();
33extern int _ptcl12();
34extern char *FilName(), *FilExt();
35
36#if DEBUGIT
37short fsdebug;
38extern int mdump();
39#endif
40
41struct bpb *_thebpb; /* BIOS parameter block pointer */
42struct dirent _thedir[MAXDIRNT]; /* directory */
43struct dirent *_dptr; /* internal directory pointer */
44
45unsigned _thefat[MAXFAT * WDPSEC]; /* file allocation table */
46
47int _fatin; /* FAT has been read */
48int _dirin; /* directory has been read */
49int _bpbin; /* BPB has been read */
50int _fatmod; /* FAT modified flag */
51int _dirmod; /* directory modified flag */
52
53long _berrno; /* BIOS error number */
54
55/*
56
57*/
58
59
60/*
61 =============================================================================
62 _cl2lsn(bpp, clnum) -- return logical sector number for cluster 'clnum'
63 using BPB pointed to by 'bpp'
64 =============================================================================
65*/
66
67unsigned
68_cl2lsn(bpp, clnum)
69struct bpb *bpp;
70unsigned clnum;
71{
72 return(bpp->datrec + (bpp->clsiz * (clnum - 2)) );
73}
74
75/*
76 =============================================================================
77 _gtcl12(fat, cl) -- return 12 bit cluster entry 'cl' from FAT pointed
78 to by 'fat'
79 =============================================================================
80*/
81
82unsigned
83_gtcl12(fat, cl)
84register char *fat;
85unsigned cl;
86{
87 register unsigned cla, clt;
88
89 cla = cl + (cl >> 1);
90 clt = ((unsigned)0xFF00 & (fat[cla+1] << 8))
91 | ((unsigned)0x00FF & fat[cla]);
92
93 if (cl & 1)
94 clt >>= 4;
95
96 clt &= (unsigned)0x0FFF;
97 return(clt);
98}
99
100/*
101
102*/
103
104/*
105 =============================================================================
106 _getfat(bufad, bpp, nfat) -- get FAT 'nfat' into buffer
107 pointed to by 'bufad' using BPB pointed to by 'bpp'
108 =============================================================================
109*/
110
111unsigned
112_getfat(bufad, bpp, nfat)
113unsigned *bufad, nfat;
114register struct bpb *bpp;
115{
116 unsigned fatsec;
117
118 fatsec = nfat ? bpp->fatrec : (bpp->fatrec - bpp->fsiz);
119 return(BIOS(B_RDWR, 0, (char *)bufad, bpp->fsiz, fatsec, 0));
120}
121
122/*
123
124*/
125
126/*
127 =============================================================================
128 _rdfat(bufad, bpp) -- read FAT into buffer pointed to by 'bufad'
129 using BPB pointed to by 'bpp'
130 =============================================================================
131*/
132
133int
134_rdfat(bufad, bpp)
135unsigned *bufad;
136struct bpb *bpp;
137{
138 if (_getfat(bufad, bpp, 0)) {
139
140 if (_getfat(bufad, bpp, 1))
141 return(IO_ERR); /* couldn't read either FAT */
142 else
143 return(1); /* secondary FAT read OK */
144
145 } else
146 return(0); /* main FAT read OK */
147}
148
149/*
150 =============================================================================
151 _rdroot(buf, bpp) -- read root directory into buffer
152 pointed to by 'buf' using BPB pointed to by 'bpp'
153 =============================================================================
154*/
155
156int
157_rdroot(buf, bpp)
158unsigned *buf;
159register struct bpb *bpp;
160{
161 return(BIOS(B_RDWR, 0, (char *)buf, bpp->rdlen,
162 (bpp->fatrec + bpp->fsiz), 0));
163}
164
165/*
166
167*/
168
169/*
170 =============================================================================
171 _nsic(fcp, bpp, fp) -- get the next sector in the file controlled
172 by the FCB at 'fcp', using the BPB pointed to by 'bpp' and
173 the FAT pointed to by 'fp'. Returns 0 if successful, or -1 on error,
174 or 1 on EOF;
175 =============================================================================
176*/
177
178int
179_nsic(fcp, bpp, fp)
180register struct fcb *fcp;
181struct bpb *bpp;
182char *fp;
183{
184 register unsigned tfe;
185
186 /* check the FCB flags */
187
188 if (!(fcp->modefl & FC_OPN)) {
189
190 errno = EINVAL; /* not open */
191 return(IO_ERR);
192 }
193
194 if (fcp->modefl & FC_BAD) {
195
196 errno = EIO; /* previous I/O error */
197 return(IO_ERR);
198 }
199
200 if (fcp->de.bclust EQ 0) { /* no sectors allocated (empty file) */
201
202 fcp->modefl |= FC_EOF;
203 return(IO_EOF);
204 }
205/*
206
207*/
208 /* update clsec and curlsn and see if we need a new cluster */
209
210 ++fcp->curlsn;
211
212 if (++fcp->clsec GE bpp->clsiz) {
213
214 /* new cluster needed -- follow the chain */
215
216 fcp->clsec = 0;
217 tfe = _gtcl12(fp, fcp->curcls);
218
219 if (tfe < 0x0FF0) { /* see if we've got a good cluster */
220
221
222 fcp->curcls = tfe; /* good cluster, update fcb */
223 fcp->curdsn = _cl2lsn(bpp, tfe);
224
225#if DEBUGIT
226 if (fsdebug)
227 printf("_nsic(): NXT curlsn=%ld, curcls=%u, curdsn=%ld\n",
228 fcp->curlsn, fcp->curcls, fcp->curdsn);
229#endif
230
231 return(IO_OK);
232 }
233
234 if (tfe < 0x0FF8) { /* see if it's a bad cluster */
235
236 fcp-> modefl |= (FC_BAD | FC_EOF); /* bad one */
237
238#if DEBUGIT
239 if (fsdebug)
240 printf("_nsic(): IO_ERR - curlsn=%ld, curcls=%u, curdsn=%ld\n",
241 fcp->curlsn, fcp->curcls, fcp->curdsn);
242#endif
243
244 return(IO_ERR);
245 }
246
247 fcp->modefl |= FC_EOF; /* EOF hit -- set EOF in FCB */
248 return(IO_EOF);
249
250/*
251
252*/
253
254 } else {
255
256 ++fcp->curdsn; /* advance to next sector in current cluster */
257
258#if DEBUGIT
259 if (fsdebug)
260 printf("_nsic(): CUR curlsn=%ld, curcls=%u, curdsn=%ld\n",
261 fcp->curlsn, fcp->curcls, fcp->curdsn);
262#endif
263
264 return(IO_OK);
265 }
266}
267
268/*
269
270*/
271
272/*
273 =============================================================================
274 _dsrch(de) -- search for the directory entry pointed to by 'de'
275 in the current directory
276 =============================================================================
277*/
278
279struct dirent *
280_dsrch(de)
281register struct dirent *de;
282{
283 unsigned i, dl;
284 register struct dirent *dp;
285
286 dp = _thedir;
287 dl = _thebpb->rdlen * (_thebpb->recsiz / DENTSIZE);
288
289 for (i = 0; i < dl; i++) { /* check each entry */
290
291 /* see if we've found it */
292
293 if (0 EQ memcmpu(de->fname, dp->fname, 11))
294 return(dp);
295
296 /* check for end of used entries */
297
298 if ('\0' EQ dp->fname[0])
299 return(DE_NULL);
300
301 dp++; /* point at next entry to check */
302 }
303
304 return(DE_NULL);
305}
306
307/*
308
309*/
310
311/*
312 =============================================================================
313 _dsnew() -- search for an available directory entry in the current
314 directory.
315 =============================================================================
316*/
317
318struct dirent *
319_dsnew()
320{
321 unsigned i, dl;
322 register struct dirent *dp;
323
324 dp = _thedir;
325 dl = _thebpb->rdlen * (_thebpb->recsiz / DENTSIZE);
326
327 for (i = 0; i < dl; i++) { /* check each entry */
328
329 /* check for a deleted entry */
330
331 if (0x00E5 EQ (0x00FF & dp->fname[0]))
332 return(dp);
333
334 /* check for end of used entries */
335
336 if ('\0' EQ dp->fname[0])
337 return(dp);
338
339 dp++; /* point at next entry to check */
340 }
341
342 return(DE_NULL); /* couldn't find an available entry */
343}
344
345/*
346
347*/
348
349/*
350 =============================================================================
351 _deadio(fcp, err) -- mark the FCB pointed to by 'fcp' as 'in error'
352 =============================================================================
353*/
354
355_deadio(fcp, err)
356register struct fcb *fcp;
357int err;
358{
359 fcp->clsec = 0;
360 fcp->curcls = 0;
361 fcp->curlsn = 0L;
362 fcp->curdsn = 0L;
363 fcp->curlen = 0L;
364 fcp->modefl &= ~FC_OPN;
365 fcp->modefl |= FC_ERR;
366 errno = err;
367}
368
369/*
370
371*/
372
373/*
374 =============================================================================
375 _seek(fcp) -- seek to logical sector number in FCB pointed to by 'fcp'.
376 Returns: -1 = error; 0 = not at EOF; 1 = soft EOF; 2 = hard EOF.
377 =============================================================================
378*/
379
380int
381_seek(fcp)
382register struct fcb *fcp;
383{
384 register unsigned acls, rcls, nc;
385 unsigned sic, spc;
386
387 if (!(fcp->modefl & FC_OPN)) { /* file must be open */
388
389 errno = EINVAL; /* invalid request */
390 return(-1); /* return with an error */
391 }
392
393 if (fcp->curlsn GT fcp->asects) { /* error if seek past EOF */
394
395#if DEBUGIT
396 if (fsdebug)
397 printf("_seek(): ERROR - seek past EOF - curlsn=%ld, asects=%ld\n",
398 fcp->curlsn, fcp->asects);
399#endif
400
401 errno = EINVAL; /* invalid request */
402 return(-1); /* return with an error */
403 }
404
405 spc = _thebpb->clsiz; /* get sectors per cluster */
406 rcls = fcp->curlsn / spc; /* calculate relative cluster */
407 sic = fcp->curlsn - (rcls * spc); /* calculate sector in cluster */
408 acls = micons(fcp->de.bclust); /* get first cluster */
409 fcp->modefl &= ~FC_EOF; /* turn off the EOF flag */
410
411/*
412
413*/
414
415#if DEBUGIT
416 if (fsdebug) {
417 printf("_seek(): ENTRY curlsn=%ld, acls=%u, sic=%d, curdsn=%ld, rcls=%u, asects=%ld\n",
418 fcp->curlsn, acls, sic, fcp->curdsn, rcls, fcp->asects);
419 }
420#endif
421
422 if (fcp->curlsn EQ fcp->asects) { /* see if we seeked to EOF */
423
424 fcp->modefl |= FC_EOF; /* flag the EOF condition */
425
426#if DEBUGIT
427 if (fsdebug)
428 printf("_seek(): EOF curlsn=%ld, acls=%u, sic=%d, curdsn=%ld\n",
429 fcp->curlsn, acls, sic, fcp->curdsn);
430#endif
431
432 if (acls EQ 0) /* see if anything allocated */
433 return(2); /* hard EOF if nothing there */
434
435 if (sic EQ 0) /* see if first in cluster */
436 return(2); /* hard EOF if so */
437 }
438
439/*
440
441*/
442 for (nc = 0; nc < rcls; nc++) { /* follow the FAT chain */
443
444 acls = _gtcl12(_thefat, acls); /* next cluster pointer */
445
446 if (acls LT 0x0FF0) /* OK if it's a good cluster */
447 continue;
448
449 fcp->modefl |= FC_ERR; /* EOF or bad cluster hit */
450 errno = EINVAL; /* mark it as an invalid seek */
451
452 if (acls LT 0x0FF8) { /* bad cluster ? */
453
454 errno = EIO; /* mark it as an I/O error */
455 fcp->modefl |= FC_BAD; /* mark FCB: bad cluster hit */
456 }
457
458 return(IO_ERR); /* ERROR: seek error */
459 }
460
461 fcp->curcls = acls; /* current cluster */
462 fcp->clsec = sic; /* sector in cluster */
463
464 fcp->curdsn = _cl2lsn(_thebpb, acls) + sic; /* disk sector number */
465
466#if DEBUGIT
467 if (fsdebug)
468 printf("_seek(): OK curlsn=%ld, acls=%u, sic=%d, curdsn=%ld\n",
469 fcp->curlsn, acls, sic, fcp->curdsn);
470#endif
471
472 if (fcp->curlsn EQ fcp->asects) /* see if we're at EOF */
473 return(1); /* soft EOF */
474
475 return(0); /* not EOF */
476}
477
478/*
479
480*/
481
482/*
483 =============================================================================
484 _ftrnc(dp) -- truncate file pointed to by directory entry 'dp'
485 =============================================================================
486*/
487
488int
489_ftrnc(dp)
490struct dirent *dp;
491{
492 register unsigned acls, ncls;
493
494#if DEBUGIT
495 register int lim;
496
497 lim = _thebpb->numcl;
498#endif
499
500 acls = micons(dp->bclust); /* get first cluster number */
501
502 /* zap entries until EOF or bad cluster */
503
504#if DEBUGIT
505 while (lim-- AND (acls LT 0x0FF0)) {
506#else
507 while (acls LT 0x0FF0) {
508#endif
509
510 ncls = _gtcl12(_thefat, acls); /* get next cluster number */
511 _ptcl12(_thefat, acls, 0); /* zap the current one */
512
513#if DEBUGIT
514 if (fsdebug)
515 printf("_ftrnc(): zapped %d\n", acls);
516#endif
517
518 acls = ncls; /* point at the next one */
519 }
520
521/*
522
523*/
524
525 dp->flen = 0L; /* file length = 0 */
526 dp->bclust = 0; /* no sectors allocated */
527 _fatmod = TRUE; /* FAT got changed */
528 _dirmod = TRUE; /* directory got changed */
529
530#if DEBUGIT
531 if (lim LE 0) {
532
533 errno = EIO;
534 printf("_ftrnc(): ERROR - lim went to %d\n", lim);
535 mdump(_thefat, (char *)_thefat+255, _thefat);
536 xtrap15();
537 return(FAILURE);
538 }
539#endif
540
541 return(SUCCESS);
542}
543
544/*
545
546*/
547
548/*
549 =============================================================================
550 _newcls() -- allocate a new cluster
551 =============================================================================
552*/
553
554int
555_newcls()
556{
557 register int tc, i;
558
559 tc = _thebpb->numcl;
560
561 for (i = 2; i < tc; i++)
562 if (0 EQ _gtcl12(_thefat, i))
563 return(i);
564
565 return(0); /* ERROR: no empty clusters left */
566}
567
568/*
569
570*/
571
572/*
573 =============================================================================
574 _alcnew() -- allocate a new cluster to extend a file
575 =============================================================================
576*/
577
578int
579_alcnew(fcp)
580register struct fcb *fcp;
581{
582 register int ac, nc, pc;
583
584#if DEBUGIT
585 register int lim;
586#endif
587
588 if (nc = _newcls()) { /* get a new cluster */
589
590#if DEBUGIT
591 lim = (fcp->asects / _thebpb->clsiz) + 1; /* limit search */
592#endif
593
594 _ptcl12(_thefat, nc, FAT_EOF); /* mark new cluster as EOF */
595 pc = micons(fcp->de.bclust); /* get first cluster */
596
597#if DEBUGIT
598 if (pc EQ 0) {
599
600 printf("_alcnew(): ERROR - pc EQ 0, bclust=$%04.4X, nc=%d\n",
601 fcp->de.bclust, nc);
602 xtrap15();
603 }
604#endif
605
606 /* find end of allocation chain */
607
608#if DEBUGIT
609 while (lim-- AND ((ac = _gtcl12(_thefat, pc)) < 0x0FF0)) {
610#else
611 while ((ac = _gtcl12(_thefat, pc)) < 0x0FF0) {
612#endif
613
614 pc = ac;
615 }
616
617/*
618
619*/
620
621#if DEBUGIT
622 if (lim LE 0) {
623
624 printf("_alcnew(): ERROR - lim ran out, nc=%d\n", nc);
625 mdump(_thefat, (char *)_thefat+63, _thefat);
626 xtrap15();
627 return(FAILURE);
628 }
629#endif
630
631 _ptcl12(_thefat, pc, nc); /* add cluster to chain */
632 fcp->asects += _thebpb->clsiz; /* update allocated sector count */
633 fcp->curcls = nc; /* current cluster = new cluster */
634 fcp->clsec = 0; /* current sector in cluster = 0 */
635
636 fcp->curdsn = _cl2lsn(_thebpb, nc); /* current disk sector */
637
638#if DEBUGIT
639 if (fsdebug) {
640
641 printf("alcnew(): allocated cluster %d (%04.4x), ",
642 nc, nc);
643 printf("previous = %d (%04.04x), asects =%ld\n",
644 pc, pc, fcp->asects);
645 }
646#endif
647
648 return(SUCCESS); /* return: file extended */
649
650 } else {
651
652#if DEBUGIT
653 if (fsdebug)
654 printf("_alcnew(): _newcls() FAILED\n");
655#endif
656
657 return(FAILURE); /* return: no clusters left */
658 }
659}
660
661/*
662
663*/
664
665/*
666 =============================================================================
667 _fmake(fcp) -- make a new file from the FCB pointed to by 'fcp'
668 =============================================================================
669*/
670
671int
672_fmake(fcp)
673struct fcb *fcp;
674{
675 register struct dirent *dp;
676
677 if (DE_NULL EQ (dp = _dsnew())) /* find a dirent */
678 return(FAILURE);
679
680 _dptr = dp; /* set the directory pointer */
681 memset(dp, 0, DENTSIZE); /* clear the dirent */
682 memcpy(dp->fname, fcp->de.fname, 12); /* setup file name, attribute */
683 dp->atrib |= F_ARCHIV; /* set the archive bit */
684 _dirmod = TRUE; /* directory got changed */
685 return(SUCCESS);
686}
687
688/*
689
690*/
691
692/*
693 =============================================================================
694 _opnvol() -- open a volume
695 =============================================================================
696*/
697
698int
699_opnvol()
700{
701 register long drc;
702
703 /* check for media change if we already have a BPB */
704
705 if (_bpbin) {
706
707 drc = BIOS(B_MCHG, 0);
708
709#if DEBUGIT
710 if (fsdebug) {
711
712 printf("_opnvol(): found _bpbin FALSE\n");
713 printf("_opnvol(): disk change test returned %ld\n", drc);
714 }
715#endif
716
717 if (drc)
718 _bpbin = FALSE;
719 } else {
720
721#if DEBUGIT
722 if (fsdebug)
723 printf("_opnvol(): found _bpbin FALSE\n");
724#endif
725
726 }
727
728 if (!_bpbin) { /* access the BPB */
729
730 _fatin = FALSE; /* invalidate the FAT and directory */
731 _dirin = FALSE;
732
733 if ((struct bpb *)0L EQ (_thebpb = BIOS(B_GBPB, 0))) {
734
735 errno = EIO; /* couldn't read the BPB */
736 return(FAILURE);
737 }
738
739 _bpbin = TRUE;
740 }
741
742 if (!_fatin) { /* access the FAT */
743
744 _dirin = FALSE;
745
746 if (_rdfat(_thefat, _thebpb) < 0) {
747
748 errno = EIO; /* couldn't read either FAT */
749 return(FAILURE);
750 }
751
752 _fatin = TRUE;
753 _fatmod = FALSE;
754 }
755/*
756
757*/
758 if (!_dirin) { /* access the root directory */
759
760 if (_rdroot(_thedir, _thebpb)) {
761
762 errno = EIO; /* couldn't read the directory */
763 return(FAILURE);
764 }
765
766 _dirin = TRUE;
767 _dirmod = FALSE;
768 }
769
770 return(SUCCESS);
771}
772
773/*
774
775*/
776
777/*
778 =============================================================================
779 _opfcb(fcp) -- open the FCB pointed to by 'fcp'. Returns 0 if
780 opened successfully, -1 if an error occurred, with the error code
781 in errno.
782 =============================================================================
783*/
784
785int
786_opfcb(fcp)
787register struct fcb *fcp;
788{
789 int rc;
790
791 /* check for an already open FCB */
792
793 if (fcp->modefl & FC_OPN) {
794
795 errno = EINVAL;
796 return(IO_ERR);
797 }
798
799 if (_opnvol()) { /* open the volume */
800
801 _deadio(fcp, errno);
802 return(IO_ERR);
803 }
804
805 /* search the directory for the file */
806
807 if (DE_NULL EQ (_dptr = _dsrch(&fcp->de))) {
808
809 /* file doesn't exist -- see if we should create it */
810
811 if (!(fcp->modefl & FC_CR)) {
812
813 _deadio(fcp, ENOENT); /* file nonexistant, not creating one */
814 return(IO_ERR);
815 }
816
817 /* create the file */
818
819 if(rc = _fmake(fcp)) {
820
821 _deadio(fcp, EIO); /* couldn't create the file */
822 return(IO_ERR);
823 }
824
825/*
826
827*/
828
829 } else {
830
831 /* file exists -- check for writes to a read-only file */
832
833 if ( (fcp->de.atrib & F_RDONLY) AND
834 (fcp->modefl & (FC_AP | FC_WR | FC_TR)) ) {
835
836 /* can't append, write or truncate RO files */
837
838 _deadio(fcp, EACCES);
839 return(IO_ERR);
840 }
841
842 /* check for append and not write */
843
844 if ((fcp->modefl & FC_AP) AND !(fcp->modefl & FC_WR)) {
845
846 /* can't append if not open to write */
847
848 _deadio(fcp, EACCES);
849 return(IO_ERR);
850 }
851
852 /* check for create and exclusive with extant file */
853
854 if ((fcp->modefl & FC_CR) AND (fcp->modefl & FC_EX)) {
855
856 /* file exists and open was create-exclusive */
857
858 _deadio(fcp, EEXIST);
859 return(IO_ERR);
860 }
861
862/*
863
864*/
865
866 /* truncate the file if requested */
867
868 if (fcp->modefl & FC_TR) {
869
870 /* see if we can write */
871
872 if (fcp->modefl & FC_WR) {
873
874 /* truncate the file */
875
876 if (_ftrnc(_dptr)) {
877
878 _deadio(fcp, EIO); /* truncation failed */
879 return(IO_ERR);
880 }
881
882 } else {
883
884 /* we can't write, so we can't truncate */
885
886 _deadio(fcp, EACCES);
887 return(IO_ERR);
888 }
889 }
890 }
891
892 /* setup the FCB fields */
893
894 memcpy(&fcp->de, _dptr, DENTSIZE);
895 fcp->clsec = 0;
896 fcp->curcls = micons(fcp->de.bclust);
897 fcp->offset = 0;
898 fcp->curlsn = 0L;
899 fcp->curdsn = fcp->de.bclust ? _cl2lsn(_thebpb, fcp->curcls) : 0;
900 fcp->curlen = miconl(fcp->de.flen);
901
902 fcp->asects = ((fcp->curlen / _thebpb->clsizb)
903 + ((fcp->curlen & (_thebpb->clsizb - 1)) ? 1 : 0))
904 * _thebpb->clsiz;
905
906 fcp->modefl &= ~(FC_EOF | FC_BAD | FC_ERR);
907 fcp->modefl |= FC_OPN;
908
909#if DEBUGIT
910 if (fsdebug)
911 SnapFCB(fcp);
912#endif
913
914 return(IO_OK);
915}
916
917/*
918
919*/
920
921/*
922 =============================================================================
923 _inifcb(fcp, name, ext, mode) -- initialize FCB pointed to by 'fcp'
924 for file named 'name'.'ext' in mode 'mode'.
925 Returns SUCCESS (0) if ok, FAILURE (-1) if not.
926 =============================================================================
927*/
928
929int
930_inifcb(fcp, name, ext, mode)
931register struct fcb *fcp;
932char *name, *ext;
933int mode;
934{
935 int fl;
936 register int i;
937 register char *s1, *s2, c;
938
939 /* clear the FCB */
940
941 memset((char *)fcp, 0, sizeof (struct fcb));
942
943 /* check for valid flags */
944
945 if (mode & ~(O_WRONLY|O_RDWR|O_NDELAY|O_APPEND|O_CREAT|O_TRUNC|O_EXCL|O_RAW))
946 return(FAILURE);
947
948/*
949
950*/
951 /* check the file name for length */
952
953 fl = TRUE;
954 s1 = name;
955
956 for (i = 0; i < 9; i++)
957 if (*s1++ EQ '\0') {
958
959 fl = FALSE;
960 break;
961 }
962
963 if (fl)
964 return(FAILURE);
965
966 /* check the file name extension for length */
967
968 fl = TRUE;
969 s1 = ext;
970
971 for (i = 0; i <4; i++)
972 if (*s1++ EQ '\0') {
973
974 fl = FALSE;
975 break;
976 }
977
978 if (fl)
979 return(FAILURE);
980
981/*
982
983*/
984 /* clear the file name and extension in the FCB to blanks */
985
986 memset(fcp->de.fname, ' ', 11);
987
988 /* move the file name into the FCB */
989
990 s1 = fcp->de.fname;
991 s2 = name;
992
993 for (i = 0; i < 8; i++) {
994
995 c = *s2++;
996
997 if ((c EQ '\0') OR (c EQ ' '))
998 break;
999
1000 *s1++ = c;
1001 }
1002
1003 /* move the file name extension into the FCB */
1004
1005 s1 = fcp->de.fext;
1006 s2 = ext;
1007
1008 for (i = 0; i < 3; i++) {
1009
1010 c = *s2++;
1011
1012 if ((c EQ '\0') OR (c EQ ' '))
1013 break;
1014
1015 *s1++ = c;
1016 }
1017
1018/*
1019
1020*/
1021
1022 /* set the flags in the FCB and exit */
1023
1024 if (mode & O_RDONLY)
1025 fcp->modefl |= FC_RD;
1026
1027 if (mode & O_WRONLY)
1028 fcp->modefl |= FC_WR;
1029
1030 if (mode & O_RDWR)
1031 fcp->modefl |= FC_RW;
1032
1033 if (mode & O_NDELAY)
1034 fcp->modefl |= FC_NB;
1035
1036 if (mode & O_APPEND)
1037 fcp->modefl |= FC_AP;
1038
1039 if (mode & O_CREAT)
1040 fcp->modefl |= FC_CR;
1041
1042 if (mode & O_TRUNC)
1043 fcp->modefl |= FC_TR;
1044
1045 if (mode & O_EXCL)
1046 fcp->modefl |= FC_EX;
1047
1048 if (mode & O_RAW)
1049 fcp->modefl |= FC_BF;
1050
1051 return(SUCCESS);
1052}
1053
1054/*
1055
1056*/
1057
1058/*
1059 =============================================================================
1060 ClsFile() -- Closes the file controlled by the FCB pointed to by 'fcp'
1061 at the bios level.
1062 =============================================================================
1063*/
1064
1065int
1066ClsFile(fcp)
1067register struct fcb *fcp;
1068{
1069 register struct dirent *dp;
1070
1071#if DEBUGIT
1072 if (fsdebug) {
1073
1074 printf("ClsFile($%08lX): closing file\n", fcp);
1075 SnapFCB(fcp);
1076 }
1077#endif
1078
1079 if (fcp->modefl & FC_OPN) { /* is it open ? */
1080
1081 if (fcp->modefl & (FC_CR | FC_AP | FC_WR)) { /* writing ? */
1082
1083 if (dp = _dsrch(&fcp->de)) { /* locate the dirent */
1084
1085 /* update the directory entry if it changed */
1086
1087 if (memcmp(dp, &fcp->de, DENTSIZE)) {
1088
1089 memcpy(dp, &fcp->de, DENTSIZE);
1090 _dirmod = TRUE;
1091#if DEBUGIT
1092 if (fsdebug) {
1093
1094 printf("ClsFile(): updated the directory. FAT:\n");
1095 mdump(_thefat, (char *)_thefat+127, _thefat);
1096 }
1097#endif
1098
1099 }
1100
1101/*
1102
1103*/
1104
1105 } else {
1106
1107#if DEBUGIT
1108 if (fsdebug)
1109 printf("ClsFile(): ERROR - can't find the directory entry\n");
1110#endif
1111
1112 errno = EIO; /* can't find the entry */
1113 return(FAILURE);
1114 }
1115 }
1116
1117#if DEBUGIT
1118 if (fsdebug)
1119 SnapFCB(fcp);
1120#endif
1121
1122 return(SUCCESS);
1123
1124 } else { /* not open */
1125
1126#if DEBUGIT
1127 if (fsdebug)
1128 printf("ClsFile(): ERROR - file not open\n");
1129#endif
1130
1131 errno = EINVAL;
1132 return(FAILURE);
1133 }
1134}
1135
1136/*
1137
1138*/
1139
1140/*
1141 =============================================================================
1142 _clsvol() -- close the volume
1143 =============================================================================
1144*/
1145
1146_clsvol()
1147{
1148 if (_fatmod) {
1149
1150 _clsfat();
1151
1152#if DEBUGIT
1153 if (fsdebug)
1154 printf("_clsvol(): modified FAT written\n");
1155#endif
1156 }
1157
1158 if (_dirmod) {
1159
1160 _clsdir();
1161
1162#if DEBUGIT
1163 if (fsdebug)
1164 printf("_clsvol(): modified directory written\n");
1165#endif
1166 }
1167
1168 _bpbin = FALSE;
1169 _fatin = FALSE;
1170 _dirin = FALSE;
1171}
1172
1173/*
1174 =============================================================================
1175 fcbinit() -- initialize an FCB
1176 =============================================================================
1177*/
1178
1179short
1180fcbinit(name, fcp)
1181register char *name;
1182register struct fcb *fcp;
1183{
1184 char tmpname[9], tmpext[4];
1185
1186 return(_inifcb(fcp, FilName(name, tmpname), FilExt(name, tmpext), 0));
1187}
1188
1189/*
1190
1191*/
1192
1193/*
1194 =============================================================================
1195 DelFile() -- Deletes the file named by fcb pointed to by 'fcp'.
1196 =============================================================================
1197*/
1198
1199int
1200DelFile(fcp)
1201struct fcb *fcp;
1202{
1203#if DEBUGIT
1204 if (fsdebug)
1205 printf("DelFile($%08.8lX): deleting [%-.8s].[%-.3s]\n",
1206 fcp, fcp->de.fname, fcp->de.fext);
1207#endif
1208
1209 if(_opnvol()) /* open the volume */
1210 return(FAILURE);
1211
1212 if (DE_NULL EQ (_dptr = _dsrch(&fcp->de))) { /* find the file */
1213
1214 errno = ENOENT; /* can't find the file */
1215 return(FAILURE);
1216 }
1217
1218 if (_dptr->atrib & F_RDONLY) {
1219
1220 errno = EACCES; /* can't delete an R/O file */
1221 return(FAILURE);
1222 }
1223
1224 if (_ftrnc(_dptr)) /* truncate the file to free its space */
1225 return(FAILURE);
1226
1227 _dptr->fname[0] = 0xE5; /* mark directory entry as free */
1228
1229#if DEBUGIT
1230 if (fsdebug)
1231 printf("DelFile($%08.8lX): file [%-.8s].[%-.3s] DELETED\n",
1232 fcp, fcp->de.fname, fcp->de.fext);
1233#endif
1234
1235 return(SUCCESS);
1236}
Note: See TracBrowser for help on using the repository browser.