package

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

commit 3f59d0ea07fb48815d9848d586b3ee481a9cb27f
parent 0fa9b7bcf545a957b73abf96bf3b0aa9483a9e2c
Author: Josuah Demangeon <mail@josuah.net>
Date:   Sun, 13 Jan 2019 00:02:10 +0100

first version making a whole loop successfully

Diffstat:
M.gitignore | 1+
MMakefile | 23+++++++++++++++--------
Mbin/pack-ftp | 8++------
Mbin/pack-get | 20++++++++------------
Mbin/pack-http | 10++--------
Mbin/pack-tar | 8++------
Dktrace.out | 0
Mpack-add.c | 82++++++++++++++++++++-----------------------------------------------------------
Mpack-build.c | 18+++++++++++-------
Apack-get.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpack.c | 167+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mpack.h | 3++-
12 files changed, 266 insertions(+), 174 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,4 @@ pack-build pack-add pack-dep +pack-get diff --git a/Makefile b/Makefile @@ -1,5 +1,7 @@ +bin = pack-build pack-dep pack-add pack-get + .PHONY: all -all: pack-build pack-dep pack-add +all: ${bin} .PHONY: clean clean: @@ -9,13 +11,13 @@ clean: install: all mkdir -p ${PREFIX} cp -r bin ${PREFIX} - cp pack-build pack-dep pack-add ${PREFIX}/bin + cp ${bin} ${PREFIX}/bin pack-build-o = pack-build.o pack.o buffer.o fmt.o fs.o log.o mem.o str.o stralloc.o forkexec.o pack-build: ${pack-build-o} ./make-bin $@ ${pack-build-o} -pack-dep-o = pack-dep.o pack.o buffer.o fmt.o fs.o log.o mem.o str.o stralloc.o +pack-dep-o = pack-dep.o pack.o buffer.o fmt.o fs.o log.o mem.o str.o stralloc.o forkexec.o pack-dep: ${pack-dep-o} ./make-bin $@ ${pack-dep-o} @@ -23,18 +25,23 @@ pack-add-o = pack-add.o pack.o buffer.o fmt.o fs.o log.o mem.o str.o stralloc.o pack-add: ${pack-add-o} ./make-bin $@ ${pack-add-o} +pack-get-o = pack-get.o pack.o buffer.o fmt.o fs.o log.o mem.o str.o stralloc.o forkexec.o +pack-get: ${pack-get-o} + ./make-bin $@ ${pack-get-o} + .c.o: ./make-o $< buffer.o: buffer.c buffer.h mem.h stralloc.h fmt.o: fmt.c fmt.h str.h -forkexec.o: forkexec.c forkexec.h +forkexec.o: forkexec.c open.h forkexec.h fs.o: fs.c fs.h mem.h open.h str.h stralloc.h log.o: log.c buffer.h log.h mem.o: mem.c mem.h -pack-add.o: pack-add.c pack.h -pack-build.o: pack-build.c buffer.h env.h fs.h log.h pack.h str.h -pack-dep.o: pack-dep.c genalloc.h env.h log.h pack.h str.h buffer.h -pack.o: pack.c buffer.h env.h fs.h genalloc.h mem.h open.h pack.h stralloc.h +pack-add.o: pack-add.c buffer.h env.h forkexec.h fs.h genalloc.h log.h pack.h str.h fmt.h open.h +pack-build.o: pack-build.c buffer.h env.h forkexec.h fs.h log.h open.h pack.h str.h stralloc.h +pack-dep.o: pack-dep.c buffer.h env.h fs.h genalloc.h log.h pack.h str.h +pack-get.o: pack-get.c buffer.h open.h pack.h stralloc.h +pack.o: pack.c buffer.h env.h fmt.h forkexec.h fs.h genalloc.h mem.h open.h pack.h stralloc.h str.o: str.c str.h stralloc.o: stralloc.c mem.h fmt.h str.h stralloc.h diff --git a/bin/pack-ftp b/bin/pack-ftp @@ -4,9 +4,5 @@ pack=${1%/*} version=${1#*/} url=$2 -trap "rm -f '$PACK/tar/$pack/$version.tar'" INT TERM EXIT - -mkdir -p "$PACK/src/$pack/$version" "$PACK/tar/$pack" -wget -O- "$url" | pack-extract "$url" >$PACK/tar/$pack/$version.tar - -trap - INT TERM EXIT +mkdir -p "$PACK/tar/$pack" +[ -f "$PACK/tar/$1.tar" ] || wget --no-check-certificate -O- "$url" | pack-extract "$url" >$PACK/tar/$1.tar diff --git a/bin/pack-get b/bin/pack-get @@ -1,19 +1,15 @@ #!/bin/sh -e -PACK=${PACK:-/var/pack} -IFS=/; set -- $1; IFS= +PACK_TAR=${PACK_TAR:-/var/pack/tar} +PACK_DEF=${PACK_TAR:-/etc/pack} pack=${1%/*} version=${1#*/} -if [ -d "$PACK/src/$pack/$version" ]; then exit 0; fi -mkdir -p "$PACK/log/$pack/$version" -exec >$PACK/log/$pack/$version/get 2>&1 - -test -f "$PACK/tar/$version/$pack.tar" || +test -f "$PACK_TAR/$version/$pack.tar" || while IFS= read -r url; do case $url in - (http://*|https://*) pack-http "$pack" "$version" "$url" ;; - (git://*) pack-git "$pack" "$version" "$url" ;; - (ftp://*|ftps://*) pack-ftp "$pack" "$version" "$url" ;; - (cvs://*) pack-cvs "$pack" "$version" "$url" ;; + (http://*|https://*) pack-http "$pack/$version" "$url" ;; + (git://*) pack-git "$pack/$version" "$url" ;; + (ftp://*|ftps://*) pack-ftp "$pack/$version" "$url" ;; + (cvs://*) pack-cvs "$pack/$version" "$url" ;; esac -done </etc/pack/$pack/$version/uri +done <$PACK_DEF/$pack/$version/uri diff --git a/bin/pack-http b/bin/pack-http @@ -4,11 +4,5 @@ pack=${1%/*} version=${1#*/} url=$2 -trap "rm -f '/etc/pack/tar/$pack/$version.tar'" INT TERM EXIT - -mkdir -p "$PACK/src/$pack/$version" "$PACK/tar/$pack" -if [ ! -f "$PACK/tar/$pack/$version.tar" ]; then - wget --no-check-certificate -O- "$url" | pack-extract "$url" >/var/pack/tar/$pack/$version.tar -fi - -trap - INT TERM EXIT +mkdir -p "$PACK/tar/$pack" +[ -f "$PACK/tar/$1.tar" ] || wget --no-check-certificate -O- "$url" | pack-extract "$url" >$PACK/tar/$1.tar diff --git a/bin/pack-tar b/bin/pack-tar @@ -1,10 +1,8 @@ #!/bin/sh -e PACK_SRC=${PACK_SRC:-/var/pack/src} PACK_TAR=${PACK_TAR:-/var/pack/tar} -pack=${1%/*} -version=${1#*/} - -trap "rm -rf '$PACK/src/$pack/$version'" EXIT TERM INT +IFS=/; set -- $1; IFS= +pack=${1:?} version=${2:?} mkdir -p "$PACK/src/$pack/$version" tar -xv -f "$PACK/tar/$pack/$version.tar" -C "$PACK/src/$pack/$version" @@ -12,5 +10,3 @@ if [ "$(ls "$PACK/src/$pack/$version" | wc -l | tr -cd 0-9)" = 1 ]; then ! mv "$PACK/src/$pack/$version/"*/* "$PACK/src/$pack/$version" ! rmdir "$PACK/src/$pack/$version"/* 2>/dev/null fi - -trap - EXIT TERM INT diff --git a/ktrace.out b/ktrace.out Binary files differ. diff --git a/pack-add.c b/pack-add.c @@ -11,8 +11,7 @@ #include "pack.h" #include "str.h" #include "fmt.h" - -#define nl() write(2, "\n", 1) +#include "open.h" void die_nomem(void) @@ -21,82 +20,44 @@ die_nomem(void) } void -rm(char const *dir, pack const *p) -{ - stralloc sa; - - stralloc_init(&sa); - if (!stralloc_cats(&sa, dir)) die_nomem(); - if (!stralloc_cats(&sa, "/")) die_nomem(); - if (!stralloc_cats(&sa, p->name)) die_nomem(); - if (!stralloc_0(&sa)) die_nomem(); - if (!fs_remove_r(sa.x) && errno != ENOTDIR && errno != ENOENT) - log_errsys2("could not delete ", sa.x); - stralloc_free(&sa); -} - -void -step(pack const *p, char const *step, char const *log, char const *dir) +step(pack const *p, char const *cmd, char const *log, char const *dir) { - char fmt[PACK_FMT]; - char const *argv[] = { NULL, NULL, NULL }; - stralloc sa; int x; buffer_puts(buffer_2, " "); - buffer_puts(buffer_2, step + (str_start(step, "pack-") ? 5 : 0)); + buffer_puts(buffer_2, cmd + (str_start(cmd, "pack-") ? 5 : 0)); buffer_puts(buffer_2, " "); buffer_flush(buffer_2); - stralloc_init(&sa); - if (!stralloc_cats(&sa, log)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->name)) goto err; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_0(&sa)) goto err; - if (!fs_mkdir_r(sa.x, 0640)) goto err; - sa.n--; - if (!stralloc_cats(&sa, "/")) goto err; - if (!stralloc_cats(&sa, step)) goto err; - if (!stralloc_0(&sa)) goto err; - - argv[0] = step; - pack_fmt(p, fmt); - argv[1] = fmt; - x = forkexec_wait_redir(argv, sa.x); - if (x != 0) { + switch ((x = pack_step(p, cmd, log))) { char fmt[4]; + case -1: + log_diesys1(100, cmd); + case 0: + break; + default: fmt_long(fmt, x); buffer_puts(buffer_2, "< exit "); buffer_puts(buffer_2, fmt); buffer_puts(buffer_2, "\n"); buffer_flush(buffer_2); - rm(dir, p); - exit(100); + if (!pack_remove(p, dir)) + log_errsys6("deleting ", dir, "/", p->name, "/", p->ver); + log_die5(100, cmd, " ", p->name, "/", p->ver); } - - stralloc_free(&sa); - return; - -err: nl(); rm(dir, p); - log_diesys3(100, step, ": ", sa.x); } int main(int argc, char **argv) { - (void)argc; - (void)argv; + genalloc ga; + size_t i; + pack p; char *def; char *log; char *tar; char *src; char *out; - genalloc ga; - stralloc sa; - size_t i; - pack p; if (argc != 2) log_usage(*argv, "package[/version]"); ++argv; @@ -121,10 +82,8 @@ main(int argc, char **argv) log_diesys1(103, "could not resolve package dependencies"); if (!genalloc_append(&ga, p)) die_nomem(); - stralloc_init(&sa); - if (!stralloc_cats(&sa, log)) die_nomem(); - if (!stralloc_cats(&sa, "/")) die_nomem(); - for (i = 0; i < genalloc_len(&ga, pack); ++i) { + for (i = 0; i < genalloc_len(&ga, pack); ++i) + { pack *p = genalloc_get(&ga, pack, i); char fmt[PACK_FMT + 80]; @@ -137,14 +96,13 @@ main(int argc, char **argv) buffer_puts(buffer_2, " "); buffer_flush(buffer_2); - step(p, "pack-get", log, tar); + step(p, "pack-get", log, src); step(p, "pack-tar", log, src); step(p, "pack-build", log, out); step(p, "pack-install", log, NULL); - buffer_flush(buffer_2); nl(); + buffer_puts(buffer_2, "\n"); + buffer_flush(buffer_2); } - buffer_flush(buffer_1); - genalloc_free(&ga); return 0; diff --git a/pack-build.c b/pack-build.c @@ -29,10 +29,11 @@ pack_envset(char const *name, char const *path) static int pack_env(pack *p, const char *def, const char *out) { - stralloc path; - stralloc line; + stralloc path = STRALLOC_ZERO; + stralloc line = STRALLOC_ZERO; buffer b; char buf[1024]; + size_t r; size_t n; size_t m; int fd = -1; @@ -54,12 +55,14 @@ pack_env(pack *p, const char *def, const char *out) buffer_init(&b, &read, fd, buf, sizeof buf); stralloc_init(&line); - while (stralloc_zero(&line), buffer_getline(&b, &line)) { + while (stralloc_zero(&line), (r = buffer_getline(&b, &line)) > 0) { pack new; - stralloc_0(&line); - m = pack_scan(&new, line.x); if (m == 0) goto err; + if (!stralloc_0(&line)) goto err; + if (line.x[line.n - 1] == '\n') line.x[--(line.n)] = '\0'; + if (line.x[m] != '\n' && line.x[m] != '\0') goto err; + m = pack_scan(&new, line.x); if (m == 0) goto err; if (!pack_version(&new, def)) goto err; path.n = n; @@ -70,10 +73,11 @@ pack_env(pack *p, const char *def, const char *out) pack_envset(new.name, path.x); } - ret = 1; + ret = (r == 0); err: stralloc_free(&path); - close(fd); + stralloc_free(&line); + if (fd >= 0) close(fd); return ret; } diff --git a/pack-get.c b/pack-get.c @@ -0,0 +1,100 @@ +#include "buffer.h" +#include "env.h" +#include "forkexec.h" +#include "fs.h" +#include "log.h" +#include "open.h" +#include "pack.h" +#include "stralloc.h" + +int +get(pack const *p, char const *cmd, char const *url) +{ + char const *argv[] = { NULL, NULL, NULL, NULL }; + char fmt[PACK_FMT]; + + log_info2("trying mirror ", url); + + pack_fmt(p, fmt); + argv[0] = cmd; + argv[1] = fmt; + argv[2] = url; + argv[3] = NULL; + if ((forkexec_wait(argv)) != 0) + { + log_err4("downloading package ", p->name, "/", p->ver); + return 0; + } + + return 1; +} + +void +die_nomem() +{ + log_diesys1(100, "malloc"); +} + +int +main(int argc, char **argv) +{ + stralloc sa; + pack p; + buffer b; + char buf[1024]; + char *log; + char *def; + char *tar; + int fd = -1; + size_t n; + size_t r; + + if (argc != 2) log_usage(*argv, "package[/version] url"); + ++argv; + + def = env_get("PACK_DEF"); if (!def) def = PACK_DEF; + log = env_get("PACK_LOG"); if (!log) log = PACK_LOG; + tar = env_get("PACK_TAR"); if (!tar) tar = PACK_TAR; + + n = pack_scan(&p, *argv); + if ((*argv)[n] != '\0') + log_die2(1, "invalid package format: ", *argv); + + if (!pack_version(&p, def)) + log_diesys2(101, "getting version of ", p.name); + + stralloc_init(&sa); + if (!stralloc_cats(&sa, def)) die_nomem(); + if (!stralloc_cats(&sa, "/")) die_nomem(); + if (!stralloc_cats(&sa, p.name)) die_nomem(); + if (!stralloc_cats(&sa, "/")) die_nomem(); + if (!stralloc_cats(&sa, p.ver)) die_nomem(); + if (!stralloc_cats(&sa, "/uri")) die_nomem(); + if (!stralloc_0(&sa)) die_nomem(); + fd = open_read(sa.x); if (fd == -1) die_nomem(); + + stralloc_zero(&sa); + if (!stralloc_cats(&sa, tar)) die_nomem(); + if (!stralloc_cats(&sa, "/")) die_nomem(); + if (!stralloc_cats(&sa, p.name)) die_nomem(); + if (!stralloc_cats(&sa, "/")) die_nomem(); + if (!stralloc_cats(&sa, p.ver)) die_nomem(); + if (!stralloc_0(&sa)) die_nomem(); + if (!fs_mkdir_r(sa.x, 0750)) + log_diesys2(101, "recursive mkdir:", sa.x); + + buffer_init(&b, &read, fd, buf, sizeof buf); + while (stralloc_zero(&sa), (r = buffer_getline(&b, &sa)) > 0) + { + if (sa.x[sa.n - 1] == '\n') sa.x[--(sa.n)] = '\0'; + if (str_start(sa.x, "http://")) if (get(&p, "pack-http", sa.x)) break; + if (str_start(sa.x, "https://")) if (get(&p, "pack-http", sa.x)) break; + if (str_start(sa.x, "git://")) if (get(&p, "pack-git", sa.x)) break; + if (str_start(sa.x, "cvs://")) if (get(&p, "pack-cvs", sa.x)) break; + } + if (r < 0) log_errsys1("buffering"); + + stralloc_free(&sa); + close(fd); + return 0; +} diff --git a/pack.c b/pack.c @@ -4,6 +4,8 @@ #include "buffer.h" #include "env.h" +#include "fmt.h" +#include "forkexec.h" #include "fs.h" #include "genalloc.h" #include "mem.h" @@ -21,7 +23,6 @@ pack_fmt(pack const *p, char *buf) buf[i++] = '/'; i += str_copy(buf + i, p->ver, PACK_FMT - i); buf[i++] = '\0'; - return 1; return i; } @@ -35,21 +36,24 @@ pack_scan(pack *p, char const *s) if (s[0] == '/') return 0; - for (n = 0, i = 0 ;; ++n, ++i) { + for (n = 0, i = 0 ;; ++n, ++i) + { if (!isprint(s[i]) || s[i] == ' ') goto end; if (s[i] == '/') break; if (i >= sizeof p->name) return 0; p->name[n] = s[i]; } - for (v = 0, ++i ;; ++i, ++v) { + for (v = 0, ++i ;; ++i, ++v) + { if (!isprint(s[i]) || s[i] == ' ') goto end; if (s[i] == '/') break; if (i > sizeof p->ver) return 0; p->ver[v] = s[i]; } -end: p->name[n] = '\0'; +end: + p->name[n] = '\0'; p->ver[v] = '\0'; return i; } @@ -57,90 +61,93 @@ end: p->name[n] = '\0'; int pack_version(pack *p, char const *def) { - stralloc path; - stralloc line; + stralloc sa; buffer b; char buf[1024]; - int fd; + int fd = -1; int ret = 0; if (*p->ver) return 1; - stralloc_init(&path); - stralloc_copys(&path, def); - stralloc_append(&path, '/'); - stralloc_cats(&path, p->name); - stralloc_cats(&path, "/default/version"); - stralloc_append(&path, '\0'); + stralloc_init(&sa); + if (!stralloc_cats(&sa, def)) goto err; + if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, p->name)) goto err; + if (!stralloc_cats(&sa, "/default/version")) goto err; + if (!stralloc_0(&sa)) goto err; - fd = open_read(path.x); if (fd == -1) goto err; + fd = open_read(sa.x); if (fd == -1) goto err; - stralloc_init(&line); + stralloc_zero(&sa); buffer_init(&b, &read, fd, buf, sizeof buf); - if (buffer_getline(&b, &line) <= 0) goto err; - if (line.x[line.n - 1] == '\n') line.n--; - if (line.n >= sizeof p->ver) goto err; + if (buffer_getline(&b, &sa) <= 0) goto err; + if (sa.x[sa.n - 1] == '\n') sa.x[--(sa.n)] = '\0'; - mem_copy(p->ver, line.x, line.n); - p->ver[line.n] = '\0'; + if (sa.n >= sizeof p->ver) goto err; - ret = 1; + mem_copy(p->ver, sa.x, sa.n); + p->ver[sa.n] = '\0'; -err: stralloc_free(&path); - stralloc_free(&line); - close(fd); + ret = 1; +err: + stralloc_free(&sa); + if (fd >= 0) close(fd); return ret; } int pack_opendepfile(pack const *p, char const *def) { - stralloc path; + stralloc sa; size_t n; int fd = -1; - 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; + stralloc_init(&sa); + if (!stralloc_copys(&sa, def)) goto err; + if (!stralloc_append(&sa, '/')) goto err; + if (!stralloc_cats(&sa, p->name)) goto err; + if (!stralloc_append(&sa, '/')) goto err; + n = sa.n; + if (!stralloc_cats(&sa, p->ver)) goto err; + if (!stralloc_cats(&sa, "/dependencies")) goto err; + if (!stralloc_append(&sa, '\0')) goto err; errno = 0; - fd = open_read(path.x); - - if (errno == ENOTDIR || errno == ENOENT) { - path.n = n; - if (!stralloc_cats(&path, "default/dependencies")) goto err; - if (!stralloc_append(&path, '\0')) goto err; + fd = open_read(sa.x); + if (errno == ENOTDIR || errno == ENOENT) + { + sa.n = n; + if (!stralloc_cats(&sa, "default/dependencies")) goto err; + if (!stralloc_append(&sa, '\0')) goto err; errno = 0; - fd = open_read(path.x); + fd = open_read(sa.x); } -err: stralloc_free(&path); +err: + stralloc_free(&sa); return fd; } int -pack_remove(pack *p, char const *prefix) +pack_remove(pack const *p, char const *dir) { - stralloc path; + stralloc sa; 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; + stralloc_init(&sa); + if (!stralloc_cats(&sa, dir)) goto err; + if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, p->name)) goto err; + if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, p->ver)) goto err; + if (!stralloc_0(&sa)) goto err; - ret = fs_remove_r(path.x); + errno = 0; + if (!fs_remove_r(sa.x) && errno != ENOTDIR && errno != ENOENT) goto err; -err: stralloc_free(&path); + ret = 1; +err: + stralloc_free(&sa); return ret; } @@ -149,7 +156,8 @@ pack_hasdep(pack const *p, genalloc *packs) { size_t i; - for (i = 0; i < genalloc_len(packs, pack); ++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)) @@ -160,13 +168,43 @@ pack_hasdep(pack const *p, genalloc *packs) } int +pack_step(pack const *p, char const *cmd, char const *log) +{ + char fmt[PACK_FMT]; + char const *argv[] = { NULL, NULL, NULL }; + stralloc sa; + int ret = -1; + + stralloc_init(&sa); + if (!stralloc_cats(&sa, log)) goto err; + if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, p->name)) goto err; + if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, p->ver)) goto err; + if (!stralloc_0(&sa)) goto err; + sa.n--; + if (!fs_mkdir_r(sa.x, 0640)) goto err; + if (!stralloc_cats(&sa, "/")) goto err; + if (!stralloc_cats(&sa, cmd)) goto err; + if (!stralloc_0(&sa)) goto err; + + argv[0] = cmd; + pack_fmt(p, fmt); + argv[1] = fmt; + ret = forkexec_wait_redir(argv, sa.x); + +err: + stralloc_free(&sa); + return ret; +} + +int pack_dep(pack const *p, genalloc *packs, char const *def) { - stralloc path = STRALLOC_ZERO; - stralloc line = STRALLOC_ZERO; + stralloc sa = STRALLOC_ZERO; buffer b; char buf[1024]; - ssize_t r; + size_t r; int fd = -1; int ret = 0; @@ -175,14 +213,15 @@ pack_dep(pack const *p, genalloc *packs, char const *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))) { + stralloc_init(&sa); + while (stralloc_zero(&sa), (r = buffer_getline(&b, &sa)) > 0) + { pack new; size_t n; - stralloc_0(&line); - n = pack_scan(&new, line.x); if (n == 0) goto err; - if (line.x[n] != '\n' && line.x[n] != '\0') goto err; + stralloc_0(&sa); + n = pack_scan(&new, sa.x); if (n == 0) goto err; + if (sa.x[n] != '\n' && sa.x[n] != '\0') goto err; if (!pack_version(&new, def)) goto err; if (pack_hasdep(&new, packs)) continue; @@ -192,8 +231,8 @@ pack_dep(pack const *p, genalloc *packs, char const *def) ret = (r == 0); -err: stralloc_free(&line); - stralloc_free(&path); +err: + stralloc_free(&sa); close(fd); return ret; } diff --git a/pack.h b/pack.h @@ -20,7 +20,8 @@ typedef struct { int pack_dep(pack const *, genalloc *, char const *); int pack_hasdep(pack const *, genalloc *); int pack_opendepfile(pack const *, char const *); -int pack_remove(pack *, char const *); +int pack_remove(pack const *, char const *); +int pack_step(pack const *, char const *, char const *); int pack_version(pack *, char const *); size_t pack_fmt(pack const *, char *); size_t pack_scan(pack *, char const *);