]> pd.if.org Git - zpackage/commitdiff
use stage instead of phase in script_hash
authorNathan Wagner <nw@hydaspes.if.org>
Mon, 17 Sep 2018 11:34:29 +0000 (11:34 +0000)
committerNathan Wagner <nw@hydaspes.if.org>
Mon, 24 Sep 2018 10:40:18 +0000 (10:40 +0000)
add zpm-runscript to makefile

improve error handling in script_hash.

Makefile
lib/dbquery.c
lib/findpkg.c
lib/script_hash.c
zpm-runscript.c [new file with mode: 0644]

index 32a48ee78df6b8f7289d4cf4f42a3e49240b254f..c876ce1588e64ab178e0434922e949f346427952 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,8 @@ LIBZPMOBJ=$(addprefix lib/, $(LIBZPMSRC:%.c=%.o))
 curdir=$(shell pwd)
 
 ZPKGBIN=zpm-addfile zpm-extract zpm-init zpm-vercmp zpm-stat zpm-hash \
-       zpm-findpkg zpm-shell zpm-soneed zpm-foreach-path zpm-parse
+       zpm-findpkg zpm-shell zpm-soneed zpm-foreach-path zpm-parse \
+       zpm-runscript
 
 SCRIPTS=zpm zpm-install zpm-merge zpm-list zpm-preserve zpm-test zpm-log \
        zpm-contents
@@ -116,6 +117,9 @@ zpm-init: zpm-init.o libzpm.a
 
 zpm-extract: zpm-extract.o libzpm.a
        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lzpm -lelf
+
+zpm-runscript: zpm-runscript.o libzpm.a
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lzpm -lelf
        
 zpm-foreach-path.o: CFLAGS+=-Wno-unused
 
index 479070c380505ab487be41e197d68e0f562b27b8..d6ef8b55239ebe19e1480381d91f5b52c4e07634 100644 (file)
@@ -28,7 +28,6 @@ sqlite3_stmt *zpm_dbquery(struct zpm *zpm, char *query, ...) {
                return 0;
        }
 
