pm

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

commit 74821245d8bf64da7337c48a14622371499a8e4f
parent 95c3494e630efb221d053b015b1aeb0276c8ed36
Author: z3bra <willyatmailoodotorg>
Date:   Tue Jun 21 01:41:37 +0200

Use regexes to extract pack metadata

This allow specifying more complex filename format, such has having different
extenstions (useful to accept multipel compression algos for example).
this also make loading from either filename/packname easier, as a pack name
would never match the filename format.

Also, this commit adds gzip compression support... Don't tell anyone!

Diffstat:
pm.c | 92+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 57 insertions(+), 35 deletions(-)
diff --git a/pm.c b/pm.c @@ -2,6 +2,7 @@ #include <dirent.h> #include <fcntl.h> #include <limits.h> +#include <regex.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -17,8 +18,7 @@ #define PACK_ROOT (getenv("ROOT")?getenv("ROOT"):"") #define PACK_DATA "var/pm" #define PACK_BUFF_SIZE 8192 -#define PACK_SEPARATOR '#' -#define PACK_EXTENSION ".tar.bz2" +#define PACK_FORMAT "\\(.*\\)#\\(.*\\)\\.tar\\.\\(bz2\\|gz\\)" #define log(l,...) if(verbose>=l){printf(__VA_ARGS__);} @@ -59,6 +59,7 @@ void usage(char *name); int is_empty(char *dir); int mkdir_parents(char *dir, mode_t mode); char *base_name(char *path); +int re_match(const char *re, const char *str); struct pack *pack_load_tarball(char *path); struct pack *pack_load_metadata(const char *datadir, char *name); @@ -157,52 +158,70 @@ base_name(char *path) /* + * Check wether a string matches a regular expression + */ +int +re_match(const char *re, const char *str) +{ + int retval = -1; + regex_t preg; + regmatch_t sub[1]; + + if (regcomp(&preg, re, 0)) { + fprintf(stderr, "%s: invalid expression\n", re); + return -1; + } + + retval = regexec(&preg, str, 1, sub, 0); + regfree(&preg); + + return retval; +} + + +/* * Load a pack from a tarball and return a pack structure */ struct pack * pack_load_tarball(char *path) { - int fd; + struct stat st; struct pack *pack = NULL; - char tmp[PATH_MAX] = ""; - char *p; + char *fn, *regex = PACK_FORMAT; + regex_t preg; + regmatch_t sub[3]; + size_t i, nmatch = 3, sublen[3]; - if ((fd = open(path, O_RDONLY)) < 0) { + if (stat(path, &st) < 0) { perror(path); return NULL; } - close(fd); + + fn = base_name(path); + + regcomp(&preg, regex, 0); + regexec(&preg, fn, nmatch, sub, 0); if (!(pack = malloc(sizeof(struct pack)))) { perror(path); + regfree(&preg); return NULL; } - pack->path = NULL; - pack->name = NULL; - pack->version = NULL; + for (i=0; i<nmatch; i++) + sublen[i] = sub[i].rm_eo - sub[i].rm_so; - pack->path = strdup(path); - snprintf(tmp, PATH_MAX, "%s", base_name(path)); + pack->path = strdup(fn); + pack->name = malloc(sublen[1] + 1); + pack->version = malloc(sublen[2] + 1); - for (p = tmp; *p && *p != PACK_SEPARATOR; p++); - if (!*p) { - pack_free(pack); - return NULL; - } - *p = 0; - pack->name = strdup(tmp); - *p = PACK_SEPARATOR; + strncpy(pack->name, fn+sub[1].rm_so, sublen[1]); + strncpy(pack->version, fn+sub[2].rm_so, sublen[2]); - snprintf(tmp, PATH_MAX, "%s", p + 1); - for (p = tmp; *p && strcmp(p, PACK_EXTENSION); p++); - if (!*p) { - pack_free(pack); - return NULL; - } - *p = 0; - pack->version = strdup(tmp); - *p = '.'; + pack->name[sublen[1]] = 0; + pack->version[sublen[2]] = 0; + + regfree(&preg); return pack; } @@ -220,8 +239,10 @@ pack_load_metadata(const char *datadir, char *name) snprintf(tmp, PATH_MAX, "%s/%s", datadir, name); - if (stat(tmp, &st) < 0) + if (stat(tmp, &st) < 0) { + perror(tmp); return NULL; + } if (!(pack = malloc(sizeof(struct pack)))) { perror("malloc"); @@ -244,13 +265,12 @@ struct pack * pack_load(const char *datadir, char *path) { struct pack *p = NULL; - struct stat st; - if ((p = pack_load_metadata(datadir, path)) != NULL) - return p; - - if (!stat(path, &st) && S_ISREG(st.st_mode)) + if (re_match(PACK_FORMAT, path) == 0) { p = pack_load_tarball(path); + } else { + p = pack_load_metadata(datadir, path); + } return p; } @@ -301,6 +321,7 @@ pack_extract(const char *rootfs, const char *datadir, struct pack *p) } a = archive_read_new(); + archive_read_support_filter_gzip(a); archive_read_support_filter_bzip2(a); archive_read_support_format_tar(a); @@ -484,6 +505,7 @@ inspect_collision(const char *rootfs, struct pack *p) struct archive_entry *e; a = archive_read_new(); + archive_read_support_filter_gzip(a); archive_read_support_filter_bzip2(a); archive_read_support_format_tar(a);