1.1 --- a/librazor/rpm.c Thu Feb 05 22:43:29 2009 +0000
1.2 +++ b/librazor/rpm.c Sat Feb 14 11:35:32 2009 +0000
1.3 @@ -736,25 +736,76 @@
1.4 }
1.5 }
1.6
1.7 -static int
1.8 -run_script(struct installer *installer,
1.9 - unsigned int program_tag, unsigned int script_tag)
1.10 +static int chroot_push(const char *root)
1.11 +{
1.12 + int fd;
1.13 +#if HAVE_CHROOT
1.14 + if (geteuid() == 0) {
1.15 + fd = open("/", O_RDONLY, 0);
1.16 + if (chroot(root) < 0) {
1.17 + fprintf(stderr, "failed to chroot to %s: %s\n",
1.18 + root, strerror(errno));
1.19 + exit(-1);
1.20 + }
1.21 + } else
1.22 +#endif
1.23 + fd = -1;
1.24 + return fd;
1.25 +}
1.26 +
1.27 +static void chroot_pop(int fd)
1.28 {
1.29 #if HAVE_CHROOT
1.30 - int pid, status, fd[2];
1.31 + if (fd >= 0) {
1.32 + fchdir(fd);
1.33 + close(fd);
1.34 + chroot(".");
1.35 + }
1.36 +#endif
1.37 +}
1.38 +
1.39 +static int
1.40 +run_script_lua(const char *root, unsigned int script_tag, const char *script)
1.41 +{
1.42 + int root_fd, retval;
1.43 #if HAVE_LUA
1.44 - int save_root, retval;
1.45 -#endif
1.46 -#else /* HAVE_CHROOT */
1.47 + const char *name;
1.48 +
1.49 + switch(script_tag) {
1.50 + case RPMTAG_PREIN:
1.51 + name = "%pre";
1.52 + break;
1.53 + case RPMTAG_POSTIN:
1.54 + name = "%post";
1.55 + break;
1.56 + case RPMTAG_PREUN:
1.57 + name = "%preun";
1.58 + break;
1.59 + case RPMTAG_POSTUN:
1.60 + name = "%postun";
1.61 + break;
1.62 + default:
1.63 + name = "script";
1.64 + break;
1.65 + }
1.66 + root_fd = chroot_push(root);
1.67 + retval = run_lua_script(root_fd < 0 ? root : NULL, name, script, -1);
1.68 + chroot_pop(root_fd);
1.69 +#else /* HAVE_LUA */
1.70 + fprintf(stderr, "lua not available to run script\n");
1.71 + retval = -1;
1.72 +#endif /* HAVE_LUA */
1.73 +
1.74 + return retval;
1.75 +}
1.76 +
1.77 +static int
1.78 +run_script_external(const char *root, const char *program, const char *script)
1.79 +{
1.80 + int root_fd, retval;
1.81 FILE *fp;
1.82 -#endif /* HAVE_CHROOT */
1.83 - const char *script = NULL, *program = NULL;
1.84
1.85 - program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
1.86 - script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
1.87 - if (program == NULL && script == NULL) {
1.88 - return 0;
1.89 - } else if (program == NULL) {
1.90 + if (program == NULL) {
1.91 #if MSWIN_API
1.92 program = getenv("COMSPEC");
1.93 if (program) {
1.94 @@ -767,107 +818,44 @@
1.95 #else
1.96 program = "/bin/sh";
1.97 #endif
1.98 - } else if (!strcmp(program, "<lua>")) {
1.99 -#if HAVE_LUA
1.100 - const char *name;
1.101 -
1.102 - switch(script_tag) {
1.103 - case RPMTAG_PREIN:
1.104 - name = "%pre";
1.105 - break;
1.106 - case RPMTAG_POSTIN:
1.107 - name = "%post";
1.108 - break;
1.109 - case RPMTAG_PREUN:
1.110 - name = "%preun";
1.111 - break;
1.112 - case RPMTAG_POSTUN:
1.113 - name = "%postun";
1.114 - break;
1.115 - default:
1.116 - name = "script";
1.117 - break;
1.118 - }
1.119 -#if HAVE_CHROOT
1.120 - if (geteuid() == 0) {
1.121 - save_root = open("/", O_RDONLY, 0);
1.122 - if (chroot(installer->root) < 0) {
1.123 - fprintf(stderr, "failed to chroot to %s: %s\n",
1.124 - installer->root, strerror(errno));
1.125 - exit(-1);
1.126 - }
1.127 - retval = run_lua_script(NULL, name, script, -1);
1.128 - fchdir(save_root);
1.129 - close(save_root);
1.130 - chroot(".");
1.131 - } else
1.132 -#endif
1.133 - {
1.134 - retval = run_lua_script(installer->root, name, script,
1.135 - -1);
1.136 - }
1.137 - return retval;
1.138 -#else /* HAVE_LUA */
1.139 - fprintf(stderr, "lua not available to run script\n");
1.140 - return -1;
1.141 -#endif /* HAVE_LUA */
1.142 }
1.143
1.144 -#if HAVE_CHROOT
1.145 - if (pipe(fd) < 0) {
1.146 - fprintf(stderr, "failed to create pipe\n");
1.147 - return -1;
1.148 - }
1.149 - pid = fork();
1.150 - if (pid < 0) {
1.151 - perror("failed to fork");
1.152 - } else if (pid == 0) {
1.153 - if (dup2(fd[0], STDIN_FILENO) < 0) {
1.154 - perror("failed redirect stdin");
1.155 - exit(-1);
1.156 - }
1.157 - if (close(fd[0]) < 0 || close(fd[1]) < 0) {
1.158 - perror("failed to close pipe");
1.159 - exit(-1);
1.160 - }
1.161 - if (chroot(installer->root) < 0) {
1.162 - fprintf(stderr, "failed to chroot to %s: %s\n",
1.163 - installer->root, strerror(errno));
1.164 - exit(-1);
1.165 - }
1.166 - printf("executing program %s in chroot %s\n",
1.167 - program, installer->root);
1.168 - if (execl(program, program, NULL)) {
1.169 - fprintf(stderr, "failed to exec %s: %s\n", program,
1.170 - strerror(errno));
1.171 - exit(-1);
1.172 - }
1.173 - } else {
1.174 - if (script && razor_write(fd[1], script, strlen(script)) < 0) {
1.175 - perror("failed to pipe script");
1.176 - return -1;
1.177 - }
1.178 - if (close(fd[0]) || close(fd[1])) {
1.179 - perror("failed to close pipe");
1.180 - return -1;
1.181 - }
1.182 - if (wait(&status) < 0) {
1.183 - perror("wait for child failed");
1.184 - return -1;
1.185 - }
1.186 - if (status)
1.187 - printf("script exited with status %d\n", status);
1.188 - }
1.189 -#else
1.190 + root_fd = chroot_push(root);
1.191 fp = popen(program, "w");
1.192 - if (fwrite(script, strlen(script), 1, fp) != 1) {
1.193 - perror("failed to pipe script");
1.194 - return -1;
1.195 - }
1.196 - pclose(fp);
1.197 -#endif
1.198
1.199 - return 0;
1.200 + if (!fp) {
1.201 + perror(program);
1.202 + retval = -1;
1.203 + } else if (fwrite(script, strlen(script), 1, fp) != 1) {
1.204 + perror("failed to write script to program");
1.205 + retval = -1;
1.206 + } else
1.207 + retval = 0;
1.208 +
1.209 + if (fp)
1.210 + pclose(fp);
1.211 + chroot_pop(root_fd);
1.212 +
1.213 + return retval;
1.214 +}
1.215 +
1.216 +static int
1.217 +run_script(struct installer *installer,
1.218 + unsigned int program_tag, unsigned int script_tag)
1.219 +{
1.220 + int retval;
1.221 + const char *script = NULL, *program = NULL;
1.222 +
1.223 + program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
1.224 + script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
1.225 + if (program == NULL && script == NULL)
1.226 + retval = 0;
1.227 + else if (strcmp(program, "<lua>") == 0)
1.228 + retval = run_script_lua(installer->root, script_tag, script);
1.229 + else
1.230 + retval = run_script_external(installer->root, program, script);
1.231 +
1.232 + return retval;
1.233 }
1.234
1.235 static int