diff options
Diffstat (limited to 'src/package.c')
-rw-r--r-- | src/package.c | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/src/package.c b/src/package.c index 464918c..2c396be 100644 --- a/src/package.c +++ b/src/package.c @@ -118,7 +118,7 @@ fail: return NULL; } -struct package* package_open(const char *fn) { +struct package* package_open(const char *fn, int force) { struct package *p; FILE *f = NULL; char path[PATH_MAX]; @@ -143,56 +143,63 @@ struct package* package_open(const char *fn) { if (fn) { if (!(f = fopen(fn, "r"))) { - fprintf(stderr, "Failed to open <%s>: %s\n", fn, strerror(errno)); - goto finish; - } - - for (;;) { - uint32_t len; - char name[PACKAGE_ITEM_NAME_LEN+1]; - FILE *d = NULL; - struct package_item *pi; - - if (!fread(name, sizeof(name)-1, 1, f)) - break; - name[sizeof(name)-1] = 0; - - if (fread(&len, sizeof(len), 1, f) != 1) { - fprintf(stderr, "Short read while reading length: %s\n", strerror(errno)); + if (errno != ENOENT || !force) { + fprintf(stderr, "Failed to open <%s>: %s\n", fn, strerror(errno)); goto finish; } + } - snprintf(path, sizeof(path), "%s/%i", p->base, p->count++); - if (!(d = fopen(path, "w+"))) { - fprintf(stderr, "Failed to open target file: %s\n", strerror(errno)); - goto finish; - } + if (f) { + + for (;;) { + uint32_t len; + char name[PACKAGE_ITEM_NAME_LEN+1]; + FILE *d = NULL; + struct package_item *pi; + + if (!fread(name, sizeof(name)-1, 1, f)) + break; + + name[sizeof(name)-1] = 0; + + if (fread(&len, sizeof(len), 1, f) != 1) { + fprintf(stderr, "Short read while reading length: %s\n", strerror(errno)); + goto finish; + } + + snprintf(path, sizeof(path), "%s/%i", p->base, p->count++); + if (!(d = fopen(path, "w+"))) { + fprintf(stderr, "Failed to open target file: %s\n", strerror(errno)); + goto finish; + } + + if (copy(f, d, len) < 0) { + fprintf(stderr, "Copy failed: %s\n", strerror(errno)); + fclose(d); + unlink(path); + goto finish; + } - if (copy(f, d, len) < 0) { - fprintf(stderr, "Copy failed: %s\n", strerror(errno)); fclose(d); - unlink(path); - goto finish; - } + if (!(pi = item_new(name, path, 1))) { + unlink(path); + fprintf(stderr, "Failed to allocate memory.\n"); + goto finish; + } - fclose(d); - if (!(pi = item_new(name, path, 1))) { - unlink(path); - fprintf(stderr, "Failed to allocate memory.\n"); - goto finish; + assert(!!p->last == !!p->items); + + if (p->last) { + p->last->next = pi; + p->last = pi; + } else + p->items = p->last = pi; } - assert(!!p->last == !!p->items); - - if (p->last) { - p->last->next = pi; - p->last = pi; - } else - p->items = p->last = pi; - } - fclose(f); + fclose(f); + } } return p; @@ -339,8 +346,10 @@ void package_remove(struct package *p) { } if (p->base) { - if (rmdir(p->base)) - fprintf(stderr, "Failed to remove <%s>: %s\n", p->base, strerror(errno)); + if (rmdir(p->base)) { + if (errno != ENOENT) + fprintf(stderr, "Failed to remove <%s>: %s\n", p->base, strerror(errno)); + } free(p->base); } |