tHandle reading arguments from stdin - pm - barely a pack manager
 (HTM) git clone git://z3bra.org/pm
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit a96b471ef2c41c2d2a6d2763b8b869561b54c00a
 (DIR) parent c293e2c77808dc0c1f1b292111dd18dd19280a46
 (HTM) Author: z3bra <willyatmailoodotorg>
       Date:   Mon, 18 Apr 2016 18:12:30 +0200
       
       Handle reading arguments from stdin
       
       This has been implemented for the install/update/delete actions.
       For install/update, `pm` will read path of files to be installed.
       For delete, `pm` expects pack names to be deleted.
       
       The implementation has to be cleaned up, as the code is duplicated and
       featured directly in the main().
       But for now, it works!
       
       Diffstat:
         M pm.c                                |      62 ++++++++++++++++++++++++++-----
       
       1 file changed, 52 insertions(+), 10 deletions(-)
       ---
 (DIR) diff --git a/pm.c b/pm.c
       t@@ -50,6 +50,7 @@ void usage(char *name);
        int is_empty(char *dir);
        int mkdir_parents(char *dir, mode_t mode);
        char *base_name(char *path);
       +char *slurp(int fd);
        
        struct pack *pack_load(char *path);
        void pack_free(struct pack *p);
       t@@ -67,15 +68,13 @@ int delete_node(char *path);
        int delete_content(char *map, size_t size);
        int delete(const char *rootfs, const char *datadir, const char *name);
        
       -char *argv0;
       -
        int verbose = 0;
        int overwrite = 0;
        
        void
        usage(char *name)
        {
       -        fprintf(stderr, "usage: %s -adfi <pack>\n" , name);
       +        fprintf(stderr, "usage: %s -adfiuv [pack]\n" , name);
        }
        
        
       t@@ -140,6 +139,32 @@ base_name(char *path)
                return b ? b + 1 : path;
        }
        
       +/*
       + * Fills the array passed as argument with lines read from the file descriptor.
       + * Returns the number of lines read
       + */
       +char *
       +slurp(int fd)
       +{
       +        size_t len = 0;
       +        off_t i = 0;
       +        char *path = NULL;
       +
       +        path = malloc(PATH_MAX);
       +        while ((len = read(fd, &path[i], 1)) > 0) {
       +                if (i >= PATH_MAX || path[i] == '\n') {
       +                        path[i] = '\0';
       +                        break;
       +                }
       +                i++;
       +        }
       +
       +        if (i == 0) {
       +                free(path);
       +                path = NULL;
       +        }
       +        return path;
       +}
        
        /*
         * Check for collisions between the filesystem and the tarball
       t@@ -650,7 +675,7 @@ int
        main (int argc, char **argv)
        {
                int r = 0;
       -        char *n = NULL;
       +        char *n = NULL, *argv0;
                struct pack *p = NULL;
                uint8_t action = ACTION_DEFAULT;
                char rootfs[PATH_MAX] = "";
       t@@ -688,27 +713,44 @@ main (int argc, char **argv)
        
                switch (action) {
                case ACTION_INSTALL:
       -                while (*argv) {
       -                        if ((p = pack_load(*(argv++)))) {
       +                /* black magic to read from stdin if no arguments given */
       +                while ((argc>0 && (n = *argv++) != NULL) || (n=slurp(0)) != NULL) {
       +                        if ((p = pack_load(n))) {
                                        r += install(rootfs, datadir, p);
                                        pack_free(p);
                                }
       +                        /* slurp() allocates memory that must be freed */
       +                        if (argc == 0) {
       +                                free(n);
       +                        }
                        }
                        break;
        
                case ACTION_UPDATE:
       -                while (*argv) {
       -                        if ((p = pack_load(*(argv++)))) {
       +                /* black magic to read from stdin if no arguments given */
       +                while ((argc>0 && (n = *argv++) != NULL) || (n=slurp(0)) != NULL) {
       +                        if ((p = pack_load(n))) {
                                        if (delete(rootfs, datadir, p->name) == 0)
                                                r += install(rootfs, datadir, p);
                                        pack_free(p);
                                }
       +                        /* slurp() allocates memory that must be freed */
       +                        if (argc == 0) {
       +                                free(n);
       +                        }
                        }
                        break;
        
                case ACTION_DELETE:
       -                while (*argv)
       -                        r += delete(rootfs, datadir, *argv++);
       +                /* black magic to read from stdin if no arguments given */
       +                while ((argc>0 && (n = *argv++) != NULL) || (n=slurp(0)) != NULL) {
       +                        r += delete(rootfs, datadir, n);
       +
       +                        /* slurp() allocates memory that must be freed */
       +                        if (argc == 0) {
       +                                free(n);
       +                        }
       +                }
                        break;
        
                case ACTION_INSPECT: