diff options
Diffstat (limited to 'lib/bkisofs/bkDelete.c')
-rw-r--r-- | lib/bkisofs/bkDelete.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/lib/bkisofs/bkDelete.c b/lib/bkisofs/bkDelete.c new file mode 100644 index 0000000..e8ab0b0 --- /dev/null +++ b/lib/bkisofs/bkDelete.c @@ -0,0 +1,151 @@ +/******************************* LICENCE ************************************** +* Any code in this file may be redistributed or modified under the terms of +* the GNU General Public Licence as published by the Free Software +* Foundation; version 2 of the licence. +****************************** END LICENCE ***********************************/ + +/****************************************************************************** +* Author: +* Andrew Smith, http://littlesvr.ca/misc/contactandrew.php +* +* Contributors: +* +******************************************************************************/ + +#include <strings.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <stdio.h> + +#include "bk.h" +#include "bkInternal.h" +#include "bkPath.h" +#include "bkError.h" +#include "bkDelete.h" + +/******************************************************************************* +* bk_delete_boot_record() +* deletes whatever reference to a boot record volinfo has +* */ +void bk_delete_boot_record(VolInfo* volInfo) +{ + volInfo->bootMediaType = BOOT_MEDIA_NONE; + + if(volInfo->bootRecordPathAndName != NULL) + { + free(volInfo->bootRecordPathAndName); + volInfo->bootRecordPathAndName = NULL; + } +} + +int bk_delete(VolInfo* volInfo, const char* pathAndName) +{ + int rc; + NewPath path; + bool dirFound; + BkDir* parentDir; + + rc = makeNewPathFromString(pathAndName, &path); + if(rc <= 0) + { + freePathContents(&path); + return rc; + } + + if(path.numChildren == 0) + { + freePathContents(&path); + return BKERROR_DELETE_ROOT; + } + + /* i want the parent directory */ + path.numChildren--; + dirFound = findDirByNewPath(&path, &(volInfo->dirTree), &parentDir); + path.numChildren++; + if(!dirFound) + { + freePathContents(&path); + return BKERROR_DIR_NOT_FOUND_ON_IMAGE; + } + + deleteNode(volInfo, parentDir, path.children[path.numChildren - 1]); + + freePathContents(&path); + + return 1; +} + +void deleteNode(VolInfo* volInfo, BkDir* parentDir, char* nodeToDeleteName) +{ + BkFileBase** childPtr; + BkFileBase* nodeToFree; + + childPtr = &(parentDir->children); + while(*childPtr != NULL) + { + if( strcmp((*childPtr)->name, nodeToDeleteName) == 0 ) + { + nodeToFree = *childPtr; + + *childPtr = (*childPtr)->next; + + if( IS_DIR(nodeToFree->posixFileMode) ) + { + deleteDirContents(volInfo, BK_DIR_PTR(nodeToFree)); + } + else if ( IS_REG_FILE(nodeToFree->posixFileMode) ) + { + deleteRegFileContents(volInfo, BK_FILE_PTR(nodeToFree)); + } + /* else the free below will be enough */ + + free(nodeToFree); + + break; + } + + childPtr = &((*childPtr)->next); + } +} + +/******************************************************************************* +* deleteDirContents() +* deletes all the contents of a directory +* recursive +* */ +void deleteDirContents(VolInfo* volInfo, BkDir* dir) +{ + BkFileBase* child; + BkFileBase* nextChild; + + child = dir->children; + while(child != NULL) + { + nextChild = child->next; + + deleteNode(volInfo, dir, child->name); + + child = nextChild; + } +} + +/* delete the contents of the BkFile structure, not the actual file contents */ +void deleteRegFileContents(VolInfo* volInfo, BkFile* file) +{ + if( file->onImage ) + free( file->pathAndName ); + + /* check whether file is being used as a boot record */ + if(volInfo->bootMediaType != BOOT_MEDIA_NONE && + volInfo->bootMediaType == BOOT_MEDIA_NO_EMULATION) + { + if(volInfo->bootRecordIsVisible && + volInfo->bootRecordOnImage == file) + { + /* and stop using it. perhaps insert a hook here one day to + * let the user know the boot record has been/will be deleted */ + bk_delete_boot_record(volInfo); + } + } +} |