1.1 --- a/rpm.c Thu Dec 27 15:46:52 2007 -0500
1.2 +++ b/rpm.c Thu Dec 27 15:47:09 2007 -0500
1.3 @@ -3,6 +3,8 @@
1.4 #include <string.h>
1.5 #include <sys/stat.h>
1.6 #include <sys/mman.h>
1.7 +#include <sys/types.h>
1.8 +#include <sys/wait.h>
1.9 #include <fcntl.h>
1.10 #include <unistd.h>
1.11 #include <arpa/inet.h>
1.12 @@ -61,11 +63,6 @@
1.13 struct rpm_header_index *filestates;
1.14 const char **dirs;
1.15
1.16 - struct rpm_header_index *prein;
1.17 - struct rpm_header_index *postin;
1.18 - struct rpm_header_index *preun;
1.19 - struct rpm_header_index *postun;
1.20 -
1.21 struct properties provides;
1.22 struct properties requires;
1.23 struct properties obsoletes;
1.24 @@ -133,11 +130,6 @@
1.25 unsigned int offset;
1.26 unsigned int tag;
1.27 } index_map[] = {
1.28 - MAP_ENTRY(prein, RPMTAG_PREIN),
1.29 - MAP_ENTRY(prein, RPMTAG_PREIN),
1.30 - MAP_ENTRY(postin, RPMTAG_POSTIN),
1.31 - MAP_ENTRY(preun, RPMTAG_PREUN),
1.32 - MAP_ENTRY(postun, RPMTAG_POSTUN),
1.33 MAP_ENTRY(name, RPMTAG_NAME),
1.34 MAP_ENTRY(version, RPMTAG_VERSION),
1.35 MAP_ENTRY(release, RPMTAG_RELEASE),
1.36 @@ -161,6 +153,22 @@
1.37 MAP_ENTRY(filestates, RPMTAG_FILESTATES),
1.38 };
1.39
1.40 +static struct rpm_header_index *
1.41 +razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
1.42 +{
1.43 + struct rpm_header_index *index, *end;
1.44 +
1.45 + index = (struct rpm_header_index *) (rpm->header + 1);
1.46 + end = index + ntohl(rpm->header->nindex);
1.47 + while (index < end) {
1.48 + if (ntohl(index->tag) == tag)
1.49 + return index;
1.50 + index++;
1.51 + }
1.52 +
1.53 + return NULL;
1.54 +}
1.55 +
1.56 struct razor_rpm *
1.57 razor_rpm_open(const char *filename)
1.58 {
1.59 @@ -304,6 +312,64 @@
1.60 }
1.61 }
1.62
1.63 +static int
1.64 +run_script(struct razor_rpm *rpm, const char *root, unsigned int tag)
1.65 +{
1.66 + struct rpm_header_index *index;
1.67 + int pid, status, fd[2];
1.68 + const char *script;
1.69 +
1.70 + index = razor_rpm_get_header(rpm, tag);
1.71 + if (index == NULL) {
1.72 + fprintf(stderr, "no script for tag %d\n", tag);
1.73 + return 0;
1.74 + }
1.75 +
1.76 + if (pipe(fd) < 0) {
1.77 + fprintf(stderr, "failed to create pipe\n");
1.78 + return -1;
1.79 + }
1.80 + pid = fork();
1.81 + if (pid < 0) {
1.82 + fprintf(stderr, "failed to fork, %m\n");
1.83 + } else if (pid == 0) {
1.84 + if (dup2(fd[0], STDIN_FILENO) < 0) {
1.85 + fprintf(stderr, "failed redirect stdin, %m\n");
1.86 + return -1;
1.87 + }
1.88 + if (close(fd[0]) < 0 || close(fd[1]) < 0) {
1.89 + fprintf(stderr, "failed to close pipe, %m\n");
1.90 + exit(-1);
1.91 + }
1.92 + if (chroot(root) < 0) {
1.93 + fprintf(stderr, "failed to chroot to %s, %m\n", root);
1.94 + return -1;
1.95 + }
1.96 + printf("executing script for %d\n", tag);
1.97 + if (execl("/bin/sh", "/bin/sh", NULL)) {
1.98 + fprintf(stderr, "failed to exec /bin/sh, %m\n");
1.99 + return -1;
1.100 + }
1.101 + } else {
1.102 + script = rpm->pool + ntohl(index->offset);
1.103 + if (write(fd[1], script, strlen(script)) < 0) {
1.104 + fprintf(stderr, "failed to pipe script, %m\n");
1.105 + return -1;
1.106 + }
1.107 + if (close(fd[0]) || close(fd[1])) {
1.108 + fprintf(stderr, "failed to close pipe, %m\n");
1.109 + return -1;
1.110 + }
1.111 + if (wait(&status) < 0) {
1.112 + fprintf(stderr, "wait for child failed, %m");
1.113 + return -1;
1.114 + }
1.115 + printf("script exited with status %d\n", status);
1.116 + }
1.117 +
1.118 + return 0;
1.119 +}
1.120 +
1.121 int
1.122 razor_rpm_install(struct razor_rpm *rpm, const char *root)
1.123 {
1.124 @@ -339,6 +405,8 @@
1.125 return -1;
1.126 }
1.127
1.128 + run_script(rpm, root, RPMTAG_PREIN);
1.129 +
1.130 stream.zalloc = NULL;
1.131 stream.zfree = NULL;
1.132 stream.opaque = NULL;
1.133 @@ -426,6 +494,8 @@
1.134 return -1;
1.135 }
1.136
1.137 + run_script(rpm, root, RPMTAG_POSTIN);
1.138 +
1.139 return 0;
1.140 }
1.141