tLoad package structure from filename - pm - barely a pack manager
 (HTM) git clone git://z3bra.org/pm
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit ab5dde9fdbeed7ac63ed95442f846c5eeabc97af
 (DIR) parent aaa99805e572cf06ba88ae8297dabac628fb1990
 (HTM) Author: z3bra <willyatmailoodotorg>
       Date:   Wed, 30 Dec 2015 01:49:31 +0100
       
       Load package structure from filename
       
       + remove "const" argument from filename
       + replace POSIX basename by in-house solution
       + use pkg->path instead of filename directly
       
       Diffstat:
         M pm.c                                |     119 ++++++++++++++++++++++++-------
       
       1 file changed, 93 insertions(+), 26 deletions(-)
       ---
 (DIR) diff --git a/pm.c b/pm.c
       t@@ -1,5 +1,4 @@
        #include <fcntl.h>
       -#include <libgen.h>
        #include <limits.h>
        #include <stdio.h>
        #include <stdlib.h>
       t@@ -17,12 +16,10 @@
        #define PACKAGE_CACHE "test/cache"
        #define PACKAGE_BUFF_SIZE 8192
        
       -struct pack {
       +struct pkg {
       +        char *path;
                char *name;
                char *version;
       -        char *filename;
       -        char *description;
       -        char *deps;
        };
        
        /* possible actions */
       t@@ -43,14 +40,18 @@ enum {
        enum {
                ERR_INVALID_ACTION = 1,
                ERR_METADATA       = 2,
       +        ERR_PACKAGE_LOAD   = 3,
        };
        
        void usage(char *name);
       -int p_mkdir(const char *dir, mode_t mode);
       -int inspect(int fd, const char *filename);
       -int metadata(const char *datadir, const char *filename);
       -int pack(const char *out, char **filename);
       -int unpack(char *root, const char *in);
       +int p_mkdir(char *dir, mode_t mode);
       +char *base_name(char *path);
       +int inspect(int fd, char *filename);
       +int metadata(char *datadir, char *filename);
       +int pack(char *out, char **filename);
       +int unpack(char *root, char *in);
       +struct pkg *pack_load_file(char *file);
       +struct pkg *pack_load(char *name);
        
        char *argv0;
        
       t@@ -65,7 +66,7 @@ usage(char *name)
         * http://nion.modprobe.de/blog/archives/357-Recursive-directory-creation.html
         */
        int
       -p_mkdir(const char *dir, mode_t mode)
       +p_mkdir(char *dir, mode_t mode)
        {
                char tmp[PATH_MAX];
                char *p = NULL;
       t@@ -85,10 +86,20 @@ p_mkdir(const char *dir, mode_t mode)
        }
        
        /*
       + * return a pointer to the basename, or NULL if path ends with '/'
       + */
       +char *
       +base_name(char *path)
       +{
       +        char *b = strrchr(path, '/');
       +        return b ? b + 1 : path;
       +}
       +
       +/*
         * write the content of an archive to the given file descriptor
         */
        int
       -inspect(int fd, const char *filename)
       +inspect(int fd, char *filename)
        {
                struct archive *a;
                struct archive_entry *e;
       t@@ -123,7 +134,7 @@ inspect(int fd, const char *filename)
         *        + /deps /asdep /version
         */
        int
       -metadata(const char *datadir, const char *filename)
       +metadata(char *datadir, char *filename)
        {
                int fd, r;
                struct stat st;
       t@@ -131,7 +142,7 @@ metadata(const char *datadir, const char *filename)
        
                name = strdup(filename);
                name = strtok(name, ":");
       -        sprintf(tmp, "%s/%s", datadir, basename(name));
       +        sprintf(tmp, "%s/%s", datadir, base_name(name));
        
                free(name);
        
       t@@ -156,7 +167,7 @@ metadata(const char *datadir, const char *filename)
         * pack mutliple files into an archive
         */
        int
       -pack(const char *out, char **filename)
       +pack(char *out, char **filename)
        {
                struct archive *a;
                struct archive_entry *e;
       t@@ -201,10 +212,10 @@ pack(const char *out, char **filename)
        }
        
        /*
       - * extract files into the gien directory
       + * extract files into the given directory
         */
        int
       -unpack(char *root, const char *in)
       +unpack(char *root, char *in)
        {
                struct archive *a;
                struct archive *w; /* write */
       t@@ -262,10 +273,60 @@ unpack(char *root, const char *in)
                return 0;
        }
        
       +struct pkg *
       +pack_load_file(char *path)
       +{
       +        struct pkg *pack = malloc(sizeof(struct pkg));
       +        char tmp[PATH_MAX];
       +        char *p;
       +
       +        pack->path = strdup(path);
       +        snprintf(tmp, PATH_MAX, "%s", base_name(path));
       +
       +        for (p = tmp; *p && *p != ':'; p++);
       +        if (!*p) {
       +                free(pack);
       +                return NULL;
       +        }
       +        *p = 0;
       +        pack->name = strdup(tmp);
       +        *p = ':';
       +
       +        snprintf(tmp, PATH_MAX, "%s", p + 1);
       +        for (p = tmp; *p && strcmp(p, ".tar.bz2"); p++);
       +        if (!*p) {
       +                free(pack);
       +                return NULL;
       +        }
       +        *p = 0;
       +        pack->version = strdup(tmp);
       +        *p = '.';
       +
       +        return pack;
       +}
       +
       +struct pkg *
       +pack_load(char *name)
       +{
       +        struct pkg *p = NULL;
       +
       +        if (strchr(name, '/'))
       +                p = pack_load_file(name);
       +
       +        if (!p) {
       +                fprintf(stderr, "could not load package %s\n", name);
       +                return NULL;
       +        }
       +
       +        printf("%s - %s (%s)\n", p->name, p->version, p->path);
       +        return p;
       +}
       +
        int
        main (int argc, char **argv)
        {
       -        const char *packname;
       +        char *fn = NULL;
       +        struct pkg *p = NULL;
                uint8_t action = ACTION_INVALID;
        
                ARGBEGIN{
       t@@ -273,15 +334,15 @@ main (int argc, char **argv)
                        if (argc <3) /* what a cute variable */
                                usage(argv0);
                        action = ACTION_PACKAGE;
       -                packname = ARGF();
       +                fn = ARGF();
                        break;
                case 'a':
                        action = ACTION_INSTALL;
       -                packname = EARGF(usage(argv0));
       +                fn = EARGF(usage(argv0));
                        break;
                case 'i':
                        action = ACTION_INSPECT;
       -                packname = EARGF(usage(argv0));
       +                fn = EARGF(usage(argv0));
                        break;
                case 'h':
                default:
       t@@ -289,16 +350,22 @@ main (int argc, char **argv)
                        return 0;
                }ARGEND;
        
       +        if (fn)
       +                p = pack_load(fn);
       +
       +        if (!p)
       +                return ERR_PACKAGE_LOAD;
       +
                switch (action) {
                case ACTION_INSTALL:
       -                if (metadata(PACKAGE_DATA, packname) == 0)
       -                        return unpack(PACKAGE_ROOT, packname);
       -                fprintf(stderr, "could not write metadata for %s\n", packname);
       +                if (metadata(PACKAGE_DATA, p->path) == 0)
       +                        return unpack(PACKAGE_ROOT, p->path);
       +                fprintf(stderr, "could not write metadata for %s\n", p->name);
                        return ERR_METADATA;
                case ACTION_INSPECT:
       -                return inspect(1, packname);
       +                return inspect(1, p->path);
                case ACTION_PACKAGE:
       -                return pack(packname, argv);
       +                return pack(p->path, argv);
                /* handle me, Octave */
                case ACTION_REMOVE:
                case ACTION_UPDATE: