tAdd function to extract files to PACKAGE_ROOT - pm - barely a pack manager
 (HTM) git clone git://z3bra.org/pm
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 40512c0e9dfffd238b3178ae25f0ea7624137ff3
 (DIR) parent 8a79a86f24490bc8a31d5796f9e506955f6c11d0
 (HTM) Author: z3bra <willyatmailoodotorg>
       Date:   Tue, 22 Dec 2015 12:45:59 +0100
       
       Add function to extract files to PACKAGE_ROOT
       
       Diffstat:
         M pack.c                              |     102 ++++++++++++++++++++++++++------
       
       1 file changed, 85 insertions(+), 17 deletions(-)
       ---
 (DIR) diff --git a/pack.c b/pack.c
       t@@ -9,6 +9,7 @@
        
        #include "arg.h"
        
       +#define PACKAGE_ROOT      "."
        #define PACKAGE_BUFF_SIZE 8192
        
        
       t@@ -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;
        }
       t@@ -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);