/*
 * FreeRTOS+FAT SL V1.0.1 (C) 2014 HCC Embedded
 *
 * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license 
 * terms.
 * 
 * FreeRTOS+FAT SL uses a dual license model that allows the software to be used 
 * under a standard GPL open source license, or a commercial license.  The 
 * standard GPL license (unlike the modified GPL license under which FreeRTOS 
 * itself is distributed) requires that all software statically linked with 
 * FreeRTOS+FAT SL is also distributed under the same GPL V2 license terms.  
 * Details of both license options follow:
 * 
 * - Open source licensing -
 * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and
 * distributed without charge provided the user adheres to version two of the 
 * GNU General Public License (GPL) and does not remove the copyright notice or 
 * this text.  The GPL V2 text is available on the gnu.org web site, and on the
 * following URL: http://www.FreeRTOS.org/gpl-2.0.txt.
 * 
 * - Commercial licensing -
 * Businesses and individuals who for commercial or other reasons cannot comply
 * with the terms of the GPL V2 license must obtain a commercial license before 
 * incorporating FreeRTOS+FAT SL into proprietary software for distribution in 
 * any form.  Commercial licenses can be purchased from 
 * http://shop.freertos.org/fat_sl and do not require any source files to be 
 * changed.
 *
 * FreeRTOS+FAT SL is distributed in the hope that it will be useful.  You
 * cannot use FreeRTOS+FAT SL unless you agree that you use the software 'as
 * is'.  FreeRTOS+FAT SL is provided WITHOUT ANY WARRANTY; without even the
 * implied warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. Real Time Engineers Ltd. and HCC Embedded disclaims all
 * conditions and terms, be they implied, expressed, or statutory.
 *
 * http://www.FreeRTOS.org
 * http://www.FreeRTOS.org/FreeRTOS-Plus
 *
 */

#include "../../api/fat_sl.h"
#include "../../psp/include/psp_string.h"

#include "dir.h"
#include "util.h"
#include "volume.h"
#include "drv.h"
#include "fat.h"
#include "file.h"

#include "../../version/ver_fat_sl.h"
#if VER_FAT_SL_MAJOR != 5 || VER_FAT_SL_MINOR != 2
 #error Incompatible FAT_SL version number!
#endif


/****************************************************************************
 *
 * _f_findfilewc
 *
 * internal function to finding file in directory entry with or without
 * wildcard
 *
 * INPUTS
 *
 * name - filename
 * ext - fileextension
 * pos - where to start searching, and contains current position
 * pde - store back the directory entry pointer
 * wc - wildcard checking?
 *
 * RETURNS
 *
 * 0 - if file was not found
 * 1 - if file was found
 *
 ***************************************************************************/
unsigned char _f_findfilewc ( char * name, char * ext, F_POS * pos, F_DIRENTRY * * pde, unsigned char wc )
{
  while ( pos->cluster < F_CLUSTER_RESERVED )
  {
    for ( ; pos->sector < pos->sectorend ; pos->sector++ )
    {
      F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos );

      if ( _f_readglsector( pos->sector ) )
      {
        return 0;                                         /*not found*/
      }

      for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ )
      {
        unsigned char  b, ok;

        if ( !de->name[0] )
        {
          return 0;                                                /*empty*/
        }

        if ( (unsigned char)( de->name[0] ) == 0xe5 )
        {
          continue;                                                 /*deleted*/
        }

        if ( de->attr & F_ATTR_VOLUME )
        {
          continue;
        }

        if ( wc )
        {
          for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ )
          {
            if ( name[b] == '*' )
            {
              break;
            }

            if ( name[b] != '?' )
            {
              if ( de->name[b] != name[b] )
              {
                ok = 0;
                break;
              }
            }
          }

          if ( ok )
          {
            for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ )
            {
              if ( ext[b] == '*' )
              {
                if ( pde )
                {
                  *pde = de;
                }

                return 1;
              }

              if ( ext[b] != '?' )
              {
                if ( de->ext[b] != ext[b] )
                {
                  ok = 0;
                  break;
                }
              }
            }

            if ( ok )
            {
              if ( pde )
              {
                *pde = de;
              }

              return 1;
            }
          }
        }
        else
        {
          for ( b = 0, ok = 1 ; b < sizeof( de->name ) ; b++ )
          {
            if ( de->name[b] != name[b] )
            {
              ok = 0;
              break;
            }
          }

          if ( ok )
          {
            for ( b = 0, ok = 1 ; b < sizeof( de->ext ) ; b++ )
            {
              if ( de->ext[b] != ext[b] )
              {
                ok = 0;
                break;
              }
            }

            if ( ok )
            {
              if ( pde )
              {
                *pde = de;
              }

              return 1;
            }
          }
        }
      }

      pos->pos = 0;
    }

    if ( !pos->cluster )
    {
      if ( gl_volume.mediatype == F_FAT32_MEDIA )
      {
        pos->cluster = gl_volume.bootrecord.rootcluster;
      }
      else
      {
        return 0;
      }
    }

    {
      unsigned long  nextcluster;
      gl_volume.fatsector = (unsigned long)-1;
      if ( _f_getclustervalue( pos->cluster, &nextcluster ) )
      {
        return 0;                                                          /*not found*/
      }

      if ( nextcluster >= F_CLUSTER_RESERVED )
      {
        return 0;                                            /*eof*/
      }

      _f_clustertopos( nextcluster, pos );
    }
  } /* _f_findfilewc */

  return 0;
}


