X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=zpm-runscript.c;h=a3f4c2f6d07efe0e21c071483264b2deca97a301;hb=f72f5c784b3c7e525d59e11e25bd2d241f0bc53a;hp=e6b1af50f51d97c146c361945488fc50cca4a2ed;hpb=0187a28d81a65b5b92c6c2dbaacce07d6277ba33;p=zpackage diff --git a/zpm-runscript.c b/zpm-runscript.c index e6b1af5..a3f4c2f 100644 --- a/zpm-runscript.c +++ b/zpm-runscript.c @@ -2,13 +2,14 @@ #include #include +#include #include #include #include #include #include #include - +#include #include @@ -32,7 +33,7 @@ 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, just run the program + * if output is null or "-", just run the program */ int interactive = 0; pid_t pid; @@ -51,7 +52,7 @@ int run(char *program, char **args, char *output, int *status) { if (pid == 0) { /* child */ - if (output) { + if (output && strcmp(output, "-") != 0) { close(2); rv = open(output, O_NOFOLLOW|O_TRUNC|O_CREAT|O_WRONLY, 0600); @@ -94,12 +95,13 @@ int main(int ac, char **av){ int failures = 0; char *pkgstr; int opt; + int required = 0; char hash[ZPM_HASH_STRLEN+1]; - char *args[3]; + char *args[4]; char *pkgid; - char *chroot = 0; + char *rootdir = 0; char *db = "/var/lib/zpm/zpm.db"; char *script = "/var/tmp/zpm-script"; char *output = "/var/tmp/zpm-script.out"; @@ -110,16 +112,16 @@ int main(int ac, char **av){ } /* ZPM_PACKAGE_FILE ? */ - while ((opt = getopt(ac, av, "f:p:s:r:")) != -1) { + rootdir = getenv("ZPM_ROOT_DIR"); + + while ((opt = getopt(ac, av, "f:p:o:s:r:R")) != -1) { switch (opt) { - case 'f': db = optarg; - break; - case 'p': phase = optarg; - break; - case 's': script = optarg; - break; - case 'r': chroot = optarg; - break; + case 'f': db = optarg; break; + case 'p': phase = optarg; break; + case 's': script = optarg; break; + case 'o': output = optarg; break; + case 'r': rootdir = optarg; break; + case 'R': required = 1; break; default: usage(); exit(EXIT_FAILURE); @@ -146,16 +148,45 @@ int main(int ac, char **av){ pkgid = zpm_findpkg(&zpm, pkgstr); if (pkgid) { if (zpm_script_hash(&zpm, pkgid, phase, hash)) { - rv = zpm_extract(&zpm, hash, script, 0700); + /* since the script file name doesn't really + * mean anything, pass in the phase as arg 0 + */ - /* perhaps also pass in the phase name? or ENV? */ /* TODO sanitize environment ? */ - args[0] = script; + args[0] = phase; args[1] = pkgid; args[2] = 0; - if (chroot) { - fprintf(stderr, "failing to chroot %s\n", chroot); + args[3] = 0; + if (argn + 1 <= ac) { + args[2] = av[argn+1]; } + + if (rootdir) { + if (chdir(rootdir) == -1) { + perror("can not chdir to rootdir"); + exit(EXIT_FAILURE); + } + 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"); + } + } else { + if (chdir("/") == -1) { + perror("can not chdir to /"); + exit(EXIT_FAILURE); + } + } + + if (!zpm_extract(&zpm, hash, script, 0700)) { + fprintf(stderr, "unable to extract script"); + exit(EXIT_FAILURE); + } + rv = run(script, args, output, &status); if (rv) { // cat(output); @@ -163,14 +194,20 @@ int main(int ac, char **av){ pkgid, rv); } /* TODO log output */ - unlink(script); - unlink(output); + if (script) { + unlink(script); + } + if (output) { + unlink(output); + } if (rv) { failures++; } } else { - fprintf(stderr, "no script for %s %s\n", phase, pkgid); - failures++; + if (required) { + fprintf(stderr, "no script for %s %s\n", phase, pkgid); + failures++; + } } free(pkgid); } else {