-       fprintf(stderr, "preparing query: %s\n", sql);
        rv = sqlite3_prepare_v2(db, sql, strlen(sql), &st, NULL);
        if (rv != SQLITE_OK) {
                SQLERROR(sqlite3_errmsg(db));
index 6f69876f76915149e2e4d5b276a2477b36d98100..900b6cbc74ebd51bfb5ce0184d95715793e72c60 100644 (file)
@@ -9,6 +9,8 @@
 
 #include "sqlite3.h"
 
+#define DMARK fprintf(stderr, "mark %s %s:%d\n", __FILE__, __func__, __LINE__)
+
 int zpm_parse_package(char *pstr, char *name, char *ver, int *rel) {
        if (name) *name = 0;
        if (ver) *ver = 0;
@@ -106,11 +108,16 @@ char *zpm_findpkg(struct zpm *zpm, char *pkgstr) {
 //     char *order = "order by package, version collate vercmp, cast(release as integer)";
        sqlite3_str *sql;
        sqlite3_stmt *stmt;
-       char *query, *pkgid;
+       char *query, *pkgid = 0;
        char package[32];
        char version[32];
        int release;
 
+       if (pkgstr == NULL) {
+               fprintf(stderr, "trying to parse null string\n");
+               return NULL;
+       }
+
        /* null pkgstr find "best" package
         * best is shortest complete package if any are complete
         * shortest incomplete if any are incomplete
index c559e877dfbcaa3d72e3a6d0bedc9b983551764a..60c87ede8eb4e1b23ab107f40f93de479d0f01bd 100644 (file)
@@ -1,3 +1,5 @@
+#define _POSIX_C_SOURCE 200809L
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -7,15 +9,18 @@
 
 int zpm_script_hash(struct zpm *zpm, char *pkgstr, char *phase, char *hash) {
        char *pkgid = 0;
-       char *template = "select hash from scripts_pkgid where pkgid = %Q and phase = %Q";
+       char *template = "select hash from scripts_pkgid where pkgid = %Q and stage = %Q";
        sqlite3_stmt *st;
 
        pkgid = zpm_findpkg(zpm, pkgstr);
 
        st = zpm_dbquery(zpm, template, pkgid, phase);
+
        free(pkgid);
 
        if (!st) {
+               zpm->error = 1;
+               zpm->errmsg = strdup(sqlite3_errmsg(zpm->db));
                return 0;
        }
 
@@ -26,6 +31,7 @@ int zpm_script_hash(struct zpm *zpm, char *pkgstr, char *phase, char *hash) {
                        hash[ZPM_HASH_STRLEN] = 0;
                        break;
                default: zpm->error = 1; /* fall through */
+                        zpm->errmsg = strdup(sqlite3_errmsg(zpm->db));
                case SQLITE_DONE:
                        sqlite3_finalize(st);
                        return 0; break; /* not found */
diff --git a/zpm-runscript.c b/zpm-runscript.c
new file mode 100644 (file)
index 0000000..e6b1af5
--- /dev/null
@@ -0,0 +1,185 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+#include <sys/mman.h>
+
+#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: db hash file\n");
+}
+
+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
+        */
+       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) {
+                       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;
+}
+
+int main(int ac, char **av){
+       struct zpm zpm;
+       int rv;
+       int status;
+       int failures = 0;
+       char *pkgstr;
+       int opt;
+
+       char hash[ZPM_HASH_STRLEN+1];
+       char *args[3];
+       char *pkgid;
+
+       char *chroot = 0;
+       char *db = "/var/lib/zpm/zpm.db";
+       char *script = "/var/tmp/zpm-script";
+       char *output = "/var/tmp/zpm-script.out";
+       char *phase = "configure";
+
+       if (getenv("ZPMDB")) {
+               db = getenv("ZPMDB");
+       }
+       /* ZPM_PACKAGE_FILE ? */
+
+       while ((opt = getopt(ac, av, "f:p:s:r:")) != -1) {
+               switch (opt) {
+                       case 'f': db = optarg;
+                                 break;
+                       case 'p': phase = optarg;
+                                 break;
+                       case 's': script = optarg;
+                                 break;
+                       case 'r': chroot = optarg;
+                                 break;
+                       default:
+                                 usage();
+                                 exit(EXIT_FAILURE);
+                                 break;
+               }
+       }
+       int argn = optind;
+
+       if (argn >= ac) {
+               usage();
+               exit(EXIT_FAILURE);
+       }
+
+       pkgstr = av[argn];
+
+       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);
+       }
+
+       pkgid = zpm_findpkg(&zpm, pkgstr);
+       if (pkgid) {
+               if (zpm_script_hash(&zpm, pkgid, phase, hash)) {
+                       rv = zpm_extract(&zpm, hash, script, 0700);
+
+                       /* perhaps also pass in the phase name?  or ENV? */
+                       /* TODO sanitize environment ? */
+                       args[0] = script;
+                       args[1] = pkgid;
+                       args[2] = 0;
+                       if (chroot) {
+                               fprintf(stderr, "failing to chroot %s\n", chroot);
+                       }
+                       rv = run(script, args, output, &status);
+                       if (rv) {
+                               //                      cat(output);
+                               fprintf(stderr, "package %s script failed with code %d\n",
+                                               pkgid, rv);
+                       }
+                       /* TODO log output */
+                       unlink(script);
+                       unlink(output);
+                       if (rv) {
+                               failures++;
+                       }
+               } else {
+                       fprintf(stderr, "no script for %s %s\n", phase, pkgid);
+                       failures++;
+               }
+               free(pkgid);
+       } else {
+               fprintf(stderr, "unable to find package for %s in %s\n",
+                               pkgstr, db);
+               failures++;
+       }
+
+       zpm_close(&zpm);
+
+       return failures ? EXIT_FAILURE : EXIT_SUCCESS;
+}