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 <stdio.h>
16 #include <string.h>
17 #include <sys/types.h>
18
19 #include "bk.h"
20 #include "bkInternal.h"
21 #include "bkError.h"
22 #include "bkGet.h"
23 #include "bkPath.h"
24
25 /*******************************************************************************
26 * bk_estimate_iso_size()
27 * Public function
28 * Estimates the size of the directory trees + file contents on the iso
29 * */
bk_estimate_iso_size(const VolInfo * volInfo,int filenameTypes)30 bk_off_t bk_estimate_iso_size(const VolInfo* volInfo, int filenameTypes)
31 {
32 /* reset alreadyCounted flags */
33 BkHardLink* currentLink;
34 currentLink = volInfo->fileLocations;
35 while(currentLink != NULL)
36 {
37 currentLink->alreadyCounted = false;
38
39 currentLink = currentLink->next;
40 }
41
42 return estimateIsoSize(&(volInfo->dirTree), filenameTypes);
43 }
44
45 /*******************************************************************************
46 * bk_get_creation_time()
47 * Public function
48 * */
bk_get_creation_time(const VolInfo * volInfo)49 time_t bk_get_creation_time(const VolInfo* volInfo)
50 {
51 return volInfo->creationTime;
52 }
53
54 /*******************************************************************************
55 * bk_get_dir_from_string()
56 * public function
57 * gets a pointer to a Dir in tree described by the string pathStr
58 * */
bk_get_dir_from_string(const VolInfo * volInfo,const char * pathStr,BkDir ** dirFoundPtr)59 int bk_get_dir_from_string(const VolInfo* volInfo, const char* pathStr,
60 BkDir** dirFoundPtr)
61 {
62 return getDirFromString(&(volInfo->dirTree), pathStr, dirFoundPtr);
63 }
64
65 /*******************************************************************************
66 * bk_get_permissions()
67 * public function
68 * gets the permissions (not all of the posix info) for an item (file, dir, etc.)
69 * */
bk_get_permissions(VolInfo * volInfo,const char * pathAndName,mode_t * permissions)70 int bk_get_permissions(VolInfo* volInfo, const char* pathAndName,
71 mode_t* permissions)
72 {
73 int rc;
74 NewPath srcPath;
75 BkFileBase* base;
76 bool itemFound;
77
78 if(permissions == NULL)
79 return BKERROR_GET_PERM_BAD_PARAM;
80
81 rc = makeNewPathFromString(pathAndName, &srcPath);
82 if(rc <= 0)
83 {
84 freePathContents(&srcPath);
85 return rc;
86 }
87
88 itemFound = findBaseByNewPath(&srcPath, &(volInfo->dirTree), &base);
89
90 freePathContents(&srcPath);
91
92 if(!itemFound)
93 return BKERROR_ITEM_NOT_FOUND_ON_IMAGE;
94
95 *permissions = base->posixFileMode & 0777;
96
97 return 1;
98 }
99
100 /*******************************************************************************
101 * bk_get_publisher()
102 * Public function
103 * Returns a pointer to the string in volInfo that holds the volume name.
104 * */
bk_get_publisher(const VolInfo * volInfo)105 const char* bk_get_publisher(const VolInfo* volInfo)
106 {
107 return volInfo->publisher;
108 }
109
110 /*******************************************************************************
111 * bk_get_volume_name()
112 * Public function
113 * Returns a pointer to the string in volInfo that holds the volume name.
114 * */
bk_get_volume_name(const VolInfo * volInfo)115 const char* bk_get_volume_name(const VolInfo* volInfo)
116 {
117 return volInfo->volId;
118 }
119
120 /*******************************************************************************
121 * estimateIsoSize()
122 * Recursive
123 * Estimate the size of the directory trees + file contents on the iso
124 * */
estimateIsoSize(const BkDir * tree,int filenameTypes)125 bk_off_t estimateIsoSize(const BkDir* tree, int filenameTypes)
126 {
127 bk_off_t estimateDrSize;
128 bk_off_t thisDirSize;
129 int numItems; /* files and directories */
130 BkFileBase* child;
131
132 thisDirSize = 0;
133 numItems = 0;
134
135 child = tree->children;
136 while(child != NULL)
137 {
138 if(IS_DIR(child->posixFileMode))
139 {
140 thisDirSize += estimateIsoSize(BK_DIR_PTR(child), filenameTypes);
141 }
142 else if(IS_REG_FILE(child->posixFileMode))
143 {
144 if(BK_FILE_PTR(child)->location == NULL ||
145 !BK_FILE_PTR(child)->location->alreadyCounted)
146 {
147 thisDirSize += BK_FILE_PTR(child)->size;
148 thisDirSize += BK_FILE_PTR(child)->size % NBYTES_LOGICAL_BLOCK;
149 }
150 if(BK_FILE_PTR(child)->location != NULL)
151 BK_FILE_PTR(child)->location->alreadyCounted = true;
152 }
153
154 numItems++;
155
156 child = child->next;
157 }
158
159 estimateDrSize = 70;
160 if(filenameTypes & FNTYPE_JOLIET)
161 estimateDrSize += 70;
162 if(filenameTypes & FNTYPE_ROCKRIDGE)
163 estimateDrSize += 70;
164
165 thisDirSize += 68 + (estimateDrSize * numItems);
166 thisDirSize += NBYTES_LOGICAL_BLOCK - (68 + (estimateDrSize * numItems)) % NBYTES_LOGICAL_BLOCK;
167
168 return thisDirSize;
169 }
170
171 /*******************************************************************************
172 * getDirFromString()
173 * recursive
174 * gets a pointer to a Dir in tree described by the string pathStr
175 * */
getDirFromString(const BkDir * tree,const char * pathStr,BkDir ** dirFoundPtr)176 int getDirFromString(const BkDir* tree, const char* pathStr, BkDir** dirFoundPtr)
177 {
178 size_t count;
179 size_t pathStrLen;
180 bool stopLooking;
181 /* name of the directory in the path this instance of the function works on */
182 char* currentDirName;
183 BkFileBase* child;
184 int rc;
185
186 pathStrLen = strlen(pathStr);
187
188 if(pathStrLen == 1 && pathStr[0] == '/')
189 /* root, special case */
190 {
191 /* cast to prevent compiler const warning */
192 *dirFoundPtr = (BkDir*)tree;
193 return 1;
194 }
195
196 if(pathStrLen < 3 || pathStr[0] != '/' || pathStr[1] == '/' ||
197 pathStr[pathStrLen - 1] != '/')
198 return BKERROR_MISFORMED_PATH;
199
200 stopLooking = false;
201 for(count = 2; count < pathStrLen && !stopLooking; count++)
202 /* find the first directory in the path */
203 {
204 if(pathStr[count] == '/')
205 /* found it */
206 {
207 /* make a copy of the string to use with strcmp */
208 currentDirName = (char*)malloc(count);
209 if(currentDirName == NULL)
210 return BKERROR_OUT_OF_MEMORY;
211
212 strncpy(currentDirName, &(pathStr[1]), count - 1);
213 currentDirName[count - 1] = '\0';
214
215 child = tree->children;
216 while(child != NULL && !stopLooking)
217 /* each child directory in tree */
218 {
219 if( strcmp(child->name, currentDirName) == 0 &&
220 IS_DIR(child->posixFileMode) )
221 /* found the right child directory */
222 {
223 if(pathStr[count + 1] == '\0')
224 /* this is the directory i'm looking for */
225 {
226 *dirFoundPtr = BK_DIR_PTR(child);
227 stopLooking = true;
228 rc = 1;
229 }
230 else
231 /* intermediate directory, go further down the tree */
232 {
233 rc = getDirFromString(BK_DIR_PTR(child),
234 &(pathStr[count]), dirFoundPtr);
235 if(rc <= 0)
236 {
237 free(currentDirName);
238 return rc;
239 }
240 stopLooking = true;
241 }
242
243 }
244
245 child = child->next;
246 }
247
248 free(currentDirName);
249
250 if(!stopLooking)
251 return BKERROR_DIR_NOT_FOUND_ON_IMAGE;
252 } /* if(found it) */
253 } /* for(find the first directory in the path) */
254
255 /* can't see how i could get here but to keep the compiler happy */
256 return 1;
257 }
258