/****************************************************************************
 *
 * _f_getfilename
 *
 * create a complete filename from name and extension
 *
 * INPUTS
 *
 * dest - where to store filename
 * name - name of the file
 * ext - extension of the file
 *
 ***************************************************************************/
static void _f_getfilename ( char * dest, char * name, char * ext )
{
  unsigned char  a, len;

  for ( len = a = F_MAXNAME ; a ; a--, len-- )
  {
    if ( name[a - 1] != ' ' )
    {
      break;
    }
  }

  for ( a = 0 ; a < len ; a++ )
  {
    *dest++ = *name++;
  }


  for ( len = a = F_MAXEXT ; a ; a--, len-- )
  {
    if ( ext[a - 1] != ' ' )
    {
      break;
    }
  }

  if ( len )
  {
    *dest++ = '.';
  }

  for ( a = 0 ; a < len ; a++ )
  {
    *dest++ = *ext++;
  }

  *dest = 0; /*terminateit*/
} /* _f_getfilename */




/****************************************************************************
 *
 * _f_getdecluster
 *
 * get a directory entry structure start cluster value
 *
 * INPUTS
 *
 * de - directory entry
 *
 * RETURNS
 *
 * directory entry cluster value
 *
 ***************************************************************************/
unsigned long _f_getdecluster ( F_DIRENTRY * de )
{
  unsigned long  cluster;

  if ( gl_volume.mediatype == F_FAT32_MEDIA )
  {
    cluster = _f_getword( &de->clusterhi );
    cluster <<= 16;
    cluster |= _f_getword( &de->clusterlo );
    return cluster;
  }

  return _f_getword( &de->clusterlo );
}


/****************************************************************************
 *
 * _f_setdecluster
 *
 * set a directory entry structure start cluster value
 *
 * INPUTS
 *
 * de - directory entry
 * cluster - value of the start cluster
 *
 ***************************************************************************/
void _f_setdecluster ( F_DIRENTRY * de, unsigned long cluster )
{
  _f_setword( &de->clusterlo, (unsigned short)( cluster & 0xffff ) );
  if ( gl_volume.mediatype == F_FAT32_MEDIA )
  {
    _f_setword( &de->clusterhi, (unsigned short)( cluster >> 16 ) );
  }
  else
  {
    _f_setword( &de->clusterhi, (unsigned short)0 );
  }
}


/****************************************************************************
 *
 * _f_findpath
 *
 * finding out if path is valid in F_NAME and
 * correct path info with absolute path (removes relatives)
 *
 * INPUTS
 *
 * fsname - filled structure with path,drive
 * pos - where to start searching, and contains current position
 *
 * RETURNS
 *
 * 0 - if path was not found or invalid
 * 1 - if path was found
 *
 ***************************************************************************/
