diff options
Diffstat (limited to 'dh_usrlocal')
-rwxr-xr-x | dh_usrlocal | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/dh_usrlocal b/dh_usrlocal new file mode 100755 index 00000000..603c37ca --- /dev/null +++ b/dh_usrlocal @@ -0,0 +1,122 @@ +#!/usr/bin/perl + +=head1 NAME + +dh_usrlocal - migrate usr/local directories to maintainer scripts + +=cut + +use warnings; +use strict; +use Debian::Debhelper::Dh_Lib; +use File::Find; +use File::stat; + +=head1 SYNOPSIS + +B<dh_usrlocal> [S<I<debhelper options>>] [B<-n>] + +=head1 DESCRIPTION + +dh_usrlocal is a debhelper program that can be used for building packages +that will provide a subdirectory in /usr/local when installed. + +It finds subdirectories of usr/local in the package build directory, and +removes them, replacing them with maintainer script snippets (unless B<-n> +is used) to create the directories at install time, and remove them when +the package is removed, in a manner compliant with Debian policy. See +L<dh_installdeb(1)> for an explantion of Debhelper maintainer script +snippets. + +If the directories found in the build tree have unusual owners, groups, or +permisions, then those values will be preserved in the directories made by +the postinst script. However, as a special exception, if a directory is owned +by root.root, it will be treated as if it is owned by root.staff and is mode +2775. This is useful, since that is the group and mode policy recommends for +directories in /usr/local. + +=head1 OPTIONS + +=over 4 + +=item B<-n>, B<--noscripts> + +Do not modify F<postinst>/F<prerm> scripts. + +=back + +=head1 NOTES + +Note that this command is not idempotent. "dh_clean -k" should be called +between invocations of this command. Otherwise, it may cause multiple +instances of the same text to be added to maintainer scripts. + +=head1 CONFORMS TO + +Debian policy, version 2.2 + +=cut + +init(); + +foreach my $package (@{$dh{DOPACKAGES}}) { + my $tmp = tmpdir($package); + + 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 $stat = stat $fn; + my $user = getpwuid $stat->uid; + my $group = getgrgid $stat->gid; + my $mode = sprintf "%04lo", ($stat->mode & 07777); + + if ($stat->uid == 0 && $stat->gid == 0) { + $group = 'staff'; + $mode = '2775'; + } + + $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"); + } + }}, "$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", @dirs); + my $justdirs = join("$ebs\n", @justdirs); + if (! $dh{NOSCRIPTS}) { + autoscript($package,"postinst", "postinst-usrlocal", + "/#DIRS#/ c${ebs}\n${dirs}"); + autoscript($package,"prerm", "prerm-usrlocal", + "/#JUSTDIRS#/ c${ebs}\n${justdirs}"); + } + } +} + +=head1 SEE ALSO + +L<debhelper(7)> + +This program is a part of debhelper. + +=head1 AUTHOR + +Andrew Stribblehill <ads@debian.org> + +=cut |