package

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

commit 60a6d13073272d562efe456001827885fbfb8768
parent dfed014c83827abc03b889d98a8faf68b5d1b2d4
Author: Josuah Demangeon <mail@josuah.net>
Date:   Tue, 15 Jan 2019 00:34:44 +0100

simplifiy and fix code, keep a "latest -> @4000..." symlink

latest always point at the build before the whole process starts

split fs.[ch] into hier.[ch] and stat.[ch]

Diffstat:
MMakefile | 17+++++++++--------
Mbin/pack-git | 8++------
Mforkexec.c | 30+-----------------------------
Mforkexec.h | 2+-
Dfs.c | 245-------------------------------------------------------------------------------
Dfs.h | 17-----------------
Ahier.c | 184+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahier.h | 9+++++++++
Mpack-add.c | 8++++----
Mpack-build.c | 164++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mpack-dep.c | 4++--
Mpack-get.c | 10+++++-----
Mpack-tree.c | 10+++++-----
Mpack.c | 1-
Astat.c | 27+++++++++++++++++++++++++++
Astat.h | 8++++++++
16 files changed, 353 insertions(+), 391 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ bin = pack-build pack-dep pack-get pack-tree # pack-add -obj = pack.o buffer.o fmt.o fs.o log.o mem.o str.o stralloc.o forkexec.o tai.o +obj = pack.o buffer.o fmt.o stat.o hier.o log.o mem.o str.o stralloc.o forkexec.o tai.o .PHONY: all all: ${bin} @@ -35,15 +35,16 @@ pack-tree: pack-tree.o ${obj} buffer.o: buffer.c buffer.h mem.h stralloc.h fmt.o: fmt.c fmt.h str.h forkexec.o: forkexec.c open.h forkexec.h -fs.o: fs.c fs.h mem.h open.h str.h stralloc.h +hier.o: hier.c hier.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 buffer.h env.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 tai.h fmt.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 env.h forkexec.h fs.h log.h open.h pack.h stralloc.h lock.h -pack-tree.o: pack-tree.c pack.h stralloc.h open.h buffer.h env.h fs.h log.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 lock.h tai.h +pack-add.o: pack-add.c buffer.h env.h fmt.h genalloc.h log.h open.h pack.h stat.h str.h +pack-build.o: pack-build.c buffer.h env.h fmt.h forkexec.h hier.h hier.h log.h open.h pack.h stat.h str.h stralloc.h tai.h +pack-dep.o: pack-dep.c buffer.h env.h stat.h genalloc.h log.h pack.h str.h +pack-get.o: pack-get.c buffer.h env.h forkexec.h hier.h lock.h log.h open.h pack.h stat.h stralloc.h +pack-tree.o: pack-tree.c buffer.h env.h log.h open.h pack.h stat.h stralloc.h +pack.o: pack.c buffer.h env.h fmt.h forkexec.h genalloc.h mem.h open.h pack.h stralloc.h lock.h tai.h +stat.o: stat.c stat.h str.o: str.c str.h stralloc.o: stralloc.c mem.h fmt.h str.h stralloc.h tai.o: tai.c tai.h diff --git a/bin/pack-git b/bin/pack-git @@ -1,9 +1,5 @@ #!/bin/sh -e -PACK_GIT=${PACK_GIT:-/var/pack/git} -PACK_TAR=${PACK_TAR:-/var/pack/tar} -pack=${1%/*} -url=$2 mkdir -p "$PACK_GIT/${1%/*}" -! git clone --bare "$url" "$PACK_GIT/$1" -git -C "$PACK_GIT/$1" archive --format=tar master >$PACK_TAR/$1/tar +! git clone --bare "$2" "$PACK_GIT/$1" +git -C "$PACK_GIT/$1" archive --format=tar master diff --git a/forkexec.c b/forkexec.c @@ -24,17 +24,15 @@ forkexec_wait(char const *argv[]) } int -forkexec_wait_redir(char const *argv[], char const *path) +forkexec_wait_redir(char const *argv[], int fd) { pid_t pid = 0; int st; - int fd; switch ((pid = fork())) { case -1: return -1; case 0: - fd = open_trunc(path); if (fd == -1) exit(125); close(1); if (dup(fd) != 1) exit(126); close(2); if (dup(fd) != 2) exit(126); execvp(*argv, (char *const *) argv); @@ -45,29 +43,3 @@ forkexec_wait_redir(char const *argv[], char const *path) return WEXITSTATUS(st); } - -/* -int -forkexec_pipe(char const **argv, int pipe_to[2], pipe_from[2]) -{ - pid_t pid; - int st; - - switch ((pid = fork())) { - case -1: - return -1; - case 0: - close(pipe_to[1]); - if (!dup2(pipe_to[1], 0)) exit(126); - close(pipe_from[0]); - if (!dup2(pipe_from[0], 1)) exit(126) - execvp(*argv, argv); - exit(127); - default: - close(pipe_to[0]); - close(pipe_from[1]); - } - - return pid; -} -*/ diff --git a/forkexec.h b/forkexec.h @@ -2,6 +2,6 @@ #define FORKEXEC_H int forkexec_wait(char const *argv[]); -int forkexec_wait_redir(char const *argv[], char const *); +int forkexec_wait_redir(char const *argv[], int); #endif diff --git a/fs.c b/fs.c @@ -1,245 +0,0 @@ -#include <dirent.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> - -#include "fs.h" -#include "mem.h" -#include "open.h" -#include "str.h" -#include "stralloc.h" - -int -fs_isdir(char const *path) -{ - struct stat st; - if (stat(path, &st) == -1) return 0; - return S_ISDIR(st.st_mode); -} - -int -fs_islink(char const *path) -{ - struct stat st; - if (stat(path, &st) == -1) return 0; - return S_ISLNK(st.st_mode); -} - -int -fs_isfile(char const *path) -{ - struct stat st; - if (stat(path, &st) == -1) return 0; - return S_ISREG(st.st_mode); -} - -int -fs_redir_read(int fd, char const *path) -{ - int newfd = open_read(path); - if (newfd == -1) return 0; - if (dup2(newfd, fd) == -1) return 0; - return 1; -} - -int -fs_redir_write(int fd, char const *path) -{ - int newfd = open_write(path); - if (newfd == -1) return 0; - if (dup2(newfd, fd) == -1) return 0; - return 1; -} - -int -fs_redir_append(int fd, char const *path) -{ - int newfd = open_append(path); - if (newfd == -1) return 0; - if (dup2(newfd, fd) == -1) return 0; - return 1; -} - -int -fs_redir_trunc(int fd, char const *path) -{ - int newfd = open_trunc(path); - if (newfd == -1) return 0; - if (dup2(newfd, fd) == -1) return 0; - return 1; -} - -int -fs_mkdir_r(char *dir, unsigned int mode) -{ - size_t n; - - for (n = (dir[0] == '/') ;; ++n) { - if (dir[n] == '/') { - dir[n] = '\0'; - if (mkdir(dir, mode) == -1 && errno != EEXIST) return 0; - dir[n] = '/'; - } else if (dir[n] == '\0') { - if (mkdir(dir, mode) == -1 && errno != EEXIST) return 0; - break; - } - } - - return 1; -} - -int -fs_copy(char const *from, char const *to, unsigned int mode) -{ - char buf[1024 * 8]; - int fd_from = -1; - int fd_to = -1; - int r = -1; - int w = 1; /* for empty files */ - - fd_from = open_read(from); if (fd_from == -1) goto err; - fd_to = open_trunc(to); if (fd_to == -1) goto err; - while (1) { - r = read(fd_from, buf, sizeof buf); if (r <= 0) break; - w = write(fd_to, buf, r); if (w < r) break; - } - if (chmod(to, mode) == -1) goto err; - -err: close(fd_from); - close(fd_to); - return r == 0 && w > 0; -} - -static int -fs_remove_r_recurse(stralloc *sa) -{ - DIR *dp; - struct dirent *de; - struct stat st; - size_t n = sa->n; - - dp = opendir(sa->x); if (dp == NULL) return 0; - - if (!stralloc_cats(sa, "/")) return 0; - n = sa->n; - - errno = 0; - while ((de = readdir(dp))) { - if (str_equal(de->d_name, ".")) continue; - if (str_equal(de->d_name, "..")) continue; - - sa->n = n; - if (!stralloc_cats(sa, de->d_name)) break; - if (!stralloc_cat0(sa)) break; - if (lstat(sa->x, &st) == -1) break; - sa->n--; - - if (S_ISDIR(st.st_mode)) { - if (!fs_remove_r_recurse(sa)) break; - } else { - if (unlink(sa->x) == -1) break; - } - } - - closedir(dp); - rmdir(sa->x); - return (errno == 0); -} - -int -fs_remove_r(char const *dir) -{ - stralloc path = STRALLOC_ZERO; - int ret = 0; - - if (!stralloc_cats(&path, dir)) goto err; - ret = fs_remove_r_recurse(&path); -err: - stralloc_free(&path); - return ret; -} - -static int -fs_copy_r_recurse(stralloc *from, stralloc *to, int action) -{ - DIR *dp; - struct dirent *de; - struct stat st; - char ln[4096]; - size_t to_n = to->n; - size_t from_n = from->n; - - if (!stralloc_cats(from, "/")) return 0; - if (!stralloc_cats(to, "/")) return 0; - from_n = from->n; - to_n = to->n; - - dp = opendir(from->x); if (!dp) return 0; - - errno = 0; - while ((de = readdir(dp))) { - if (str_equal(de->d_name, ".")) continue; - if (str_equal(de->d_name, "..")) continue; - - to->n = to_n; - if (!stralloc_cats(to, de->d_name)) break; - if (!stralloc_cat0(to)) break; - - from->n = from_n; - if (!stralloc_cats(from, de->d_name)) break; - if (!stralloc_cat0(from)) break; - if (lstat(from->x, &st) == -1) break; - - if (S_ISDIR(st.st_mode)) { - if (mkdir(to->x, st.st_mode) == -1 && errno != EEXIST) break; - if (!fs_copy_r_recurse(from, to, action)) break; - } else if (S_ISREG(st.st_mode)) { - switch (action) { - case 0: - if (!fs_copy(from->x, to->x, st.st_mode)) goto end; - break; - case 1: - if (symlink(from->x, to->x) == -1) goto end; - break; - } - } else if (S_ISLNK(st.st_mode)) { - if (readlink(from->x, ln, sizeof ln) == -1) break; - if (symlink(ln, to->x) == -1) break; - } else break; - } -end: - closedir(dp); - return errno == 0; -} - -int -fs_copy_r(char const *from, char const *to) -{ - stralloc sa_from = STRALLOC_ZERO; - stralloc sa_to = STRALLOC_ZERO; - int ret = 0; - - if (!stralloc_cats(&sa_from, from)) goto err; - if (!stralloc_cats(&sa_to, to)) goto err; - ret = fs_copy_r_recurse(&sa_from, &sa_to, 0); - -err: stralloc_free(&sa_from); - stralloc_free(&sa_to); - return ret; -} - -int -fs_copy_rl(char const *from, char const *to) -{ - stralloc sa_from = STRALLOC_ZERO; - stralloc sa_to = STRALLOC_ZERO; - int ret = 0; - - if (!stralloc_cats(&sa_from, from)) goto err; - if (!stralloc_cats(&sa_to, to)) goto err; - ret = fs_copy_r_recurse(&sa_from, &sa_to, 1); - -err: stralloc_free(&sa_from); - stralloc_free(&sa_to); - return ret; -} diff --git a/fs.h b/fs.h @@ -1,17 +0,0 @@ -#ifndef FS_H -#define FS_H - -int fs_copy(char const *, char const *, unsigned int); -int fs_copy_r(char const *, char const *); -int fs_copy_rl(char const *, char const *); -int fs_isdir(char const *); -int fs_isfile(char const *); -int fs_islink(char const *); -int fs_mkdir_r(char *, unsigned int); -int fs_redir_append(int, char const *); -int fs_redir_read(int, char const *); -int fs_redir_trunc(int, char const *); -int fs_redir_write(int, char const *); -int fs_remove_r(char const *); - -#endif diff --git a/hier.c b/hier.c @@ -0,0 +1,184 @@ +#include <dirent.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> + +#include "hier.h" +#include "open.h" +#include "str.h" +#include "stralloc.h" + +int +hier_mkdir(char *dir, unsigned int mode) +{ + size_t n; + + for (n = (dir[0] == '/') ;; ++n) { + if (dir[n] == '/') { + dir[n] = '\0'; + if (mkdir(dir, mode) == -1 && errno != EEXIST) return 0; + dir[n] = '/'; + } else if (dir[n] == '\0') { + if (mkdir(dir, mode) == -1 && errno != EEXIST) return 0; + break; + } + } + + return 1; +} + +static int +hier_remove_recurse(stralloc *sa) +{ + DIR *dp; + struct dirent *de; + struct stat st; + size_t n = sa->n; + + dp = opendir(sa->x); if (dp == NULL) return 0; + + if (!stralloc_cats(sa, "/")) return 0; + n = sa->n; + + errno = 0; + while ((de = readdir(dp))) { + if (str_equal(de->d_name, ".")) continue; + if (str_equal(de->d_name, "..")) continue; + + sa->n = n; + if (!stralloc_cats(sa, de->d_name)) break; + if (!stralloc_cat0(sa)) break; + if (lstat(sa->x, &st) == -1) break; + sa->n--; + + if (S_ISDIR(st.st_mode)) { + if (!hier_remove_recurse(sa)) break; + } else { + if (unlink(sa->x) == -1) break; + } + } + + closedir(dp); + rmdir(sa->x); + return (errno == 0); +} + +int +hier_remove(char const *dir) +{ + stralloc path = STRALLOC_ZERO; + int ret = 0; + + if (!stralloc_cats(&path, dir)) goto err; + ret = hier_remove_recurse(&path); +err: + stralloc_free(&path); + return ret; +} + +static int +copy(char const *from, char const *to, unsigned int mode) +{ + char buf[1024 * 8]; + int fd_from = -1; + int fd_to = -1; + int r = -1; + int w = 1; /* for empty files */ + + fd_from = open_read(from); if (fd_from == -1) goto err; + fd_to = open_trunc(to); if (fd_to == -1) goto err; + while (1) { + r = read(fd_from, buf, sizeof buf); if (r <= 0) break; + w = write(fd_to, buf, r); if (w < r) break; + } + if (chmod(to, mode) == -1) goto err; + +err: close(fd_from); + close(fd_to); + return r == 0 && w > 0; +} + +static int +hier_copy_recurse(stralloc *from, stralloc *to, int action) +{ + DIR *dp; + struct dirent *de; + struct stat st; + char ln[4096]; + size_t to_n = to->n; + size_t from_n = from->n; + + if (!stralloc_cats(from, "/")) return 0; + if (!stralloc_cats(to, "/")) return 0; + from_n = from->n; + to_n = to->n; + + dp = opendir(from->x); if (!dp) return 0; + + errno = 0; + while ((de = readdir(dp))) { + if (str_equal(de->d_name, ".")) continue; + if (str_equal(de->d_name, "..")) continue; + + to->n = to_n; + if (!stralloc_cats(to, de->d_name)) break; + if (!stralloc_cat0(to)) break; + + from->n = from_n; + if (!stralloc_cats(from, de->d_name)) break; + if (!stralloc_cat0(from)) break; + if (lstat(from->x, &st) == -1) break; + + if (S_ISDIR(st.st_mode)) { + if (mkdir(to->x, st.st_mode) == -1 && errno != EEXIST) break; + if (!hier_copy_recurse(from, to, action)) break; + } else if (S_ISREG(st.st_mode)) { + switch (action) { + case 0: + if (!copy(from->x, to->x, st.st_mode)) goto end; + break; + case 1: + if (symlink(from->x, to->x) == -1) goto end; + break; + } + } else if (S_ISLNK(st.st_mode)) { + if (readlink(from->x, ln, sizeof ln) == -1) break; + if (symlink(ln, to->x) == -1) break; + } else break; + } +end: + closedir(dp); + return errno == 0; +} + +int +hier_copy(char const *from, char const *to) +{ + stralloc sa_from = STRALLOC_ZERO; + stralloc sa_to = STRALLOC_ZERO; + int ret = 0; + + if (!stralloc_cats(&sa_from, from)) goto err; + if (!stralloc_cats(&sa_to, to)) goto err; + ret = hier_copy_recurse(&sa_from, &sa_to, 0); + +err: stralloc_free(&sa_from); + stralloc_free(&sa_to); + return ret; +} + +int +hier_symlink(char const *from, char const *to) +{ + stralloc sa_from = STRALLOC_ZERO; + stralloc sa_to = STRALLOC_ZERO; + int ret = 0; + + if (!stralloc_cats(&sa_from, from)) goto err; + if (!stralloc_cats(&sa_to, to)) goto err; + ret = hier_copy_recurse(&sa_from, &sa_to, 1); + +err: stralloc_free(&sa_from); + stralloc_free(&sa_to); + return ret; +} diff --git a/hier.h b/hier.h @@ -0,0 +1,9 @@ +#ifndef HIER_H +#define HIER_H + +int hier_copy(char const *, char const *); +int hier_mkdir(char *, unsigned int); +int hier_remove(char const *); +int hier_symlink(char const *, char const *); + +#endif diff --git a/pack-add.c b/pack-add.c @@ -4,13 +4,13 @@ #include "buffer.h" #include "env.h" -#include "fs.h" +#include "fmt.h" #include "genalloc.h" #include "log.h" +#include "open.h" #include "pack.h" +#include "stat.h" #include "str.h" -#include "fmt.h" -#include "open.h" void die_nomem(void) @@ -57,7 +57,7 @@ main(int argc, char **argv) dir = env_get("PACK_DIR"); if (!dir) dir = PACK_DIR; def = env_get("PACK_DEF"); if (!def) def = PACK_DEF; - if (!fs_isdir(def)) log_diesys1(101, def); + if (!stat_isdir(def)) log_diesys1(101, def); i = pack_scan(&p, *argv); if (i == 0 || (*argv)[i] != '\0') diff --git a/pack-build.c b/pack-build.c @@ -1,28 +1,44 @@ #include <sys/types.h> +#include <sys/dirent.h> #include <sys/stat.h> #include <ctype.h> -#include <sys/dirent.h> #include <dirent.h> #include <errno.h> +#include <stdio.h> #include "buffer.h" #include "env.h" +#include "fmt.h" #include "forkexec.h" -#include "fs.h" +#include "hier.h" +#include "hier.h" #include "log.h" #include "open.h" #include "pack.h" +#include "stat.h" #include "str.h" #include "stralloc.h" #include "tai.h" -#include "fmt.h" + +static int +untar(void) +{ + char const *argv[] = { "tar", "-x", "-f", "../../source.tar", NULL }; + int fd; + + if ((fd = open_trunc("../log/1-untar")) == -1) return 0; + if (forkexec_wait_redir(argv, fd) != 0) { close(fd); return 0; } + close(fd); + + return 1; +} static int patch(pack const *p, char *def) { char const *argv[] = { "patch", "-N", NULL }; char const *d[2]; - stralloc path; + stralloc sa; size_t n; size_t m; DIR *dp = NULL; @@ -31,22 +47,23 @@ patch(pack const *p, char *def) int fd = -1; int ret = 0; - stralloc_init(&path); - if (!stralloc_cats(&path, def)) goto err; - if (!stralloc_cats(&path, "/")) goto err; - if (!stralloc_cats(&path, p->name)) goto err; - if (!stralloc_cats(&path, "/")) goto err; - n = path.n; + 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, "/")) goto err; + n = sa.n; + if ((fd = open_trunc("../log/2-patch")) == -1) goto err; d[0] = "default"; d[1] = p->ver; for (i = 0; i < 2; ++i) { - path.n = n; - if (!stralloc_cats(&path, d[i])) goto err; - if (!stralloc_cats(&path, "/patch/")) goto err; - m = path.n; - if (!stralloc_cat0(&path)) goto err; - dp = opendir(path.x); + sa.n = n; + if (!stralloc_cats(&sa, d[i])) goto err; + if (!stralloc_cats(&sa, "/patch/")) goto err; + m = sa.n; + if (!stralloc_cat0(&sa)) goto err; + dp = opendir(sa.x); if (dp == NULL) { if (errno == ENOTDIR || errno == ENOENT) continue; goto err; @@ -55,30 +72,33 @@ patch(pack const *p, char *def) if (str_equal(de->d_name, ".")) continue; if (str_equal(de->d_name, "..")) continue; - path.n = m; - if (!stralloc_cats(&path, de->d_name)) goto err; - if (!stralloc_cat0(&path)) goto err; - if (!fs_redir_read(0, path.x)) goto err; - if (forkexec_wait(argv) != 0) goto err; - close(fd); + sa.n = m; + if (!stralloc_cats(&sa, de->d_name)) goto err; + if (!stralloc_cat0(&sa)) goto err; + close(0); + if (open_read(sa.x) == -1) goto err; + if (write(fd, "=== patch ===\n", 23) == -1) goto err; + if (forkexec_wait_redir(argv, fd) != 0) goto err; + if (write(fd, "\n", 1) == -1) goto err; } closedir(dp); } ret = 1; - -err: stralloc_free(&path); - close(fd); +err: + close(0); + stralloc_free(&sa); + if (fd >= 0) { write(fd, "=== end ===\n", 12); close(fd); } if (ret == 0) closedir(dp); return ret; } static int -build(pack const *p, char const *def) +data(pack const *p, char const *def) { - stralloc sa; - char const *argv[] = { NULL, NULL }; + stralloc sa = STRALLOC_ZERO; size_t n; + int ret = 0; stralloc_init(&sa); if (!stralloc_cats(&sa, def)) goto err; @@ -86,32 +106,33 @@ build(pack const *p, char const *def) if (!stralloc_cats(&sa, p->name)) goto err; if (!stralloc_cats(&sa, "/")) goto err; n = sa.n; - if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cats(&sa, "/build")) goto err; + if (!stralloc_cats(&sa, "default/data")) goto err; if (!stralloc_cat0(&sa)) goto err; - argv[0] = sa.x; - forkexec_wait_redir(argv, "../log"); - if (!(errno == ENOTDIR || errno == ENOENT)) goto err; + if (!close(open_trunc("../log/3-data"))) goto err; + + if (stat_isdir(sa.x)) if (!hier_copy(sa.x, ".")) goto err; sa.n = n; - if (!stralloc_cats(&sa, "default/build")) goto err; + if (!stralloc_cats(&sa, p->ver)) goto err; + if (!stralloc_cats(&sa, "/data")) goto err; if (!stralloc_cat0(&sa)) goto err; - argv[0] = sa.x; - forkexec_wait_redir(argv, "../log"); - if (!(errno == ENOTDIR || errno == ENOENT)) goto err; + if (stat_isdir(sa.x)) if (!hier_copy(sa.x, ".")) goto err; -err: stralloc_free(&sa); - return 0; + ret = 1; +err: + stralloc_free(&sa); + return ret; } static int -data(pack const *p, char const *def) +build(pack const *p, char const *def) { - stralloc sa = STRALLOC_ZERO; + stralloc sa; + char const *argv[] = { NULL, NULL }; size_t n; - int ret = 0; + int fd = - 1; stralloc_init(&sa); if (!stralloc_cats(&sa, def)) goto err; @@ -119,29 +140,26 @@ data(pack const *p, char const *def) if (!stralloc_cats(&sa, p->name)) goto err; if (!stralloc_cats(&sa, "/")) goto err; n = sa.n; - if (!stralloc_cats(&sa, "default/data")) goto err; - if (!stralloc_cat0(&sa)) goto err; - if (fs_isdir(sa.x)) if (!fs_copy_r(sa.x, ".")) goto err; + if ((fd = open_trunc("../log/4-build")) == -1) goto err; - sa.n = n; if (!stralloc_cats(&sa, p->ver)) goto err; - if (!stralloc_cats(&sa, "/data")) goto err; + if (!stralloc_cats(&sa, "/build")) goto err; if (!stralloc_cat0(&sa)) goto err; + argv[0] = sa.x; + forkexec_wait_redir(argv, fd); + if (!(errno == ENOTDIR || errno == ENOENT)) goto err; - if (fs_isdir(sa.x)) if (!fs_copy_r(sa.x, ".")) goto err; - - ret = 1; + sa.n = n; + if (!stralloc_cats(&sa, "default/build")) goto err; + if (!stralloc_cat0(&sa)) goto err; + argv[0] = sa.x; + forkexec_wait_redir(argv, fd); + if (!(errno == ENOTDIR || errno == ENOENT)) goto err; err: stralloc_free(&sa); - return ret; -} - -static int -untar(void) -{ - char const *argv[] = { "tar", "-x", "-f", "../source.tar", NULL }; - return (forkexec_wait_redir(argv, "log") == 0); + if (fd >= 0) close(fd); + return 0; } static int @@ -206,8 +224,8 @@ env(pack *p, char const *def, char const *pkg, char const *id) if (!pack_env_set(new.name, sa.x)) goto err; } ret = (r == 0); - -err: stralloc_free(&sa); +err: + stralloc_free(&sa); stralloc_free(&line); if (fd >= 0) close(fd); return ret; @@ -242,8 +260,8 @@ main(int argc, char **argv) if (!pkg) usage(*argv, "-p"); if (!*av) usage(*argv, "package[/version]"); - if (!fs_isdir(def)) log_diesys1(101, def); - if (!fs_isdir(pkg)) log_diesys1(101, pkg); + if (!stat_isdir(def)) log_diesys1(101, def); + if (!stat_isdir(pkg)) log_diesys1(101, pkg); tai_now(&t); id[0] = '@'; @@ -269,20 +287,30 @@ main(int argc, char **argv) log_diesys8(101, "chdir ", pkg, "/", p.name, "/", p.ver, "/", id); if (mkdir("build", 075) == -1 && errno != EEXIST) log_diesys9(101, "mkdir ", pkg, "/", p.name, "/", p.ver, "/", id, "/build"); - if (!env(&p, def, pkg, id)) - log_diesys2(100, "could not set environment variables for ", *argv); - if (!untar()) - log_diesys9(101, "untar to ", pkg, "/", p.name, "/", p.ver, "/", id, "/source"); + if (mkdir("log", 075) == -1 && errno != EEXIST) + log_diesys9(101, "mkdir ", pkg, "/", p.name, "/", p.ver, "/", id, "/log"); if (mkdir("source", 075) == -1 && errno != EEXIST) log_diesys9(101, "mkdir ", pkg, "/", p.name, "/", p.ver, "/", id, "/source"); + if (symlink(id, "latest") == -1 && errno != EEXIST) + log_diesys9(101, "symlink ", pkg, "/", p.name, "/", p.ver, "/", id, "/latest"); + if (rename("latest", "../latest") == -1 && errno != EEXIST) + log_diesys7(101, "rename ", pkg, "/", p.name, "/", p.ver, "/latest"); if (chdir("source") == -1) log_diesys4(101, "could not change directory to ", pkg, "/", p.name); - if (!data(&p, def)) - log_diesys6(100, "copying ", p.name, "'s data from ", def, " to ", pkg); + if (!untar()) + log_diesys9(101, "untar ", pkg, "/", p.name, "/", p.ver, "/", id, "/source"); if (!patch(&p, def)) log_diesys3(100, "patching ", p.name, "'s source"); + if (!data(&p, def)) + log_diesys6(100, "copying ", p.name, "'s data from ", def, " to ", pkg); + if (!env(&p, def, pkg, id)) + log_diesys2(100, "could not set environment variables for ", *argv); if (!build(&p, def)) log_diesys2(100, "could not execute build script of ", p.name); + if (symlink(id, "../current") == -1 && errno != EEXIST) + log_diesys9(101, "symlink ", pkg, "/", p.name, "/", p.ver, "/", id, "/current"); + if (rename("../../current", "current") == -1 && errno != EEXIST) + log_diesys7(101, "rename ", pkg, "/", p.name, "/", p.ver, "/current"); return 0; } diff --git a/pack-dep.c b/pack-dep.c @@ -4,7 +4,7 @@ #include "buffer.h" #include "env.h" -#include "fs.h" +#include "stat.h" #include "genalloc.h" #include "log.h" #include "pack.h" @@ -26,7 +26,7 @@ main(int argc, char **argv) def = env_get("PACK_DEF"); if (!def) def = PACK_DEF; - if (!fs_isdir(def)) log_diesys1(101, def); + if (!stat_isdir(def)) log_diesys1(101, def); n = pack_scan(&p, *argv); if (n == 0 || (*argv)[n] != '\0') diff --git a/pack-get.c b/pack-get.c @@ -4,12 +4,13 @@ #include "buffer.h" #include "env.h" #include "forkexec.h" -#include "fs.h" +#include "hier.h" +#include "lock.h" #include "log.h" #include "open.h" #include "pack.h" +#include "stat.h" #include "stralloc.h" -#include "lock.h" int get(pack const *p, char const *cmd, char const *url) @@ -76,8 +77,7 @@ main(int argc, char **argv) if (!pkg) usage(*argv, "-p"); if (!*av) usage(*argv, "package[/version]"); - if (!fs_isdir(def)) log_diesys1(101, def); - if (!fs_isdir(pkg)) log_diesys1(101, pkg); + if (!stat_isdir(def)) log_diesys1(101, def); n = pack_scan(&p, *av); if ((*av)[n] != '\0') @@ -102,7 +102,7 @@ main(int argc, char **argv) if (!stralloc_cats(&sa, "/")) die_nomem(); if (!stralloc_cats(&sa, p.ver)) die_nomem(); if (!stralloc_cat0(&sa)) die_nomem(); - if (!fs_mkdir_r(sa.x, 0750)) + if (!hier_mkdir(sa.x, 0750)) log_diesys2(101, "mkdir ", sa.x); if (chdir(sa.x) == -1) log_diesys2(101, "chdir ", sa.x); diff --git a/pack-tree.c b/pack-tree.c @@ -1,13 +1,13 @@ #include <unistd.h> #include <errno.h> -#include "pack.h" -#include "stralloc.h" -#include "open.h" #include "buffer.h" #include "env.h" -#include "fs.h" #include "log.h" +#include "open.h" +#include "pack.h" +#include "stat.h" +#include "stralloc.h" int tree(pack *p, stralloc *prefix, char const *def) @@ -76,7 +76,7 @@ main(int argc, char **argv) pack p; def = env_get("PACK_DEF"); if (!def) def = PACK_DEF; - if (!fs_isdir(def)) log_diesys1(101, def); + if (!stat_isdir(def)) log_diesys1(101, def); if (argc != 2) log_usage(*argv, "package[/version]"); ++argv; diff --git a/pack.c b/pack.c @@ -7,7 +7,6 @@ #include "env.h" #include "fmt.h" #include "forkexec.h" -#include "fs.h" #include "genalloc.h" #include "mem.h" #include "open.h" diff --git a/stat.c b/stat.c @@ -0,0 +1,27 @@ +#include <sys/stat.h> + +#include "stat.h" + +int +stat_isdir(char const *path) +{ + struct stat st; + if (stat(path, &st) == -1) return 0; + return S_ISDIR(st.st_mode); +} + +int +stat_islink(char const *path) +{ + struct stat st; + if (stat(path, &st) == -1) return 0; + return S_ISLNK(st.st_mode); +} + +int +stat_isfile(char const *path) +{ + struct stat st; + if (stat(path, &st) == -1) return 0; + return S_ISREG(st.st_mode); +} diff --git a/stat.h b/stat.h @@ -0,0 +1,8 @@ +#ifndef STAT_H +#define STAT_H + +int stat_isdir(char const *); +int stat_isfile(char const *); +int stat_islink(char const *); + +#endif