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 setdir(char *rootdir) {
33 if (rootdir && strcmp(rootdir, "/")) {
34 if (chdir(rootdir) == -1) {
35 perror("can not chdir to rootdir");
39 /* chroot is deprecated, and not in posix. need to use
40 * OS/kernel specific code.
42 fprintf(stderr, "support for chroot equivalent not supported on this OS\n");
44 fprintf(stderr, "unable to chroot as non root user\n");
47 if (chdir("/") == -1) {
48 perror("can not chdir to /");
56 int run(char *program, char **args, char *output, int *status) {
57 /* if stdout is a terminal, leave stdout where it goes,
58 * if it's not a terminal, redirect stdout to output.
59 * in either case, send stderr to output, unless null
60 * if output is null or "-", just run the program
68 interactive = isatty(1);
79 if (output && strcmp(output, "-") != 0) {
81 rv = open(output, O_NOFOLLOW|O_TRUNC|O_CREAT|O_WRONLY,
84 perror("cannot open output file");
89 perror("unable to redirect stdout");
95 rv = execvp(program, args);
97 perror("cannot exec");
104 perror("error waiting for child");
108 if (WIFEXITED(*status)) {
109 return WEXITSTATUS(*status);
122 int main(int ac, char **av){
131 char hash[ZPM_HASH_STRLEN+1];
136 char *db = "/var/lib/zpm/zpm.db";
137 char *script = "/var/tmp/zpm-script";
138 char *output = "/var/tmp/zpm-script.out";
141 int scriptishash = 0;
145 if (getenv("ZPMDB")) {
146 db = getenv("ZPMDB");
148 /* ZPM_PACKAGE_FILE ? */
150 rootdir = getenv("ZPM_ROOT_DIR");
152 /* run, set, show, hash */
153 /* set -S, if -H set the hash, output hash, unless quiet
154 * show: -o, or stdout,
155 * All modes: [-f pkgfile] default to zpmdb
156 * All modes: [-p phase], default to configure
157 * All modes: [-R rootdir], chdir, attempt to chroot
158 * All modes: [-N], required, error if no such script
160 * run: zpm-script -r -p foo <pkgid args...>
161 * set: zpm-script -s <pkgid [script]>
162 * set: zpm-script -s -h <pkgid [hash]>
163 * show: zpm-script -l [-a] [-o outfile] <pkgid>
164 * show hash: zpm-script -lh <pkgid>
166 while ((opt = getopt(ac, av, "f:p:rslRFho:S:q")) != -1) {
168 case 'f': db = optarg; break;
169 case 'p': phase = optarg; break;
170 case 'r': mode = RUN; break;
171 case 's': mode = SET; break;
172 case 'l': mode = LIST; break;
173 case 'R': rootdir = optarg; break;
174 case 'F': required = 1; break;
175 case 'a': all = 1; break;
177 case 'h': scriptishash = 1; break;
178 case 'o': output = optarg; break;
179 case 'S': script = optarg; break;
195 if (!zpm_open(&zpm, db)) {
196 fprintf(stderr, "unable to open zpm database: %s\n", db);
198 fprintf(stderr, "error detail: %s\n", zpm.errmsg);
203 /* first non option arg is always a package id */
205 pkgid = zpm_findpkg(&zpm, pkgstr);
208 fprintf(stderr, "no package for %s\n", pkgstr);
228 setscript = av[argn];
233 rv = zpm_import(&zpm,setscript,0,hash);
235 fprintf(stderr, "unable to import %s\n",
243 if (!fail && !zpm_script_set(&zpm,pkgid,phase,sethash)) {
244 fprintf(stderr, "unable to set %s script hash %s\n",
246 sethash ? sethash : "null");
247 fprintf(stderr, "zpm error: %s\n", zpm.errmsg);
250 } else if (mode == LIST) {
251 if (!zpm_script_hash(&zpm, pkgid, phase, hash)) {
253 } else if (scriptishash) {
254 printf("%s\n", hash);
259 if (!zpm_extract(&zpm, hash, output, 0700)) {
270 output = "/var/tmp/zpm-script.out";
274 script = "/var/tmp/zpm-script";
277 /* since the script file name doesn't really
278 * mean anything, pass in the phase as arg 0
280 /* TODO sanitize environment ? */
290 if (!zpm_script_hash(&zpm, pkgid, phase, hash)) {
295 if (!setdir(rootdir)) {
300 if (!zpm_extract(&zpm, hash, script, 0700)) {
301 fprintf(stderr, "unable to extract script");
306 rv = run(script, args, output, &status);
308 fprintf(stderr, "package %s script failed with code %d\n",
313 /* TODO log output */
326 return (fail == HARD || (required && fail)) ? EXIT_FAILURE : 0;