package

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

commit 111c160a73dae7ab000c9d652432eda929802b5f
parent 778bc8ce8ad9f7f7cbf540b63369be180a722fe4
Author: Josuah Demangeon <mail@josuah.net>
Date:   Thu, 10 Jan 2019 03:27:22 +0100

apply patches

Diffstat:
MMakefile | 4+++-
Aforkexec.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Aforkexec.h | 6++++++
Mfs.c | 34+++++++++++++++++++++++++++++-----
Mfs.h | 1+
Apack-add.c | 6++++++
Mpack-build.c | 124++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
7 files changed, 183 insertions(+), 41 deletions(-)

diff --git a/Makefile b/Makefile @@ -11,7 +11,7 @@ install: all cp -r bin ${PREFIX} cp pack-build pack-dep ${PREFIX}/bin -pack-build-o = pack-build.o pack.o buffer.o fmt.o fs.o log.o mem.o str.o stralloc.o +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} @@ -24,9 +24,11 @@ pack-dep: ${pack-dep-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 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 diff --git a/forkexec.c b/forkexec.c @@ -0,0 +1,49 @@ +#include <stdlib.h> +#include <unistd.h> +#include <sys/wait.h> + +#include "forkexec.h" + +int +forkexec_wait(char *const argv[]) +{ + pid_t pid; + int st; + + switch ((pid = fork())) { + case -1: + return -1; + case 0: + execvp(*argv, argv); + exit(127); + } + if (waitpid(pid, &st, 0) == -1) return -1; + + 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 @@ -0,0 +1,6 @@ +#ifndef FORKEXEC_H +#define FORKEXEC_H + +int forkexec_wait(char *const *); + +#endif diff --git a/fs.c b/fs.c @@ -101,7 +101,7 @@ err: close(fd_from); } static int -fs_copyr_recurse(stralloc *from, stralloc *to) +fs_copyr_recurse(stralloc *from, stralloc *to, int action) { DIR *dp; struct dirent *de; @@ -136,15 +136,22 @@ fs_copyr_recurse(stralloc *from, stralloc *to) if (S_ISDIR(st.st_mode)) { if (lstat(to->x, &st) == 0) continue; if (mkdir(to->x, st.st_mode) == -1) break; - if (!fs_copyr_recurse(from, to)) break; + if (!fs_copyr_recurse(from, to, action)) break; } else if (S_ISREG(st.st_mode)) { - if (!fs_copy(from->x, to->x, st.st_mode)) break; + 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; } @@ -159,7 +166,24 @@ fs_copyr(char const *from, char const *to) if (!stralloc_copys(&sa_from, from)) goto err; if (!stralloc_copys(&sa_to, to)) goto err; - ret = fs_copyr_recurse(&sa_from, &sa_to); + ret = fs_copyr_recurse(&sa_from, &sa_to, 0); + +err: stralloc_free(&sa_from); + stralloc_free(&sa_to); + return ret; +} + +int +fs_copyrl(char const *from, char const *to) +{ + stralloc sa_from = STRALLOC_ZERO; + stralloc sa_to = STRALLOC_ZERO; + int ret = 0; + + if (!stralloc_copys(&sa_from, from)) goto err; + if (!stralloc_copys(&sa_to, to)) goto err; + + ret = fs_copyr_recurse(&sa_from, &sa_to, 1); err: stralloc_free(&sa_from); stralloc_free(&sa_to); diff --git a/fs.h b/fs.h @@ -3,6 +3,7 @@ int fs_copy(char const *, char const *, unsigned int); int fs_copyr(char const *, char const *); +int fs_copyrl(char const *, char const *); int fs_mkdirr(char *, unsigned int); int fs_rmdirr(char const *); diff --git a/pack-add.c b/pack-add.c @@ -0,0 +1,6 @@ +#include "pack.h" + +int +main(int argc, char *argv) +{ +} diff --git a/pack-build.c b/pack-build.c @@ -1,16 +1,18 @@ #include <sys/stat.h> -#include <errno.h> +#include <sys/types.h> #include <ctype.h> +#include <sys/dirent.h> +#include <dirent.h> +#include <errno.h> #include "buffer.h" #include "env.h" +#include "forkexec.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) { @@ -118,25 +120,15 @@ err: stralloc_free(&path); return ret; } -static int -pack_build(pack const *p, char const *def, char const *src) +/* CWD must be set to the source directory */ +int +pack_build(pack const *p, char const *def) { 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; @@ -160,11 +152,80 @@ err: stralloc_free(&path); return 0; } -static void -rm(pack *p, char *dir) +int +pack_chdir(pack const *p, char const *src) +{ + stralloc path; + int ret = 0; + + 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; + if (!stralloc_cats(&path, p->ver)) goto err; + if (!stralloc_append(&path, '\0')) goto err; + + if (chdir(path.x) == -1) goto err; + + ret = 1; + +err: stralloc_free(&path); + return ret; +} + +/* CWD must be set to the source directory */ +int +pack_patch(pack const *p, char *def) { - if (!pack_remove(p, dir)) - log_errsys6("could not remove ", dir, "/", p->name, "/", p->ver); + char const *argv[] = { "patch", "-N1", NULL, NULL }; + char const *d[2]; + stralloc path; + size_t n; + size_t m; + DIR *dp = NULL; + struct dirent *de; + int i; + 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; + + 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_append(&path, '\0')) goto err; + dp = opendir(path.x); + if (dp == NULL) { + if (errno == ENOTDIR || errno == ENOENT) continue; + goto err; + } + + while ((de = readdir(dp)) != NULL) { + 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_append(&path, '\0')) goto err; + argv[2] = path.x; + if (forkexec_wait(argv) != 0) goto err; + } + closedir(dp); + } + + ret = 1; +err: stralloc_free(&path); + closedir(dp); + return 0; } int @@ -193,30 +254,23 @@ main(int argc, char **argv) ++argv; n = pack_scan(&p, *argv); - if (!n || (*argv)[n] != '\0') { - rm(&p, out); + if (!n || (*argv)[n] != '\0') log_die2(1, "invalid package name format: ", *argv); - } - if (!pack_version(&p, def)) { - rm(&p, out); + if (!pack_version(&p, def)) log_diesys2(100, "could not read the version of ", p.name); - } - if (!pack_data(&p, def, src)) { - rm(&p, out); + if (!pack_data(&p, def, src)) log_diesys6(100, "copying ", p.name, "'s data from ", def, " to ", src); - } - if (!pack_env(&p, def, out)) { - rm(&p, out); + if (!pack_env(&p, def, out)) log_diesys2(100, "could not set environment variables for ", *argv); - } - if (!pack_build(&p, def, src)) { - rm(&p, out); + if (!pack_chdir(&p, src)) + log_diesys1(100, "could not change directory to the source directory"); + + if (!pack_build(&p, def)) log_diesys2(100, "could not execute build script of ", p.name); - } return 0; }