summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/bkisofs/bkPath.c')
-rw-r--r--lib/bkisofs/bkPath.c375
1 files changed, 375 insertions, 0 deletions
diff --git a/lib/bkisofs/bkPath.c b/lib/bkisofs/bkPath.c
new file mode 100644
index 0000000..49bdabb
--- /dev/null
+++ b/lib/bkisofs/bkPath.c
@@ -0,0 +1,375 @@
+/******************************* LICENCE **************************************
+* Any code in this file may be redistributed or modified under the terms of
+* the GNU General Public Licence as published by the Free Software
+* Foundation; version 2 of the licence.
+****************************** END LICENCE ***********************************/
+
+/******************************************************************************
+* Author:
+* Andrew Smith, http://littlesvr.ca/misc/contactandrew.php
+*
+* Contributors:
+* Henrique Pinto
+* - fixed bug that caused crash in makeNewPathFromString()
+******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "bk.h"
+#include "bkInternal.h"
+#include "bkError.h"
+#include "bkPath.h"
+#include "bkMangle.h"
+
+/******************************************************************************
+* nameIsValid9660()
+* Checks each character in name to see whether it's allowed in the more strict
+* ISO9660 fields.
+* */
+bool nameIsValid9660(const char* name)
+{
+ size_t count;
+ size_t nameLen;
+
+ nameLen = strlen(name);
+
+ for(count = 0; count < nameLen; count++)
+ {
+ if(!charIsValid9660(name[count]))
+ return false;
+ }
+
+ return true;
+}
+
+bool findBaseByNewPath(NewPath* path, BkDir* tree, BkFileBase** base)
+{
+ BkDir* parentDir;
+ bool dirFound;
+ BkFileBase* child;
+
+ /* parent directory */
+ path->numChildren--;
+ dirFound = findDirByNewPath(path, tree, &parentDir);
+ path->numChildren++;
+ if(!dirFound)
+ return false;
+
+ child = parentDir->children;
+ while(child != NULL)
+ {
+ if(strcmp(child->name, path->children[path->numChildren - 1]) == 0)
+ {
+ *base = child;
+ return true;
+ }
+
+ child = child->next;
+ }
+
+ return false;
+}
+
+bool findDirByNewPath(const NewPath* path, BkDir* tree, BkDir** dir)
+{
+ bool dirFound;
+ unsigned count;
+ BkFileBase* child;
+
+ *dir = tree;
+ for(count = 0; count < path->numChildren; count++)
+ /* each directory in the path */
+ {
+ child = (*dir)->children;
+ dirFound = false;
+ while(child != NULL && !dirFound)
+ /* find the directory */
+ {
+ if(strcmp(child->name, path->children[count]) == 0)
+ {
+ if( !IS_DIR(child->posixFileMode) )
+ return false;
+
+ dirFound = true;
+ *dir = BK_DIR_PTR(child);
+ }
+ else
+ child = child->next;
+ }
+ if(!dirFound)
+ return false;
+ }
+
+ return true;
+}
+
+/******************************************************************************
+* freeDirToWriteContents()
+* Recursively deletes all the dynamically allocated contents of dir.
+* */
+void freeDirToWriteContents(DirToWrite* dir)
+{
+ BaseToWrite* currentChild;
+ BaseToWrite* nextChild;
+
+ currentChild = dir->children;
+ while(currentChild != NULL)
+ {
+ nextChild = currentChild->next;
+
+ if( IS_DIR(currentChild->posixFileMode) )
+ {
+ freeDirToWriteContents(DIRTW_PTR(currentChild));
+ }
+ else if( IS_REG_FILE(currentChild->posixFileMode) )
+ {
+ if(!FILETW_PTR(currentChild)->onImage)
+ free(FILETW_PTR(currentChild)->pathAndName);
+ }
+
+ free(currentChild);
+
+ currentChild = nextChild;
+ }
+}
+
+void freePathContents(NewPath* path)
+{
+ unsigned count;
+
+ for(count = 0; count < path->numChildren; count++)
+ {
+ /* if the path was not allocated properly (maybe ran out of memory)
+ * the first unallocated item is null */
+ if(path->children[count] == NULL)
+ break;
+
+ free(path->children[count]);
+ }
+
+ if(path->children != NULL)
+ free(path->children);
+}
+
+int getLastNameFromPath(const char* srcPathAndName, char* lastName)
+{
+ size_t count;
+ size_t srcLen;
+ size_t lastCharIndex;
+ size_t firstCharIndex;
+ bool lastCharFound;
+ int count2;
+
+ srcLen = strlen(srcPathAndName);
+
+ /* FIND the last name */
+ lastCharIndex = srcLen;
+ lastCharFound = false;
+ for(count = srcLen; /* unsigned */; count--)
+ {
+ if(srcPathAndName[count] != '/')
+ {
+ if(!lastCharFound)
+ {
+ lastCharIndex = count;
+ lastCharFound = true;
+
+ firstCharIndex = lastCharIndex;
+ }
+ else
+ {
+ firstCharIndex = count;
+ }
+ }
+ else
+ {
+ if(lastCharFound)
+ break;
+ }
+
+ if(count == 0)
+ break;
+ }
+ if(!lastCharFound)
+ return BKERROR_MISFORMED_PATH;
+ /* END FIND the last name */
+
+ if(lastCharIndex - firstCharIndex > NCHARS_FILE_ID_MAX_STORE - 1)
+ return BKERROR_MAX_NAME_LENGTH_EXCEEDED;
+
+ /* copy the name */
+ for(count = firstCharIndex, count2 = 0; count <= lastCharIndex; count++, count2++)
+ {
+ lastName[count2] = srcPathAndName[count];
+ }
+ lastName[count2] = '\0';
+
+ return 1;
+}
+
+int makeNewPathFromString(const char* strPath, NewPath* pathPath)
+{
+ size_t count;
+ size_t pathStrLen;
+ unsigned numChildrenDone;
+ int nextChildLen;
+ const char* nextChild;
+
+ pathStrLen = strlen(strPath);
+ pathPath->numChildren = 0;
+ pathPath->children = NULL;
+
+ if(strPath[0] != '/')
+ return BKERROR_MISFORMED_PATH;
+
+ /* count number of children */
+ for(count = 1; count < pathStrLen; count++)
+ {
+ if(strPath[count] != '/' && strPath[count - 1] == '/')
+ pathPath->numChildren++;
+ }
+
+ if(pathPath->numChildren == 0)
+ {
+ pathPath->children = NULL;
+ return 1;
+ }
+
+ pathPath->children = (char**)malloc(sizeof(char*) * pathPath->numChildren);
+ if(pathPath->children == NULL)
+ return BKERROR_OUT_OF_MEMORY;
+
+ numChildrenDone = 0;
+ nextChildLen = 0;
+ nextChild = &(strPath[1]);
+ for(count = 1; count <= pathStrLen; count++)
+ {
+ if(strPath[count] == '/' || (strPath[count] == '\0' && strPath[count - 1] != '/'))
+ {
+ if(strPath[count] == '/' && strPath[count - 1] == '/')
+ /* double slash */
+ {
+ nextChild = &(strPath[count + 1]);
+ continue;
+ }
+ else
+ /* this is the end of the string or the slash following a dir name */
+ {
+ pathPath->children[numChildrenDone] = (char*)malloc(nextChildLen + 1);
+ if(pathPath->children[numChildrenDone] == NULL)
+ return BKERROR_OUT_OF_MEMORY;
+
+ strncpy(pathPath->children[numChildrenDone], nextChild, nextChildLen);
+ pathPath->children[numChildrenDone][nextChildLen] = '\0';
+
+ numChildrenDone++;
+ nextChildLen = 0;
+
+ nextChild = &(strPath[count + 1]);
+ }
+ }
+ else
+ {
+ nextChildLen++;
+ }
+ }
+
+ if(numChildrenDone != pathPath->numChildren)
+ return BKERROR_SANITY;
+
+ return 1;
+}
+
+/******************************************************************************
+* nameIsValid()
+* Checks each character in name to see whether it's allowed in an identifier
+* */
+bool nameIsValid(const char* name)
+{
+ size_t count;
+ size_t nameLen;
+
+ nameLen = strlen(name);
+
+ for(count = 0; count < nameLen; count++)
+ {
+ /* can be any ascii char between decimal 32 and 126 except '/' (47) */
+ if(name[count] < 32 || name[count] > 126 || name[count] == 47)
+ return false;
+ }
+
+ return true;
+}
+
+#ifdef DEBUG
+void printDirToWrite(DirToWrite* dir, int level, int filenameTypes)
+{
+ BaseToWrite* child;
+ int count;
+
+ child = dir->children;
+ while(child != NULL)
+ {
+ if(IS_DIR(child->posixFileMode))
+ {
+ if(filenameTypes & FNTYPE_9660)
+ {
+ for(count = 0; count < level; count ++)
+ printf(" ");
+ printf("dir9 '%s'\n", child->name9660);fflush(NULL);
+ }
+
+ if(filenameTypes & FNTYPE_JOLIET)
+ {
+ for(count = 0; count < level; count ++)
+ printf(" ");
+ printf("dirJ '%s'\n", child->nameJoliet);fflush(NULL);
+ }
+
+ if(filenameTypes & FNTYPE_ROCKRIDGE)
+ {
+ for(count = 0; count < level; count ++)
+ printf(" ");
+ printf("dirR '%s'\n", child->nameRock);fflush(NULL);
+ }
+
+ printDirToWrite(DIRTW_PTR(child), level + 1, filenameTypes);
+ }
+
+ child = child->next;
+ }
+
+ child = dir->children;
+ while(child != NULL)
+ {
+ if(!IS_DIR(child->posixFileMode))
+ {
+ if(filenameTypes & FNTYPE_9660)
+ {
+ for(count = 0; count < level; count ++)
+ printf(" ");
+ printf("file9 '%s'\n", child->name9660);fflush(NULL);
+ }
+
+ if(filenameTypes & FNTYPE_JOLIET)
+ {
+ for(count = 0; count < level; count ++)
+ printf(" ");
+ printf("fileJ '%s'\n", child->nameJoliet);fflush(NULL);
+ }
+
+ if(filenameTypes & FNTYPE_ROCKRIDGE)
+ {
+ for(count = 0; count < level; count ++)
+ printf(" ");
+ printf("fileR '%s'\n", child->nameRock);fflush(NULL);
+ }
+ }
+
+ child = child->next;
+ }
+}
+#endif /* DEBUG */