unsigned char _f_findpath ( F_NAME * fsname, F_POS * pos )
{
  char       * path = fsname->path;
  char       * mpath = path;
  F_DIRENTRY * de;

  _f_clustertopos( 0, pos );

  for ( ; *path ; )
  {
    char           name[F_MAXNAME];
    char           ext[F_MAXEXT];

    unsigned char  len = _f_setnameext( path, name, ext );

    if ( ( pos->cluster == 0 ) && ( len == 1 ) && ( name[0] == '.' ) )
    {
      _f_clustertopos( 0, pos );
    }
    else
    {
      if ( !_f_findfilewc( name, ext, pos, &de, 0 ) )
      {
        return 0;
      }

      if ( !( de->attr & F_ATTR_DIR ) )
      {
        return 0;
      }

      _f_clustertopos( _f_getdecluster( de ), pos );
    }


    if ( name[0] == '.' )
    {
      if ( len == 1 )
      {
        path += len;

        if ( !( *path ) )
        {
          if ( mpath != fsname->path )
          {
            mpath--;                                  /*if we are now at the top*/
          }

          break;
        }

        path++;
        continue;
      }

      if ( name[1] != '.' )
      {
        return 0;                       /*invalid name*/
      }

      if ( len != 2 )
      {
        return 0;                 /*invalid name !*/
      }

      path += len;

      if ( mpath == fsname->path )
      {
        return 0;                              /*we are in the top*/
      }

      mpath--;       /*no on separator*/
      for ( ; ; )
      {
        if ( mpath == fsname->path )
        {
          break;                                /*we are now at the top*/
        }

        mpath--;
        if ( *mpath == '/' )
        {
          mpath++;
          break;
        }
      }

      if ( !( *path ) )
      {
        if ( mpath != fsname->path )
        {
          mpath--;                                /*if we are now at the top*/
        }

        break;
      }

      path++;
      continue;
    }
    else
    {
      if ( path == mpath )                              /*if no was dots just step*/
      {
        path += len;
        mpath += len;
      }
      else
      {
        unsigned char  a;
        for ( a = 0 ; a < len ; a++ )
        {
          *mpath++ = *path++;                            /*copy if in different pos*/
        }
      }
    }

    if ( !( *path ) )
    {
      break;
    }

    path++;
    *mpath++ = '/';   /*add separator*/
  }

  *mpath = 0; /*terminate it*/
  return 1;
} /* _f_findpath */


/****************************************************************************
 *
 * fn_getcwd
 *
 * getting a current working directory of current drive
 *
 * INPUTS
 *
 * buffer - where to store current working folder
 * maxlen - buffer length (possible size is F_MAXPATH)
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_getcwd ( char * buffer, unsigned char maxlen, char root )
{
  unsigned char  a;

  if ( !maxlen )
  {
    return F_NO_ERROR;
  }

  maxlen--;     /*need for termination*/
  if ( root && maxlen )
  {
    *buffer++ = '/';
    maxlen--;
  }

  for ( a = 0 ; a < maxlen ; a++ )
  {
    char  ch = gl_volume.cwd[a];
    buffer[a] = ch;
    if ( !ch )
    {
      break;
    }
  }

  buffer[a] = 0;    /*add terminator at the end*/

  return F_NO_ERROR;
} /* fn_getcwd */



/****************************************************************************
 *
 * fn_findfirst
 *
 * find a file(s) or directory(s) in directory
 *
 * INPUTS
 *
 * filename - filename (with or without wildcards)
 * find - where to store found file information
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_findfirst ( const char * filename, F_FIND * find )
{
  unsigned char  ret;

  if ( _f_setfsname( filename, &find->findfsname ) )
  {
    return F_ERR_INVALIDNAME;  /*invalid name*/
  }

  if ( _f_checkname( find->findfsname.filename, find->findfsname.fileext ) )
  {
    return F_ERR_INVALIDNAME;  /*invalid name, wildcard is ok*/
  }


  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( !_f_findpath( &find->findfsname, &find->pos ) )
  {
    return F_ERR_INVALIDDIR;   /*search for path*/
  }

  return fn_findnext( find );
} /* fn_findfirst */



/****************************************************************************
 *
 * fn_findnext
 *
 * find further file(s) or directory(s) in directory
 *
 * INPUTS
 *
 * find - where to store found file information (findfirst should call 1st)
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_findnext ( F_FIND * find )
{
  F_DIRENTRY   * de;
  unsigned char  a;
  unsigned char  ret;

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( !_f_findfilewc( find->findfsname.filename, find->findfsname.fileext, &find->pos, &de, 1 ) )
  {
    return F_ERR_NOTFOUND;
  }

  for ( a = 0 ; a < F_MAXNAME ; a++ )
  {
    find->name[a] = de->name[a];
  }

  for ( a = 0 ; a < F_MAXEXT ; a++ )
  {
    find->ext[a] = de->ext[a];
  }

  _f_getfilename( find->filename, (char *)de->name, (char *)de->ext );

  find->attr = de->attr;
  find->cdate = _f_getword( &de->cdate );
  find->ctime = _f_getword( &de->ctime );
  find->filesize = (long)_f_getlong( &de->filesize );
  find->cluster = _f_getdecluster( de );
  find->pos.pos++;   /*goto next position*/

  return 0;
} /* fn_findnext */



