pm

barely a pack manager
git clone git://z3bra.org/pm
Log | Files | Refs | README | LICENSE

commit 6145d57d9b2344b47c1b3033b0ac9a4c6328d722
parent 886dcf4ddd6603a07716e03a99d0215d3e659a3c
Author: z3bra <willyatmailoodotorg>
Date:   Thu Jan 14 00:28:18 2016

chdir() during unpacking

Using chdir() within the unpack() function allow unpacking tarballs
using relative pathnames.

We also need to chdir back to the old directory after every
operation in order to keep this relative path valid.

Another solution could be to readlink(2) all path during pack
loading. We'll see if that's a better option on the long term.

Diffstat:
 pm.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/pm.c b/pm.c @@ -59,7 +59,7 @@ int inspect(char *datadir, char *packname); int write_metadata(char *datadir, struct pack *pack); int write_entry(struct archive *a, struct archive *w); -int unpack(char *datadir, struct pack *p); +int unpack(char *rootfs, char *datadir, struct pack *p); int install(char *rootfs, char *datadir, struct pack *p); int delete_content(FILE *metafile); int delete(const char *rootfs, const char *datadir, const char *name); @@ -145,6 +145,7 @@ int inspect_collision(char *rootfs, struct pack *p) { int r = 0; + char cwd[PATH_MAX] = ""; struct stat st; struct archive *a; struct archive_entry *e; @@ -157,6 +158,7 @@ inspect_collision(char *rootfs, struct pack *p) if (r != ARCHIVE_OK) return -1; + getcwd(cwd, PATH_MAX); chdir(rootfs); while (archive_read_next_header(a, &e) == ARCHIVE_OK) { if (stat(archive_entry_pathname(e), &st) == 0 && !S_ISDIR(st.st_mode)) { @@ -168,6 +170,7 @@ inspect_collision(char *rootfs, struct pack *p) } archive_read_free(a); + chdir(cwd); return r; } @@ -317,12 +320,13 @@ write_entry(struct archive *a, struct archive *w) * Extract a tarball to the given directory */ int -unpack(char *datadir, struct pack *p) +unpack(char *rootfs, char *datadir, struct pack *p) { int r, fd; struct archive *a; struct archive *w; struct archive_entry *e; + char cwd[PATH_MAX] = ""; char tmp[PATH_MAX] = ""; int mask = ARCHIVE_EXTRACT_PERM @@ -348,6 +352,8 @@ unpack(char *datadir, struct pack *p) w = archive_write_disk_new(); archive_write_disk_set_options(w, mask); + getcwd(cwd, PATH_MAX); + chdir(rootfs); while ((r = archive_read_next_header(a, &e)) != ARCHIVE_EOF) { if (r != ARCHIVE_OK) { fprintf(stderr, "%s: %s\n", archive_entry_pathname(e), @@ -370,6 +376,7 @@ unpack(char *datadir, struct pack *p) dprintf(fd, "%s\n", archive_entry_pathname(e)); archive_write_finish_entry(w); } + chdir(cwd); archive_write_free(w); archive_read_free(a); @@ -405,15 +412,6 @@ install(char *rootfs, char *datadir, struct pack *p) return -1; } - /* - * ensure we can chdir to the rootfs and write metadata - * to the datadir - */ - if (chdir(rootfs) < 0) { - perror(rootfs); - return -1; - } - if (verbose == 1) printf("%s: writing metadata\n", p->name); if (write_metadata(datadir, p) < 0) { @@ -423,7 +421,7 @@ install(char *rootfs, char *datadir, struct pack *p) if (verbose == 1) printf("%s: extracting %s\n", p->name, p->path); - r = unpack(datadir, p); + r = unpack(rootfs, datadir, p); if (verbose == 1) printf("%s: installation %s\n", p->name, r != 0 ? "failed" : "complete");