summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2017-04-16 00:31:57 -0400
committerAndrew Gregory <andrew.gregory.8@gmail.com>2017-04-16 19:41:35 -0400
commitfae33a1faf3f94ea46049664ef483b2a3e0d3f01 (patch)
treee33404cef3acbbf18b774a33eab3006a7b986c5e /src
parent6a4c6a02de9b45abe4c0f78c4f5d14d92d3359d6 (diff)
add --sysroot option
--root is not sufficient to properly operate on a mounted guest system. Using --root still uses the host system's configuration and there is no way to correctly use the guest configuration without manually modifying any Include directives. --sysroot provides an easier way to operate on a guest system by chrooting immediately after option parsing before configuration parsing or performing any operations. It is currently limited to the root user, but that's enough for restoring a guest system to a working state, which is the primary intended use case. Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/pacman/conf.h2
-rw-r--r--src/pacman/pacman.c24
-rw-r--r--src/pacman/util.c3
3 files changed, 23 insertions, 6 deletions
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index e67f7c51..53b44be6 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -67,6 +67,7 @@ typedef struct __config_t {
char *dbpath;
char *logfile;
char *gpgdir;
+ char *sysroot;
alpm_list_t *hookdirs;
alpm_list_t *cachedirs;
@@ -195,6 +196,7 @@ enum {
OP_PRINT,
OP_QUIET,
OP_ROOT,
+ OP_SYSROOT,
OP_RECURSIVE,
OP_SEARCH,
OP_REGEX,
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 9d1cf6bb..605aec3e 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -214,6 +214,7 @@ static void usage(int op, const char * const myname)
addlist(_(" -r, --root <path> set an alternate installation root\n"));
addlist(_(" -v, --verbose be verbose\n"));
addlist(_(" --arch <arch> set an alternate architecture\n"));
+ addlist(_(" --sysroot operate on a mounted guest system (root-only)\n"));
addlist(_(" --cachedir <dir> set an alternate package cache location\n"));
addlist(_(" --hookdir <dir> set an alternate hook location\n"));
addlist(_(" --color <when> colorize the output\n"));
@@ -447,6 +448,10 @@ static int parsearg_global(int opt)
free(config->rootdir);
config->rootdir = strdup(optarg);
break;
+ case OP_SYSROOT:
+ free(config->sysroot);
+ config->sysroot = strdup(optarg);
+ break;
case OP_DISABLEDLTIMEOUT:
config->disable_dl_timeout = 1;
break;
@@ -917,6 +922,7 @@ static int parseargs(int argc, char *argv[])
{"print", no_argument, 0, OP_PRINT},
{"quiet", no_argument, 0, OP_QUIET},
{"root", required_argument, 0, OP_ROOT},
+ {"sysroot", required_argument, 0, OP_SYSROOT},
{"recursive", no_argument, 0, OP_RECURSIVE},
{"search", no_argument, 0, OP_SEARCH},
{"regex", no_argument, 0, OP_REGEX},
@@ -1150,6 +1156,18 @@ int main(int argc, char *argv[])
cleanup(ret);
}
+ /* check if we have sufficient permission for the requested operation */
+ if(myuid > 0 && needs_root()) {
+ pm_printf(ALPM_LOG_ERROR, _("you cannot perform this operation unless you are root.\n"));
+ cleanup(EXIT_FAILURE);
+ }
+
+ if(config->sysroot && (chroot(config->sysroot) != 0 || chdir("/") != 0)) {
+ pm_printf(ALPM_LOG_ERROR,
+ _("chroot to '%s' failed: (%s)\n"), config->sysroot, strerror(errno));
+ cleanup(EXIT_FAILURE);
+ }
+
/* we support reading targets from stdin if a cmdline parameter is '-' */
if(alpm_list_find_str(pm_targets, "-")) {
if(!isatty(fileno(stdin))) {
@@ -1222,12 +1240,6 @@ int main(int argc, char *argv[])
config->logmask &= ~ALPM_LOG_WARNING;
}
- /* check if we have sufficient permission for the requested operation */
- if(myuid > 0 && needs_root()) {
- pm_printf(ALPM_LOG_ERROR, _("you cannot perform this operation unless you are root.\n"));
- cleanup(EXIT_FAILURE);
- }
-
if(config->verbose > 0) {
alpm_list_t *j;
printf("Root : %s\n", alpm_option_get_root(config->handle));
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 64ea8c57..ae8a74d3 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -103,6 +103,9 @@ int trans_release(void)
int needs_root(void)
{
+ if(config->sysroot) {
+ return 1;
+ }
switch(config->op) {
case PM_OP_DATABASE:
return !config->op_q_check;