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