This is an automated email from the git hooks/post-receive script.

guillem pushed a commit to branch main
in repository dpkg.

View the commit online:
https://git.dpkg.org/cgit/dpkg/dpkg.git/commit/?id=3c23f8f541c1e0a8434fea4163565be2fdc385da

commit 3c23f8f541c1e0a8434fea4163565be2fdc385da
Author: Guillem Jover <guil...@debian.org>
AuthorDate: Sun Jun 20 15:30:15 2021 +0200

    u-a: Fix admindir setting
    
    When specifying the --root option, or one of DPKG_ROOT or DPKG_ADMINDIR
    environment variables, we need to take into account the installation
    directory as the prefix for the administrative directory, instead of
    using it also as the actual administrative directory.
    
    Prompted-by: Johannes Schauer Marin Rodrigues <jo...@debian.org>
    Stable-Candidate: 1.20.x
---
 utils/Makefile.am             |   7 +-
 utils/t/update_alternatives.t | 153 ++++++++++++++++++++++++++++++++++++++++--
 utils/update-alternatives.c   |  16 ++---
 3 files changed, 163 insertions(+), 13 deletions(-)

diff --git a/utils/Makefile.am b/utils/Makefile.am
index 53dcdd7f1..0bfb2e9f9 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -79,7 +79,12 @@ endif
 uninstall-local:
        rm -f $(DESTDIR)$(sysconfdir)/alternatives/README
 
-TEST_ENV_VARS = DPKG_DATADIR=$(top_srcdir)/data
+TEST_ENV_VARS = \
+       DPKG_DATADIR=$(top_srcdir)/data \
+       UA_ROOTDIR_ENVVAR=DPKG_ROOT \
+       UA_ADMINDIR_ENVVAR=DPKG_ADMINDIR \
+       UA_ADMINDIR_DEFAULT=$(admindir) \
+       # EOL
 
 test_tmpdir = t.tmp
 test_scripts = \
diff --git a/utils/t/update_alternatives.t b/utils/t/update_alternatives.t
index 3f4ac44c1..a4885dda9 100644
--- a/utils/t/update_alternatives.t
+++ b/utils/t/update_alternatives.t
@@ -32,8 +32,11 @@ my $bindir = File::Spec->rel2abs("$tmpdir/bin");
 my @ua = ("$ENV{builddir}/update-alternatives", '--log', '/dev/null',
           '--quiet', '--admindir', "$admindir", '--altdir', "$altdir");
 
