aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-09-27 23:13:06 +0200
committerXavier Del Campo Romero <xavi92@disroot.org>2026-09-27 23:13:06 +0200
commit8233150b4ed2c4a6e1639e7d5e578f4b6b2a363a (patch)
tree026666876f5d90733b5978182698afc2b253d217
parentebf718f8be84c3785ed8744e214388ea556ebccb (diff)
downloadslcl-8233150b4ed2c4a6e1639e7d5e578f4b6b2a363a.tar.gz
zip.c: Add top-level directory
It is desirable to keep the contents of the generated file below a directory, ideally named after the ZIP file itself, so that extraction tools can extract the files to a subdirectory, rather than spilling its contents to the working directory.
-rw-r--r--zip.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/zip.c b/zip.c
index 668030c..c6cde50 100644
--- a/zip.c
+++ b/zip.c
@@ -152,29 +152,46 @@ static int read_file(void *const buf, const size_t n, bool *const done,
static int setup_file(struct zip *const z, const char *const fpath,
const time_t t)
{
+ int ret = -1, fd = -1;
struct stat sb;
+ struct dynstr d;
+ char *bndup = NULL;
ZIPentry *entry = NULL;
- const int fd = open(fpath, O_RDONLY | O_NONBLOCK);
- /* zs_entrybegin is not const-correct. */
- char *path = (char *)fpath + strlen(z->basedir);
+ const char *path = fpath + strlen(z->basedir), *bn;
+
+ dynstr_init(&d);
- if (fd < 0)
+ if (!(bndup = strdup(z->basedir)))
+ {
+ fprintf(stderr, "%s: strdup(3): %s\n", __func__, strerror(errno));
+ goto end;
+ }
+ else if (!(bn = basename(bndup)))
+ {
+ fprintf(stderr, "%s: basename(3) failed\n", __func__);
+ goto end;
+ }
+ else if (dynstr_append(&d, "%s/%s", bn, path))
+ {
+ fprintf(stderr, "%s: dynstr_append failed\n", __func__);
+ goto end;
+ }
+ else if ((fd = open(fpath, O_RDONLY | O_NONBLOCK)) < 0)
{
fprintf(stderr, "%s: open(2) %s: %s\n", __func__, fpath,
strerror(errno));
- goto failure;
+ goto end;
}
else if (fstat(fd, &sb))
{
fprintf(stderr, "%s: fstat(2) %s: %s\n", __func__, fpath,
strerror(errno));
- goto failure;
+ goto end;
}
- else if (!(entry = zs_entrybegin(z->stream, path, t, ZS_DEFLATE,
- NULL)))
+ else if (!(entry = zs_entrybegin(z->stream, d.str, t, ZS_DEFLATE, NULL)))
{
fprintf(stderr, "%s: zs_entrybegin failed\n", __func__);
- goto failure;
+ goto end;
}
z->fd = fd;
@@ -182,15 +199,16 @@ static int setup_file(struct zip *const z, const char *const fpath,
z->entry = entry;
z->filesz = sb.st_size;
z->next = read_file;
- return 0;
+ ret = 0;
+end:
-failure:
-
- if (fd && close(fd))
+ if (ret && fd >= 0 && close(fd))
fprintf(stderr, "%s: close(2) %s: %s\n", __func__, fpath,
strerror(errno));
- return -1;
+ dynstr_free(&d);
+ free(bndup);
+ return ret;
}
static int setup(const char *const fpath, const struct stat *sb,