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