pm

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

commit 40512c0e9dfffd238b3178ae25f0ea7624137ff3
parent 8a79a86f24490bc8a31d5796f9e506955f6c11d0
Author: z3bra <willyatmailoodotorg>
Date:   Tue Dec 22 12:45:59 2015

Add function to extract files to PACKAGE_ROOT

Diffstat:
 pack.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 85 insertions(+), 17 deletions(-)

diff --git a/pack.c b/pack.c @@ -9,6 +9,7 @@ #include "arg.h" +#define PACKAGE_ROOT "." #define PACKAGE_BUFF_SIZE 8192 @@ -76,27 +77,90 @@ pack_creat(const char *out, char **filename) while (*filename) { stat(*filename, &st); - e = archive_entry_new(); + if (!S_ISDIR(st.st_mode)) { + e = archive_entry_new(); - archive_entry_set_pathname(e, *filename); - archive_entry_set_size(e, st.st_size); - archive_entry_set_filetype(e, AE_IFREG); - archive_entry_set_mode(e, st.st_mode); - archive_write_header(a, e); + archive_entry_set_pathname(e, *filename); + archive_entry_set_size(e, st.st_size); + archive_entry_set_filetype(e, AE_IFREG); + archive_entry_set_mode(e, st.st_mode); + archive_write_header(a, e); - fd = open(*filename, O_RDONLY); - if (fd < 0) - return fd; + fd = open(*filename, O_RDONLY); + if (fd < 0) + return fd; - while ((len = read(fd, buf, sizeof(buf))) > 0) - archive_write_data(a, buf, len); + while ((len = read(fd, buf, sizeof(buf))) > 0) + archive_write_data(a, buf, len); - close(fd); - archive_entry_free(e); + close(fd); + archive_entry_free(e); + } filename++; } - archive_write_free(a); + return 0; +} + + +/* + * create the files contained in the archive under the given directory + */ +int +pack_unpack(char *root, const char *in) +{ + struct archive *a; + struct archive *w; /* write */ + struct archive_entry *e; + const void *buf; + size_t len; + off_t off; + int r; + int mask = ARCHIVE_EXTRACT_PERM + |ARCHIVE_EXTRACT_NO_OVERWRITE + |ARCHIVE_EXTRACT_SECURE_NODOTDOT; + + /* extract the package at the specified root */ + if (chdir(root) < 0) { + perror("chdir"); + return -1; + } + + a = archive_read_new(); + archive_read_support_filter_all(a); + archive_read_support_format_all(a); + + w = archive_write_disk_new(); + archive_write_disk_set_options(w, mask); + archive_write_disk_set_standard_lookup(w); + + r = archive_read_open_filename(a, in, 0); + if (r != ARCHIVE_OK) + return r; + + while (archive_read_next_header(a, &e) != ARCHIVE_EOF) { + + r = archive_write_header(w, e); + if (r < ARCHIVE_WARN) { + fprintf(stderr, "%s\n", archive_error_string(w)); + return r; + } + + if (archive_entry_size(e) > 0) + do { + r = archive_read_data_block(a, &buf, &len, &off); + if (r != ARCHIVE_OK) + return r; + /* returns the number of bytes written */ + r = archive_write_data_block(w, buf, len, off); + } while (r > 0); + if (r < 0) + return r; + } + archive_read_close(a); + archive_read_free(a); + archive_write_close(w); + archive_write_free(w); return 0; } @@ -104,15 +168,19 @@ pack_creat(const char *out, char **filename) int main (int argc, char **argv) { - const char *out; + const char *fn; ARGBEGIN{ case 'l': pack_list(EARGF(usage(argv0))); break; case 'c': - out = EARGF(usage(argv0)); - pack_creat(out, ++argv); + fn = EARGF(usage(argv0)); + pack_creat(fn, ++argv); + break; + case 'e': + fn = EARGF(usage(argv0)); + pack_unpack(PACKAGE_ROOT, fn); break; default: usage(argv0);