#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>
/* 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;
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);
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";
}
/* 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);
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);
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 {