File Coverage

blib/lib/Dpkg/Source/Functions.pm
Criterion Covered Total %
statement 29 63 46.0
branch 4 30 13.3
condition n/a
subroutine 8 12 66.6
pod 0 5 0.0
total 41 110 37.2


line stmt bran cond sub pod time code
1             # Copyright © 2008-2010, 2012-2015 Guillem Jover
2             #
3             # This program is free software; you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by
5             # the Free Software Foundation; either version 2 of the License, or
6             # (at your option) any later version.
7             #
8             # This program is distributed in the hope that it will be useful,
9             # but WITHOUT ANY WARRANTY; without even the implied warranty of
10             # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11             # GNU General Public License for more details.
12             #
13             # You should have received a copy of the GNU General Public License
14             # along with this program. If not, see .
15              
16             package Dpkg::Source::Functions;
17              
18 6     6   70627 use strict;
  6         25  
  6         180  
19 6     6   30 use warnings;
  6         18  
  6         412  
20              
21             our $VERSION = '0.01';
22             our @EXPORT_OK = qw(
23             erasedir
24             fixperms
25             chmod_if_needed
26             fs_time
27             is_binary
28             );
29              
30 6     6   35 use Exporter qw(import);
  6         36  
  6         205  
31 6     6   2509 use Errno qw(ENOENT);
  6         6952  
  6         629  
32              
33 6     6   451 use Dpkg::ErrorHandling;
  6         13  
  6         556  
34 6     6   46 use Dpkg::Gettext;
  6         120  
  6         422  
35 6     6   479 use Dpkg::IPC;
  6         12  
  6         3765  
36              
37             sub erasedir {
38 0     0 0 0 my $dir = shift;
39 0 0       0 if (not lstat($dir)) {
40 0 0       0 return if $! == ENOENT;
41 0         0 syserr(g_('cannot stat directory %s (before removal)'), $dir);
42             }
43 0         0 system 'rm', '-rf', '--', $dir;
44 0 0       0 subprocerr("rm -rf $dir") if $?;
45 0 0       0 if (not stat($dir)) {
46 0 0       0 return if $! == ENOENT;
47 0         0 syserr(g_("unable to check for removal of directory '%s'"), $dir);
48             }
49 0         0 error(g_("rm -rf failed to remove '%s'"), $dir);
50             }
51              
52             sub fixperms {
53 0     0 0 0 my $dir = shift;
54 0         0 my ($mode, $modes_set);
55             # Unfortunately tar insists on applying our umask _to the original
56             # permissions_ rather than mostly-ignoring the original
57             # permissions. We fix it up with chmod -R (which saves us some
58             # work) but we have to construct a u+/- string which is a bit
59             # of a palaver. (Numeric doesn't work because we need [ugo]+X
60             # and [ugo]= doesn't work because that unsets sgid on dirs.)
61 0         0 $mode = 0777 & ~umask;
62 0         0 for my $i (0 .. 2) {
63 0 0       0 $modes_set .= ',' if $i;
64 0         0 $modes_set .= qw(u g o)[$i];
65 0         0 for my $j (0 .. 2) {
66 0 0       0 $modes_set .= $mode & (0400 >> ($i * 3 + $j)) ? '+' : '-';
67 0         0 $modes_set .= qw(r w X)[$j];
68             }
69             }
70 0         0 system('chmod', '-R', '--', $modes_set, $dir);
71 0 0       0 subprocerr("chmod -R -- $modes_set $dir") if $?;
72             }
73              
74             # Only change the pathname permissions if they differ from the desired.
75             #
76             # To be able to build a source tree, a user needs write permissions on it,
77             # but not necessarily ownership of those files.
78             sub chmod_if_needed {
79 0     0 0 0 my ($newperms, $pathname) = @_;
80 0         0 my $oldperms = (stat $pathname)[2] & 07777;
81              
82 0 0       0 return 1 if $oldperms == $newperms;
83 0         0 return chmod $newperms, $pathname;
84             }
85              
86             # Touch the file and read the resulting mtime.
87             #
88             # If the file doesn't exist, create it, read the mtime and unlink it.
89             #
90             # Use this instead of time() when the timestamp is going to be
91             # used to set file timestamps. This avoids confusion when an
92             # NFS server and NFS client disagree about what time it is.
93             sub fs_time($) {
94 2     2 0 10 my $file = shift;
95 2         4 my $is_temp = 0;
96 2 50       60 if (not -e $file) {
97 0 0       0 open(my $temp_fh, '>', $file) or syserr(g_('cannot write %s'));
98 0         0 close($temp_fh);
99 0         0 $is_temp = 1;
100             } else {
101 2 50       66 utime(undef, undef, $file) or
102             syserr(g_('cannot change timestamp for %s'), $file);
103             }
104 2 50       52 stat($file) or syserr(g_('cannot read timestamp from %s'), $file);
105 2         12 my $mtime = (stat(_))[9];
106 2 50       8 unlink($file) if $is_temp;
107 2         30 return $mtime;
108             }
109              
110             sub is_binary($) {
111 0     0 0   my $file = shift;
112              
113             # Perform the same check as diff(1), look for a NUL character in the first
114             # 4 KiB of the file.
115 0 0         open my $fh, '<', $file
116             or syserr(g_('cannot open file %s for binary detection'), $file);
117 0           read $fh, my $buf, 4096, 0;
118 0           my $res = index $buf, "\0";
119 0           close $fh;
120              
121 0           return $res >= 0;
122             }
123              
124             1;