From 57915068f2893fa246e1865fcf51cc50a5707189 Mon Sep 17 00:00:00 2001 From: Markus Mittendrein Date: Tue, 21 Apr 2020 22:02:50 +0200 Subject: Use openAsChild internally when opening a directory inside a group using openExisting --- src/cc4group.c | 138 ++++++++++++++++++++++++++++++--------------------------- src/cc4group.h | 2 +- 2 files changed, 74 insertions(+), 66 deletions(-) diff --git a/src/cc4group.c b/src/cc4group.c index 38662e0..99d4730 100644 --- a/src/cc4group.c +++ b/src/cc4group.c @@ -38,6 +38,8 @@ static bool cc4group_openExisting(CC4Group* const this, const char* const path); static void cc4group_delete(CC4Group* const this); +static bool cc4group_openAsChildOn(CC4Group* const this, const char* const path, CC4Group* const child); + // extraction to disk static bool cc4group_extractAll(CC4Group* const this, const char* const targetPath); static bool cc4group_extractSingle(CC4Group* const this, const char* const entryPath, const char* const targetPath); @@ -95,7 +97,6 @@ struct CC4Group_t { uint8_t* uncompressedData; size_t uncompressedSize; C4GroupEntryData root; - C4GroupEntryData realRoot; CleanUpJobList* cleanupJobs; @@ -129,7 +130,6 @@ struct CC4Group_t { const char* path; const char* name; const char* pathInParent; - bool subRooted; }; typedef struct { @@ -255,6 +255,14 @@ static void cc4group_printToStderrWarningCallback(const CC4Group* const this, co va_end (ap); } +static void cc4group_copyErrorInformation(const CC4Group* const src, CC4Group* const dst) +{ + dst->error.code = src->error.code; + dst->error.formatter = src->error.formatter; + dst->error.causer = src->error.causer; + dst->error.method = src->error.method; +} + static const CC4Group_WarningCallback cc4group_defaultWarningCallback = cc4group_printToStderrWarningCallback; static CC4Group_WarningCallback cc4group_warn = cc4group_defaultWarningCallback; @@ -1048,27 +1056,6 @@ static bool cc4group_openMemory(CC4Group* const this, const void* const compress return cc4group_uncompressGroup(this, cc4group_completeDataReadCallback, &data, memoryManagement, NULL, NULL); } -static bool cc4group_setSubRoot(CC4Group* const this, const char* const subPath) -{ - if(subPath != NULL && *subPath != '\0') - { - const C4GroupEntryData* subRoot = cc4group_getDirectoryByPath(this, subPath, false, NULL); - - if(subRoot == NULL || cc4group_getChildren(this, subRoot) == NULL) - { - return false; - } - - this->realRoot = this->root; - this->root = *subRoot; - this->subRooted = true; - this->pathInParent = strdup(subPath); - this->name = strdup(subRoot->core.FileName); - } - - return true; -} - static bool cc4group_cleanupMappedGroupFile(void* const arg) { CompleteDataReadCallbackArg* data = arg; @@ -1129,6 +1116,47 @@ static bool cc4group_uncompressGroupFromFile(CC4Group* const this, const char* c } } + if(subPath != NULL && subPath[0] != '\0') + { + CC4Group* const parent = cc4group.new(); + if(parent == NULL) + { + SET_ERRNO_ERROR("malloc: allocating the parent group"); + goto ret; + } + + if(!cc4group.openExisting(parent, tmpPath)) + { + cc4group_copyErrorInformation(parent, this); + this->error.method = "Nested cc4group.openExisting opening the parent group"; + goto ret2; + } + + if(this->name != NULL) + { + free((void*)this->name); + this->name = NULL; + } + if(this->path != NULL) + { + free((void*)this->path); + this->path = NULL; + } + + if(!cc4group_openAsChildOn(parent, subPath, this)) + { + cc4group_copyErrorInformation(parent, this); + this->error.method = "cc4group.openAsChild on parent group"; + goto ret2; + } + + success = true; + + ret2: + cc4group.delete(parent); + goto ret; + } + struct stat st; if(fstat(file, &st) == -1) { @@ -1178,19 +1206,6 @@ ret: } } - if(success) - { - success = cc4group_setSubRoot(this, subPath); - if(success && subPath != NULL && *subPath != '\0') - { - if(this->path != NULL) - { - free((void*)this->path); - } - this->path = cc4group_absolutePath(tmpPath); - } - } - free(tmpPath); return success; @@ -1206,7 +1221,6 @@ static void cc4group_init(CC4Group* const this) this->path = NULL; this->name = NULL; this->pathInParent = NULL; - this->subRooted = false; this->uncompressedData = NULL; this->uncompressedSize = 0; @@ -2745,12 +2759,6 @@ static bool cc4group_save(CC4Group* const this) return false; } - if(this->subRooted) - { - SET_MESSAGE_ERROR("Refusing to save a group opened with a path inside the actual group. cc4group.saveParent might be used."); - return false; - } - return cc4group_saveAsOverwrite(this, this->path); } @@ -2762,17 +2770,6 @@ static bool cc4group_saveParent(CC4Group* const this) root = root->parent; } - if(root->subRooted) - { - C4GroupEntryData tmp = root->root; - root->root = root->realRoot; - root->subRooted = false; - bool success = cc4group_save(root); - root->root = tmp; - root->subRooted = true; - return success; - } - return cc4group_save(root); } @@ -3260,7 +3257,7 @@ static bool cc4group_setExecutable(CC4Group* const this, bool const executable, return true; } -static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const path) +static bool cc4group_openAsChildOn(CC4Group* const this, const char* const path, CC4Group* const child) { assert(this); @@ -3268,14 +3265,7 @@ static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const pa if(entry == NULL) { - return NULL; - } - - CC4Group* child = cc4group_new(); - if(child == NULL) - { - SET_ERRNO_ERROR("malloc: allocating the child group object"); - return NULL; + return false; } memcpy(&child->root.core, &entry->core, sizeof(child->root.core)); @@ -3288,7 +3278,7 @@ static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const pa if(child->root.children == NULL) { cc4group_delete(child); - return NULL; + return false; } child->parent = this; @@ -3299,6 +3289,24 @@ static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const pa CleanUpJobListAppend(child->cleanupJobs, (CC4Group_CleanupJob){.func = (CC4Group_CleanupFunc)cc4group_unreference, .data = this}); + return true; +} + +static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const path) +{ + CC4Group* child = cc4group_new(); + if(child == NULL) + { + SET_ERRNO_ERROR("malloc: allocating the child group object"); + return NULL; + } + + if(!cc4group_openAsChildOn(this, path, child)) + { + cc4group_delete(child); + return NULL; + } + return child; } @@ -3319,7 +3327,7 @@ static const char* cc4group_getName(const CC4Group* const this) static char* cc4group_getFullName(const CC4Group* const this) { - if(!this->parent && !this->subRooted) + if(!this->parent) { return strdup(this->path); } diff --git a/src/cc4group.h b/src/cc4group.h index 51bacbb..4bcec34 100644 --- a/src/cc4group.h +++ b/src/cc4group.h @@ -247,7 +247,7 @@ typedef struct { bool (*create)(CC4Group* const this); // opens a group or a normal folder on the filesystem; path may point to a directory inside a group; path "-" can be used to read the group from stdin - // if path points to a directory inside a group, saving behaves the same as for cc4group.openAsChild + // for the case where path points to a directory inside a group, this is implemented internally using openAsChild, thus the same caveats apply bool (*openExisting)(CC4Group* const this, const char* const path); // opens a group that is stored entirely in memory -- cgit v1.2.3-54-g00ecf