/****************************************************************************
 *
 * fn_chdir
 *
 * change current working directory
 *
 * INPUTS
 *
 * dirname - new working directory name
 *
 * RETURNS
 *
 * 0 - if successfully
 * other - if any error
 *
 ***************************************************************************/
unsigned char fn_chdir ( const char * dirname )
{
  F_POS          pos;
  F_NAME         fsname;
  unsigned char  len;
  unsigned char  a;
  unsigned char  ret;

  ret = _f_setfsname( dirname, &fsname );

  if ( ret == 1 )
  {
    return F_ERR_INVALIDNAME;             /*invalid name*/
  }

  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )
  {
    return F_ERR_INVALIDNAME;                                                    /*invalid name*/
  }

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  for ( len = 0 ; fsname.path[len] ; )
  {
    len++;
  }

  if ( len && ( ( fsname.filename[0] != 32 ) || ( fsname.fileext[0] != 32 ) ) )
  {
    fsname.path[len++] = '/';
  }

  _f_getfilename( fsname.path + len, fsname.filename, fsname.fileext );

  if ( !( _f_findpath( &fsname, &pos ) ) )
  {
    return F_ERR_NOTFOUND;
  }

  for ( a = 0 ; a < F_MAXPATH ; a++ )
  {
    gl_volume.cwd[a] = fsname.path[a];
  }

  return F_NO_ERROR;
} /* fn_chdir */



/****************************************************************************
 *
 * _f_initentry
 *
 * init directory entry, this function is called if a new entry is coming
 *
 * INPUTS
 *
 * de - directory entry which needs to be initialized
 * name - fil ename  (8)
 * ext - file extension (3)
 *
 ***************************************************************************/
static void _f_initentry ( F_DIRENTRY * de, char * name, char * ext )
{
  unsigned short  date;
  unsigned short  time;

  psp_memset( de, 0, sizeof( F_DIRENTRY ) ); /*reset all entries*/

  psp_memcpy( de->name, name, sizeof( de->name ) );
  psp_memcpy( de->ext, ext, sizeof( de->ext ) );

  f_igettimedate( &time, &date );
  _f_setword( &de->cdate, date ); /*if there is realtime clock then creation date could be set from*/
  _f_setword( &de->ctime, time ); /*if there is realtime clock then creation time could be set from*/
}





/****************************************************************************
 *
 * _f_addentry
 *
 * Add a new directory entry into driectory list
 *
 * INPUTS
 *
 * fs_name - filled structure what to add into directory list
 * pos - where directory cluster chains starts
 * pde - F_DIRENTRY pointer where to store the entry where it was added
 *
 * RETURNS
 *
 * 0 - if successfully added
 * other - if any error (see FS_xxx errorcodes)
 *
 ***************************************************************************/
