pm

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

commit e6ba7b3f0f832855bd1ea7323644fcf0c9d39258
parent e7c528b75ba86304b270abc8181868ed3f5efd32
Author: z3bra <willyatmailoodotorg>
Date:   Tue Jan 12 10:27:00 2016

Check for collision before unpacking

Diffstat:
 pm.c | 50 +++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 7 deletions(-)

diff --git a/pm.c b/pm.c @@ -51,6 +51,7 @@ char *base_name(char *path); struct pack *pack_load(char *path); void pack_free(struct pack *p); +int inspect_collision(char *rootfs, struct pack *p); int inspect_system(int fd, char *datadir); int inspect_files(int fd, char *datadir, char *packname); int inspect(char *datadir, char *packname); @@ -134,6 +135,41 @@ base_name(char *path) /* + * Check for collisions between the filesystem and the tarball + */ +int +inspect_collision(char *rootfs, struct pack *p) +{ + int r = 0; + struct stat st; + struct archive *a; + struct archive_entry *e; + + a = archive_read_new(); + archive_read_support_filter_bzip2(a); + archive_read_support_format_tar(a); + + r = archive_read_open_filename(a, p->path, 0); + if (r != ARCHIVE_OK) + return -1; + + chdir(rootfs); + while (archive_read_next_header(a, &e) == ARCHIVE_OK) { + if (stat(archive_entry_pathname(e), &st) == 0 && !S_ISDIR(st.st_mode)) { + fprintf(stderr, "%s: File exists\n", archive_entry_pathname(e)); + r = -1; + break; + } + archive_read_data_skip(a); + } + + archive_read_free(a); + + return r; +} + + +/* * Write files installed by a pack to a file descriptor */ int @@ -273,19 +309,16 @@ write_entry(struct archive *a, struct archive *w) } +/* + * Extract a tarball to the given directory + */ int unpack(struct archive *a, char *meta, int mask) { int r, fd; - struct stat st; struct archive *w; struct archive_entry *e; - if (stat(meta, &st) == 0 && (mask & ARCHIVE_EXTRACT_NO_OVERWRITE)) { - fprintf(stderr, "%s: File exists\n", meta); - return -1; - } - if ((fd = open(meta, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { perror(meta); return -1; @@ -337,8 +370,11 @@ install(char *rootfs, char *datadir, struct pack *p, int overwrite) int mask = ARCHIVE_EXTRACT_PERM |ARCHIVE_EXTRACT_SECURE_NODOTDOT; - if (overwrite == 0) + if (overwrite == 0) { + if (inspect_collision(rootfs, p) != 0) + return -1; mask |= ARCHIVE_EXTRACT_NO_OVERWRITE; + } /* * ensure we can chdir to the rootfs and write metadata