-delete $ENV{DPKG_ROOT};
-delete $ENV{DPKG_ADMINDIR};
+my $rootdir_envvar = $ENV{UA_ROOTDIR_ENVVAR} // 'DPKG_ROOT';
+my $admindir_envvar = $ENV{UA_ADMINDIR_ENVVAR} // 'DPKG_ADMINDIR';
+
+delete $ENV{$rootdir_envvar};
+delete $ENV{$admindir_envvar};
 
 my %paths = (
     true => find_command('true'),
@@ -97,6 +100,7 @@ my @choices = (
 );
 my $nb_slaves = 4;
 plan tests => (4 * ($nb_slaves + 1) + 2) * 26 # number of check_choices
+               + 30                           # number of directory checks
                + 110;                         # rest
 
 sub cleanup {
@@ -106,8 +110,18 @@ sub cleanup {
 
 sub call_ua {
     my ($params, %opts) = @_;
-    spawn(exec => [ @ua, @$params ], nocheck => 1,
-         wait_child => 1, env => { LC_ALL => 'C' }, %opts);
+
+    my %env;
+    %env = %{delete $opts{env}} if exists $opts{env};
+    my @cmd;
+    if (exists $opts{cmd}) {
+        @cmd = @{delete $opts{cmd}};
+    } else {
+        @cmd = @ua;
+    }
+
+    spawn(exec => [ @cmd, @{$params} ], nocheck => 1,
+        wait_child => 1, env => { LC_ALL => 'C', %env }, %opts);
     my $test_id = '';
     $test_id = "$opts{test_id}: " if defined $opts{test_id};
     if ($opts{expect_failure}) {
@@ -119,6 +133,29 @@ sub call_ua {
     }
 }
 
+sub call_ua_dirs {
+    my (%opts) = @_;
+
+    $opts{cmd} = [ "$ENV{builddir}/update-alternatives" ];
+
+    my @params;
+    @params = @{delete $opts{params}} if exists $opts{params};
+    push @params, qw(--debug);
+    push @params, qw(--log /dev/null);
+    push @params, qw(--get-selections);
+
+    die unless exists $opts{expected};
+
+    my $stderr;
+    my $expected = delete $opts{expected};
+    $opts{to_file} = '/dev/null';
+    $opts{error_to_string} = \$stderr;
+
+    call_ua(\@params, %opts);
+
+    ok($stderr =~ $expected, "output '$stderr' does not match expected 
'$expected'");
+}
+
 sub install_choice {
     my ($id, %opts) = @_;
     my $alt = $choices[$id];
@@ -251,6 +288,114 @@ sub check_choice {
 }
 
 ### START OF TESTS
+cleanup();
+
+# check directory overrides
+
+my $DEFAULT_ROOTDIR = '';
+my $DEFAULT_ADMINDIR = $ENV{UA_ADMINDIR_DEFAULT} // 
'/var/lib/dpkg/alternatives';
+
+# ENV_ADMINDIR + defaults
+call_ua_dirs(
+    env => {
+        $admindir_envvar => '/admindir_env',
+    },
+    expected => "root=$DEFAULT_ROOTDIR admdir=/admindir_env",
+);
+
+# ENV_ROOT + defaults
+call_ua_dirs(
+    env => { $rootdir_envvar => '/rootdir_env' },
+    expected => "root=/rootdir_env admdir=/rootdir_env$DEFAULT_ADMINDIR",
+);
+
+# ENV_ROOT + ENV_ADMINDIR
+call_ua_dirs(
+    env => {
+        $rootdir_envvar => '/rootdir_env',
+        $admindir_envvar => '/admindir_env',
+    },
+    expected => 'root=/rootdir_env admdir=/admindir_env',
+);
+
+# ENV_ADMINDIR + options
+call_ua_dirs(
+    env => { $admindir_envvar => '/admindir_env' },
+    params => [ qw(--root /rootdir_opt) ],
+    expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
+);
+call_ua_dirs(
+    env => { $admindir_envvar => '/admindir_env' },
+    params => [ qw(--admindir /admindir_opt) ],
+    expected => "root=$DEFAULT_ROOTDIR admdir=/admindir_opt",
+);
+call_ua_dirs(
+    env => { $admindir_envvar => '/admindir_env' },
+    params => [ qw(--root /rootdir_opt --admindir /admindir_opt) ],
+    expected => 'root=/rootdir_opt admdir=/admindir_opt',
+);
+call_ua_dirs(
+    env => { $admindir_envvar => '/admindir_env' },
+    params => [ qw(--admindir /admindir_opt --root /rootdir_opt) ],
+    expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
+);
+
+# DPKG_ROOT + options
+call_ua_dirs(
+    env => { $rootdir_envvar => '/rootdir_env' },
+    params => [ qw(--root /rootdir_opt) ],
+    expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
+);
+call_ua_dirs(
+    env => { $rootdir_envvar => '/rootdir_env' },
+    params => [ qw(--admindir /admindir_opt) ],
+    expected => 'root=/rootdir_env admdir=/admindir_opt',
+);
+call_ua_dirs(
+    env => { $rootdir_envvar => '/rootdir_env' },
+    params => [ qw(--root /rootdir_opt --admindir /admindir_opt) ],
+    expected => 'root=/rootdir_opt admdir=/admindir_opt',
+);
+call_ua_dirs(
+    env => { $rootdir_envvar => '/rootdir_env' },
+    params => [ qw(--admindir /admindir_opt --root /rootdir_opt) ],
+    expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
+);
+
+# ENV_ROOT + ENV_ADMINDIR + options
+call_ua_dirs(
+    env => {
+        $rootdir_envvar => '/rootdir_env',
+        $admindir_envvar => '/admindir_env',
+    },
+    params => [ qw(--root /rootdir_opt) ],
+    expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
+);
+call_ua_dirs(
+    env => {
+        $rootdir_envvar => '/rootdir_env',
+        $admindir_envvar => '/admindir_env',
+    },
+    params => [ qw(--admindir /admindir_opt) ],
+    expected => 'root=/rootdir_env admdir=/admindir_opt',
+);
+call_ua_dirs(
+    env => {
+        $rootdir_envvar => '/rootdir_env',
+        $admindir_envvar => '/admindir_env',
+    },
+    params => [ qw(--root /rootdir_opt --admindir /admindir_opt) ],
+    expected => 'root=/rootdir_opt admdir=/admindir_opt',
+);
+call_ua_dirs(
+    env => {
+        $rootdir_envvar => '/rootdir_env',
+        $admindir_envvar => '/admindir_env',
+    },
+    params => [ qw(--admindir /admindir_opt --root /rootdir_opt) ],
+    expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
+);
+
 cleanup();
 # removal when not installed should not fail
 remove_choice(0);
diff --git a/utils/update-alternatives.c b/utils/update-alternatives.c
index 4e1d3c500..d3db37c9c 100644
--- a/utils/update-alternatives.c
+++ b/utils/update-alternatives.c
@@ -563,9 +563,9 @@ fsys_set_dir(const char *dir)
 }
 
 static char *
-fsys_gen_admindir(const char *basedir)
+fsys_gen_admindir(void)
 {
-       return xasprintf("%s%s/%s", instdir, basedir, "alternatives");
+       return fsys_get_path(ADMINDIR "/alternatives");
 }
 
 static bool
@@ -2813,7 +2813,7 @@ set_rootdir(const char *dir)
        log_file = fsys_get_path(LOGDIR "/alternatives.log");
        altdir = SYSCONFDIR "/alternatives";
        free(admdir);
-       admdir = fsys_gen_admindir(dir);
+       admdir = fsys_gen_admindir();
 
        return instdir;
 }
@@ -2821,17 +2821,15 @@ set_rootdir(const char *dir)
 static char *
 admindir_init(void)
 {
-       const char *basedir, *basedir_env;
+       const char *basedir_env;
 
        /* Try to get the admindir from an environment variable, usually set
         * by the system package manager. */
        basedir_env = getenv(ADMINDIR_ENVVAR);
        if (basedir_env)
-               basedir = basedir_env;
+               return strdup(basedir_env);
        else
-               basedir = ADMINDIR;
-
-       return fsys_gen_admindir(basedir);
+               return fsys_gen_admindir();
 }
 
 #define MISSING_ARGS(nb) (argc < i + nb + 1)
@@ -3038,6 +3036,8 @@ main(int argc, char **argv)
                         "config", "set", "set-selections", "install",
                         "remove", "all", "remove-all", "auto");
 
+       debug("root=%s admdir=%s altdir=%s", instdir, admdir, altdir);
+
        /* The following actions might modify the current alternative. */
        if (action == ACTION_SET ||
            action == ACTION_AUTO ||

-- 
Dpkg.Org's dpkg

Reply via email to