unsigned char _f_addentry ( F_NAME * fsname, F_POS * pos, F_DIRENTRY * * pde )
{
  unsigned char   ret;
  unsigned short  date;
  unsigned short  time;

  if ( !fsname->filename[0] )
  {
    return F_ERR_INVALIDNAME;
  }

  if ( fsname->filename[0] == '.' )
  {
    return F_ERR_INVALIDNAME;
  }

  while ( pos->cluster < F_CLUSTER_RESERVED )
  {
    for ( ; pos->sector < pos->sectorend ; pos->sector++ )
    {
      F_DIRENTRY * de = (F_DIRENTRY *)( gl_sector + sizeof( F_DIRENTRY ) * pos->pos );

      ret = _f_readglsector( pos->sector );
      if ( ret )
      {
        return ret;
      }

      for ( ; pos->pos < F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ; de++, pos->pos++ )
      {
        if ( ( !de->name[0] ) || ( (unsigned char)( de->name[0] ) == 0xe5 ) )
        {
          _f_initentry( de, fsname->filename, fsname->fileext );
          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 ( pde )
          {
            *pde = de;
          }

          return F_NO_ERROR;
        }
      }

      pos->pos = 0;
    }

    if ( !pos->cluster )
    {
      if ( gl_volume.mediatype == F_FAT32_MEDIA )
      {
        pos->cluster = gl_volume.bootrecord.rootcluster;
      }
      else
      {
        return F_ERR_NOMOREENTRY;
      }
    }

    {
      unsigned long  cluster;

      gl_volume.fatsector = (unsigned long)-1;
      ret = _f_getclustervalue( pos->cluster, &cluster );    /*try to get next cluster*/
      if ( ret )
      {
        return ret;
      }

      if ( cluster < F_CLUSTER_RESERVED )
      {
        _f_clustertopos( cluster, pos );
      }
      else
      {
        ret = _f_alloccluster( &cluster );        /*get a new one*/
        if ( ret )
        {
          return ret;
        }

        if ( cluster < F_CLUSTER_RESERVED )
        {
          if ( gl_file.mode != F_FILE_CLOSE )
          {
            return F_ERR_NOMOREENTRY;
          }

          _f_clustertopos( cluster, &gl_file.pos );

          ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );
          if ( ret )
          {
            return ret;
          }

          ret = _f_setclustervalue( pos->cluster, gl_file.pos.cluster );
          if ( ret )
          {
            return ret;
          }

          ret = _f_writefatsector();
          if ( ret )
          {
            return ret;
          }

          gl_volume.fatsector = (unsigned long)-1;
          psp_memset( gl_sector, 0, F_SECTOR_SIZE );
          while ( gl_file.pos.sector < gl_file.pos.sectorend )
          {
            ret = _f_writeglsector( gl_file.pos.sector );
            if ( ret )
            {
              return ret;
            }

            gl_file.pos.sector++;
          }

          _f_clustertopos( gl_file.pos.cluster, pos );
        }
        else
        {
          return F_ERR_NOMOREENTRY;
        }
      }
    }
  } /* _f_addentry */

  return F_ERR_NOMOREENTRY;
}



/****************************************************************************
 *
 * fn_mkdir
 *
 * making a new directory
 *
 * INPUTS
 *
 * dirname - new directory name
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_mkdir ( const char * dirname )
{
  F_POS          posdir;
  F_POS          pos;
  F_DIRENTRY   * de;
  F_NAME         fsname;
  unsigned long  cluster;
  unsigned char  ret;

 #if F_FILE_CHANGED_EVENT
  ST_FILE_CHANGED  fc;
 #endif

  if ( _f_setfsname( dirname, &fsname ) )
  {
    return F_ERR_INVALIDNAME;                                    /*invalid name*/
  }

  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )
  {
    return F_ERR_INVALIDNAME;                                                    /*invalid name*/
  }

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( !_f_findpath( &fsname, &posdir ) )
  {
    return F_ERR_INVALIDDIR;
  }

  pos = posdir;

  if ( fsname.filename[0] == '.' )
  {
    return F_ERR_NOTFOUND;
  }

  if ( _f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )
  {
    return F_ERR_DUPLICATED;
  }

  pos = posdir;

  gl_volume.fatsector = (unsigned long)-1;
  ret = _f_alloccluster( &cluster );
  if ( ret )
  {
    return ret;
  }

  ret = _f_addentry( &fsname, &pos, &de );
  if ( ret )
  {
    return ret;
  }

  de->attr |= F_ATTR_DIR;       /*set as directory*/

 #if F_FILE_CHANGED_EVENT
  if ( f_filechangedevent )
  {
    fc.action = FACTION_ADDED;
    fc.flags = FFLAGS_DIR_NAME | FFLAGS_ATTRIBUTES | FFLAGS_SIZE | FFLAGS_LAST_WRITE;
    fc.attr = de->attr;
    fc.ctime = _f_getword( de->ctime );
    fc.cdate = _f_getword( de->cdate );
    fc.filesize = _f_getlong( de->filesize );
  }

 #endif

  if ( gl_file.mode != F_FILE_CLOSE )
  {
    return F_ERR_LOCKED;
  }

  _f_clustertopos( cluster, &gl_file.pos );
  _f_setdecluster( de, cluster ); /*new dir*/

  (void)_f_writeglsector( (unsigned long)-1 );  /*write actual directory sector*/


  de = (F_DIRENTRY *)gl_sector;

  _f_initentry( de, ".       ", "   " );
  de->attr = F_ATTR_DIR;          /*set as directory*/
  _f_setdecluster( de, cluster ); /*current*/
  de++;

  _f_initentry( de, "..      ", "   " );
  de->attr = F_ATTR_DIR;                 /*set as directory*/
  _f_setdecluster( de, posdir.cluster ); /*parent*/
  de++;

  psp_memset( de, 0, ( F_SECTOR_SIZE - 2 * sizeof( F_DIRENTRY ) ) );


  ret = _f_writeglsector( gl_file.pos.sector );
  if ( ret )
  {
    return ret;
  }

  gl_file.pos.sector++;
  psp_memset( gl_sector, 0, ( 2 * sizeof( F_DIRENTRY ) ) );
  while ( gl_file.pos.sector < gl_file.pos.sectorend )
  {
    ret = _f_writeglsector( gl_file.pos.sector );
    if ( ret )
    {
      return ret;
    }

    gl_file.pos.sector++;
  }

  gl_volume.fatsector = (unsigned long)-1;
  ret = _f_setclustervalue( gl_file.pos.cluster, F_CLUSTER_LAST );
  if ( ret )
  {
    return ret;
  }

  ret = _f_writefatsector();
 #if F_FILE_CHANGED_EVENT
  if ( f_filechangedevent && !ret )
  {
    fc.action = FACTION_ADDED;
    fc.flags = FFLAGS_DIR_NAME;

    if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )
    {
      f_filechangedevent( &fc );
    }
  }

 #endif

  return ret;
} /* fn_mkdir */



