⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdi_file.c

📁 Flash file system
💻 C
📖 第 1 页 / 共 5 页
字号:

/*
 * definition for SRAM File Lookup Table
 */
typedef struct tag_file_lookup
{
   char     file_name[FILE_NAME_SIZE + 1];  /* filename plus null char */
   FILE_ID  file_info_id;                   /* file info param id */
} FILE_LOOKUP;

static FILE_LOOKUP FileLookupTable[NUM_FILES]; /* SRAM File Lookup Table */

static WORD FLTIndex;         /* index into FLT of previous match */

static char FLTSearchName[FILE_NAME_SIZE + 1]; /* search name plus null char */

static WORD FLTSearchIndex;   /* index into FLT used by FDI_findfirst and
                               * FDI_findnext */

static WORD FileInitComplete = FALSE; /* flag to confirm file init
                                       * function was called */

/* invalid filename characters array
 * must end with '\0' character as array end marker
 */
static const char InvalidFilenameChars[] = {'?', '*', FILE_EOS};

/* the following aren't defined as static since they are used for testing
 * purposes.
 */
SEM_MTX_ID FileAPIMutexSemaphore = SEM_NULL;  /* File Manager API semaphore */

WORD EnableDataStreaming;  /* set during initialization for data streaming */

/* ### Local Function Declarations
 * ################################# */

static ERR_CODE FileNameSearch(const char *, WORD_PTR, FILE_INFO *);
static ERR_CODE FileDelete(FILE_ID, FILE_ID, int);
static ERR_CODE DeletePLRFile(FILE_ID, FILE_INFO *);
static ERR_CODE RestoreFile(FILE_ID, FILE_INFO *);
static DWORD GetNextFreeFLTIndex(DWORD);
static int FileNameMatch(const char *, const char *);
static int FileNameValid(const char *);
static int FilesOnFlashValid(void);

/* please replace these functions with something appropriate for your OS */
static int FileGetTime(void);
static int FileGetDate(void);
static int FileGetGID(void);
static int FileGetUID(void);

/* ### Global Declarations
 * ################################# */

ERR_CODE FDI_errno; /* track file system errors not associated
                     * with an open file identifier */


/*############################################################################
 *### FDI_fopen
 *###
 *### DESCRIPTION:
 *###    The function FDI_fopen takes as arguments a file name and a mode;
 *###    each is specified as a character string.  The file name is used in
 *###    an implementation-specified matter to open or create a file and
 *###    associate it with a stream.  Returns the StreamInfoTable index used
 *###    for the opened file.
 *###
 *### USAGE:
 *###    file_identifier = FDI_fopen(filename_ptr, wb);
 *###
 *### PARAMETERS:
 *###
 *### INPUTS:
 *###  filename_ptr         const character string for file name
 *###  mode                 const character string for type specification;
 *###                       modes supported: rb, wb, ab, rb+, wb+, ab+
 *### OUTPUTS:
 *###
 *### RETURNS:
 *###  Returns the StreamInfoTable index used for the opened file.
 *###  If an error is detected, FDI_fopen returns 0.
 *###*/
