summaryrefslogtreecommitdiff
path: root/dh_usrlocal
diff options
context:
space:
mode:
authorNicolas Boulenguez <nicolas.boulenguez@free.fr>2018-04-07 10:20:38 +0000
committerNiels Thykier <niels@thykier.net>2018-04-07 10:20:44 +0000
commit778a9174cafc20340455d726b7ece4243f5fa070 (patch)
treecafee816b29ac16239d89697c93fbfb1e3d9ed7c /dh_usrlocal
parentf1d6cad9c7a709455acf26887c0263ab96af9772 (diff)
downloaddebhelper-778a9174cafc20340455d726b7ece4243f5fa070.tar.gz
dh_usrlocal: prerm must not remove dir in usr/local
Signed-off-by: Niels Thykier <niels@thykier.net>
Diffstat (limited to 'dh_usrlocal')
-rwxr-xr-xdh_usrlocal79
1 files changed, 37 insertions, 42 deletions
diff --git a/dh_usrlocal b/dh_usrlocal
index 5e06e658..31269ee6 100755
--- a/dh_usrlocal
+++ b/dh_usrlocal
@@ -77,54 +77,49 @@ foreach my $package (@{$dh{DOPACKAGES}}) {
if (-d "$tmp/usr/local") {
my (@dirs, @justdirs);
- find({bydepth => 1,
- no_chdir => 1,
- wanted => sub {
- my $fn = $File::Find::name;
- if (-d $fn) {
- my $user = 'root';
- my $group = 'staff';
- my $mode = '02775';
- if (should_use_root()) {
- my $stat = stat $fn;
- $user = getpwuid $stat->uid;
- $group = getgrgid $stat->gid;
- $mode = sprintf "%04lo", ($stat->mode & 07777);
- if ($stat->uid == 0 && $stat->gid == 0) {
- $group = 'staff';
- $mode = '02775';
- }
- }
-
-
-
- $fn =~ s!^\Q$tmp\E!!;
- return if $fn eq '/usr/local';
-
- # @dirs is in parents-first order for dir creation...
- unshift @dirs, "$fn $mode $user $group";
- # ...whereas @justdirs is depth-first for removal.
- push @justdirs, $fn;
- doit('rmdir', $_);
- }
- else {
- warning("$fn is not a directory");
- }
+ find({no_chdir => 1,
+ preprocess => sub {
+ # Ensure a reproducible traversal.
+ return sort @_;
+ },
+ postprocess => sub {
+ # Uninstall, unless a direct child of /usr/local.
+ $_ = $File::Find::dir;
+ s!^\Q$tmp\E!!;
+ push @justdirs, $_ if m!/usr/local/.*/!;
+ # Remove a directory after its childs.
+ doit('rmdir', $File::Find::dir);
+ },
+ wanted => sub {
+ # rmdir would fail later anyways.
+ error("${File::Find::name} is not a directory")
+ if not -d $File::Find::name;
+ # Install directory before its childs.
+ my $fn = $File::Find::name;
+ $fn =~ s!^\Q$tmp\E!!;
+ return if $fn eq '/usr/local';
+ if (should_use_root()) {
+ my $stat = stat $File::Find::dir;
+ if ($stat->uid == 0 && $stat->gid == 0) {
+ push @dirs, "$fn 02775 root staff";
+ } else {
+ my $user = getpwuid $stat->uid;
+ my $group = getgrgid $stat->gid;
+ my $mode = sprintf "%04lo", ($stat->mode & 07777);
+ push @dirs, "$fn $mode $user $group";
+ }
+ } else {
+ push @dirs, "$fn 02775 root staff";
+ }
}}, "$tmp/usr/local");
- doit('rmdir', "$tmp/usr/local");
-
- my $bs = "\\"; # A single plain backslash
- my $ebs = $bs x 2; # Escape the backslash from the shell
+
# This constructs the body of a 'sed' c\ expression which
# is parsed by the shell in double-quotes
- my $dirs = join("$ebs\n", sort @dirs);
- pop @justdirs; # don't remove directories directly in /usr/local
- my $justdirs = join("$ebs\n", reverse sort @justdirs);
if (! $dh{NOSCRIPTS}) {
autoscript($package,"postinst", "postinst-usrlocal",
- "/#DIRS#/ c${ebs}\n${dirs}");
+ { 'DIRS' => join ("\n", @dirs)}) if @dirs;
autoscript($package,"prerm", "prerm-usrlocal",
- "/#JUSTDIRS#/ c${ebs}\n${justdirs}") if length $justdirs;
+ { 'JUSTDIRS' => join ("\n", @justdirs)}) if @justdirs;
}
}
}