/**************************************************************************** * * fn_getfreespace * * get total/free/used/bad diskspace * * INPUTS * pspace - pointer where to store the information * * RETURNS * error code * ***************************************************************************/ unsigned char fn_getfreespace ( F_SPACE * pspace ) { unsigned char ret; unsigned long a; unsigned long clustersize; ret = _f_getvolume(); if ( ret ) { return ret; } psp_memset( pspace, 0, sizeof( F_SPACE ) ); pspace->total = gl_volume.maxcluster; gl_volume.fatsector = (unsigned long)-1; for ( a = 2 ; a < gl_volume.maxcluster + 2 ; a++ ) { unsigned long value; ret = _f_getclustervalue( a, &value ); if ( ret ) { return ret; } if ( !value ) { ++( pspace->free ); } else if ( value == F_CLUSTER_BAD ) { ++( pspace->bad ); } else { ++( pspace->used ); } } clustersize = (unsigned long)( gl_volume.bootrecord.sector_per_cluster * F_SECTOR_SIZE ); for ( a = 0 ; ( clustersize & 1 ) == 0 ; a++ ) { clustersize >>= 1; } pspace->total_high = ( pspace->total ) >> ( 32 - a ); pspace->total <<= a; pspace->free_high = ( pspace->free ) >> ( 32 - a ); pspace->free <<= a; pspace->used_high = ( pspace->used ) >> ( 32 - a ); pspace->used <<= a; pspace->bad_high = ( pspace->bad ) >> ( 32 - a ); pspace->bad <<= a; return F_NO_ERROR; } /* fn_getfreespace */
/**************************************************************************** * * _f_seteof * * Set end of file * * INPUT: f - file pointer * filesize - required new size * RETURN: F_NO_ERROR - on success * other if error * ***************************************************************************/ unsigned char _f_seteof ( F_FILE * f, long filesize ) { unsigned char rc = F_NO_ERROR; if ( !f ) { return F_ERR_NOTOPEN; /*if error*/ } if ( ( unsigned long) filesize < gl_file.filesize ) { rc = _f_fseek( filesize ); if ( rc == F_NO_ERROR ) { unsigned long cluster; rc = _f_getclustervalue( gl_file.pos.cluster, &cluster ); if ( rc == F_NO_ERROR ) { if ( cluster != F_CLUSTER_LAST ) { rc = _f_removechain( cluster ); if ( rc ) { return rc; } rc = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST ); if ( rc ) { return rc; } rc = _f_writefatsector(); if ( rc ) { return rc; } } gl_file.filesize = (unsigned long)filesize; } } } else if ( (unsigned long) filesize > gl_file.filesize ) { rc = _f_fseek( filesize ); } return rc; } /* _f_seteof */
/**************************************************************************** * * _f_fseek * * subfunction for f_seek it moves position into given offset and read * the current sector * * INPUTS * offset - position from start * * RETURNS * * error code or zero if successful * ***************************************************************************/ static unsigned char _f_fseek ( long offset ) { unsigned long cluster; unsigned long tmp; unsigned char ret = F_NO_ERROR; long remain; if ( offset < 0 ) { offset = 0; } if ( ( (unsigned long) offset <= gl_file.filesize ) && ( (unsigned long) offset >= gl_file.abspos ) && ( (unsigned long) offset < gl_file.abspos + F_SECTOR_SIZE ) ) { gl_file.relpos = (unsigned short)( offset - gl_file.abspos ); } else { if ( gl_file.modified ) { ret = _f_writeglsector( (unsigned long)-1 ); if ( ret ) { gl_file.mode = F_FILE_CLOSE; /*cant accessed any more*/ return ret; } } if ( gl_file.startcluster ) { gl_file.abspos = 0; gl_file.relpos = 0; gl_file.pos.cluster = gl_file.startcluster; remain = gl_file.filesize; tmp = gl_volume.bootrecord.sector_per_cluster; tmp *= F_SECTOR_SIZE; /* set to cluster size */ /*calc cluster*/ gl_volume.fatsector = (unsigned long)-1; while ( (unsigned long)offset >= tmp ) { ret = _f_getclustervalue( gl_file.pos.cluster, &cluster ); if ( ret ) { gl_file.mode = F_FILE_CLOSE; return ret; } if ( (long) tmp >= remain ) { break; } remain -= tmp; offset -= tmp; gl_file.abspos += tmp; if ( cluster >= F_CLUSTER_RESERVED ) { break; } gl_file.pos.cluster = cluster; } _f_clustertopos( gl_file.pos.cluster, &gl_file.pos ); if ( remain && offset ) { while ( ( offset > (long) F_SECTOR_SIZE ) && ( remain > (long) F_SECTOR_SIZE ) ) { gl_file.pos.sector++; offset -= F_SECTOR_SIZE; remain -= F_SECTOR_SIZE; gl_file.abspos += F_SECTOR_SIZE; } } if ( remain < offset ) { gl_file.relpos = (unsigned short)remain; ret = _f_extend( gl_file.filesize + offset - remain ); } else { gl_file.relpos = (unsigned short)offset; } } else { ret = _f_extend( offset ); } } return ret; } /* _f_fseek */
/**************************************************************************** * * _f_emptywritebuffer * * empty write buffer if it contains unwritten data * * RETURNS * error code or zero if successful * ***************************************************************************/ static unsigned char _f_stepnextsector ( void ) { unsigned char ret; unsigned char b_alloc; b_alloc = 0; gl_volume.fatsector = (unsigned long)-1; if ( gl_file.startcluster == 0 ) { b_alloc = 1; } else { ++gl_file.pos.sector; if ( gl_file.pos.sector >= gl_file.pos.sectorend ) { unsigned long value; ret = _f_getclustervalue( gl_file.pos.cluster, &value ); if ( ret ) { return ret; } if ( ( value >= 2 ) && ( value < F_CLUSTER_RESERVED ) ) /*we are in chain*/ { _f_clustertopos( value, &gl_file.pos ); /*go to next cluster*/ } else { b_alloc = 1; } } } if ( b_alloc != 0 ) { unsigned long nextcluster; ret = _f_alloccluster( &nextcluster ); if ( ret ) { return ret; } ret = _f_setclustervalue( nextcluster, F_CLUSTER_LAST ); if ( ret ) { return ret; } if ( gl_file.startcluster == 0 ) { gl_file.startcluster = nextcluster; } else { ret = _f_setclustervalue( gl_file.pos.cluster, nextcluster ); if ( ret ) { return ret; } } _f_clustertopos( nextcluster, &gl_file.pos ); return _f_writefatsector(); } return F_NO_ERROR; } /* _f_stepnextsector */
static unsigned char _f_emptywritebuffer ( void ) { unsigned char ret; ret = _f_writeglsector( gl_file.pos.sector ); if ( ret ) { return ret; } gl_file.modified = 0; gl_file.pos.sector++; if ( gl_file.pos.sector >= gl_file.pos.sectorend ) { unsigned long value; gl_volume.fatsector = (unsigned long)-1; ret = _f_getclustervalue( gl_file.pos.cluster, &value ); if ( ret ) { return ret; } if ( ( value >= 2 ) && ( value < F_CLUSTER_RESERVED ) ) /*we are in chain*/ { gl_file.prevcluster = gl_file.pos.cluster; _f_clustertopos( value, &gl_file.pos ); /*go to next cluster*/ } else { unsigned long nextcluster; ret = _f_alloccluster( &nextcluster ); if ( ret ) { return ret; } ret = _f_setclustervalue( nextcluster, F_CLUSTER_LAST ); if ( ret ) { return ret; } ret = _f_setclustervalue( gl_file.pos.cluster, nextcluster ); if ( ret ) { return ret; } gl_file.prevcluster = gl_file.pos.cluster; _f_clustertopos( nextcluster, &gl_file.pos ); return _f_writefatsector(); } } return F_NO_ERROR; } /* _f_emptywritebuffer */