librazor/rpm.c
changeset 358 13beaca8b75f
parent 352 4866573c6944
child 359 c9c90315ea24
     1.1 --- a/librazor/rpm.c	Thu Feb 05 22:43:29 2009 +0000
     1.2 +++ b/librazor/rpm.c	Fri Apr 17 23:08:11 2009 +0100
     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