FILE_ID
FDI_fopen(const char *filename_ptr, const char *mode)
{
   COMMAND_CONTROL cmd_cntrl;          /* define command control structure for
                                        * FDI API's */
   char            open_mode[8];       /* copy of input parameter lower case */
   WORD            index_src = 0;      /* character array index */
   WORD            index_dest = 0;     /* character array index */
   ERR_CODE        status = ERR_NONE;  /* define ERROR_CODE variable */
   BYTE            fdi_status;         /* returned by FDI_Status */
   DWORD           index1;             /* loop control variable */
   FILE_ID         return_index;       /* local to hold the table index used */
   STREAM_INFO     *stream_info_ptr;   /* pointer to table entry used */
   WORD            permissions =       /* default rwx for usr, grp and wld */
                                 S_IRWXU | S_IRWXG | S_IRWXW;

   /* make sure file init function has been called */
   if (FileInitComplete == FALSE)
   {
      FDI_errno = ERR_INIT;
      return FILE_NULL;
   }

   /* make sure filename_ptr is valid */
   if (FileNameValid(filename_ptr) == FALSE)
   {
      FDI_errno = ERR_PARAM;
      return FILE_NULL;
   }

   /* lock the File Manager API semaphore */
   SEM_MTX_WAIT(FileAPIMutexSemaphore);

   /* test for an open file and return error if true
    * look for an existing file already in StreamInfoTable
    */
   for (index1 = 1; index1 <= NUM_OPEN_FILES; index1++)
   {
      if (FileNameMatch(filename_ptr,
                        StreamInfoTable[index1].open_file_info.file_name))
      {
         FDI_errno = ERR_OPEN;

         /* unlock the File Manager API semaphore */
         SEM_MTX_POST(FileAPIMutexSemaphore);

         return FILE_NULL;
      }
   }

   /* assign a StreamInfoTable entry to utilize for the file stream */
   for (index1 = 1; index1 <= NUM_OPEN_FILES; index1++)
   {
      if (StreamInfoTable[index1].mode_flag == MODE_INVALID)
      {
         break;
      }
   }
   if (index1 > NUM_OPEN_FILES)
   {
      FDI_errno = ERR_MAX_OPEN;

      /* unlock the File Manager API semaphore */
      SEM_MTX_POST(FileAPIMutexSemaphore);

      return FILE_NULL;
   }

   /* set assigned table entry to a pointer to STREAM_INFO */
   stream_info_ptr = &(StreamInfoTable[index1]);

   /* save index used to return to user */
   return_index = index1;

   *open_mode = FILE_EOS;
   /*
    * copy parameter mode to a local copy open_mode converting uppercase
    * to lower case and ignoring white spaces
    */
   while ((mode[index_src] != FILE_EOS) &&
          (index_src < (int)(sizeof(open_mode) - 1)))
   {
      /* convert uppercase characters to lower case */
      if (isupper((int)mode[index_src]))
      {
         open_mode[index_dest++] = tolower((int)mode[index_src]);
      }
      else if (mode[index_src] != '\t' && mode[index_src] != ' ')
      {
         open_mode[index_dest++] = mode[index_src];
      }
      index_src++;
   }
   open_mode[index_dest] = FILE_EOS;       /* close the string */

   /*
    * set stream info field mode_flag based on input parameter mode for
    *    supported invoking modes
    */
   switch (open_mode[0])
   {
      case 'r':
         stream_info_ptr->mode_flag |= (FILE_MUST_EXIST | READ_PERMITTED);
         break;
      case 'w':
         stream_info_ptr->mode_flag |= (FILE_CONTENT_LOST | WRITE_PERMITTED);
         break;
      case 'a':
         stream_info_ptr->mode_flag |= (WRITE_END_ONLY | WRITE_PERMITTED);
         break;
      default:
         break;
   }
   /*
    * IF mode_flag was not modified in the previous switch OR the
    * second character in mode is not a 'b'
    */
   if ((stream_info_ptr->mode_flag == MODE_INVALID) || (open_mode[1] != 'b'))
   {
      INIT_STREAM_INFO(stream_info_ptr);
      FDI_errno = ERR_PARAM;

      /* unlock the File Manager API semaphore */
      SEM_MTX_POST(FileAPIMutexSemaphore);

      return FILE_NULL;
   }

   if (open_mode[2] == '+')
   {
      stream_info_ptr->mode_flag |= (READ_PERMITTED | WRITE_PERMITTED);
   }
   else if (open_mode[2] != FILE_EOS)      /* error unknown mode */
   {
      INIT_STREAM_INFO(stream_info_ptr);
      FDI_errno = ERR_PARAM;

      /* unlock the File Manager API semaphore */
      SEM_MTX_POST(FileAPIMutexSemaphore);

      return FILE_NULL;
   }

   /*
    * make a copy of the string pointed to by the parameter filename_ptr
    * in STREAM_INFO structure
    */
   if (strncpy(stream_info_ptr->open_file_info.file_name, filename_ptr,
               (FILE_NAME_SIZE + 1)) == NULL)
   {
      /* clear STREAM_INFO of all the file's information */
      INIT_STREAM_INFO(stream_info_ptr);
      FDI_errno = ERR_PARAM;

      /* unlock the File Manager API semaphore */
      SEM_MTX_POST(FileAPIMutexSemaphore);

      return FILE_NULL;
   }

   /* if the file name matches the search info file name */
   if (!strcmp(stream_info_ptr->open_file_info.file_name,
               SearchInfoPtr->open_file_info.file_name))
   {
      /* copy the search info file information */
      stream_info_ptr->open_file_info = SearchInfoPtr->open_file_info;

      /* set matching files flag true */
      stream_info_ptr->file_info_id = SearchInfoPtr->file_info_id;

      /* update FLTIndex with the FLTSearchIndex from the search */
      FLTIndex = FLTSearchIndex;
   }
   else /* else there is no file info in search info or there was no match */
   {
      /* look for an existing file matching STREAM_INFO field file_name
       * FLTIndex is set in FileNameSearch if the file is found */
      status = FileNameSearch(stream_info_ptr->open_file_info.file_name,
                              &(stream_info_ptr->file_info_id),
                              &(stream_info_ptr->open_file_info));

      /* return an error if the file did not exist and FILE_MUST_EXIST */
      if ((status == ERR_NOTEXISTS) &&
          (stream_info_ptr->mode_flag & FILE_MUST_EXIST))
      {
         /* clear STREAM_INFO of all the file's information */
         INIT_STREAM_INFO(stream_info_ptr);
         FDI_errno = status;

         /* unlock the File Manager API semaphore */
         SEM_MTX_POST(FileAPIMutexSemaphore);

         return FILE_NULL;
      }
   }
   /*
    * if the file exists and was opened with write mode, then check
    * the file permissions for write access.
    */
   if ((status == ERR_NONE) &&
       (stream_info_ptr->mode_flag & WRITE_PERMITTED) != 0)
   {
      /* check file for correct permissions */
      if (((getuid() == stream_info_ptr->open_file_info.owner_id) &&
           ((stream_info_ptr->open_file_info.permissions & S_IWUSR) !=
            S_IWUSR)) ||
          ((getuid() != stream_info_ptr->open_file_info.owner_id) &&
           (getgid() == stream_info_ptr->open_file_info.group_id) &&
           ((stream_info_ptr->open_file_info.permissions & S_IWGRP) !=
            S_IWGRP)) ||
          ((getuid() != stream_info_ptr->open_file_info.owner_id) &&
           (getgid() != stream_info_ptr->open_file_info.group_id) &&
           ((stream_info_ptr->open_file_info.permissions & S_IWWLD) !=
           S_IWWLD)))
      {
         /* clear STREAM_INFO of all the file's information */
         INIT_STREAM_INFO(stream_info_ptr);
         FDI_errno = ERR_ACCESS;

         /* unlock the File Manager API semaphore */
         SEM_MTX_POST(FileAPIMutexSemaphore);

         return FILE_NULL;
      }
   }
   /*
    * if the file exists and was opened with read mode, then check
    * the file permissions for read access.
    */
   if ((status == ERR_NONE) &&
       (stream_info_ptr->mode_flag & READ_PERMITTED) != 0)
   {
      /* check file for correct permissions */
      if (((getuid() == stream_info_ptr->open_file_info.owner_id) &&
           ((stream_info_ptr->open_file_info.permissions & S_IRUSR) !=
            S_IRUSR)) ||
          ((getuid() != stream_info_ptr->open_file_info.owner_id) &&
           (getgid() == stream_info_ptr->open_file_info.group_id) &&
           ((stream_info_ptr->open_file_info.permissions & S_IRGRP) !=
            S_IRGRP)) ||
          ((getuid() != stream_info_ptr->open_file_info.owner_id) &&
           (getgid() != stream_info_ptr->open_file_info.group_id) &&
           ((stream_info_ptr->open_file_info.permissions & S_IRWLD) !=
           S_IRWLD)))
      {
         /* clear STREAM_INFO of all the file's information */
         INIT_STREAM_INFO(stream_info_ptr);
         FDI_errno = ERR_ACCESS;

         /* unlock the File Manager API semaphore */
         SEM_MTX_POST(FileAPIMutexSemaphore);

         return FILE_NULL;
      }
   }
   /*
    * if the file exists and was opened with a 'w' mode, then the current
    * file contents is lost and the file is deleted.
    */
   if ((status == ERR_NONE) &&
       (stream_info_ptr->mode_flag & FILE_CONTENT_LOST))
   {
      /* save permissions for the newly created file */
      permissions = stream_info_ptr->open_file_info.permissions;

      status = FileDelete(stream_info_ptr->file_info_id,
                          stream_info_ptr->open_file_info.data_id, TRUE);
      if (status != ERR_NONE)
      {
         /* clear STREAM_INFO of all the file's information */
         INIT_STREAM_INFO(stream_info_ptr);
         FDI_errno = status;

         /* unlock the File Manager API semaphore */
         SEM_MTX_POST(FileAPIMutexSemaphore);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -