twl_wrapsdk/build/libraries/fatfs/ARM7/apideltr.c
Shirait 4fe5688d29 add SD driver and FATFS library (tentative)
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@96 4ee2a332-4b2b-5046-8439-1ba90f034370
2007-05-30 10:22:28 +00:00

250 lines
8.1 KiB
C

/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 1987-2003
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* APIDELTR.C - Contains user api level source code.
The following routines are included:
pc_deltree - Delete an entire directory tree.
*/
#include <rtfs.h>
/****************************************************************************
PC_DELTREE - Delete a directory tree.
Description
Delete the directory specified in name, all subdirectories of that
directory, and all files contained therein. Fail if name is not a
directory, or is read only.
Returns
Returns TRUE if the directory was successfully removed.
errno will be set to one of these values
0 - No error
PEINVALIDDRIVEID- Drive component of path is invalid
PEINVALIDPATH - Path specified by name is badly formed.
PENOENT - Can't find path specified by name.
PEACCES - Directory or one of its subdirectories is read only or
in use.
An ERTFS system error
*****************************************************************************/
/* Remove a directory */
BOOLEAN pc_deltree(byte *name) /*__apifn__*/
{
DROBJ *parent_obj;
DROBJ *pobj;
DROBJ *pdotdot;
DROBJ *pchild;
BOOLEAN ret_val;
DDRIVE *pdrive;
byte *path;
byte *filename;
byte fileext[4];
int driveno;
int p_errno;
int dir_depth;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
parent_obj = 0;
pchild = 0;
pobj = 0;
pdotdot = 0;
ret_val = FALSE;
dir_depth = 1;
p_errno = 0;
rtfs_set_errno(0); /* pc_deltree: clear error status */
/* Get the drive and make sure it is mounted */
driveno = check_drive_name_mount(name);
if (driveno < 0)
{ /* pc_deltree: errno was by check_drive */
return(FALSE);
}
pdrive = pc_drno2dr(driveno);
/* Use the buffers in the DRIVE structure. Access is locked via semaphore */
path = (byte *)&(pdrive->pathname_buffer[0]);
filename = (byte *)&(pdrive->filename_buffer[0]);
/* Get out the filename and d:parent */
if (!pc_parsepath(path,filename,fileext,name))
{
p_errno = PEINVALIDPATH;
goto errex;
}
/* Find the parent and make sure it is a directory \ */
parent_obj = pc_fndnode(path);
if (!parent_obj)
goto errex; /* pc_fndnode set errno */
if (!pc_isadir(parent_obj) || pc_isavol(parent_obj))
{
p_errno = PENOENT;
goto errex;
}
/* Find the file and init the structure */
pobj = pc_get_inode(0, parent_obj, filename, (byte*)fileext, GET_INODE_MATCH);
if (!pobj)
goto errex; /* pc_get_inode set errno */
if ( !pc_isadir(pobj) || (pobj->finode->opencount > 1) ||
(pobj->finode->fattribute & ARDONLY ))
{
p_errno = PEACCES;
goto errex;
}
/* Search through the directory. look at all files */
/* Call pc_get_inode with 0 to give us an obj */
while (dir_depth > 0)
{
if (pchild)
pc_freeobj(pchild);
pchild = pc_get_inode(0, pobj, 0 , 0, GET_INODE_STAR);
if (pdotdot) {
pc_freeobj(pdotdot);
pdotdot = 0;
}
if (pchild) do
{
/* delete all nodes which are not subdirs;
step into all subdirs and destroy their contents. */
if (!(pc_isdot(pchild->finode->fname, pchild->finode->fext) ) )
{
if (!(pc_isdotdot(pchild->finode->fname, pchild->finode->fext) ) )
{
if (pc_isadir(pchild))
{
if ( (pchild->finode->opencount > 1) ||
(pchild->finode->fattribute&ARDONLY) )
{
p_errno = PEACCES;
ret_val = FALSE;
goto errex;
}
dir_depth++;
pc_freeobj(pobj);
pobj = pchild; /* enter first subdir */
pchild = 0;
goto start_over;
}
else
{
/* Be sure it is not the root. Since the root is an abstraction
we can not delete it plus Check access permissions */
if ( pc_isroot(pchild) || (pchild->finode->opencount > 1) ||
(pchild->finode->fattribute&(ARDONLY|AVOLUME|ADIRENT)))
{
p_errno = PEACCES;
ret_val = FALSE;
goto errex;
}
else
{
/* Remove the file */
/* calculate max number of clusters to release.
Add bytespcluster-1 in case we are not on a cluster boundary */
ret_val = pc_rmnode(pchild);
if (!ret_val)
goto errex; /* pc_rmnode sets errno */
goto start_over;
}
}
}
else
{
if (pdotdot)
pc_freeobj(pdotdot);
pdotdot = pc_get_mom(pchild);
}
}
}
while (pc_get_inode(pchild, pobj, 0 , 0, GET_INODE_STAR));
if (get_errno() != PENOENT)
goto errex; /* pc_get_inode set errno */
/* dir empty; step out and delete */
if (pobj) {
pc_freeobj(pobj);
pobj = 0;
}
if (pchild) {
pc_freeobj(pchild);
pchild = 0;
}
dir_depth--;
if (dir_depth > 0)
{
if (!pdotdot)
{
p_errno = PEINVALIDCLUSTER;
goto errex;
}
pchild = pc_get_inode(0, pdotdot, 0 , 0, GET_INODE_STAR);
if (pchild)
{
do
{
if (!(pc_isdot(pchild->finode->fname, pchild->finode->fext) ) )
{
if (!(pc_isdotdot(pchild->finode->fname, pchild->finode->fext) ) )
{
ret_val = pc_rmnode(pchild); /* remove the directory */
if (!ret_val)
goto errex; /* pc_mnode set errno */
break;
}
}
} while (pc_get_inode(pchild, pdotdot, 0, 0, GET_INODE_STAR));
}
else
{
if (get_errno() != PENOENT)
goto errex; /* pc_get_inode set errno */
}
pobj = pdotdot;
pdotdot = 0;
}
else
{
pobj = pc_get_inode(0, parent_obj, filename, (byte*)fileext, GET_INODE_MATCH);
if (!pobj)
goto errex; /* pc_mnode set errno */
ret_val = pc_rmnode(pobj); /* Remove the directory */
if (!ret_val)
goto errex; /* pc_mnode set errno */
}
start_over:
;
}
errex:
if (pdotdot)
pc_freeobj(pdotdot);
if (pchild)
pc_freeobj(pchild);
if (pobj)
pc_freeobj(pobj);
if (parent_obj)
pc_freeobj(parent_obj);
if (p_errno)
rtfs_set_errno(p_errno);
if (!release_drive_mount_write(driveno))/* Release lock, unmount if aborted */
ret_val = FALSE;
return(ret_val);
}