/****************************************************************************
 *
 * 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 */
Пример #2
0
/****************************************************************************
 *
 * _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 */