/****************************************************************************
 *
 * fn_rmdir
 *
 * Remove directory, only could be removed if empty
 *
 * INPUTS
 *
 * dirname - which directory needed to be removed
 *
 * RETURNS
 *
 * error code or zero if successful
 *
 ***************************************************************************/
unsigned char fn_rmdir ( const char * dirname )
{
  unsigned char  ret;
  F_POS          pos;
  F_DIRENTRY   * de;
  F_NAME         fsname;
  unsigned long  dirsector;
  unsigned char  a;

  if ( _f_setfsname( dirname, &fsname ) )
  {
    return F_ERR_INVALIDNAME;                                    /*invalid name*/
  }

  if ( _f_checknamewc( fsname.filename, fsname.fileext ) )
  {
    return F_ERR_INVALIDNAME;                                                    /*invalid name*/
  }

  if ( fsname.filename[0] == '.' )
  {
    return F_ERR_NOTFOUND;
  }

  ret = _f_getvolume();
  if ( ret )
  {
    return ret;
  }

  if ( !( _f_findpath( &fsname, &pos ) ) )
  {
    return F_ERR_INVALIDDIR;
  }

  if ( !_f_findfilewc( fsname.filename, fsname.fileext, &pos, &de, 0 ) )
  {
    return F_ERR_NOTFOUND;
  }

  if ( !( de->attr & F_ATTR_DIR ) )
  {
    return F_ERR_INVALIDDIR;                                       /*not a directory*/
  }

  dirsector = gl_volume.actsector;

  if ( gl_file.mode != F_FILE_CLOSE )
  {
    return F_ERR_LOCKED;
  }

  _f_clustertopos( _f_getdecluster( de ), &gl_file.pos );

  for ( ; ; )
  {
    F_DIRENTRY * de2;
    char         ch = 0;

    ret = _f_getcurrsector();
    if ( ret == F_ERR_EOF )
    {
      break;
    }

    if ( ret )
    {
      return ret;
    }

    de2 = (F_DIRENTRY *)gl_sector;
    for ( a = 0 ; a < ( F_SECTOR_SIZE / sizeof( F_DIRENTRY ) ) ; a++, de2++ )
    {
      ch = de2->name[0];
      if ( !ch )
      {
        break;
      }

      if ( (unsigned char)ch == 0xe5 )
      {
        continue;
      }

      if ( ch == '.' )
      {
        continue;
      }

      return F_ERR_NOTEMPTY;       /*something is there*/
    }

    if ( !ch )
    {
      break;
    }

    gl_file.pos.sector++;
  }

  ret = _f_readglsector( dirsector );
  if ( ret )
  {
    return ret;
  }

  de->name[0] = (unsigned char)0xe5;

  ret = _f_writeglsector( dirsector );
  if ( ret )
  {
    return ret;
  }

  gl_volume.fatsector = (unsigned long)-1;
  ret = _f_removechain( _f_getdecluster( de ) );
 #if F_FILE_CHANGED_EVENT
  if ( f_filechangedevent && !ret )
  {
    ST_FILE_CHANGED  fc;
    fc.action = FACTION_REMOVED;
    fc.flags = FFLAGS_DIR_NAME;

    if ( !_f_createfullname( fc.filename, sizeof( fc.filename ), fsname.path, fsname.filename, fsname.fileext ) )
    {
      f_filechangedevent( &fc );
    }
  }

 #endif
  return ret;
} /* fn_rmdir */


