1 #define _POSIX_C_SOURCE 200809L
19 * -f package file, otherwise localdb
20 * -p phase, defaults to 'configure'
21 * -s script name, defaults to /var/tmp/zpm-script
22 * -r chroot to directory
23 * -o script output, /var/tmp/zpm-script.out, '-' for stdout
29 fprintf(stderr, "usage: db hash file\n");
32 int run(char *program, char **args, char *output, int *status) {
33 /* if stdout is a terminal, leave stdout where it goes,
34 * if it's not a terminal, redirect stdout to output.
35 * in either case, send stderr to output, unless null
36 * if output is null or "-", just run the program
44 interactive = isatty(1);
55 if (output && strcmp(output, "-") != 0) {
57 rv = open(output, O_NOFOLLOW|O_TRUNC|O_CREAT|O_WRONLY,
60 perror("cannot open output file");
65 perror("unable to redirect stdout");
71 rv = execvp(program, args);
73 perror("cannot exec");
80 perror("error waiting for child");
84 if (WIFEXITED(*status)) {
85 return WEXITSTATUS(*status);
91 int main(int ac, char **av){
100 char hash[ZPM_HASH_STRLEN+1];
105 char *db = "/var/lib/zpm/zpm.db";
106 char *script = "/var/tmp/zpm-script";
107 char *output = "/var/tmp/zpm-script.out";
108 char *phase = "configure";
110 if (getenv("ZPMDB")) {
111 db = getenv("ZPMDB");
113 /* ZPM_PACKAGE_FILE ? */
115 rootdir = getenv("ZPM_ROOT_DIR");
117 while ((opt = getopt(ac, av, "f:p:o:s:r:R")) != -1) {
119 case 'f': db = optarg; break;
120 case 'p': phase = optarg; break;
121 case 's': script = optarg; break;
122 case 'o': output = optarg; break;
123 case 'r': rootdir = optarg; break;
124 case 'R': required = 1; break;
140 if (!zpm_open(&zpm, db)) {
141 fprintf(stderr, "unable to open zpm database: %s\n", db);
143 fprintf(stderr, "error detail: %s\n", zpm.errmsg);
148 pkgid = zpm_findpkg(&zpm, pkgstr);
150 if (zpm_script_hash(&zpm, pkgid, phase, hash)) {
151 /* since the script file name doesn't really
152 * mean anything, pass in the phase as arg 0
155 /* TODO sanitize environment ? */
160 if (argn + 1 <= ac) {
161 args[2] = av[argn+1];
165 if (chdir(rootdir) == -1) {
166 perror("can not chdir to rootdir");
169 if (geteuid() == 0) {
170 /* chroot is deprecated, and not in
171 * posix. need to use OS/kernel
174 fprintf(stderr, "support for chroot equivalent not supported on this OS\n");
176 fprintf(stderr, "unable to chroot as non root user\n");
179 if (chdir("/") == -1) {
180 perror("can not chdir to /");
185 if (!zpm_extract(&zpm, hash, script, 0700)) {
186 fprintf(stderr, "unable to extract script");
190 rv = run(script, args, output, &status);
193 fprintf(stderr, "package %s script failed with code %d\n",
196 /* TODO log output */
208 fprintf(stderr, "no script for %s %s\n", phase, pkgid);
214 fprintf(stderr, "unable to find package for %s in %s\n",
221 return failures ? EXIT_FAILURE : EXIT_SUCCESS;