X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=zpm-script.c;fp=zpm-script.c;h=0000000000000000000000000000000000000000;hb=5dd3c3e64a9574112dda77a5afc167f5daa53fd8;hp=7c03b241792ae1f91ea504215b1400526580c71b;hpb=bd21f0a1265b43ad5f05353a39db31c16826f05c;p=zpackage diff --git a/zpm-script.c b/zpm-script.c deleted file mode 100644 index 7c03b24..0000000 --- a/zpm-script.c +++ /dev/null @@ -1,348 +0,0 @@ -#define _POSIX_C_SOURCE 200809L - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "zpm.h" - -/* - * -f package file, otherwise localdb - * -p phase, defaults to 'configure' - * -s script name, defaults to /var/tmp/zpm-script - * -r chroot to directory - * -o script output, /var/tmp/zpm-script.out, '-' for stdout - * - * arg is package id - */ - -void usage(void) { - fprintf(stderr, "usage: zpm script ...\n"); -} - -int setdir(char *rootdir) { - if (chdir(rootdir ? rootdir : "/") == -1) { - perror("can not chdir to rootdir"); - return 0; - } -#if 0 - if (rootdir && strcmp(rootdir, "/")) { - if (geteuid() == 0) { - /* chroot is deprecated, and not in posix. need to use - * OS/kernel specific code. - */ - fprintf(stderr, "support for chroot equivalent not supported on this OS\n"); - } else { - fprintf(stderr, "unable to chroot as non root user\n"); - } - } -#endif - return 1; -} - - -int run(char *program, char **args, char *output, int *status) { - /* if stdout is a terminal, leave stdout where it goes, - * if it's not a terminal, redirect stdout to output. - * in either case, send stderr to output, unless null - * if output is null or "-", just run the program - */ - int interactive = 0; - pid_t pid; - int rv; - - errno = 0; - - interactive = isatty(1); - - pid = fork(); - - if (pid == -1) { - *status = 1; - return -1; - } - - if (pid == 0) { - /* child */ - if (output && strcmp(output, "-") != 0) { - close(2); - rv = open(output, O_NOFOLLOW|O_TRUNC|O_CREAT|O_WRONLY, - 0600); - if (rv == -1) { - perror("cannot open output file"); - } - if (!interactive) { - rv = dup2(2,1); - if (rv == -1) { - perror("unable to redirect stdout"); - exit(EXIT_FAILURE); - } - } - } - - rv = execvp(program, args); - if (rv == -1) { - perror("cannot exec"); - exit(EXIT_FAILURE); - } - } - - pid = wait(status); - if (pid == -1) { - perror("error waiting for child"); - return -2; - } - - if (WIFEXITED(*status)) { - return WEXITSTATUS(*status); - } - - return -3; -} - -#define RUN 1 -#define SET 2 -#define LIST 3 - -#define SOFT 1 -#define HARD 2 - -static int list_scripts(void *ud, const char *pkg, const char *stage, - const char *hash) { - printf("%s %s %.8s\n", pkg, stage, hash); - return 0; -} - -int main(int ac, char **av){ - struct zpm zpm; - int rv; - int status; - int required = 0; - int fail = 0; - char *pkgstr; - int opt; - - char hash[ZPM_HASH_STRLEN+1]; - char *args[4]; - char *pkgid; - - char *rootdir = 0; - char *db = "/var/lib/zpm/local.db"; - char *script = "/var/tmp/zpm-script"; - char *output = "/var/tmp/zpm-script.out"; - char *phase = 0; - char *envvar = 0; - int quiet = 0; - int scriptishash = 0; - int mode = RUN; - - if (getenv("ZPMDB")) { - db = getenv("ZPMDB"); - } - /* ZPM_PACKAGE_FILE ? */ - - rootdir = getenv("ZPM_ROOT_DIR"); - - envvar = getenv("ZPM_SCRIPT_FILE"); - if (envvar) { - script = envvar; - } - - envvar = getenv("ZPM_SCRIPT_OUTPUT"); - if (envvar) { - output = envvar; - } - - /* run, set, show, hash */ - /* set -S, if -H set the hash, output hash, unless quiet - * show: -o, or stdout, - * All modes: [-f pkgfile] default to zpmdb - * All modes: [-p phase], default to configure - * All modes: [-R rootdir], chdir, attempt to chroot - * All modes: [-N], required, error if no such script - * - * run: zpm-script -r -p foo - * set: zpm-script -s - * set: zpm-script -s -h - * show: zpm-script -l [-a] [-o outfile] - * show hash: zpm-script -lh - */ - while ((opt = getopt(ac, av, "f:p:rslRFho:S:q")) != -1) { - switch (opt) { - case 'f': db = optarg; break; - case 'p': phase = optarg; break; - case 'r': mode = RUN; break; - case 's': mode = SET; break; - case 'l': mode = LIST; break; - case 'R': rootdir = optarg; break; - case 'F': required = 1; break; - - case 'h': scriptishash = 1; break; - case 'o': output = optarg; break; - case 'S': script = optarg; break; - case 'q': quiet = 1; break; - - default: - usage(); - exit(EXIT_FAILURE); - break; - } - } - int argn = optind; - - if (argn >= ac) { - usage(); - exit(EXIT_FAILURE); - } - - if (!zpm_open(&zpm, db)) { - fprintf(stderr, "unable to open zpm database: %s\n", db); - if (zpm.errmsg) { - fprintf(stderr, "error detail: %s\n", zpm.errmsg); - } - exit(EXIT_FAILURE); - } - - /* first non option arg is always a package id */ - pkgstr = av[argn]; - pkgid = zpm_findpkg(&zpm, pkgstr, NULL); - - if (!pkgid) { - fprintf(stderr, "no package for %s\n", pkgstr); - zpm_close(&zpm); - exit(EXIT_FAILURE); - } - - argn++; - - if (mode == SET) { - char *sethash = 0; - char *setscript = 0; - int rv = 0; - - if (!phase) { - phase = "configure"; - } - - if (argn < ac) { - if (scriptishash) { - sethash = av[argn]; - } else { - setscript = av[argn]; - } - } - - if (setscript) { - rv = zpm_import(&zpm,setscript,0,hash); - if (!rv) { - fprintf(stderr, "unable to import %s\n", - setscript); - fail = HARD; - } else { - sethash = hash; - } - } - - if (!fail && !zpm_script_set(&zpm,pkgid,phase,sethash)) { - fprintf(stderr, "unable to set %s script hash %s\n", - pkgid, - sethash ? sethash : "null"); - fprintf(stderr, "zpm error: %s\n", zpm.errmsg); - fail = HARD; - } - } else if (mode == LIST) { - if (!phase) { - zpm_foreach_script(&zpm, pkgid, phase, 0, list_scripts); - } else if (!zpm_script_hash(&zpm, pkgid, phase, hash)) { - fail = SOFT; - } else if (scriptishash) { - if (!quiet) { - printf("%s\n", hash); - } - } else { - if (!output) { - output = "-"; - } - if (!zpm_extract(&zpm, hash, output, 0700)) { - fail = HARD; - } - } - } else { - /* run a script */ - if (!phase) { - phase = "configure"; - } - - if (!output) { - output = "/var/tmp/zpm-script.out"; - } - - if (!script) { - script = "/var/tmp/zpm-script"; - } - - /* since the script file name doesn't really - * mean anything, pass in the phase as arg 0 - */ - /* TODO sanitize environment ? */ - args[0] = phase; - args[1] = pkgid; - args[2] = 0; - args[3] = 0; - - if (argn <= ac) { - args[2] = av[argn]; - } - - if (!zpm_script_hash(&zpm, pkgid, phase, hash)) { - fail = SOFT; - goto cleanup; - } - - if (!setdir(rootdir)) { - fail = HARD; - goto cleanup; - } - - if (!zpm_extract(&zpm, hash, script, 0700)) { - fprintf(stderr, "unable to extract script"); - fail = HARD; - zpm_note_add(&zpm, pkgid, NULL, hash, "unable to extract %s script", phase); - goto cleanup; - } - - rv = run(script, args, output, &status); - if (rv) { - fprintf(stderr, "package %s script failed with code %d\n", - pkgid, rv); - - zpm_import(&zpm, output, 0, hash); - zpm_note_add(&zpm, pkgid, NULL, hash, "package %s script failed with code %d", phase, rv); - - fail = HARD; - } - - /* TODO log output */ - if (script) { - unlink(script); - } - if (output) { - unlink(output); - } - } - -cleanup: - free(pkgid); - zpm_close(&zpm); - - return (fail == HARD || (required && fail)) ? EXIT_FAILURE : 0; -}