]> git.donarmstrong.com Git - debhelper.git/blob - dh_usrlocal
r589: * Added dh_scrollkeeper, by Ross Burton.
[debhelper.git] / dh_usrlocal
1 #!/usr/bin/perl
2
3 =head1 NAME
4
5 dh_usrlocal - migrate usr/local directories to maintainer scripts
6
7 =cut
8
9 use warnings;
10 use strict;
11 use Debian::Debhelper::Dh_Lib;
12 use File::Find;
13 use File::stat;
14
15 =head1 SYNOPSIS
16
17 B<dh_usrlocal> [S<I<debhelper options>>] [B<-n>]
18
19 =head1 DESCRIPTION
20
21 dh_usrlocal is a debhelper program that can be used for building packages
22 that will provide a subdirectory in /usr/local when installed.
23
24 It finds subdirectories of usr/local in the package build directory, and
25 removes them, replacing them with maintainer script snippets (unless B<-n>
26 is used) to create the directories at install time, and remove them when
27 the package is removed, in a manner compliant with Debian policy. See
28 L<dh_installdeb(1)> for an explantion of Debhelper maintainer script
29 snippets.
30
31 If the directories found in the build tree have unusual owners, groups, or
32 permisions, then those values will be preserved in the directories made by
33 the postinst script. However, as a special exception, if a directory is owned
34 by root.root, it will be treated as if it is owned by root.staff and is mode
35 2775. This is useful, since that is the group and mode policy recommends for
36 directories in /usr/local.
37
38 =head1 OPTIONS
39
40 =over 4
41
42 =item B<-n>, B<--noscripts>
43
44 Do not modify F<postinst>/F<prerm> scripts.
45
46 =back
47
48 =head1 NOTES
49
50 Note that this command is not idempotent. "dh_clean -k" should be called
51 between invocations of this command. Otherwise, it may cause multiple
52 instances of the same text to be added to maintainer scripts.
53
54 =head1 CONFORMS TO
55
56 Debian policy, version 2.2
57
58 =cut
59
60 init();
61
62 foreach my $package (@{$dh{DOPACKAGES}}) {
63         my $tmp = tmpdir($package);
64
65         if (-d "$tmp/usr/local") {
66                 my (@dirs, @justdirs);
67                 find({bydepth => 1,
68                       no_chdir => 1,
69                       wanted => sub {
70                         my $fn = $File::Find::name;
71                         if (-d $fn) {
72                                 my $stat = stat $fn;
73                                 my $user = getpwuid $stat->uid;
74                                 my $group = getgrgid $stat->gid;
75                                 my $mode = sprintf "%04lo", ($stat->mode & 07777);
76
77                                 if ($stat->uid == 0 && $stat->gid == 0) {
78                                         $group = 'staff';
79                                         $mode = '2775';
80                                 }
81
82                                 $fn =~ s!^\Q$tmp\E!!;
83                                 return if $fn eq '/usr/local';
84                                 
85                                 # @dirs is in parents-first order for dir creation...
86                                 unshift @dirs, "$fn $mode $user $group";
87                                 # ...whereas @justdirs is depth-first for removal.
88                                 push @justdirs, $fn;
89                                 doit("rmdir $_");
90                         }
91                         else {
92                                 warning("$fn is not a directory");
93                         }
94                       }}, "$tmp/usr/local");
95                 doit("rmdir $tmp/usr/local");
96         
97                 my $bs = "\\";     # A single plain backslash
98                 my $ebs = $bs x 2; # Escape the backslash from the shell
99                 # This constructs the body of a 'sed' c\ expression which
100                 # is parsed by the shell in double-quotes
101                 my $dirs = join("$ebs\n", @dirs);
102                 my $justdirs = join("$ebs\n", @justdirs);
103                 if (! $dh{NOSCRIPTS}) { 
104                         autoscript($package,"postinst", "postinst-usrlocal",
105                                    "/#DIRS#/ c${ebs}\n${dirs}");
106                         autoscript($package,"prerm", "prerm-usrlocal",
107                                    "/#JUSTDIRS#/ c${ebs}\n${justdirs}");
108                 }
109         }
110 }
111
112 =head1 SEE ALSO
113
114 L<debhelper(7)>
115
116 This program is a part of debhelper.
117
118 =head1 AUTHOR
119
120 Andrew Stribblehill <ads@debian.org>
121
122 =cut