package

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

commit b1feacc60da23576363d8a3d2211a8282fc56ee7
parent cb3cdaedd4c38a14dc712d5b75e0efd2c380842b
Author: Josuah Demangeon <mail@josuah.net>
Date:   Mon,  7 Jan 2019 00:01:52 +0100

add a pack-remove function

Diffstat:
Mfs.c | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mfs.h | 1+
Mpack-build.c | 47++++++++++++++++++++++++++++++++---------------
Mpack-dep.c | 10++++++----
Mpack.c | 21+++++++++++++++++++++
Mpack.h | 4+++-
6 files changed, 152 insertions(+), 54 deletions(-)

diff --git a/fs.c b/fs.c @@ -15,82 +15,137 @@ fs_mkdirr(char *dir) char *d = dir + (*dir == '/'); int end = 0; - do { + while (!end) { d += str_chr(d, '/'); if (*d == '\0') end = 1; *d = '\0'; if (mkdir(dir, 0600) == -1 && errno != EEXIST) return 0; *d = '/'; - - } while (!end); + } return 1; } +static int +fs_rmdirr_recurse(stralloc *path) +{ + DIR *dp; + struct dirent *de; + struct stat st; + size_t n = path->n; + + dp = opendir(path->x); if (dp == NULL) return 0; + + if (!stralloc_append(path, '/')) return 0; + n = path->n; + + errno = 0; + while ((de = readdir(dp))) { + if (str_equal(de->d_name, ".")) continue; + if (str_equal(de->d_name, "..")) continue; + + if (!stralloc_cats(path, de->d_name)) break; + if (!stralloc_append(path, '\0')) break; + + if (lstat(path->x, &st) == -1) break; + + if (S_ISDIR(st.st_mode)) { + if (!fs_rmdirr_recurse(path)) break; + if (rmdir(path->x) == -1) break; + } else { + if (unlink(path->x) == -1) break; + } + + path->n = n; + } + + closedir(dp); + return errno == 0; +} + +int +fs_rmdirr(char const *dir) +{ + stralloc path = STRALLOC_ZERO; + int ret = 0; + + if (!stralloc_copys(&path, dir)) goto err; + + ret = fs_rmdirr_recurse(&path); + +err: stralloc_free(&path); + return ret; +} + int fs_copy(char const *from, char const *to, unsigned int mode) { char buf[1024 * 8]; - int fd_f; - int fd_t; + int fd_from = -1; + int fd_to = -1; int r = -1; int w = -1; - fd_f = open_read(from); if (fd_f == -1) return 0; - fd_t = open_trunc(to); if (fd_t == -1) { close(fd_f); return 0; } + fd_from = open_read(from); if (fd_from == -1) goto err; + fd_to = open_trunc(to); if (fd_to == -1) goto err; if (chmod(to, mode) == -1) goto err; while (1) { - r = read(fd_f, buf, sizeof buf); if (r <= 0) break; - w = write(fd_t, buf, r); if (w < r) break; + r = read(fd_from, buf, sizeof buf); if (r <= 0) break; + w = write(fd_to, buf, r); if (w < r) break; } -err: close(fd_f); - close(fd_t); +err: close(fd_from); + close(fd_to); return r == 0 && w == 0; } static int -fs_copyr_recurse(stralloc *f, stralloc *t) +fs_copyr_recurse(stralloc *from, stralloc *to) { DIR *dp; struct dirent *de; struct stat st; char ln[4096]; + size_t to_n = to->n; + size_t from_n = from->n; + + dp = opendir(from->x); if (!dp) return 0; - dp = opendir(f->x); if (!dp) return 0; + if (!stralloc_append(from, '/')) return 0; + if (!stralloc_append(to, '/')) return 0; + from_n = from->n; + to_n = to->n; errno = 0; while ((de = readdir(dp))) { if (str_equal(de->d_name, ".")) continue; if (str_equal(de->d_name, "..")) continue; - if (!stralloc_append(f, '/')) break; - if (!stralloc_cats(f, de->d_name)) break; - if (!stralloc_append(f, '\0')) break; + if (!stralloc_cats(from, de->d_name)) break; + if (!stralloc_append(from, '\0')) break; - if (!stralloc_append(t, '/')) break; - if (!stralloc_cats(t, de->d_name)) break; - if (!stralloc_append(t, '\0')) break; + if (!stralloc_cats(to, de->d_name)) break; + if (!stralloc_append(to, '\0')) break; - if (lstat(f->x, &st) == -1) break; + if (lstat(from->x, &st) == -1) break; if (S_ISDIR(st.st_mode)) { - if (mkdir(t->x, st.st_mode) == -1) break; - if (!fs_copyr_recurse(f, t)) break; + if (mkdir(to->x, st.st_mode) == -1) break; + if (!fs_copyr_recurse(from, to)) break; } if (S_ISREG(st.st_mode)) { - if (!fs_copy(f->x, t->x, st.st_mode)) break; + if (!fs_copy(from->x, to->x, st.st_mode)) break; } if (S_ISLNK(st.st_mode)) { - if (readlink(f->x, ln, sizeof ln) == -1) break; - if (symlink(ln, t->x) == -1) break; + if (readlink(from->x, ln, sizeof ln) == -1) break; + if (symlink(ln, to->x) == -1) break; } else break; - f->n = mem_rchr(f->x, '/', f->n) - 1; - t->n = mem_rchr(t->x, '/', t->n) - 1; + from->n = from_n; + to->n = to_n; } closedir(dp); @@ -100,16 +155,16 @@ fs_copyr_recurse(stralloc *f, stralloc *t) int fs_copyr(char const *from, char const *to) { - stralloc sa_f = STRALLOC_ZERO; - stralloc sa_t = STRALLOC_ZERO; + stralloc sa_from = STRALLOC_ZERO; + stralloc sa_to = STRALLOC_ZERO; int ret = 0; - if (!stralloc_copys(&sa_f, from)) goto err; - if (!stralloc_copys(&sa_t, to)) goto err; + if (!stralloc_copys(&sa_from, from)) goto err; + if (!stralloc_copys(&sa_to, to)) goto err; - ret = fs_copyr_recurse(&sa_f, &sa_t); + ret = fs_copyr_recurse(&sa_from, &sa_to); -err: stralloc_free(&sa_f); - stralloc_free(&sa_t); +err: stralloc_free(&sa_from); + stralloc_free(&sa_to); return ret; } diff --git a/fs.h b/fs.h @@ -4,5 +4,6 @@ int fs_copy(char const *, char const *, unsigned int); int fs_copyr(char const *, char const *); int fs_mkdirr(char *); +int fs_rmdirr(char const *); #endif diff --git a/pack-build.c b/pack-build.c @@ -55,7 +55,7 @@ err: stralloc_free(&sa_def); return ret; } -static void +static int pack_envset(char const *name, char const *path) { char buf[NAME_MAX]; @@ -64,7 +64,7 @@ pack_envset(char const *name, char const *path) for (i = 0; name[i] != '\0'; ++i) buf[i] = isalnum(name[i]) ? name[i] : '_'; buf[i] = '\0'; - env_set(buf, path); + return env_set(buf, path); } static int @@ -76,13 +76,9 @@ pack_env(pack *p, const char *def, const char *out) char buf[1024]; size_t n; size_t m; - int fd; + int fd = -1; 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; @@ -93,6 +89,10 @@ pack_env(pack *p, const char *def, const char *out) if (!stralloc_append(&path, '\0')) goto err; pack_envset("PREFIX", path.x); + 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), buffer_getline(&b, &line)) { @@ -160,6 +160,13 @@ err: stralloc_free(&path); return 0; } +static void +rm(pack *p, char *dir) +{ + if (!pack_remove(p, dir)) + log_errsys6("could not remove ", dir, "/", p->name, "/", p->ver); +} + int main(int argc, char **argv) { @@ -174,9 +181,9 @@ main(int argc, char **argv) if (argc != 2) log_usage(*argv, "package[/version]"); - def = env_get("PACK_DEF"); if (!def) def = "/etc/pack"; - src = env_get("PACK_SRC"); if (!src) src = "/var/pack"; - out = env_get("PACK_OUT"); if (!out) out = "/usr/pack"; + def = env_get("PACK_DEF"); if (!def) def = PACK_DEF; + src = env_get("PACK_SRC"); if (!src) src = PACK_SRC; + out = env_get("PACK_OUT"); if (!out) out = PACK_OUT; if (stat(def, &st) == -1) log_diesys1(101, def); if (!S_ISDIR(st.st_mode)) errno = ENOTDIR, log_diesys1(101, def); @@ -186,20 +193,30 @@ main(int argc, char **argv) ++argv; n = pack_scan(&p, *argv); - if (!n || (*argv)[n] != '\0') + if (!n || (*argv)[n] != '\0') { + rm(&p, out); log_die2(1, "invalid package name format: ", *argv); + } - if (!pack_version(&p, def)) + if (!pack_version(&p, def)) { + rm(&p, out); log_diesys2(100, "could not read the version of ", p.name); + } - if (!pack_data(&p, def, src)) + if (!pack_data(&p, def, src)) { + rm(&p, out); log_diesys6(100, "copying ", p.name, "'s data from ", def, " to ", src); + } - if (!pack_env(&p, def, out)) + if (!pack_env(&p, def, out)) { + rm(&p, out); log_diesys2(100, "could not set environment variables for ", *argv); + } - if (!pack_build(&p, def, src)) + if (!pack_build(&p, def, src)) { + rm(&p, out); log_diesys2(100, "could not execute build script of ", p.name); + } return 0; } diff --git a/pack-dep.c b/pack-dep.c @@ -88,6 +88,8 @@ main(int argc, char **argv) genalloc packs; size_t i; + if (argc < 2) log_usage(*argv, "package[/version] ..."); + def = env_get("PACK_DEF"); if (!def) def = PACK_DEF; if (stat(def, &st) == -1) log_diesys1(101, def); @@ -99,22 +101,22 @@ main(int argc, char **argv) pack p; size_t n = pack_scan(&p, *argv); - if (n == 0 || (*argv)[n] != '\0') - log_die2(1, "invalid package name: ", *argv); + if (n == 0 || (*argv)[n] != '\0') log_die2(1, "invalid package name: ", *argv); genalloc_append(&packs, p); } if (!pack_dep(&packs, def)) log_diesys1(103, "could not resolve package dependencies"); - for (i = 0; i < genalloc_len(&packs, pack); i++) { + i = genalloc_len(&packs, pack) - 1; + do { char fmt[PACK_FMT]; pack *p = genalloc_get(&packs, pack, i); pack_fmt(p, fmt); buffer_puts(buffer_1, fmt); buffer_putc(buffer_1, '\n'); - } + } while (i-- > 0); buffer_flush(buffer_1); return 0; diff --git a/pack.c b/pack.c @@ -4,6 +4,7 @@ #include "buffer.h" #include "env.h" +#include "fs.h" #include "genalloc.h" #include "mem.h" #include "open.h" @@ -120,3 +121,23 @@ pack_opendepfile(pack const *p, char const *def) err: stralloc_free(&path); return fd; } + +int +pack_remove(pack *p, char const *prefix) +{ + stralloc path; + int ret = 0; + + stralloc_init(&path); + if (!stralloc_copys(&path, prefix)) goto err; + if (!stralloc_append(&path, '/')) goto err; + 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; + + ret = fs_rmdirr(path.x); + +err: stralloc_free(&path); + return ret; +} diff --git a/pack.h b/pack.h @@ -5,8 +5,9 @@ #include "genalloc.h" #define PACK_DEF "/etc/pack" -#define PACK_OUT "/var/pack" +#define PACK_SRC "/var/pack/src" #define PACK_LOG "/var/log/pack" +#define PACK_OUT "/var/pack/pkg" #define PACK_FMT (NAME_MAX * 2 + 1) @@ -16,6 +17,7 @@ typedef struct { } pack; int pack_opendepfile(pack const *, char const *); +int pack_remove(pack *, char const *); int pack_version(pack *, char const *); size_t pack_fmt(pack const *, char *); size_t pack_scan(pack *, char const *);