rtfsprofatfilesystem/rtfscommon/source/apiunlink.c
2015-10-12 08:29:49 -04:00

134 lines
3.8 KiB
C

/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 1987-2007
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* APIUNLINK.C - Contains user api level file IO source code.
PC_UNLINK - Delete a file.
*/
#include "rtfs.h"
#if (!RTFS_CFG_READONLY) /* Excluded from build if read only */
/****************************************************************************
PC_UNLINK - Delete a file.
Description
Delete the file in name. Fail if not a simple file,if it is open,
does not exist or is read only.
Returns
Returns TRUE if it successfully deleted the file.
errno is set to one of the following
0 - No error
PEINVALIDDRIVEID- Drive component is invalid
PEINVALIDPATH - Path specified badly formed.
PENOENT - Can't find file to delete
PEACCESS - File in use, is read only or is not a simple file.
An ERTFS system error
***************************************************************************/
/* Delete a file */
#if (INCLUDE_CS_UNICODE)
BOOLEAN pc_unlink_cs(byte *name, int use_charset)
#else
BOOLEAN pc_unlink(byte *name)
#endif
{
DROBJ *pobj;
DROBJ *parent_obj;
BOOLEAN ret_val;
DDRIVE *pdrive;
byte *path;
byte *filename;
byte fileext[4];
int driveno;
int p_errno;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
ret_val = FALSE;
parent_obj = 0;
pobj = 0;
p_errno = 0;
rtfs_clear_errno(); /* pc_unlink: clear error status */
/* Get the drive and make sure it is mounted */
driveno = check_drive_name_mount(name, CS_CHARSET_ARGS);
if (driveno < 0)
{
/* errno was set by check_drive */
return(FALSE);
}
pdrive = pc_drno2dr(driveno);
/* Allocate scratch buffers in the DRIVE structure. */
if (!pc_alloc_path_buffers(pdrive))
goto errex;
path = pdrive->pathname_buffer;
filename = pdrive->filename_buffer;
/* Get out the filename and d:parent */
if (!pc_parsepath(path, filename,fileext,name, CS_CHARSET_ARGS))
{
p_errno = PEINVALIDPATH;
goto errex;
}
/* Find the parent and make sure it is a directory */
parent_obj = pc_fndnode(path, CS_CHARSET_ARGS);
if (!parent_obj)
goto errex; /* pc_fndnode set errno */
if (!pc_isadir(parent_obj) || pc_isavol(parent_obj))
{
p_errno = PEACCES;
goto errex;
}
/* Find the file */
pobj = pc_get_inode(0, parent_obj, filename, (byte*)fileext, GET_INODE_MATCH, CS_CHARSET_ARGS);
/* if pc_get_inode() fails it sets errno to PENOENT or to an internal or IO error status */
if (pobj)
{
if (pc_isroot(pobj) || (pobj->finode->opencount > 1) ||
(pobj->finode->fattribute&(ARDONLY|AVOLUME)))
{
access_error:
p_errno = PEACCES;
ret_val = FALSE;
goto errex;
}
if (pobj->finode->fattribute&ADIRENT)
{
goto access_error;
}
else
{ /* pc_rmnode sets errno */
ret_val = pc_rmnode(pobj);
}
}
errex:
pc_release_path_buffers(pdrive);
if (pobj)
pc_freeobj(pobj);
if (parent_obj)
{
pc_freeobj(parent_obj);
}
/* Set errno if we have one and not set by lower level already */
if (ret_val)
rtfs_clear_errno();
else if ((p_errno) && !get_errno())
rtfs_set_errno(p_errno, __FILE__, __LINE__);
if (!release_drive_mount_write(driveno))/* Release lock, unmount if aborted */
ret_val = FALSE;
return(ret_val);
}
#endif /* Exclude from build if read only */