1 /******************************* LICENCE **************************************
2 * Any code in this file may be redistributed or modified under the terms of
3 * the GNU General Public Licence as published by the Free Software
4 * Foundation; version 2 of the licence.
5 ****************************** END LICENCE ***********************************/
6 
7 /******************************************************************************
8 * Author:
9 * Andrew Smith, http://littlesvr.ca/misc/contactandrew.php
10 *
11 * Contributors:
12 *
13 ******************************************************************************/
14 
15 #include <strings.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/types.h>
19 #include <stdio.h>
20 
21 #include "bk.h"
22 #include "bkInternal.h"
23 #include "bkPath.h"
24 #include "bkError.h"
25 #include "bkDelete.h"
26 
27 /*******************************************************************************
28 * bk_delete_boot_record()
29 * deletes whatever reference to a boot record volinfo has
30 * */
bk_delete_boot_record(VolInfo * volInfo)31 void bk_delete_boot_record(VolInfo* volInfo)
32 {
33     volInfo->bootMediaType = BOOT_MEDIA_NONE;
34 
35     if(volInfo->bootRecordPathAndName != NULL)
36     {
37         free(volInfo->bootRecordPathAndName);
38         volInfo->bootRecordPathAndName = NULL;
39     }
40 }
41 
bk_delete(VolInfo * volInfo,const char * pathAndName)42 int bk_delete(VolInfo* volInfo, const char* pathAndName)
43 {
44     int rc;
45     NewPath path;
46     bool dirFound;
47     BkDir* parentDir;
48 
49     rc = makeNewPathFromString(pathAndName, &path);
50     if(rc <= 0)
51     {
52         freePathContents(&path);
53         return rc;
54     }
55 
56     if(path.numChildren == 0)
57     {
58         freePathContents(&path);
59         return BKERROR_DELETE_ROOT;
60     }
61 
62     /* i want the parent directory */
63     path.numChildren--;
64     dirFound = findDirByNewPath(&path, &(volInfo->dirTree), &parentDir);
65     path.numChildren++;
66     if(!dirFound)
67     {
68         freePathContents(&path);
69         return BKERROR_DIR_NOT_FOUND_ON_IMAGE;
70     }
71 
72     deleteNode(volInfo, parentDir, path.children[path.numChildren - 1]);
73 
74     freePathContents(&path);
75 
76     return 1;
77 }
78 
deleteNode(VolInfo * volInfo,BkDir * parentDir,char * nodeToDeleteName)79 void deleteNode(VolInfo* volInfo, BkDir* parentDir, char* nodeToDeleteName)
80 {
81     BkFileBase** childPtr;
82     BkFileBase* nodeToFree;
83 
84     childPtr = &(parentDir->children);
85     while(*childPtr != NULL)
86     {
87         if( strcmp((*childPtr)->name, nodeToDeleteName) == 0 )
88         {
89             nodeToFree = *childPtr;
90 
91             *childPtr = (*childPtr)->next;
92 
93             if( IS_DIR(nodeToFree->posixFileMode) )
94             {
95                 deleteDirContents(volInfo, BK_DIR_PTR(nodeToFree));
96             }
97             else if ( IS_REG_FILE(nodeToFree->posixFileMode) )
98             {
99                 deleteRegFileContents(volInfo, BK_FILE_PTR(nodeToFree));
100             }
101             /* else the free below will be enough */
102 
103             free(nodeToFree);
104 
105             break;
106         }
107 
108         childPtr = &((*childPtr)->next);
109     }
110 }
111 
112 /*******************************************************************************
113 * deleteDirContents()
114 * deletes all the contents of a directory
115 * recursive
116 * */
deleteDirContents(VolInfo * volInfo,BkDir * dir)117 void deleteDirContents(VolInfo* volInfo, BkDir* dir)
118 {
119     BkFileBase* child;
120     BkFileBase* nextChild;
121 
122     child = dir->children;
123     while(child != NULL)
124     {
125         nextChild = child->next;
126 
127         deleteNode(volInfo, dir, child->name);
128 
129         child = nextChild;
130     }
131 }
132 
133 /* delete the contents of the BkFile structure, not the actual file contents */
deleteRegFileContents(VolInfo * volInfo,BkFile * file)134 void deleteRegFileContents(VolInfo* volInfo, BkFile* file)
135 {
136     if( file->onImage )
137         free( file->pathAndName );
138 
139     /* check whether file is being used as a boot record */
140     if(volInfo->bootMediaType != BOOT_MEDIA_NONE &&
141        volInfo->bootMediaType == BOOT_MEDIA_NO_EMULATION)
142     {
143         if(volInfo->bootRecordIsVisible &&
144            volInfo->bootRecordOnImage == file)
145         {
146             /* and stop using it. perhaps insert a hook here one day to
147             * let the user know the boot record has been/will be deleted */
148             bk_delete_boot_record(volInfo);
149         }
150     }
151 }
152