package

simple and robust package manager
Log | Files | Refs | README

commit fe49d97332ac094b3815e16e2383f6a7fe8c9c41
parent 8f593641f43b35ba8706b454a899647ff7534bef
Author: Josuah Demangeon <mail@josuah.net>
Date:   Thu,  3 Jan 2019 00:43:52 +0100

pack-build and pack-dep working

Diffstat:
Mfmt.c | 6+++---
Mpack-build.c | 185++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mpack-dep.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpack.c | 131+++++++++----------------------------------------------------------------------
Mpack.h | 4+---
5 files changed, 265 insertions(+), 130 deletions(-)

diff --git a/fmt.c b/fmt.c @@ -71,12 +71,12 @@ fmt_plusminus(char *dest, int i) } size_t -fmt_strn(char *out, size_t n, char const *in) +fmt_strn(char *dest, size_t n, char const *src) { size_t len; - if (*out) return str_copy(out, in, n); - len = str_len(in); + if (*dest) return str_copy(dest, src, n); + len = str_len(src); return n < len ? n : len; } diff --git a/pack-build.c b/pack-build.c @@ -1,34 +1,205 @@ #include <sys/stat.h> #include <errno.h> +#include <ctype.h> +#include "buffer.h" #include "env.h" +#include "fs.h" #include "log.h" #include "pack.h" #include "str.h" +#define nomem() log_diesys1(100, "malloc") + +static int +pack_data(pack const *p, char const *def, char const *src) +{ + stralloc sa_def = STRALLOC_ZERO; + stralloc sa_src = STRALLOC_ZERO; + struct stat sb; + size_t n; + int ret = 0; + + stralloc_init(&sa_src); + if (!stralloc_copys(&sa_src, src)) goto err; + if (!stralloc_append(&sa_src, '/')) goto err; + if (!stralloc_cats(&sa_src, p->name)) goto err; + if (!stralloc_append(&sa_src, '/')) goto err; + if (!stralloc_cats(&sa_src, p->ver)) goto err; + if (!stralloc_append(&sa_src, '\0')) goto err; + + stralloc_init(&sa_def); + if (!stralloc_copys(&sa_def, def)) goto err; + if (!stralloc_append(&sa_def, '/')) goto err; + if (!stralloc_cats(&sa_def, p->name)) goto err; + if (!stralloc_append(&sa_def, '/')) goto err; + n = sa_def.n; + if (!stralloc_cats(&sa_def, "default/data")) goto err; + if (!stralloc_append(&sa_def, '\0')) goto err; + + if (stat(sa_def.x, &sb) == 0) + if (!fs_copyr(sa_def.x, sa_src.x)) goto err; + + sa_def.n = n; + if (!stralloc_cats(&sa_def, p->ver)) goto err; + if (!stralloc_cats(&sa_def, "/data")) goto err; + if (!stralloc_append(&sa_def, '\0')) goto err; + + if (stat(sa_def.x, &sb) == 0) + if (!fs_copyr(sa_def.x, sa_src.x)) goto err; + + ret = 1; + +err: stralloc_free(&sa_def); + stralloc_free(&sa_src); + return ret; +} + +static void +pack_envset(char const *name, char const *path) +{ + char buf[NAME_MAX]; + int i; + + for (i = 0; name[i] != '\0'; ++i) + buf[i] = isalnum(name[i]) ? name[i] : '_'; + buf[i] = '\0'; + env_set(buf, path); +} + +static int +pack_env(pack *p, const char *def, const char *out) +{ + stralloc path; + stralloc line; + buffer b; + char buf[1024]; + size_t n; + size_t m; + int fd; + int ret = 0; + + errno = 0; + fd = pack_opendepfile(p, def); + if (fd == -1) return (errno == ENOTDIR || errno == ENOENT); + + stralloc_init(&path); + if (!stralloc_copys(&path, out)) goto err; + if (!stralloc_append(&path, '/')) goto err; + n = path.n; + if (!stralloc_cats(&path, p->name)) goto err; + if (!stralloc_append(&path, '/')) goto err; + if (!stralloc_cats(&path, p->ver)) goto err; + if (!stralloc_append(&path, '\0')) goto err; + pack_envset("PREFIX", path.x); + + buffer_init(&b, &read, fd, buf, sizeof buf); + stralloc_init(&line); + while (stralloc_zero(&line), buffer_getline(&b, &line)) { + pack new; + + stralloc_append(&line, '\0'); + m = pack_scan(&new, line.x); if (m == 0) goto err; + if (line.x[m] != '\n' && line.x[m] != '\0') goto err; + if (!pack_version(&new, def)) goto err; + + path.n = n; + if (!stralloc_cats(&path, new.name)) goto err; + if (!stralloc_append(&path, '/')) goto err; + if (!stralloc_cats(&path, new.ver)) goto err; + if (!stralloc_append(&path, '\0')) goto err; + pack_envset(new.name, path.x); + } + + ret = 1; + +err: stralloc_free(&path); + close(fd); + return ret; +} + +static int +pack_build(pack const *p, char const *def, char const *src) +{ + stralloc path; + char *argv[] = { "build", NULL }; + size_t n; + + stralloc_init(&path); + + if (!stralloc_copys(&path, src)) goto err; + if (!stralloc_append(&path, '/')) goto err; + if (!stralloc_cats(&path, p->name)) goto err; + if (!stralloc_append(&path, '/')) goto err; + n = path.n; + if (!stralloc_cats(&path, p->ver)) goto err; + if (!stralloc_append(&path, '\0')) goto err; + + if (chdir(path.x) == -1) goto err; + + if (!stralloc_copys(&path, def)) goto err; + if (!stralloc_append(&path, '/')) goto err; + if (!stralloc_cats(&path, p->name)) goto err; + if (!stralloc_append(&path, '/')) goto err; + n = path.n; + if (!stralloc_cats(&path, p->ver)) goto err; + if (!stralloc_cats(&path, "/build")) goto err; + if (!stralloc_append(&path, '\0')) goto err; + + execv(path.x, argv); + if (!(errno == ENOTDIR || errno == ENOENT)) goto err; + + path.n = n; + if (!stralloc_cats(&path, "default/build")) goto err; + if (!stralloc_append(&path, '\0')) goto err; + + execv(path.x, argv); + if (!(errno == ENOTDIR || errno == ENOENT)) goto err; + +err: stralloc_free(&path); + return 0; +} + int main(int argc, char **argv) { (void)argc; (void)argv; char *def; + char *src; char *out; pack p; struct stat st; + size_t n; - str_copy(p.name, "dwm", sizeof p.name); - str_copy(p.ver, "git", sizeof p.ver); + if (argc != 2) log_usage(*argv, "package[/version]"); def = env_get("PACK_DEF"); if (!def) def = "/etc/pack"; - out = env_get("PACK_OUT"); if (!out) out = "/var/pack"; + src = env_get("PACK_SRC"); if (!src) src = "/var/pack"; + out = env_get("PACK_OUT"); if (!out) out = "/usr/pack"; if (stat(def, &st) == -1) log_diesys1(101, def); if (!S_ISDIR(st.st_mode)) errno = ENOTDIR, log_diesys1(101, def); - if (stat(out, &st) == -1) log_diesys1(101, out); - if (!S_ISDIR(st.st_mode)) errno = ENOTDIR, log_diesys1(101, out); + if (stat(src, &st) == -1) log_diesys1(101, src); + if (!S_ISDIR(st.st_mode)) errno = ENOTDIR, log_diesys1(101, src); + + ++argv; + + n = pack_scan(&p, *argv); + if (!n || (*argv)[n] != '\0') + log_die2(1, "invalid package name format: ", *argv); + + if (!pack_version(&p, def)) + log_diesys2(100, "could not read the version of ", p.name); + + if (!pack_data(&p, def, src)) + log_diesys6(100, "copying ", p.name, "'s data from ", def, " to ", src); + + if (!pack_env(&p, def, out)) + log_diesys2(100, "could not set environment variables for ", *argv); - if (!pack_data(&p, def, out)) - log_diesys6(1, "copying ", p.name, "'s data directory from ", def, " to ", out); + if (!pack_build(&p, def, src)) + log_diesys2(100, "could not execute build script of ", p.name); return 0; } diff --git a/pack-dep.c b/pack-dep.c @@ -9,6 +9,75 @@ #include "str.h" #include "buffer.h" +static int +pack_hasdep(pack const *p, genalloc *packs) +{ + size_t i; + + for (i = 0; i < genalloc_len(packs, pack); ++i) { + pack *x = genalloc_get(packs, pack, i); + if (str_equal(x->name, p->name)) + if (str_equal(x->ver, p->ver)) + return 1; + } + + return 0; +} + +static int +pack_dep_recurse(pack const *p, genalloc *packs, char const *def) +{ + stralloc path = STRALLOC_ZERO; + stralloc line = STRALLOC_ZERO; + buffer b; + char buf[1024]; + ssize_t r; + int fd = -1; + int ret = 0; + + errno = 0; + fd = pack_opendepfile(p, def); + if (fd == -1) return (errno == ENOTDIR || errno == ENOENT); + + buffer_init(&b, &read, fd, buf, sizeof buf); + stralloc_init(&line); + while (stralloc_zero(&line), (r = buffer_getline(&b, &line))) { + pack new; + size_t n; + + stralloc_append(&line, '\0'); + n = pack_scan(&new, line.x); if (n == 0) goto err; + if (line.x[n] != '\n' && line.x[n] != '\0') goto err; + if (!pack_version(&new, def)) goto err; + + if (pack_hasdep(&new, packs)) continue; + if (!genalloc_append(packs, new)) goto err; + if (!pack_dep_recurse(&new, packs, def)) goto err; + } + + ret = (r == 0); + +err: stralloc_free(&line); + stralloc_free(&path); + close(fd); + return ret; +} + +static int +pack_dep(genalloc *packs, char const *def) +{ + size_t n = genalloc_len(packs, pack); + size_t i; + + for (i = 0; i < n; ++i) { + pack *p = genalloc_get(packs, pack, i); + if (!pack_version(p, def)) return 0; + if (!pack_dep_recurse(p, packs, def)) return 0; + } + + return 1; +} + int main(int argc, char **argv) { diff --git a/pack.c b/pack.c @@ -1,10 +1,10 @@ -#include <sys/stat.h> #include <ctype.h> -#include <unistd.h> #include <errno.h> +#include <unistd.h> #include "buffer.h" -#include "fs.h" +#include "env.h" +#include "genalloc.h" #include "mem.h" #include "open.h" #include "pack.h" @@ -89,137 +89,34 @@ err: stralloc_free(&path); return ret; } -static int -pack_dep_has(pack const *p, genalloc *packs) -{ - size_t i; - - for (i = 0; i < genalloc_len(packs, pack); ++i) { - pack *x = genalloc_get(packs, pack, i); - if (str_equal(x->name, p->name)) - if (str_equal(x->ver, p->ver)) - return 1; - } - - return 0; -} - int -pack_dep_recurse(pack const *p, genalloc *packs, char const *def) +pack_opendepfile(pack const *p, char const *def) { stralloc path; - stralloc line; - buffer b; - char buf[1024]; - ssize_t r; + size_t n; int fd = -1; - int ret = 0; stralloc_init(&path); if (!stralloc_copys(&path, def)) goto err; if (!stralloc_append(&path, '/')) goto err; if (!stralloc_cats(&path, p->name)) goto err; if (!stralloc_append(&path, '/')) goto err; + n = path.n; if (!stralloc_cats(&path, p->ver)) goto err; if (!stralloc_cats(&path, "/dependencies")) goto err; - if (!stralloc_append(&path, '\0')) goto err; + if (!stralloc_append(&path, '\0')) goto err; errno = 0; fd = open_read(path.x); if (errno == ENOTDIR || errno == ENOENT) { - stralloc_zero(&path); - if (!stralloc_copys(&path, def)) goto err; - if (!stralloc_append(&path, '/')) goto err; - if (!stralloc_cats(&path, p->name)) goto err; - if (!stralloc_cats(&path, "/default/dependencies")) goto err; - if (!stralloc_append(&path, '\0')) goto err; - } - - errno = 0; - fd = open_read(path.x); - stralloc_free(&path); - if (errno == ENOTDIR || errno == ENOENT) return 1; - if (fd == -1) return 0; - - buffer_init(&b, &read, fd, buf, sizeof buf); - stralloc_init(&line); - while (stralloc_zero(&line), (r = buffer_getline(&b, &line))) { - pack new; - size_t n; - - stralloc_append(&line, '\0'); - n = pack_scan(&new, line.x); if (n == 0) goto err; - pack_version(&new, def); - - if (pack_dep_has(&new, packs)) continue; - if (!genalloc_append(packs, new)) goto err; - if (!pack_dep_recurse(&new, packs, def)) goto err; + path.n = n; + if (!stralloc_cats(&path, "default/dependencies")) goto err; + if (!stralloc_append(&path, '\0')) goto err; + errno = 0; + fd = open_read(path.x); } - ret = (r == 0); - -err: stralloc_free(&line); - stralloc_free(&path); - close(fd); - return ret; -} - -int -pack_dep(genalloc *packs, char const *def) -{ - size_t n = genalloc_len(packs, pack); - size_t i; - - for (i = 0; i < n; ++i) { - pack *p = genalloc_get(packs, pack, i); - pack_version(p, def); - if (!pack_dep_recurse(p, packs, def)) return 0; - } - - return 1; -} - -int -pack_data(pack const *p, char const *def, char const *out) -{ - stralloc sa_def = STRALLOC_ZERO; - stralloc sa_out = STRALLOC_ZERO; - int ret = 0; - struct stat sb; - - stralloc_init(&sa_out); - if (!stralloc_copys(&sa_out, out)) goto err; - if (!stralloc_append(&sa_out, '/')) goto err; - if (!stralloc_cats(&sa_out, p->name)) goto err; - if (!stralloc_append(&sa_out, '/')) goto err; - if (!stralloc_cats(&sa_out, p->ver)) goto err; - if (!stralloc_append(&sa_out, '\0')) goto err; - - stralloc_init(&sa_def); - if (!stralloc_copys(&sa_def, def)) goto err; - if (!stralloc_append(&sa_def, '/')) goto err; - if (!stralloc_cats(&sa_def, p->name)) goto err; - if (!stralloc_append(&sa_def, '/')) goto err; - if (!stralloc_cats(&sa_def, "default")) goto err; - if (!stralloc_cats(&sa_def, "/data")) goto err; - if (!stralloc_append(&sa_def, '\0')) goto err; - - if (stat(sa_def.x, &sb) == 0) - if (!fs_copyr(sa_def.x, sa_out.x)) goto err; - - sa_def.n = mem_rchr(sa_def.x, sa_def.n, '/') - 1; - sa_def.n = mem_rchr(sa_def.x, sa_def.n, '/'); - if (!stralloc_cats(&sa_def, p->ver)) goto err; - if (!stralloc_cats(&sa_def, "/data")) goto err; - if (!stralloc_append(&sa_def, '\0')) goto err; - - if (stat(sa_def.x, &sb) == 0) - if (!fs_copyr(sa_def.x, sa_out.x)) goto err; - - ret = 1; - -err: stralloc_free(&sa_def); - stralloc_free(&sa_out); - return ret; +err: stralloc_free(&path); + return fd; } diff --git a/pack.h b/pack.h @@ -15,9 +15,7 @@ typedef struct { char ver[NAME_MAX]; } pack; -int pack_data(pack const *, char const *, char const *); -int pack_dep(genalloc *, char const *); -int pack_dep_recurse(pack const *, genalloc *, char const *); +int pack_opendepfile(pack const *, char const *); int pack_version(pack *, char const *); size_t pack_fmt(pack const *, char *); size_t pack_scan(pack *, char const *);