Ejemplo n.º 1
0
static int run_script(const char *action)
{
	char *env_PREVIOUS, *env_CURRENT;
	char *argv[5];
	int r;

	bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action);

	argv[0] = (char*) G.script_name;
	argv[1] = (char*) G.iface;
	argv[2] = (char*) action;
	argv[3] = (char*) G.extra_arg;
	argv[4] = NULL;

	env_PREVIOUS = xasprintf("%s=%s", IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_prev_status));
	putenv(env_PREVIOUS);
	env_CURRENT = xasprintf("%s=%s", IFPLUGD_ENV_CURRENT, strstatus(G.iface_last_status));
	putenv(env_CURRENT);

	/* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */
	r = spawn_and_wait(argv);

	bb_unsetenv_and_free(env_PREVIOUS);
	bb_unsetenv_and_free(env_CURRENT);

	bb_error_msg("exit code: %d", r & 0xff);
	return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r;
}
Ejemplo n.º 2
0
static void undo_xsetenv(void)
{
	char **pp = env_cur = &env_var[0];
	while (*pp) {
		char *var = *pp;
		bb_unsetenv_and_free(var);
		*pp++ = NULL;
	}
}
Ejemplo n.º 3
0
/* We set environment *before* vfork (because we want to use vfork),
 * so we cannot use setenv() - repeated calls to setenv() may leak memory!
 * Using putenv(), and freeing memory after unsetenv() won't leak */
static void safe_setenv(char **pvar_val, const char *var, const char *val)
{
	char *var_val = *pvar_val;

	if (var_val) {
		bb_unsetenv_and_free(var_val);
	}
	*pvar_val = xasprintf("%s=%s", var, val);
	putenv(*pvar_val);
}
void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
{
	file_header_t *file_header = archive_handle->file_header;

#if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */
	char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
	if (!sctx)
		sctx = archive_handle->tar__sctx[PAX_GLOBAL];
	if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
		setfscreatecon(sctx);
		free(archive_handle->tar__sctx[PAX_NEXT_FILE]);
		archive_handle->tar__sctx[PAX_NEXT_FILE] = NULL;
	}
#endif

	if ((file_header->mode & S_IFMT) == S_IFREG) {
		pid_t pid;
		int p[2], status;
		char *tar_env[TAR_MAX];

		memset(tar_env, 0, sizeof(tar_env));

		xpipe(p);
		pid = BB_MMU ? xfork() : xvfork();
		if (pid == 0) {
			/* Child */
			/* str2env(tar_env, TAR_FILETYPE, "f"); - parent should do it once */
			oct2env(tar_env, TAR_MODE, file_header->mode);
			str2env(tar_env, TAR_FILENAME, file_header->name);
			str2env(tar_env, TAR_REALNAME, file_header->name);
#if ENABLE_FEATURE_TAR_UNAME_GNAME
			str2env(tar_env, TAR_UNAME, file_header->tar__uname);
			str2env(tar_env, TAR_GNAME, file_header->tar__gname);
#endif
			dec2env(tar_env, TAR_SIZE, file_header->size);
			dec2env(tar_env, TAR_UID, file_header->uid);
			dec2env(tar_env, TAR_GID, file_header->gid);
			close(p[1]);
			xdup2(p[0], STDIN_FILENO);
			signal(SIGPIPE, SIG_DFL);
			execl(archive_handle->tar__to_command_shell,
				archive_handle->tar__to_command_shell,
				"-c",
				archive_handle->tar__to_command,
				NULL);
			bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell);
		}
		close(p[0]);
		/* Our caller is expected to do signal(SIGPIPE, SIG_IGN)
		 * so that we don't die if child don't read all the input: */
		bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size);
		close(p[1]);

		if (safe_waitpid(pid, &status, 0) == -1)
			bb_perror_msg_and_die("waitpid");
		if (WIFEXITED(status) && WEXITSTATUS(status))
			bb_error_msg_and_die("'%s' returned status %d",
				archive_handle->tar__to_command, WEXITSTATUS(status));
		if (WIFSIGNALED(status))
			bb_error_msg_and_die("'%s' terminated on signal %d",
				archive_handle->tar__to_command, WTERMSIG(status));

		if (!BB_MMU) {
			int i;
			for (i = 0; i < TAR_MAX; i++) {
				if (tar_env[i])
					bb_unsetenv_and_free(tar_env[i]);
			}
		}
	}

#if 0 /* ENABLE_FEATURE_TAR_SELINUX */
	if (sctx)
		/* reset the context after creating an entry */
		setfscreatecon(NULL);
#endif
}