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 <string.h>
17 #include <stdio.h>
18 
19 #include "bk.h"
20 #include "bkSet.h"
21 #include "bkDelete.h"
22 #include "bkPath.h"
23 #include "bkError.h"
24 #include "bkIoWrappers.h"
25 
bk_cancel_operation(VolInfo * volInfo)26 void bk_cancel_operation(VolInfo* volInfo)
27 {
28     volInfo->stopOperation = true;
29 }
30 
31 /*******************************************************************************
32 * bk_destroy_vol_info()
33 * Frees any memory refered to by volinfo.
34 * If an image was open for reading closes it.
35 * Does not reinitialize the structure.
36 * */
bk_destroy_vol_info(VolInfo * volInfo)37 void bk_destroy_vol_info(VolInfo* volInfo)
38 {
39     BkHardLink* currentLink;
40     BkHardLink* nextLink;
41 
42     deleteDirContents(volInfo, &(volInfo->dirTree));
43 
44     if(volInfo->bootRecordPathAndName != NULL)
45         free(volInfo->bootRecordPathAndName);
46 
47     if(volInfo->imageForReading > 0)
48         bkClose(volInfo->imageForReading);
49 
50     currentLink = volInfo->fileLocations;
51     while(currentLink != NULL)
52     {
53         nextLink = currentLink->next;
54         free(currentLink);
55         currentLink = nextLink;
56     }
57 }
58 
59 /*******************************************************************************
60 * bk_init_vol_info()
61 *
62 * */
bk_init_vol_info(VolInfo * volInfo,bool scanForDuplicateFiles)63 int bk_init_vol_info(VolInfo* volInfo, bool scanForDuplicateFiles)
64 {
65     memset(volInfo, 0, sizeof(VolInfo));
66 
67     volInfo->dirTree.base.posixFileMode = 040755;
68     volInfo->posixFileDefaults = 0100644;
69     volInfo->posixDirDefaults = 040755;
70 
71     volInfo->scanForDuplicateFiles = scanForDuplicateFiles;
72 
73     return 1;
74 }
75 
76 /*******************************************************************************
77 * bk_rename()
78 * Rename the file/dir.
79 * */
bk_rename(VolInfo * volInfo,const char * srcPathAndName,const char * newName)80 int bk_rename(VolInfo* volInfo, const char* srcPathAndName,
81               const char* newName)
82 {
83     int rc;
84     NewPath srcPath;
85     BkDir* parentDir;
86     bool dirFound;
87     BkFileBase* child;
88     bool done;
89     size_t newNameLen;
90 
91     newNameLen = strlen(newName);
92 
93     if(newNameLen > NCHARS_FILE_ID_MAX_STORE - 1)
94         return BKERROR_MAX_NAME_LENGTH_EXCEEDED;
95     if(newNameLen == 0)
96         return BKERROR_BLANK_NAME;
97     if( !nameIsValid(newName) )
98         return BKERROR_NAME_INVALID_CHAR;
99 
100     rc = makeNewPathFromString(srcPathAndName, &srcPath);
101     if(rc <= 0)
102     {
103         freePathContents(&srcPath);
104         return rc;
105     }
106 
107     if(srcPath.numChildren == 0)
108     {
109         freePathContents(&srcPath);
110         return BKERROR_RENAME_ROOT;
111     }
112 
113     if( strcmp(srcPath.children[srcPath.numChildren - 1], newName) == 0 )
114     /* rename to the same name, ignore silently */
115         return 1;
116 
117     /* i want the parent directory */
118     srcPath.numChildren--;
119     dirFound = findDirByNewPath(&srcPath, &(volInfo->dirTree), &parentDir);
120     srcPath.numChildren++;
121     if(!dirFound)
122     {
123         freePathContents(&srcPath);
124         return BKERROR_DIR_NOT_FOUND_ON_IMAGE;
125     }
126 
127     done = false;
128 
129     child = parentDir->children;
130     while(child != NULL && !done)
131     {
132         if(itemIsInDir(newName, parentDir))
133             return BKERROR_DUPLICATE_RENAME;
134 
135         if(strcmp(child->name, srcPath.children[srcPath.numChildren - 1]) == 0)
136         {
137             strcpy(child->name, newName);
138 
139             done = true;
140         }
141 
142         child = child->next;
143     }
144 
145     freePathContents(&srcPath);
146 
147     if(done)
148         return 1;
149     else
150         return BKERROR_ITEM_NOT_FOUND_ON_IMAGE;
151 }
152 
153 /*******************************************************************************
154 * bk_set_boot_file()
155 * Set a file on the image to be the no-emulation boot record for el torito.
156 * */
bk_set_boot_file(VolInfo * volInfo,const char * srcPathAndName)157 int bk_set_boot_file(VolInfo* volInfo, const char* srcPathAndName)
158 {
159     int rc;
160     NewPath path;
161     BkDir* srcDirInTree;
162     BkFileBase* child;
163     bool found;
164 
165     rc = makeNewPathFromString(srcPathAndName, &path);
166     if(rc <= 0)
167     {
168         freePathContents(&path);
169         return rc;
170     }
171 
172     path.numChildren--;
173     found = findDirByNewPath(&path, &(volInfo->dirTree), &srcDirInTree);
174     if(!found)
175         return BKERROR_DIR_NOT_FOUND_ON_IMAGE;
176     path.numChildren++;
177 
178     /* FIND the file */
179     found = false;
180     child = srcDirInTree->children;
181     while(child != NULL && !found)
182     {
183         if(strcmp(child->name, path.children[path.numChildren - 1]) == 0)
184         {
185             if( !IS_REG_FILE(child->posixFileMode) )
186             {
187                 freePathContents(&path);
188                 return BKERROR_NOT_REG_FILE_FOR_BR;
189             }
190 
191             found = true;
192 
193             volInfo->bootMediaType = BOOT_MEDIA_NO_EMULATION;
194 
195             volInfo->bootRecordSize = BK_FILE_PTR(child)->size;
196 
197             if(volInfo->bootRecordPathAndName != NULL)
198             {
199                 free(volInfo->bootRecordPathAndName);
200                 volInfo->bootRecordPathAndName = NULL;
201             }
202 
203             volInfo->bootRecordIsVisible = true;
204 
205             volInfo->bootRecordOnImage = BK_FILE_PTR(child);
206         }
207 
208         child = child->next;
209     }
210     if(!found)
211     {
212         freePathContents(&path);
213         return BKERROR_FILE_NOT_FOUND_ON_IMAGE;
214     }
215     /* END FIND the file */
216 
217     freePathContents(&path);
218 
219     return 1;
220 }
221 
bk_set_follow_symlinks(VolInfo * volInfo,bool doFollow)222 void bk_set_follow_symlinks(VolInfo* volInfo, bool doFollow)
223 {
224     volInfo->followSymLinks = doFollow;
225 }
226 
227 /*******************************************************************************
228 * bk_get_sermissions()
229 * public function
230 * sets the permissions (not all of the posix info) for an item (file, dir, etc.)
231 * */
bk_set_permissions(VolInfo * volInfo,const char * pathAndName,mode_t permissions)232 int bk_set_permissions(VolInfo* volInfo, const char* pathAndName,
233                        mode_t permissions)
234 {
235     int rc;
236     NewPath srcPath;
237     BkFileBase* base;
238     bool itemFound;
239 
240     rc = makeNewPathFromString(pathAndName, &srcPath);
241     if(rc <= 0)
242     {
243         freePathContents(&srcPath);
244         return rc;
245     }
246 
247     itemFound = findBaseByNewPath(&srcPath, &(volInfo->dirTree), &base);
248 
249     freePathContents(&srcPath);
250 
251     if(!itemFound)
252         return BKERROR_ITEM_NOT_FOUND_ON_IMAGE;
253 
254     /* set all permission bits in posixFileMode to 0 */
255     base->posixFileMode &= ~0777;
256 
257     /* copy permissions into posixFileMode */
258     base->posixFileMode |= permissions & 0777;
259 
260     return 1;
261 }
262 
263 /*******************************************************************************
264 * bk_set_publisher()
265 * Copies publisher into volInfo, a maximum of 128 characters.
266 * */
bk_set_publisher(VolInfo * volInfo,const char * publisher)267 int bk_set_publisher(VolInfo* volInfo, const char* publisher)
268 {
269     /* unfortunately some disks (e.g. Fedora 7) don't follow this rule
270     if( !nameIsValid9660(publisher) )
271         return BKERROR_NAME_INVALID_CHAR;*/
272 
273     strncpy(volInfo->publisher, publisher, 128);
274 
275     return 1;
276 }
277 
278 /*******************************************************************************
279 * bk_set_vol_name()
280 * Copies volName into volInfo, a maximum of 32 characters.
281 * */
bk_set_vol_name(VolInfo * volInfo,const char * volName)282 int bk_set_vol_name(VolInfo* volInfo, const char* volName)
283 {
284     /* unfortunately some disks (e.g. Fedora 7) don't follow this rule
285     if( !nameIsValid9660(volName) )
286         return BKERROR_NAME_INVALID_CHAR;*/
287 
288     strncpy(volInfo->volId, volName, 32);
289 
290     return 1;
291 }
292 
293 /*******************************************************************************
294 * itemIsInDir()
295 * checks the contents of a directory (files and dirs) to see whether it
296 * has an item named
297 * */
itemIsInDir(const char * name,const BkDir * dir)298 bool itemIsInDir(const char* name, const BkDir* dir)
299 {
300     BkFileBase* child;
301 
302     child = dir->children;
303     while(child != NULL)
304     {
305         if(strcmp(child->name, name) == 0)
306             return true;
307         child = child->next;
308     }
309 
310     return false;
311 }
312