📄 fdi_file.c
字号:
/*
* 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 + -