/**************************************************************************** * * _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 */
/**************************************************************************** * * fn_open * * open a file for reading/writing/appending * * INPUTS * * filename - which file need to be opened * mode - string how to open ("r"-read, "w"-write, "w+"-overwrite, "a"-append * * RETURNS * * F_FILE pointer if successfully * 0 - if any error * ***************************************************************************/ F_FILE * fn_open ( const char * filename, const char * mode ) { F_DIRENTRY * de; F_NAME fsname; unsigned short date; unsigned short time; unsigned char m_mode = F_FILE_CLOSE; if ( mode[1] == 0 ) { if ( mode[0] == 'r' ) { m_mode = F_FILE_RD; } if ( mode[0] == 'w' ) { m_mode = F_FILE_WR; } if ( mode[0] == 'a' ) { m_mode = F_FILE_A; } } if ( ( mode[1] == '+' ) && ( mode[2] == 0 ) ) { if ( mode[0] == 'r' ) { m_mode = F_FILE_RDP; } if ( mode[0] == 'w' ) { m_mode = F_FILE_WRP; } if ( mode[0] == 'a' ) { m_mode = F_FILE_AP; } } if ( m_mode == F_FILE_CLOSE ) { return 0; /*invalid mode*/ } if ( _f_setfsname( filename, &fsname ) ) { return 0; /*invalid name*/ } if ( _f_checknamewc( fsname.filename, fsname.fileext ) ) { return 0; /*invalid name*/ } if ( fsname.filename[0] == '.' ) { return 0; } if ( _f_getvolume() ) { return 0; /*cant open any*/ } if ( gl_file.mode != F_FILE_CLOSE ) { return 0; } psp_memset( &gl_file, 0, 21 ); if ( !_f_findpath( &fsname, &gl_file.dirpos ) ) { return 0; } switch ( m_mode ) { case F_FILE_RDP: /*r*/ case F_FILE_RD: /*r*/ if ( !_f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) ) { return 0; } if ( de->attr & F_ATTR_DIR ) { return 0; /*directory*/ } gl_file.startcluster = _f_getdecluster( de ); if ( gl_file.startcluster ) { _f_clustertopos( gl_file.startcluster, &gl_file.pos ); gl_file.filesize = _f_getlong( &de->filesize ); gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE); if ( _f_fseek( 0 ) ) { return 0; } } #if F_FILE_CHANGED_EVENT if ( m_mode == F_FILE_RDP ) { _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext ); } #endif break; case F_FILE_AP: case F_FILE_A: /*a*/ psp_memcpy( &( gl_file.pos ), &( gl_file.dirpos ), sizeof( F_POS ) ); if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.dirpos, &de, 0 ) ) { if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) ) { return 0; } gl_file.startcluster = _f_getdecluster( de ); gl_file.filesize = _f_getlong( &de->filesize ); if ( gl_file.startcluster ) { _f_clustertopos( gl_file.startcluster, &gl_file.pos ); gl_file.abspos = (unsigned long) (-1 * (long) F_SECTOR_SIZE); /*forcing seek to read 1st sector! abspos=0;*/ if ( _f_fseek( (long)gl_file.filesize ) ) { gl_file.mode = F_FILE_CLOSE; return 0; } } } else { psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) ); _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos ); if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) ) { return 0; /*couldnt be added*/ } de->attr |= F_ATTR_ARC; /*set as archiv*/ if ( _f_writeglsector( (unsigned long)-1 ) ) { return 0; } } #if F_FILE_CHANGED_EVENT _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext ); #endif break; case F_FILE_WR: /*w*/ case F_FILE_WRP: /*w+*/ _f_clustertopos( gl_file.dirpos.cluster, &gl_file.pos ); if ( _f_findfilewc( fsname.filename, fsname.fileext, &gl_file.pos, &de, 0 ) ) { unsigned long cluster = _f_getdecluster( de ); /*exist*/ if ( de->attr & ( F_ATTR_DIR | F_ATTR_READONLY ) ) { return 0; } psp_memcpy( &( gl_file.dirpos ), &( gl_file.pos ), sizeof( F_POS ) ); _f_setlong( de->filesize, 0 ); /*reset size;*/ de->attr |= F_ATTR_ARC; /*set as archiv*/ _f_setword( de->clusterlo, 0 ); /*no points anywhere*/ _f_setword( de->clusterhi, 0 ); if ( gl_volume.mediatype == F_FAT32_MEDIA ) { f_igettimedate( &time, &date ); _f_setword( &de->crtdate, date ); /*if there is realtime clock then creation date could be set from*/ _f_setword( &de->crttime, time ); /*if there is realtime clock then creation time could be set from*/ _f_setword( &de->lastaccessdate, date ); /*if there is realtime clock then creation date could be set from*/ } if ( _f_writeglsector( (unsigned long)-1 ) ) { return 0; } if ( _f_removechain( cluster ) ) { return 0; /*remove */ } } else { if ( _f_addentry( &fsname, &gl_file.dirpos, &de ) ) { return 0; /*couldnt be added*/ } psp_memset( &gl_file, 0, 21 ); de->attr |= F_ATTR_ARC; /*set as archiv*/ if ( _f_writeglsector( (unsigned long)-1 ) ) { return 0; } } #if F_FILE_CHANGED_EVENT _f_createfullname( gl_file.filename, sizeof( gl_file.filename ), fsname.path, fsname.filename, fsname.fileext ); #endif break; default: return 0; /*invalid mode*/ } /* switch */ if ( ( m_mode != F_FILE_RD ) && ( gl_file.startcluster == 0 ) ) { gl_volume.fatsector = (unsigned long)-1; if ( _f_alloccluster( &( gl_file.startcluster ) ) ) { return 0; } _f_clustertopos( gl_file.startcluster, &gl_file.pos ); if ( _f_setclustervalue( gl_file.startcluster, F_CLUSTER_LAST ) ) { return 0; } if ( _f_writefatsector() ) { return 0; } } gl_file.mode = m_mode; /* lock it */ return (F_FILE *)1; } /* fn_open */
/**************************************************************************** * * _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 */