}
}
-static int
-run_script(struct installer *installer,
- unsigned int program_tag, unsigned int script_tag)
+static int chroot_push(const char *root)
{
+ int fd;
#if HAVE_CHROOT
- int pid, status, fd[2];
-#if HAVE_LUA
- int save_root, retval;
+ if (geteuid() == 0) {
+ fd = open("/", O_RDONLY, 0);
+ if (chroot(root) < 0) {
+ fprintf(stderr, "failed to chroot to %s: %s\n",
+ root, strerror(errno));
+ exit(-1);
+ }
+ } else
+#endif
+ fd = -1;
+ return fd;
+}
+
+static void chroot_pop(int fd)
+{
+#if HAVE_CHROOT
+ if (fd >= 0) {
+ fchdir(fd);
+ close(fd);
+ chroot(".");
+ }
#endif
-#else /* HAVE_CHROOT */
+}
+
+static int
+run_script_lua(const char *root, unsigned int script_tag, const char *script)
+{
+ int root_fd, retval;
+#if HAVE_LUA
+ const char *name;
+
+ switch(script_tag) {
+ case RPMTAG_PREIN:
+ name = "%pre";
+ break;
+ case RPMTAG_POSTIN:
+ name = "%post";
+ break;
+ case RPMTAG_PREUN:
+ name = "%preun";
+ break;
+ case RPMTAG_POSTUN:
+ name = "%postun";
+ break;
+ default:
+ name = "script";
+ break;
+ }
+ root_fd = chroot_push(root);
+ retval = run_lua_script(root_fd < 0 ? root : NULL, name, script, -1);
+ chroot_pop(root_fd);
+#else /* HAVE_LUA */
+ fprintf(stderr, "lua not available to run script\n");
+ retval = -1;
+#endif /* HAVE_LUA */
+
+ return retval;
+}
+
+static int
+run_script_external(const char *root, const char *program, const char *script)
+{
+ int root_fd, retval;
FILE *fp;
-#endif /* HAVE_CHROOT */
- const char *script = NULL, *program = NULL;
- program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
- script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
- if (program == NULL && script == NULL) {
- return 0;
- } else if (program == NULL) {
+ if (program == NULL) {
#if MSWIN_API
program = getenv("COMSPEC");
if (program) {
#else
program = "/bin/sh";
#endif
- } else if (!strcmp(program, "<lua>")) {
-#if HAVE_LUA
- const char *name;
-
- switch(script_tag) {
- case RPMTAG_PREIN:
- name = "%pre";
- break;
- case RPMTAG_POSTIN:
- name = "%post";
- break;
- case RPMTAG_PREUN:
- name = "%preun";
- break;
- case RPMTAG_POSTUN:
- name = "%postun";
- break;
- default:
- name = "script";
- break;
- }
-#if HAVE_CHROOT
- if (geteuid() == 0) {
- save_root = open("/", O_RDONLY, 0);
- if (chroot(installer->root) < 0) {
- fprintf(stderr, "failed to chroot to %s: %s\n",
- installer->root, strerror(errno));
- exit(-1);
- }
- retval = run_lua_script(NULL, name, script, -1);
- fchdir(save_root);
- close(save_root);
- chroot(".");
- } else
-#endif
- {
- retval = run_lua_script(installer->root, name, script,
- -1);
- }
- return retval;
-#else /* HAVE_LUA */
- fprintf(stderr, "lua not available to run script\n");
- return -1;
-#endif /* HAVE_LUA */
}
-#if HAVE_CHROOT
- if (pipe(fd) < 0) {
- fprintf(stderr, "failed to create pipe\n");
- return -1;
- }
- pid = fork();
- if (pid < 0) {
- perror("failed to fork");
- } else if (pid == 0) {
- if (dup2(fd[0], STDIN_FILENO) < 0) {
- perror("failed redirect stdin");
- exit(-1);
- }
- if (close(fd[0]) < 0 || close(fd[1]) < 0) {
- perror("failed to close pipe");
- exit(-1);
- }
- if (chroot(installer->root) < 0) {
- fprintf(stderr, "failed to chroot to %s: %s\n",
- installer->root, strerror(errno));
- exit(-1);
- }
- printf("executing program %s in chroot %s\n",
- program, installer->root);
- if (execl(program, program, NULL)) {
- fprintf(stderr, "failed to exec %s: %s\n", program,
- strerror(errno));
- exit(-1);
- }
- } else {
- if (script && razor_write(fd[1], script, strlen(script)) < 0) {
- perror("failed to pipe script");
- return -1;
- }
- if (close(fd[0]) || close(fd[1])) {
- perror("failed to close pipe");
- return -1;
- }
- if (wait(&status) < 0) {
- perror("wait for child failed");
- return -1;
- }
- if (status)
- printf("script exited with status %d\n", status);
- }
-#else
+ root_fd = chroot_push(root);
fp = popen(program, "w");
- if (fwrite(script, strlen(script), 1, fp) != 1) {
- perror("failed to pipe script");
- return -1;
- }
- pclose(fp);
-#endif
- return 0;
+ if (!fp) {
+ perror(program);
+ retval = -1;
+ } else if (fwrite(script, strlen(script), 1, fp) != 1) {
+ perror("failed to write script to program");
+ retval = -1;
+ } else
+ retval = 0;
+
+ if (fp)
+ pclose(fp);
+ chroot_pop(root_fd);
+
+ return retval;
+}
+
+static int
+run_script(struct installer *installer,
+ unsigned int program_tag, unsigned int script_tag)
+{
+ int retval;
+ const char *script = NULL, *program = NULL;
+
+ program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
+ script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
+ if (program == NULL && script == NULL)
+ retval = 0;
+ else if (strcmp(program, "<lua>") == 0)
+ retval = run_script_lua(installer->root, script_tag, script);
+ else
+ retval = run_script_external(installer->root, program, script);
+
+ return retval;
}
static int