#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;
// 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
+#define _POSIX_C_SOURCE 200809L
+
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
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;
}
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 */
--- /dev/null
+#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;
+}