Refactor run_script for improved readability
authorJ. Ali Harlow <ali@juiblex.co.uk>
Sat, 14 Feb 2009 11:35:32 +0000 (11:35 +0000)
committerJ. Ali Harlow <ali@juiblex.co.uk>
Sat, 14 Feb 2009 11:35:32 +0000 (11:35 +0000)
librazor/rpm.c

index 8ca7bdd..51acc52 100644 (file)
@@ -736,25 +736,76 @@ create_path(struct installer *installer, const char *path, unsigned int mode)
        }
 }
 
-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) {
@@ -767,107 +818,44 @@ run_script(struct installer *installer,
 #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