summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAurelien Foret <aurelien@archlinux.org>2005-11-05 19:21:25 +0000
committerAurelien Foret <aurelien@archlinux.org>2005-11-05 19:21:25 +0000
commit414d6d83c911ee7ce63c504cdc8ab8721daefda6 (patch)
treef1b545f55e5e7b9d8688d4758e43b633d6abcb9f
parentbbfe57b95ad56f5c627e989b3d494da0bc951309 (diff)
downloadpacman-414d6d83c911ee7ce63c504cdc8ab8721daefda6.tar.xz
Used the chroot syscall instead of the chroot binary
(patch from Christian Hamaer <krics@linuxforum.hu>)
-rw-r--r--TODO3
-rw-r--r--lib/libalpm/util.c60
2 files changed, 34 insertions, 29 deletions
diff --git a/TODO b/TODO
index a54eb394..7925aa85 100644
--- a/TODO
+++ b/TODO
@@ -9,9 +9,6 @@ GLOBAL
LIBALPM
=======
-- remove the dependency with /usr/bin/chroot (implement the chroot handling
-using the chroot() syscall)
-
- review errors handling (globalise pm_errno usage, improve error
meanings)
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 680c4095..178de865 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -24,12 +24,14 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <dirent.h>
#include <time.h>
#include <syslog.h>
+#include <sys/wait.h>
#ifdef CYGWIN
#include <limits.h> /* PATH_MAX */
#endif
@@ -40,8 +42,6 @@
#include "util.h"
#include "alpm.h"
-static char *chrootbin = NULL;
-
/* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */
long _alpm_gzopen_frontend(char *pathname, int oflags, int mode)
{
@@ -271,7 +271,6 @@ int _alpm_rmrf(char *path)
struct dirent *dp;
DIR *dirp;
char name[PATH_MAX];
- extern int errno;
if(!unlink(path)) {
return(0);
@@ -362,29 +361,13 @@ int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, cha
char *scriptpath;
struct stat buf;
char cwd[PATH_MAX];
+ pid_t pid;
if(stat(installfn, &buf)) {
/* not found */
return(0);
}
- if(chrootbin == NULL) {
- char *dirs[] = {"/usr/sbin","/usr/bin","/sbin","/bin"};
- int i;
- for(i = 0; i < 4 && !chrootbin; i++) {
- char cpath[PATH_MAX];
- snprintf(cpath, PATH_MAX, "%s/chroot", dirs[i]);
- if(!stat(cpath, &buf)) {
- chrootbin = strdup(cpath);
- _alpm_log(PM_LOG_FLOW2, "found chroot binary: %s", chrootbin);
- }
- }
- if(chrootbin == NULL) {
- _alpm_log(PM_LOG_ERROR, "cannot find chroot binary - unable to run scriptlet");
- return(1);
- }
- }
-
if(!strcmp(script, "pre_upgrade") || !strcmp(script, "pre_install")) {
snprintf(tmpdir, PATH_MAX, "%stmp/", root);
if(stat(tmpdir, &buf)) {
@@ -420,16 +403,41 @@ int _alpm_runscriptlet(char *root, char *installfn, char *script, char *ver, cha
chdir("/");
_alpm_log(PM_LOG_FLOW2, "executing %s script...", script);
+
if(oldver) {
- snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s %s\" | %s %s /bin/sh",
- scriptpath, script, ver, oldver, chrootbin, root);
+ snprintf(cmdline, PATH_MAX, "source %s %s %s %s",
+ scriptpath, script, ver, oldver);
} else {
- snprintf(cmdline, PATH_MAX, "echo \"umask 0022; source %s %s %s\" | %s %s /bin/sh",
- scriptpath, script, ver, chrootbin, root);
+ snprintf(cmdline, PATH_MAX, "source %s %s %s",
+ scriptpath, script, ver);
}
_alpm_log(PM_LOG_DEBUG, "%s", cmdline);
- system(cmdline);
-
+
+ pid = fork();
+ if(pid == -1) {
+ _alpm_log(PM_LOG_ERROR, "could not fork a new process (%s)", strerror(errno));
+ chdir(cwd);
+ return(1);
+ }
+
+ if(pid == 0) {
+ _alpm_log(PM_LOG_DEBUG, "chrooting in %s", root);
+ if(chroot(root) != 0) {
+ _alpm_log(PM_LOG_ERROR, "could not change the root directory (%s)", strerror(errno));
+ return (1);
+ }
+ umask(0022);
+ _alpm_log(PM_LOG_DEBUG, "executing \"%s\"", cmdline);
+ execl("/bin/sh", "sh", "-c", cmdline, (char *)0);
+ exit(0);
+ } else {
+ if(waitpid(pid, 0, 0) == -1) {
+ _alpm_log(PM_LOG_ERROR, "call to waitpid failed (%s)", strerror(errno));
+ chdir(cwd);
+ return(1);
+ }
+ }
+
if(strlen(tmpdir) && _alpm_rmrf(tmpdir)) {
_alpm_log(PM_LOG_WARNING, "could not remove tmpdir %s", tmpdir);
}