]> pd.if.org Git - zpackage/blobdiff - zpm-runscript.c
add gc script
[zpackage] / zpm-runscript.c
index e6b1af50f51d97c146c361945488fc50cca4a2ed..a3f4c2f6d07efe0e21c071483264b2deca97a301 100644 (file)
@@ -2,13 +2,14 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
-
+#include <unistd.h>
 
 #include <sys/mman.h>
 
@@ -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 {