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

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

Removed form-feed comments.

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