| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package ExtUtils::Install; | 
| 2 | 3 |  |  | 3 |  | 433892 | use strict; | 
|  | 3 |  |  |  |  | 29 |  | 
|  | 3 |  |  |  |  | 109 |  | 
| 3 |  |  |  |  |  |  |  | 
| 4 | 3 |  |  | 3 |  | 16 | use Config qw(%Config); | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 158 |  | 
| 5 | 3 |  |  | 3 |  | 18 | use Cwd qw(cwd); | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 170 |  | 
| 6 | 3 |  |  | 3 |  | 21 | use Exporter (); | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 73 |  | 
| 7 | 3 |  |  | 3 |  | 16 | use File::Basename qw(dirname); | 
|  | 3 |  |  |  |  | 12 |  | 
|  | 3 |  |  |  |  | 194 |  | 
| 8 | 3 |  |  | 3 |  | 1738 | use File::Copy; | 
|  | 3 |  |  |  |  | 9950 |  | 
|  | 3 |  |  |  |  | 195 |  | 
| 9 | 3 |  |  | 3 |  | 23 | use File::Path; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 191 |  | 
| 10 | 3 |  |  | 3 |  | 19 | use File::Spec; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 737 |  | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | our @ISA = ('Exporter'); | 
| 13 |  |  |  |  |  |  | our @EXPORT = ('install','uninstall','pm_to_blib', 'install_default'); | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | our $MUST_REBOOT; | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | =pod | 
| 18 |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  | =head1 NAME | 
| 20 |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  | ExtUtils::Install - install files from here to there | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 24 |  |  |  |  |  |  |  | 
| 25 |  |  |  |  |  |  | use ExtUtils::Install; | 
| 26 |  |  |  |  |  |  |  | 
| 27 |  |  |  |  |  |  | install({ 'blib/lib' => 'some/install/dir' } ); | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | uninstall($packlist); | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | pm_to_blib({ 'lib/Foo/Bar.pm' => 'blib/lib/Foo/Bar.pm' }); | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | =head1 VERSION | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | 2.20 | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | =cut | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | our $VERSION = '2.20';  # <-- do not forget to update the POD section just above this line! | 
| 40 |  |  |  |  |  |  | $VERSION = eval $VERSION; | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | =pod | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | Handles the installing and uninstalling of perl modules, scripts, man | 
| 47 |  |  |  |  |  |  | pages, etc... | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | Both install() and uninstall() are specific to the way | 
| 50 |  |  |  |  |  |  | ExtUtils::MakeMaker handles the installation and deinstallation of | 
| 51 |  |  |  |  |  |  | perl modules. They are not designed as general purpose tools. | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | On some operating systems such as Win32 installation may not be possible | 
| 54 |  |  |  |  |  |  | until after a reboot has occurred. This can have varying consequences: | 
| 55 |  |  |  |  |  |  | removing an old DLL does not impact programs using the new one, but if | 
| 56 |  |  |  |  |  |  | a new DLL cannot be installed properly until reboot then anything | 
| 57 |  |  |  |  |  |  | depending on it must wait. The package variable | 
| 58 |  |  |  |  |  |  |  | 
| 59 |  |  |  |  |  |  | $ExtUtils::Install::MUST_REBOOT | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | is used to store this status. | 
| 62 |  |  |  |  |  |  |  | 
| 63 |  |  |  |  |  |  | If this variable is true then such an operation has occurred and | 
| 64 |  |  |  |  |  |  | anything depending on this module cannot proceed until a reboot | 
| 65 |  |  |  |  |  |  | has occurred. | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | If this value is defined but false then such an operation has | 
| 68 |  |  |  |  |  |  | occurred, but should not impact later operations. | 
| 69 |  |  |  |  |  |  |  | 
| 70 |  |  |  |  |  |  | =begin _private | 
| 71 |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  | =head2 _chmod($$;$) | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | Wrapper to chmod() for debugging and error trapping. | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | =head2 _warnonce(@) | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | Warns about something only once. | 
| 79 |  |  |  |  |  |  |  | 
| 80 |  |  |  |  |  |  | =head2 _choke(@) | 
| 81 |  |  |  |  |  |  |  | 
| 82 |  |  |  |  |  |  | Dies with a special message. | 
| 83 |  |  |  |  |  |  |  | 
| 84 |  |  |  |  |  |  | =end _private | 
| 85 |  |  |  |  |  |  |  | 
| 86 |  |  |  |  |  |  | =cut | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | BEGIN { | 
| 89 | 3 | 50 |  | 3 |  | 25 | *_Is_VMS        = $^O eq 'VMS'     ? sub(){1} : sub(){0}; | 
| 90 | 3 | 50 |  |  |  | 11 | *_Is_Win32      = $^O eq 'MSWin32' ? sub(){1} : sub(){0}; | 
| 91 | 3 | 50 |  |  |  | 9 | *_Is_cygwin     = $^O eq 'cygwin'  ? sub(){1} : sub(){0}; | 
| 92 | 3 | 50 | 33 |  |  | 17689 | *_CanMoveAtBoot = ($^O eq 'MSWin32' || $^O eq 'cygwin') ? sub(){1} : sub(){0}; | 
| 93 |  |  |  |  |  |  | } | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | my $Inc_uninstall_warn_handler; | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | # install relative to here | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | my $INSTALL_ROOT = $ENV{PERL_INSTALL_ROOT}; | 
| 100 |  |  |  |  |  |  | my $INSTALL_QUIET = $ENV{PERL_INSTALL_QUIET}; | 
| 101 |  |  |  |  |  |  | $INSTALL_QUIET = 1 | 
| 102 |  |  |  |  |  |  | if (!exists $ENV{PERL_INSTALL_QUIET} and | 
| 103 |  |  |  |  |  |  | defined $ENV{MAKEFLAGS} and | 
| 104 |  |  |  |  |  |  | $ENV{MAKEFLAGS} =~ /\b(s|silent|quiet)\b/); | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | my $Curdir = File::Spec->curdir; | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | sub _estr(@) { | 
| 109 | 0 |  |  | 0 |  | 0 | return join "\n",'!' x 72,@_,'!' x 72,''; | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | {my %warned; | 
| 113 |  |  |  |  |  |  | sub _warnonce(@) { | 
| 114 | 0 |  |  | 0 |  | 0 | my $first=shift; | 
| 115 | 0 |  |  |  |  | 0 | my $msg=_estr "WARNING: $first",@_; | 
| 116 | 0 | 0 |  |  |  | 0 | warn $msg unless $warned{$msg}++; | 
| 117 |  |  |  |  |  |  | }} | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | sub _choke(@) { | 
| 120 | 0 |  |  | 0 |  | 0 | my $first=shift; | 
| 121 | 0 |  |  |  |  | 0 | my $msg=_estr "ERROR: $first",@_; | 
| 122 | 0 |  |  |  |  | 0 | require Carp; | 
| 123 | 0 |  |  |  |  | 0 | Carp::croak($msg); | 
| 124 |  |  |  |  |  |  | } | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | sub _croak { | 
| 127 | 0 |  |  | 0 |  | 0 | require Carp; | 
| 128 | 0 |  |  |  |  | 0 | Carp::croak(@_); | 
| 129 |  |  |  |  |  |  | } | 
| 130 |  |  |  |  |  |  | sub _confess { | 
| 131 | 0 |  |  | 0 |  | 0 | require Carp; | 
| 132 | 0 |  |  |  |  | 0 | Carp::confess(@_); | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | sub _compare { | 
| 136 |  |  |  |  |  |  | # avoid loading File::Compare in the common case | 
| 137 | 34 | 100 | 100 | 34 |  | 1118 | if (-f $_[1] && -s _ == -s $_[0]) { | 
| 138 | 14 |  |  |  |  | 609 | require File::Compare; | 
| 139 | 14 |  |  |  |  | 1245 | return File::Compare::compare(@_); | 
| 140 |  |  |  |  |  |  | } | 
| 141 | 20 |  |  |  |  | 218 | return 1; | 
| 142 |  |  |  |  |  |  | } | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  |  | 
| 145 |  |  |  |  |  |  | sub _chmod($$;$) { | 
| 146 | 15 |  |  | 15 |  | 56 | my ( $mode, $item, $verbose )=@_; | 
| 147 | 15 |  | 50 |  |  | 161 | $verbose ||= 0; | 
| 148 | 15 | 100 |  |  |  | 278 | if (chmod $mode, $item) { | 
| 149 | 13 | 50 |  |  |  | 61 | printf "chmod(0%o, %s)\n",$mode, $item if $verbose > 1; | 
| 150 |  |  |  |  |  |  | } else { | 
| 151 | 2 |  |  |  |  | 30 | my $err="$!"; | 
| 152 | 2 | 50 |  |  |  | 27 | _warnonce sprintf "WARNING: Failed chmod(0%o, %s): %s\n", | 
| 153 |  |  |  |  |  |  | $mode, $item, $err | 
| 154 |  |  |  |  |  |  | if -e $item; | 
| 155 |  |  |  |  |  |  | } | 
| 156 |  |  |  |  |  |  | } | 
| 157 |  |  |  |  |  |  |  | 
| 158 |  |  |  |  |  |  | =begin _private | 
| 159 |  |  |  |  |  |  |  | 
| 160 |  |  |  |  |  |  | =head2 _move_file_at_boot( $file, $target, $moan  ) | 
| 161 |  |  |  |  |  |  |  | 
| 162 |  |  |  |  |  |  | OS-Specific, Win32/Cygwin | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | Schedules a file to be moved/renamed/deleted at next boot. | 
| 165 |  |  |  |  |  |  | $file should be a filespec of an existing file | 
| 166 |  |  |  |  |  |  | $target should be a ref to an array if the file is to be deleted | 
| 167 |  |  |  |  |  |  | otherwise it should be a filespec for a rename. If the file is existing | 
| 168 |  |  |  |  |  |  | it will be replaced. | 
| 169 |  |  |  |  |  |  |  | 
| 170 |  |  |  |  |  |  | Sets $MUST_REBOOT to 0 to indicate a deletion operation has occurred | 
| 171 |  |  |  |  |  |  | and sets it to 1 to indicate that a move operation has been requested. | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | returns 1 on success, on failure if $moan is false errors are fatal. | 
| 174 |  |  |  |  |  |  | If $moan is true then returns 0 on error and warns instead of dies. | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | =end _private | 
| 177 |  |  |  |  |  |  |  | 
| 178 |  |  |  |  |  |  | =cut | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | { | 
| 181 |  |  |  |  |  |  | my $Has_Win32API_File; | 
| 182 |  |  |  |  |  |  | sub _move_file_at_boot { #XXX OS-SPECIFIC | 
| 183 | 0 |  |  | 0 |  | 0 | my ( $file, $target, $moan  )= @_; | 
| 184 | 0 |  |  |  |  | 0 | _confess("Panic: Can't _move_file_at_boot on this platform!") | 
| 185 |  |  |  |  |  |  | unless _CanMoveAtBoot; | 
| 186 |  |  |  |  |  |  |  | 
| 187 | 0 | 0 |  |  |  | 0 | my $descr= ref $target | 
| 188 |  |  |  |  |  |  | ? "'$file' for deletion" | 
| 189 |  |  |  |  |  |  | : "'$file' for installation as '$target'"; | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | # *note* _CanMoveAtBoot is only incidentally the same condition as below | 
| 192 |  |  |  |  |  |  | # this needs not hold true in the future. | 
| 193 |  |  |  |  |  |  | $Has_Win32API_File = (_Is_Win32 || _Is_cygwin) | 
| 194 | 0 | 0 |  |  |  | 0 | ? (eval {require Win32API::File; 1} || 0) | 
| 195 |  |  |  |  |  |  | : 0 unless defined $Has_Win32API_File; | 
| 196 | 0 | 0 |  |  |  | 0 | if ( ! $Has_Win32API_File ) { | 
| 197 |  |  |  |  |  |  |  | 
| 198 | 0 |  |  |  |  | 0 | my @msg=( | 
| 199 |  |  |  |  |  |  | "Cannot schedule $descr at reboot.", | 
| 200 |  |  |  |  |  |  | "Try installing Win32API::File to allow operations on locked files", | 
| 201 |  |  |  |  |  |  | "to be scheduled during reboot. Or try to perform the operation by", | 
| 202 |  |  |  |  |  |  | "hand yourself. (You may need to close other perl processes first)" | 
| 203 |  |  |  |  |  |  | ); | 
| 204 | 0 | 0 |  |  |  | 0 | if ( $moan ) { _warnonce(@msg) } else { _choke(@msg) } | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 205 | 0 |  |  |  |  | 0 | return 0; | 
| 206 |  |  |  |  |  |  | } | 
| 207 | 0 |  |  |  |  | 0 | my $opts= Win32API::File::MOVEFILE_DELAY_UNTIL_REBOOT(); | 
| 208 | 0 | 0 |  |  |  | 0 | $opts= $opts | Win32API::File::MOVEFILE_REPLACE_EXISTING() | 
| 209 |  |  |  |  |  |  | unless ref $target; | 
| 210 |  |  |  |  |  |  |  | 
| 211 | 0 |  |  |  |  | 0 | _chmod( 0666, $file ); | 
| 212 | 0 | 0 |  |  |  | 0 | _chmod( 0666, $target ) unless ref $target; | 
| 213 |  |  |  |  |  |  |  | 
| 214 | 0 | 0 |  |  |  | 0 | if (Win32API::File::MoveFileEx( $file, $target, $opts )) { | 
| 215 | 0 | 0 | 0 |  |  | 0 | $MUST_REBOOT ||= ref $target ? 0 : 1; | 
| 216 | 0 |  |  |  |  | 0 | return 1; | 
| 217 |  |  |  |  |  |  | } else { | 
| 218 | 0 |  |  |  |  | 0 | my @msg=( | 
| 219 |  |  |  |  |  |  | "MoveFileEx $descr at reboot failed: $^E", | 
| 220 |  |  |  |  |  |  | "You may try to perform the operation by hand yourself. ", | 
| 221 |  |  |  |  |  |  | "(You may need to close other perl processes first).", | 
| 222 |  |  |  |  |  |  | ); | 
| 223 | 0 | 0 |  |  |  | 0 | if ( $moan ) { _warnonce(@msg) } else { _choke(@msg) } | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 224 |  |  |  |  |  |  | } | 
| 225 | 0 |  |  |  |  | 0 | return 0; | 
| 226 |  |  |  |  |  |  | } | 
| 227 |  |  |  |  |  |  | } | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | =begin _private | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | =head2 _unlink_or_rename( $file, $tryhard, $installing ) | 
| 233 |  |  |  |  |  |  |  | 
| 234 |  |  |  |  |  |  | OS-Specific, Win32/Cygwin | 
| 235 |  |  |  |  |  |  |  | 
| 236 |  |  |  |  |  |  | Tries to get a file out of the way by unlinking it or renaming it. On | 
| 237 |  |  |  |  |  |  | some OS'es (Win32 based) DLL files can end up locked such that they can | 
| 238 |  |  |  |  |  |  | be renamed but not deleted. Likewise sometimes a file can be locked such | 
| 239 |  |  |  |  |  |  | that it cant even be renamed or changed except at reboot. To handle | 
| 240 |  |  |  |  |  |  | these cases this routine finds a tempfile name that it can either rename | 
| 241 |  |  |  |  |  |  | the file out of the way or use as a proxy for the install so that the | 
| 242 |  |  |  |  |  |  | rename can happen later (at reboot). | 
| 243 |  |  |  |  |  |  |  | 
| 244 |  |  |  |  |  |  | $file : the file to remove. | 
| 245 |  |  |  |  |  |  | $tryhard : should advanced tricks be used for deletion | 
| 246 |  |  |  |  |  |  | $installing : we are not merely deleting but we want to overwrite | 
| 247 |  |  |  |  |  |  |  | 
| 248 |  |  |  |  |  |  | When $tryhard is not true if the unlink fails its fatal. When $tryhard | 
| 249 |  |  |  |  |  |  | is true then the file is attempted to be renamed. The renamed file is | 
| 250 |  |  |  |  |  |  | then scheduled for deletion. If the rename fails then $installing | 
| 251 |  |  |  |  |  |  | governs what happens. If it is false the failure is fatal. If it is true | 
| 252 |  |  |  |  |  |  | then an attempt is made to schedule installation at boot using a | 
| 253 |  |  |  |  |  |  | temporary file to hold the new file. If this fails then a fatal error is | 
| 254 |  |  |  |  |  |  | thrown, if it succeeds it returns the temporary file name (which will be | 
| 255 |  |  |  |  |  |  | a derivative of the original in the same directory) so that the caller can | 
| 256 |  |  |  |  |  |  | use it to install under. In all other cases of success returns $file. | 
| 257 |  |  |  |  |  |  | On failure throws a fatal error. | 
| 258 |  |  |  |  |  |  |  | 
| 259 |  |  |  |  |  |  | =end _private | 
| 260 |  |  |  |  |  |  |  | 
| 261 |  |  |  |  |  |  | =cut | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | sub _unlink_or_rename { #XXX OS-SPECIFIC | 
| 264 | 7 |  |  | 7 |  | 72 | my ( $file, $tryhard, $installing )= @_; | 
| 265 |  |  |  |  |  |  |  | 
| 266 |  |  |  |  |  |  | # this chmod was originally unconditional. However, its not needed on | 
| 267 |  |  |  |  |  |  | # POSIXy systems since permission to unlink a file is specified by the | 
| 268 |  |  |  |  |  |  | # directory rather than the file; and in fact it screwed up hard- and | 
| 269 |  |  |  |  |  |  | # symlinked files. Keep it for other platforms in case its still | 
| 270 |  |  |  |  |  |  | # needed there. | 
| 271 | 7 | 50 |  |  |  | 155 | if ($^O =~ /^(dos|os2|MSWin32|VMS)$/) { | 
| 272 | 0 |  |  |  |  | 0 | _chmod( 0666, $file ); | 
| 273 |  |  |  |  |  |  | } | 
| 274 | 7 |  |  |  |  | 27 | my $unlink_count = 0; | 
| 275 | 7 |  |  |  |  | 504 | while (unlink $file) { $unlink_count++; } | 
|  | 7 |  |  |  |  | 172 |  | 
| 276 | 7 | 50 |  |  |  | 84 | return $file if $unlink_count > 0; | 
| 277 | 0 |  |  |  |  | 0 | my $error="$!"; | 
| 278 |  |  |  |  |  |  |  | 
| 279 | 0 |  |  |  |  | 0 | _choke("Cannot unlink '$file': $!") | 
| 280 |  |  |  |  |  |  | unless _CanMoveAtBoot && $tryhard; | 
| 281 |  |  |  |  |  |  |  | 
| 282 | 0 |  |  |  |  | 0 | my $tmp= "AAA"; | 
| 283 | 0 |  |  |  |  | 0 | ++$tmp while -e "$file.$tmp"; | 
| 284 | 0 |  |  |  |  | 0 | $tmp= "$file.$tmp"; | 
| 285 |  |  |  |  |  |  |  | 
| 286 | 0 |  |  |  |  | 0 | warn "WARNING: Unable to unlink '$file': $error\n", | 
| 287 |  |  |  |  |  |  | "Going to try to rename it to '$tmp'.\n"; | 
| 288 |  |  |  |  |  |  |  | 
| 289 | 0 | 0 |  |  |  | 0 | if ( rename $file, $tmp ) { | 
|  |  | 0 |  |  |  |  |  | 
| 290 | 0 |  |  |  |  | 0 | warn "Rename successful. Scheduling '$tmp'\nfor deletion at reboot.\n"; | 
| 291 |  |  |  |  |  |  | # when $installing we can set $moan to true. | 
| 292 |  |  |  |  |  |  | # IOW, if we cant delete the renamed file at reboot its | 
| 293 |  |  |  |  |  |  | # not the end of the world. The other cases are more serious | 
| 294 |  |  |  |  |  |  | # and need to be fatal. | 
| 295 | 0 |  |  |  |  | 0 | _move_file_at_boot( $tmp, [], $installing ); | 
| 296 | 0 |  |  |  |  | 0 | return $file; | 
| 297 |  |  |  |  |  |  | } elsif ( $installing ) { | 
| 298 | 0 |  |  |  |  | 0 | _warnonce("Rename failed: $!. Scheduling '$tmp'\nfor". | 
| 299 |  |  |  |  |  |  | " installation as '$file' at reboot.\n"); | 
| 300 | 0 |  |  |  |  | 0 | _move_file_at_boot( $tmp, $file ); | 
| 301 | 0 |  |  |  |  | 0 | return $tmp; | 
| 302 |  |  |  |  |  |  | } else { | 
| 303 | 0 |  |  |  |  | 0 | _choke("Rename failed:$!", "Cannot proceed."); | 
| 304 |  |  |  |  |  |  | } | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  | } | 
| 307 |  |  |  |  |  |  |  | 
| 308 |  |  |  |  |  |  | =head1 Functions | 
| 309 |  |  |  |  |  |  |  | 
| 310 |  |  |  |  |  |  | =begin _private | 
| 311 |  |  |  |  |  |  |  | 
| 312 |  |  |  |  |  |  | =head2 _get_install_skip | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | Handles loading the INSTALL.SKIP file. Returns an array of patterns to use. | 
| 315 |  |  |  |  |  |  |  | 
| 316 |  |  |  |  |  |  | =cut | 
| 317 |  |  |  |  |  |  |  | 
| 318 |  |  |  |  |  |  | sub _get_install_skip { | 
| 319 | 19 |  |  | 19 |  | 89 | my ( $skip, $verbose )= @_; | 
| 320 | 19 | 50 |  |  |  | 62 | if ($ENV{EU_INSTALL_IGNORE_SKIP}) { | 
| 321 | 0 | 0 |  |  |  | 0 | print "EU_INSTALL_IGNORE_SKIP is set, ignore skipfile settings\n" | 
| 322 |  |  |  |  |  |  | if $verbose>2; | 
| 323 | 0 |  |  |  |  | 0 | return []; | 
| 324 |  |  |  |  |  |  | } | 
| 325 | 19 | 50 |  |  |  | 59 | if ( ! defined $skip ) { | 
| 326 | 19 | 50 |  |  |  | 57 | print "Looking for install skip list\n" | 
| 327 |  |  |  |  |  |  | if $verbose>2; | 
| 328 | 19 |  |  |  |  | 127 | for my $file ( 'INSTALL.SKIP', $ENV{EU_INSTALL_SITE_SKIPFILE} ) { | 
| 329 | 38 | 100 |  |  |  | 120 | next unless $file; | 
| 330 | 19 | 50 |  |  |  | 77 | print "\tChecking for $file\n" | 
| 331 |  |  |  |  |  |  | if $verbose>2; | 
| 332 | 19 | 50 |  |  |  | 240 | if (-e $file) { | 
| 333 | 0 |  |  |  |  | 0 | $skip= $file; | 
| 334 | 0 |  |  |  |  | 0 | last; | 
| 335 |  |  |  |  |  |  | } | 
| 336 |  |  |  |  |  |  | } | 
| 337 |  |  |  |  |  |  | } | 
| 338 | 19 | 50 | 33 |  |  | 112 | if ($skip && !ref $skip) { | 
|  |  | 50 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 339 | 0 | 0 |  |  |  | 0 | print "Reading skip patterns from '$skip'.\n" | 
| 340 |  |  |  |  |  |  | if $verbose; | 
| 341 | 0 | 0 |  |  |  | 0 | if (open my $fh,$skip ) { | 
| 342 | 0 |  |  |  |  | 0 | my @patterns; | 
| 343 | 0 |  |  |  |  | 0 | while (<$fh>) { | 
| 344 | 0 |  |  |  |  | 0 | chomp; | 
| 345 | 0 | 0 |  |  |  | 0 | next if /^\s*(?:#|$)/; | 
| 346 | 0 | 0 |  |  |  | 0 | print "\tSkip pattern: $_\n" if $verbose>3; | 
| 347 | 0 |  |  |  |  | 0 | push @patterns, $_; | 
| 348 |  |  |  |  |  |  | } | 
| 349 | 0 |  |  |  |  | 0 | $skip= \@patterns; | 
| 350 |  |  |  |  |  |  | } else { | 
| 351 | 0 |  |  |  |  | 0 | warn "Can't read skip file:'$skip':$!\n"; | 
| 352 | 0 |  |  |  |  | 0 | $skip=[]; | 
| 353 |  |  |  |  |  |  | } | 
| 354 |  |  |  |  |  |  | } elsif ( UNIVERSAL::isa($skip,'ARRAY') ) { | 
| 355 | 0 | 0 |  |  |  | 0 | print "Using array for skip list\n" | 
| 356 |  |  |  |  |  |  | if $verbose>2; | 
| 357 |  |  |  |  |  |  | } elsif ($verbose) { | 
| 358 | 0 | 0 |  |  |  | 0 | print "No skip list found.\n" | 
| 359 |  |  |  |  |  |  | if $verbose>1; | 
| 360 | 0 |  |  |  |  | 0 | $skip= []; | 
| 361 |  |  |  |  |  |  | } | 
| 362 | 19 | 50 |  |  |  | 47 | warn "Got @{[0+@$skip]} skip patterns.\n" | 
|  | 0 |  |  |  |  | 0 |  | 
| 363 |  |  |  |  |  |  | if $verbose>3; | 
| 364 | 19 |  |  |  |  | 43 | return $skip | 
| 365 |  |  |  |  |  |  | } | 
| 366 |  |  |  |  |  |  |  | 
| 367 |  |  |  |  |  |  | =head2 _have_write_access | 
| 368 |  |  |  |  |  |  |  | 
| 369 |  |  |  |  |  |  | Abstract a -w check that tries to use POSIX::access() if possible. | 
| 370 |  |  |  |  |  |  |  | 
| 371 |  |  |  |  |  |  | =cut | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | { | 
| 374 |  |  |  |  |  |  | my  $has_posix; | 
| 375 |  |  |  |  |  |  | sub _have_write_access { | 
| 376 | 26 |  |  | 26 |  | 65 | my $dir=shift; | 
| 377 | 26 | 100 |  |  |  | 86 | unless (defined $has_posix) { | 
| 378 |  |  |  |  |  |  | $has_posix = (!_Is_cygwin && !_Is_Win32 | 
| 379 | 3 |  | 50 |  |  | 8 | && eval { local $^W; require POSIX; 1} ) || 0; | 
| 380 |  |  |  |  |  |  | } | 
| 381 | 26 | 50 |  |  |  | 71 | if ($has_posix) { | 
| 382 | 26 |  |  |  |  | 465 | return POSIX::access($dir, POSIX::W_OK()); | 
| 383 |  |  |  |  |  |  | } else { | 
| 384 | 0 |  |  |  |  | 0 | return -w $dir; | 
| 385 |  |  |  |  |  |  | } | 
| 386 |  |  |  |  |  |  | } | 
| 387 |  |  |  |  |  |  | } | 
| 388 |  |  |  |  |  |  |  | 
| 389 |  |  |  |  |  |  | =head2 _can_write_dir(C<$dir>) | 
| 390 |  |  |  |  |  |  |  | 
| 391 |  |  |  |  |  |  | Checks whether a given directory is writable, taking account | 
| 392 |  |  |  |  |  |  | the possibility that the directory might not exist and would have to | 
| 393 |  |  |  |  |  |  | be created first. | 
| 394 |  |  |  |  |  |  |  | 
| 395 |  |  |  |  |  |  | Returns a list, containing: C<($writable, $determined_by, @create)> | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | C<$writable> says whether the directory is (hypothetically) writable | 
| 398 |  |  |  |  |  |  |  | 
| 399 |  |  |  |  |  |  | C<$determined_by> is the directory the status was determined from. It will be | 
| 400 |  |  |  |  |  |  | either the C<$dir>, or one of its parents. | 
| 401 |  |  |  |  |  |  |  | 
| 402 |  |  |  |  |  |  | C<@create> is a list of directories that would probably have to be created | 
| 403 |  |  |  |  |  |  | to make the requested directory. It may not actually be correct on | 
| 404 |  |  |  |  |  |  | relative paths with C<..> in them. But for our purposes it should work ok | 
| 405 |  |  |  |  |  |  |  | 
| 406 |  |  |  |  |  |  | =cut | 
| 407 |  |  |  |  |  |  |  | 
| 408 |  |  |  |  |  |  | sub _can_write_dir { | 
| 409 | 26 |  |  | 26 |  | 1029 | my $dir=shift; | 
| 410 |  |  |  |  |  |  | return | 
| 411 | 26 | 50 | 33 |  |  | 381 | unless defined $dir and length $dir; | 
| 412 |  |  |  |  |  |  |  | 
| 413 | 26 |  |  |  |  | 610 | my ($vol, $dirs, $file) = File::Spec->splitpath($dir,1); | 
| 414 | 26 |  |  |  |  | 244 | my @dirs = File::Spec->splitdir($dirs); | 
| 415 | 26 | 100 |  |  |  | 710 | unshift @dirs, File::Spec->curdir | 
| 416 |  |  |  |  |  |  | unless File::Spec->file_name_is_absolute($dir); | 
| 417 |  |  |  |  |  |  |  | 
| 418 | 26 |  |  |  |  | 165 | my $path=''; | 
| 419 | 26 |  |  |  |  | 54 | my @make; | 
| 420 | 26 |  |  |  |  | 141 | while (@dirs) { | 
| 421 | 50 |  |  |  |  | 88 | if (_Is_VMS) { | 
| 422 |  |  |  |  |  |  | $dir = File::Spec->catdir($vol,@dirs); | 
| 423 |  |  |  |  |  |  | } | 
| 424 |  |  |  |  |  |  | else { | 
| 425 | 50 |  |  |  |  | 322 | $dir = File::Spec->catdir(@dirs); | 
| 426 | 50 | 50 | 33 |  |  | 413 | $dir = File::Spec->catpath($vol,$dir,'') | 
| 427 |  |  |  |  |  |  | if defined $vol and length $vol; | 
| 428 |  |  |  |  |  |  | } | 
| 429 | 50 | 50 |  |  |  | 125 | next if ( $dir eq $path ); | 
| 430 | 50 | 100 |  |  |  | 571 | if ( ! -e $dir ) { | 
| 431 | 24 |  |  |  |  | 76 | unshift @make,$dir; | 
| 432 | 24 |  |  |  |  | 40 | next; | 
| 433 |  |  |  |  |  |  | } | 
| 434 | 26 | 50 |  |  |  | 192 | if ( _have_write_access($dir) ) { | 
| 435 | 26 |  |  |  |  | 305 | return 1,$dir,@make | 
| 436 |  |  |  |  |  |  | } else { | 
| 437 | 0 |  |  |  |  | 0 | return 0,$dir,@make | 
| 438 |  |  |  |  |  |  | } | 
| 439 |  |  |  |  |  |  | } continue { | 
| 440 | 24 |  |  |  |  | 62 | pop @dirs; | 
| 441 |  |  |  |  |  |  | } | 
| 442 | 0 |  |  |  |  | 0 | return 0; | 
| 443 |  |  |  |  |  |  | } | 
| 444 |  |  |  |  |  |  |  | 
| 445 |  |  |  |  |  |  | =head2 _mkpath($dir,$show,$mode,$verbose,$dry_run) | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | Wrapper around File::Path::mkpath() to handle errors. | 
| 448 |  |  |  |  |  |  |  | 
| 449 |  |  |  |  |  |  | If $verbose is true and >1 then additional diagnostics will be produced, also | 
| 450 |  |  |  |  |  |  | this will force $show to true. | 
| 451 |  |  |  |  |  |  |  | 
| 452 |  |  |  |  |  |  | If $dry_run is true then the directory will not be created but a check will be | 
| 453 |  |  |  |  |  |  | made to see whether it would be possible to write to the directory, or that | 
| 454 |  |  |  |  |  |  | it would be possible to create the directory. | 
| 455 |  |  |  |  |  |  |  | 
| 456 |  |  |  |  |  |  | If $dry_run is not true dies if the directory can not be created or is not | 
| 457 |  |  |  |  |  |  | writable. | 
| 458 |  |  |  |  |  |  |  | 
| 459 |  |  |  |  |  |  | =cut | 
| 460 |  |  |  |  |  |  |  | 
| 461 |  |  |  |  |  |  | sub _mkpath { | 
| 462 | 34 |  |  | 34 |  | 193 | my ($dir,$show,$mode,$verbose,$dry_run)=@_; | 
| 463 | 34 | 0 | 33 |  |  | 110 | if ( $verbose && $verbose > 1 && ! -d $dir) { | 
|  |  |  | 33 |  |  |  |  | 
| 464 | 0 |  |  |  |  | 0 | $show= 1; | 
| 465 | 0 |  |  |  |  | 0 | printf "mkpath(%s,%d,%#o)\n", $dir, $show, $mode; | 
| 466 |  |  |  |  |  |  | } | 
| 467 | 34 | 100 |  |  |  | 88 | if (!$dry_run) { | 
| 468 | 28 |  |  |  |  | 93 | my @created; | 
| 469 | 28 | 50 |  |  |  | 57 | eval { | 
| 470 | 28 |  |  |  |  | 6174 | @created = File::Path::mkpath($dir,$show,$mode); | 
| 471 | 28 |  |  |  |  | 136 | 1; | 
| 472 |  |  |  |  |  |  | } or _choke("Can't create '$dir'","$@"); | 
| 473 |  |  |  |  |  |  | # if we created any directories, we were able to write and don't need | 
| 474 |  |  |  |  |  |  | # extra checks | 
| 475 | 28 | 100 |  |  |  | 137 | if (@created) { | 
| 476 | 10 |  |  |  |  | 33 | return; | 
| 477 |  |  |  |  |  |  | } | 
| 478 |  |  |  |  |  |  | } | 
| 479 | 24 |  |  |  |  | 122 | my ($can,$root,@make)=_can_write_dir($dir); | 
| 480 | 24 | 50 | 33 |  |  | 136 | if (!$can) { | 
|  |  | 50 |  |  |  |  |  | 
| 481 | 0 | 0 |  |  |  | 0 | my @msg=( | 
| 482 |  |  |  |  |  |  | "Can't create '$dir'", | 
| 483 |  |  |  |  |  |  | $root ? "Do not have write permissions on '$root'" | 
| 484 |  |  |  |  |  |  | : "Unknown Error" | 
| 485 |  |  |  |  |  |  | ); | 
| 486 | 0 | 0 |  |  |  | 0 | if ($dry_run) { | 
| 487 | 0 |  |  |  |  | 0 | _warnonce @msg; | 
| 488 |  |  |  |  |  |  | } else { | 
| 489 | 0 |  |  |  |  | 0 | _choke @msg; | 
| 490 |  |  |  |  |  |  | } | 
| 491 |  |  |  |  |  |  | } elsif ($show and $dry_run) { | 
| 492 | 0 |  |  |  |  | 0 | print "$_\n" for @make; | 
| 493 |  |  |  |  |  |  | } | 
| 494 |  |  |  |  |  |  |  | 
| 495 |  |  |  |  |  |  | } | 
| 496 |  |  |  |  |  |  |  | 
| 497 |  |  |  |  |  |  | =head2 _copy($from,$to,$verbose,$dry_run) | 
| 498 |  |  |  |  |  |  |  | 
| 499 |  |  |  |  |  |  | Wrapper around File::Copy::copy to handle errors. | 
| 500 |  |  |  |  |  |  |  | 
| 501 |  |  |  |  |  |  | If $verbose is true and >1 then additional diagnostics will be emitted. | 
| 502 |  |  |  |  |  |  |  | 
| 503 |  |  |  |  |  |  | If $dry_run is true then the copy will not actually occur. | 
| 504 |  |  |  |  |  |  |  | 
| 505 |  |  |  |  |  |  | Dies if the copy fails. | 
| 506 |  |  |  |  |  |  |  | 
| 507 |  |  |  |  |  |  | =cut | 
| 508 |  |  |  |  |  |  |  | 
| 509 |  |  |  |  |  |  | sub _copy { | 
| 510 | 15 |  |  | 15 |  | 67 | my ( $from, $to, $verbose, $dry_run)=@_; | 
| 511 | 15 | 50 | 33 |  |  | 106 | if ($verbose && $verbose>1) { | 
| 512 | 0 |  |  |  |  | 0 | printf "copy(%s,%s)\n", $from, $to; | 
| 513 |  |  |  |  |  |  | } | 
| 514 | 15 | 100 |  |  |  | 69 | if (!$dry_run) { | 
| 515 | 13 | 50 |  |  |  | 182 | File::Copy::copy($from,$to) | 
| 516 |  |  |  |  |  |  | or _croak( _estr "ERROR: Cannot copy '$from' to '$to': $!" ); | 
| 517 |  |  |  |  |  |  | } | 
| 518 |  |  |  |  |  |  | } | 
| 519 |  |  |  |  |  |  |  | 
| 520 |  |  |  |  |  |  | =pod | 
| 521 |  |  |  |  |  |  |  | 
| 522 |  |  |  |  |  |  | =head2 _chdir($from) | 
| 523 |  |  |  |  |  |  |  | 
| 524 |  |  |  |  |  |  | Wrapper around chdir to catch errors. | 
| 525 |  |  |  |  |  |  |  | 
| 526 |  |  |  |  |  |  | If not called in void context returns the cwd from before the chdir. | 
| 527 |  |  |  |  |  |  |  | 
| 528 |  |  |  |  |  |  | dies on error. | 
| 529 |  |  |  |  |  |  |  | 
| 530 |  |  |  |  |  |  | =cut | 
| 531 |  |  |  |  |  |  |  | 
| 532 |  |  |  |  |  |  | sub _chdir { | 
| 533 | 76 |  |  | 76 |  | 283 | my ($dir)= @_; | 
| 534 | 76 |  |  |  |  | 141 | my $ret; | 
| 535 | 76 | 50 |  |  |  | 261 | if (defined wantarray) { | 
| 536 | 0 |  |  |  |  | 0 | $ret= cwd; | 
| 537 |  |  |  |  |  |  | } | 
| 538 | 76 | 50 |  |  |  | 1093 | chdir $dir | 
| 539 |  |  |  |  |  |  | or _choke("Couldn't chdir to '$dir': $!"); | 
| 540 | 76 |  |  |  |  | 848 | return $ret; | 
| 541 |  |  |  |  |  |  | } | 
| 542 |  |  |  |  |  |  |  | 
| 543 |  |  |  |  |  |  | =end _private | 
| 544 |  |  |  |  |  |  |  | 
| 545 |  |  |  |  |  |  | =head2 install | 
| 546 |  |  |  |  |  |  |  | 
| 547 |  |  |  |  |  |  | # deprecated forms | 
| 548 |  |  |  |  |  |  | install(\%from_to); | 
| 549 |  |  |  |  |  |  | install(\%from_to, $verbose, $dry_run, $uninstall_shadows, | 
| 550 |  |  |  |  |  |  | $skip, $always_copy, \%result); | 
| 551 |  |  |  |  |  |  |  | 
| 552 |  |  |  |  |  |  | # recommended form as of 1.47 | 
| 553 |  |  |  |  |  |  | install([ | 
| 554 |  |  |  |  |  |  | from_to => \%from_to, | 
| 555 |  |  |  |  |  |  | verbose => 1, | 
| 556 |  |  |  |  |  |  | dry_run => 0, | 
| 557 |  |  |  |  |  |  | uninstall_shadows => 1, | 
| 558 |  |  |  |  |  |  | skip => undef, | 
| 559 |  |  |  |  |  |  | always_copy => 1, | 
| 560 |  |  |  |  |  |  | result => \%install_results, | 
| 561 |  |  |  |  |  |  | ]); | 
| 562 |  |  |  |  |  |  |  | 
| 563 |  |  |  |  |  |  |  | 
| 564 |  |  |  |  |  |  | Copies each directory tree of %from_to to its corresponding value | 
| 565 |  |  |  |  |  |  | preserving timestamps and permissions. | 
| 566 |  |  |  |  |  |  |  | 
| 567 |  |  |  |  |  |  | There are two keys with a special meaning in the hash: "read" and | 
| 568 |  |  |  |  |  |  | "write".  These contain packlist files.  After the copying is done, | 
| 569 |  |  |  |  |  |  | install() will write the list of target files to $from_to{write}. If | 
| 570 |  |  |  |  |  |  | $from_to{read} is given the contents of this file will be merged into | 
| 571 |  |  |  |  |  |  | the written file. The read and the written file may be identical, but | 
| 572 |  |  |  |  |  |  | on AFS it is quite likely that people are installing to a different | 
| 573 |  |  |  |  |  |  | directory than the one where the files later appear. | 
| 574 |  |  |  |  |  |  |  | 
| 575 |  |  |  |  |  |  | If $verbose is true, will print out each file removed.  Default is | 
| 576 |  |  |  |  |  |  | false.  This is "make install VERBINST=1". $verbose values going | 
| 577 |  |  |  |  |  |  | up to 5 show increasingly more diagnostics output. | 
| 578 |  |  |  |  |  |  |  | 
| 579 |  |  |  |  |  |  | If $dry_run is true it will only print what it was going to do | 
| 580 |  |  |  |  |  |  | without actually doing it.  Default is false. | 
| 581 |  |  |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | If $uninstall_shadows is true any differing versions throughout @INC | 
| 583 |  |  |  |  |  |  | will be uninstalled.  This is "make install UNINST=1" | 
| 584 |  |  |  |  |  |  |  | 
| 585 |  |  |  |  |  |  | As of 1.37_02 install() supports the use of a list of patterns to filter out | 
| 586 |  |  |  |  |  |  | files that shouldn't be installed. If $skip is omitted or undefined then | 
| 587 |  |  |  |  |  |  | install will try to read the list from INSTALL.SKIP in the CWD. This file is | 
| 588 |  |  |  |  |  |  | a list of regular expressions and is just like the MANIFEST.SKIP file used | 
| 589 |  |  |  |  |  |  | by L. | 
| 590 |  |  |  |  |  |  |  | 
| 591 |  |  |  |  |  |  | A default site INSTALL.SKIP may be provided by setting then environment | 
| 592 |  |  |  |  |  |  | variable EU_INSTALL_SITE_SKIPFILE, this will only be used when there isn't a | 
| 593 |  |  |  |  |  |  | distribution specific INSTALL.SKIP. If the environment variable | 
| 594 |  |  |  |  |  |  | EU_INSTALL_IGNORE_SKIP is true then no install file filtering will be | 
| 595 |  |  |  |  |  |  | performed. | 
| 596 |  |  |  |  |  |  |  | 
| 597 |  |  |  |  |  |  | If $skip is undefined then the skip file will be autodetected and used if it | 
| 598 |  |  |  |  |  |  | is found. If $skip is a reference to an array then it is assumed the array | 
| 599 |  |  |  |  |  |  | contains the list of patterns, if $skip is a true non reference it is | 
| 600 |  |  |  |  |  |  | assumed to be the filename holding the list of patterns, any other value of | 
| 601 |  |  |  |  |  |  | $skip is taken to mean that no install filtering should occur. | 
| 602 |  |  |  |  |  |  |  | 
| 603 |  |  |  |  |  |  | B | 
| 604 |  |  |  |  |  |  |  | 
| 605 |  |  |  |  |  |  | As of version 1.47 the following additions were made to the install interface. | 
| 606 |  |  |  |  |  |  | Note that the new argument style and use of the %result hash is recommended. | 
| 607 |  |  |  |  |  |  |  | 
| 608 |  |  |  |  |  |  | The $always_copy parameter which when true causes files to be updated | 
| 609 |  |  |  |  |  |  | regardless as to whether they have changed, if it is defined but false then | 
| 610 |  |  |  |  |  |  | copies are made only if the files have changed, if it is undefined then the | 
| 611 |  |  |  |  |  |  | value of the environment variable EU_INSTALL_ALWAYS_COPY is used as default. | 
| 612 |  |  |  |  |  |  |  | 
| 613 |  |  |  |  |  |  | The %result hash will be populated with the various keys/subhashes reflecting | 
| 614 |  |  |  |  |  |  | the install. Currently these keys and their structure are: | 
| 615 |  |  |  |  |  |  |  | 
| 616 |  |  |  |  |  |  | install             => { $target    => $source }, | 
| 617 |  |  |  |  |  |  | install_fail        => { $target    => $source }, | 
| 618 |  |  |  |  |  |  | install_unchanged   => { $target    => $source }, | 
| 619 |  |  |  |  |  |  |  | 
| 620 |  |  |  |  |  |  | install_filtered    => { $source    => $pattern }, | 
| 621 |  |  |  |  |  |  |  | 
| 622 |  |  |  |  |  |  | uninstall           => { $uninstalled => $source }, | 
| 623 |  |  |  |  |  |  | uninstall_fail      => { $uninstalled => $source }, | 
| 624 |  |  |  |  |  |  |  | 
| 625 |  |  |  |  |  |  | where C<$source> is the filespec of the file being installed. C<$target> is where | 
| 626 |  |  |  |  |  |  | it is being installed to, and C<$uninstalled> is any shadow file that is in C<@INC> | 
| 627 |  |  |  |  |  |  | or C<$ENV{PERL5LIB}> or other standard locations, and C<$pattern> is the pattern that | 
| 628 |  |  |  |  |  |  | caused a source file to be skipped. In future more keys will be added, such as to | 
| 629 |  |  |  |  |  |  | show created directories, however this requires changes in other modules and must | 
| 630 |  |  |  |  |  |  | therefore wait. | 
| 631 |  |  |  |  |  |  |  | 
| 632 |  |  |  |  |  |  | These keys will be populated before any exceptions are thrown should there be an | 
| 633 |  |  |  |  |  |  | error. | 
| 634 |  |  |  |  |  |  |  | 
| 635 |  |  |  |  |  |  | Note that all updates of the %result are additive, the hash will not be | 
| 636 |  |  |  |  |  |  | cleared before use, thus allowing status results of many installs to be easily | 
| 637 |  |  |  |  |  |  | aggregated. | 
| 638 |  |  |  |  |  |  |  | 
| 639 |  |  |  |  |  |  | B | 
| 640 |  |  |  |  |  |  |  | 
| 641 |  |  |  |  |  |  | If there is only one argument and it is a reference to an array then | 
| 642 |  |  |  |  |  |  | the array is assumed to contain a list of key-value pairs specifying | 
| 643 |  |  |  |  |  |  | the options. In this case the option "from_to" is mandatory. This style | 
| 644 |  |  |  |  |  |  | means that you do not have to supply a cryptic list of arguments and can | 
| 645 |  |  |  |  |  |  | use a self documenting argument list that is easier to understand. | 
| 646 |  |  |  |  |  |  |  | 
| 647 |  |  |  |  |  |  | This is now the recommended interface to install(). | 
| 648 |  |  |  |  |  |  |  | 
| 649 |  |  |  |  |  |  | B | 
| 650 |  |  |  |  |  |  |  | 
| 651 |  |  |  |  |  |  | If all actions were successful install will return a hashref of the results | 
| 652 |  |  |  |  |  |  | as described above for the $result parameter. If any action is a failure | 
| 653 |  |  |  |  |  |  | then install will die, therefore it is recommended to pass in the $result | 
| 654 |  |  |  |  |  |  | parameter instead of using the return value. If the result parameter is | 
| 655 |  |  |  |  |  |  | provided then the returned hashref will be the passed in hashref. | 
| 656 |  |  |  |  |  |  |  | 
| 657 |  |  |  |  |  |  | =cut | 
| 658 |  |  |  |  |  |  |  | 
| 659 |  |  |  |  |  |  | sub install { #XXX OS-SPECIFIC | 
| 660 | 19 |  |  | 19 | 1 | 47220 | my($from_to,$verbose,$dry_run,$uninstall_shadows,$skip,$always_copy,$result) = @_; | 
| 661 | 19 | 100 | 100 |  |  | 206 | if (@_==1 and eval { 1+@$from_to }) { | 
|  | 13 |  |  |  |  | 114 |  | 
| 662 | 12 |  |  |  |  | 140 | my %opts        = @$from_to; | 
| 663 |  |  |  |  |  |  | $from_to        = $opts{from_to} | 
| 664 | 12 | 50 |  |  |  | 83 | or _confess("from_to is a mandatory parameter"); | 
| 665 | 12 |  |  |  |  | 22 | $verbose        = $opts{verbose}; | 
| 666 | 12 |  |  |  |  | 22 | $dry_run        = $opts{dry_run}; | 
| 667 | 12 |  |  |  |  | 28 | $uninstall_shadows  = $opts{uninstall_shadows}; | 
| 668 | 12 |  |  |  |  | 26 | $skip           = $opts{skip}; | 
| 669 | 12 |  |  |  |  | 24 | $always_copy    = $opts{always_copy}; | 
| 670 | 12 |  |  |  |  | 37 | $result         = $opts{result}; | 
| 671 |  |  |  |  |  |  | } | 
| 672 |  |  |  |  |  |  |  | 
| 673 | 19 |  | 100 |  |  | 180 | $result ||= {}; | 
| 674 | 19 |  | 50 |  |  | 187 | $verbose ||= 0; | 
| 675 | 19 |  | 100 |  |  | 233 | $dry_run  ||= 0; | 
| 676 |  |  |  |  |  |  |  | 
| 677 | 19 |  |  |  |  | 180 | $skip= _get_install_skip($skip,$verbose); | 
| 678 |  |  |  |  |  |  | $always_copy =  $ENV{EU_INSTALL_ALWAYS_COPY} | 
| 679 |  |  |  |  |  |  | || $ENV{EU_ALWAYS_COPY} | 
| 680 | 19 | 50 | 50 |  |  | 202 | || 0 | 
| 681 |  |  |  |  |  |  | unless defined $always_copy; | 
| 682 |  |  |  |  |  |  |  | 
| 683 | 19 |  |  |  |  | 111 | my(%from_to) = %$from_to; | 
| 684 | 19 |  |  |  |  | 60 | my(%pack, $dir, %warned); | 
| 685 | 19 |  |  |  |  | 1215 | require ExtUtils::Packlist; | 
| 686 | 19 |  |  |  |  | 293 | my($packlist) = ExtUtils::Packlist->new(); | 
| 687 |  |  |  |  |  |  |  | 
| 688 | 19 |  |  |  |  | 73 | local(*DIR); | 
| 689 | 19 |  |  |  |  | 44 | for (qw/read write/) { | 
| 690 | 38 |  |  |  |  | 94 | $pack{$_}=$from_to{$_}; | 
| 691 | 38 |  |  |  |  | 82 | delete $from_to{$_}; | 
| 692 |  |  |  |  |  |  | } | 
| 693 | 19 |  |  |  |  | 106 | my $tmpfile = install_rooted_file($pack{"read"}); | 
| 694 | 19 | 100 |  |  |  | 389 | $packlist->read($tmpfile) if (-f $tmpfile); | 
| 695 | 19 |  |  |  |  | 68291 | my $cwd = cwd(); | 
| 696 | 19 |  |  |  |  | 299 | my @found_files; | 
| 697 |  |  |  |  |  |  | my %check_dirs; | 
| 698 | 19 |  |  |  |  | 453 | require File::Find; | 
| 699 |  |  |  |  |  |  |  | 
| 700 | 19 |  |  |  |  | 671 | my $blib_lib  = File::Spec->catdir('blib', 'lib'); | 
| 701 | 19 |  |  |  |  | 226 | my $blib_arch = File::Spec->catdir('blib', 'arch'); | 
| 702 |  |  |  |  |  |  |  | 
| 703 |  |  |  |  |  |  | # File::Find seems to always be Unixy except on MacPerl :( | 
| 704 | 19 | 50 |  |  |  | 537 | my $current_directory = $^O eq 'MacOS' ? $Curdir : '.'; | 
| 705 |  |  |  |  |  |  |  | 
| 706 | 19 |  |  |  |  | 255 | MOD_INSTALL: foreach my $source (sort keys %from_to) { | 
| 707 |  |  |  |  |  |  | #copy the tree to the target directory without altering | 
| 708 |  |  |  |  |  |  | #timestamp and permission and remember for the .packlist | 
| 709 |  |  |  |  |  |  | #file. The packlist file contains the absolute paths of the | 
| 710 |  |  |  |  |  |  | #install locations. AFS users may call this a bug. We'll have | 
| 711 |  |  |  |  |  |  | #to reconsider how to add the means to satisfy AFS users also. | 
| 712 |  |  |  |  |  |  |  | 
| 713 |  |  |  |  |  |  | #October 1997: we want to install .pm files into archlib if | 
| 714 |  |  |  |  |  |  | #there are any files in arch. So we depend on having ./blib/arch | 
| 715 |  |  |  |  |  |  | #hardcoded here. | 
| 716 |  |  |  |  |  |  |  | 
| 717 | 19 |  |  |  |  | 482 | my $targetroot = install_rooted_dir($from_to{$source}); | 
| 718 |  |  |  |  |  |  |  | 
| 719 | 19 | 50 | 66 |  |  | 364 | if ($source eq $blib_lib and | 
|  |  |  | 33 |  |  |  |  | 
| 720 |  |  |  |  |  |  | exists $from_to{$blib_arch} and | 
| 721 |  |  |  |  |  |  | directory_not_empty($blib_arch) | 
| 722 |  |  |  |  |  |  | ){ | 
| 723 | 0 |  |  |  |  | 0 | $targetroot = install_rooted_dir($from_to{$blib_arch}); | 
| 724 | 0 |  |  |  |  | 0 | print "Files found in $blib_arch: installing files in $blib_lib into architecture dependent library tree\n"; | 
| 725 |  |  |  |  |  |  | } | 
| 726 |  |  |  |  |  |  |  | 
| 727 | 19 | 50 |  |  |  | 501 | next unless -d $source; | 
| 728 | 19 |  |  |  |  | 248 | _chdir($source); | 
| 729 |  |  |  |  |  |  | # 5.5.3's File::Find missing no_chdir option | 
| 730 |  |  |  |  |  |  | # XXX OS-SPECIFIC | 
| 731 |  |  |  |  |  |  | File::Find::find(sub { | 
| 732 | 76 |  |  | 76 |  | 1309 | my ($mode,$size,$atime,$mtime) = (stat)[2,7,8,9]; | 
| 733 |  |  |  |  |  |  |  | 
| 734 | 76 | 100 |  |  |  | 7115 | return if !-f _; | 
| 735 | 19 |  |  |  |  | 61 | my $origfile = $_; | 
| 736 |  |  |  |  |  |  |  | 
| 737 | 19 | 50 |  |  |  | 60 | return if $origfile eq ".exists"; | 
| 738 | 19 |  |  |  |  | 272 | my $targetdir  = File::Spec->catdir($targetroot, $File::Find::dir); | 
| 739 | 19 |  |  |  |  | 223 | my $targetfile = File::Spec->catfile($targetdir, $origfile); | 
| 740 | 19 |  |  |  |  | 165 | my $sourcedir  = File::Spec->catdir($source, $File::Find::dir); | 
| 741 | 19 |  |  |  |  | 162 | my $sourcefile = File::Spec->catfile($sourcedir, $origfile); | 
| 742 |  |  |  |  |  |  |  | 
| 743 | 19 |  |  |  |  | 87 | for my $pat (@$skip) { | 
| 744 | 0 | 0 |  |  |  | 0 | if ( $sourcefile=~/$pat/ ) { | 
| 745 | 0 | 0 |  |  |  | 0 | print "Skipping $targetfile (filtered)\n" | 
| 746 |  |  |  |  |  |  | if $verbose>1; | 
| 747 | 0 |  |  |  |  | 0 | $result->{install_filtered}{$sourcefile} = $pat; | 
| 748 | 0 |  |  |  |  | 0 | return; | 
| 749 |  |  |  |  |  |  | } | 
| 750 |  |  |  |  |  |  | } | 
| 751 |  |  |  |  |  |  | # we have to do this for back compat with old File::Finds | 
| 752 |  |  |  |  |  |  | # and because the target is relative | 
| 753 | 19 |  |  |  |  | 156 | my $save_cwd = File::Spec->catfile($cwd, $sourcedir); | 
| 754 | 19 |  |  |  |  | 120 | _chdir($cwd); | 
| 755 | 19 |  | 100 |  |  | 313 | my $diff = $always_copy || _compare($sourcefile, $targetfile); | 
| 756 | 19 | 100 |  |  |  | 2171 | $check_dirs{$targetdir}++ | 
| 757 |  |  |  |  |  |  | unless -w $targetfile; | 
| 758 |  |  |  |  |  |  |  | 
| 759 | 19 |  |  |  |  | 137 | push @found_files, | 
| 760 |  |  |  |  |  |  | [ $diff, $File::Find::dir, $origfile, | 
| 761 |  |  |  |  |  |  | $mode, $size, $atime, $mtime, | 
| 762 |  |  |  |  |  |  | $targetdir, $targetfile, $sourcedir, $sourcefile, | 
| 763 |  |  |  |  |  |  |  | 
| 764 |  |  |  |  |  |  | ]; | 
| 765 |  |  |  |  |  |  | #restore the original directory we were in when File::Find | 
| 766 |  |  |  |  |  |  | #called us so that it doesn't get horribly confused. | 
| 767 | 19 |  |  |  |  | 81 | _chdir($save_cwd); | 
| 768 | 19 |  |  |  |  | 4132 | }, $current_directory ); | 
| 769 | 19 |  |  |  |  | 265 | _chdir($cwd); | 
| 770 |  |  |  |  |  |  | } | 
| 771 | 19 |  |  |  |  | 158 | foreach my $targetdir (sort keys %check_dirs) { | 
| 772 | 7 |  |  |  |  | 63 | _mkpath( $targetdir, 0, 0755, $verbose, $dry_run ); | 
| 773 |  |  |  |  |  |  | } | 
| 774 | 19 |  |  |  |  | 64 | foreach my $found (@found_files) { | 
| 775 | 19 |  |  |  |  | 129 | my ($diff, $ffd, $origfile, $mode, $size, $atime, $mtime, | 
| 776 |  |  |  |  |  |  | $targetdir, $targetfile, $sourcedir, $sourcefile)= @$found; | 
| 777 |  |  |  |  |  |  |  | 
| 778 | 19 |  |  |  |  | 71 | my $realtarget= $targetfile; | 
| 779 | 19 | 100 |  |  |  | 62 | if ($diff) { | 
| 780 |  |  |  |  |  |  | eval { | 
| 781 | 12 | 100 |  |  |  | 303 | if (-f $targetfile) { | 
|  |  | 100 |  |  |  |  |  | 
| 782 | 5 | 50 |  |  |  | 89 | print "_unlink_or_rename($targetfile)\n" if $verbose>1; | 
| 783 | 5 | 50 |  |  |  | 104 | $targetfile= _unlink_or_rename( $targetfile, 'tryhard', 'install' ) | 
| 784 |  |  |  |  |  |  | unless $dry_run; | 
| 785 |  |  |  |  |  |  | } elsif ( ! -d $targetdir ) { | 
| 786 | 2 |  |  |  |  | 13 | _mkpath( $targetdir, 0, 0755, $verbose, $dry_run ); | 
| 787 |  |  |  |  |  |  | } | 
| 788 | 12 |  |  |  |  | 409 | print "Installing $targetfile\n"; | 
| 789 |  |  |  |  |  |  |  | 
| 790 | 12 |  |  |  |  | 302 | _copy( $sourcefile, $targetfile, $verbose, $dry_run, ); | 
| 791 |  |  |  |  |  |  |  | 
| 792 |  |  |  |  |  |  |  | 
| 793 |  |  |  |  |  |  | #XXX OS-SPECIFIC | 
| 794 | 12 | 50 |  |  |  | 4151 | print "utime($atime,$mtime,$targetfile)\n" if $verbose>1; | 
| 795 | 12 | 50 |  |  |  | 251 | utime($atime,$mtime + _Is_VMS,$targetfile) unless $dry_run>1; | 
| 796 |  |  |  |  |  |  |  | 
| 797 |  |  |  |  |  |  |  | 
| 798 | 12 | 50 |  |  |  | 59 | $mode = 0444 | ( $mode & 0111 ? 0111 : 0 ); | 
| 799 | 12 | 50 |  |  |  | 51 | $mode = $mode | 0222 | 
| 800 |  |  |  |  |  |  | if $realtarget ne $targetfile; | 
| 801 | 12 |  |  |  |  | 91 | _chmod( $mode, $targetfile, $verbose ); | 
| 802 | 12 |  |  |  |  | 148 | $result->{install}{$targetfile} = $sourcefile; | 
| 803 | 12 |  |  |  |  | 58 | 1 | 
| 804 | 12 | 50 |  |  |  | 35 | } or do { | 
| 805 | 0 |  |  |  |  | 0 | $result->{install_fail}{$targetfile} = $sourcefile; | 
| 806 | 0 |  |  |  |  | 0 | die $@; | 
| 807 |  |  |  |  |  |  | }; | 
| 808 |  |  |  |  |  |  | } else { | 
| 809 | 7 |  |  |  |  | 116 | $result->{install_unchanged}{$targetfile} = $sourcefile; | 
| 810 | 7 | 50 |  |  |  | 59 | print "Skipping $targetfile (unchanged)\n" if $verbose; | 
| 811 |  |  |  |  |  |  | } | 
| 812 |  |  |  |  |  |  |  | 
| 813 | 19 | 100 |  |  |  | 75 | if ( $uninstall_shadows ) { | 
| 814 | 8 | 50 |  |  |  | 163 | inc_uninstall($sourcefile,$ffd, $verbose, | 
| 815 |  |  |  |  |  |  | $dry_run, | 
| 816 |  |  |  |  |  |  | $realtarget ne $targetfile ? $realtarget : "", | 
| 817 |  |  |  |  |  |  | $result); | 
| 818 |  |  |  |  |  |  | } | 
| 819 |  |  |  |  |  |  |  | 
| 820 |  |  |  |  |  |  | # Record the full pathname. | 
| 821 | 17 |  |  |  |  | 230 | $packlist->{$targetfile}++; | 
| 822 |  |  |  |  |  |  | } | 
| 823 |  |  |  |  |  |  |  | 
| 824 | 17 | 50 |  |  |  | 63 | if ($pack{'write'}) { | 
| 825 | 17 |  |  |  |  | 1490 | $dir = install_rooted_dir(dirname($pack{'write'})); | 
| 826 | 17 |  |  |  |  | 89 | _mkpath( $dir, 0, 0755, $verbose, $dry_run ); | 
| 827 | 17 | 50 |  |  |  | 71 | print "Writing $pack{'write'}\n" if $verbose; | 
| 828 | 17 | 100 |  |  |  | 130 | $packlist->write(install_rooted_file($pack{'write'})) unless $dry_run; | 
| 829 |  |  |  |  |  |  | } | 
| 830 |  |  |  |  |  |  |  | 
| 831 | 17 |  |  |  |  | 131 | _do_cleanup($verbose); | 
| 832 | 17 |  |  |  |  | 610 | return $result; | 
| 833 |  |  |  |  |  |  | } | 
| 834 |  |  |  |  |  |  |  | 
| 835 |  |  |  |  |  |  | =begin _private | 
| 836 |  |  |  |  |  |  |  | 
| 837 |  |  |  |  |  |  | =head2 _do_cleanup | 
| 838 |  |  |  |  |  |  |  | 
| 839 |  |  |  |  |  |  | Standardize finish event for after another instruction has occurred. | 
| 840 |  |  |  |  |  |  | Handles converting $MUST_REBOOT to a die for instance. | 
| 841 |  |  |  |  |  |  |  | 
| 842 |  |  |  |  |  |  | =end _private | 
| 843 |  |  |  |  |  |  |  | 
| 844 |  |  |  |  |  |  | =cut | 
| 845 |  |  |  |  |  |  |  | 
| 846 |  |  |  |  |  |  | sub _do_cleanup { | 
| 847 | 17 |  |  | 17 |  | 57 | my ($verbose) = @_; | 
| 848 | 17 | 50 |  |  |  | 79 | if ($MUST_REBOOT) { | 
|  |  | 50 |  |  |  |  |  | 
| 849 | 0 |  |  |  |  | 0 | die _estr "Operation not completed! ", | 
| 850 |  |  |  |  |  |  | "You must reboot to complete the installation.", | 
| 851 |  |  |  |  |  |  | "Sorry."; | 
| 852 |  |  |  |  |  |  | } elsif (defined $MUST_REBOOT & $verbose) { | 
| 853 | 0 |  |  |  |  | 0 | warn _estr "Installation will be completed at the next reboot.\n", | 
| 854 |  |  |  |  |  |  | "However it is not necessary to reboot immediately.\n"; | 
| 855 |  |  |  |  |  |  | } | 
| 856 |  |  |  |  |  |  | } | 
| 857 |  |  |  |  |  |  |  | 
| 858 |  |  |  |  |  |  | =begin _undocumented | 
| 859 |  |  |  |  |  |  |  | 
| 860 |  |  |  |  |  |  | =head2 install_rooted_file( $file ) | 
| 861 |  |  |  |  |  |  |  | 
| 862 |  |  |  |  |  |  | Returns $file, or catfile($INSTALL_ROOT,$file) if $INSTALL_ROOT | 
| 863 |  |  |  |  |  |  | is defined. | 
| 864 |  |  |  |  |  |  |  | 
| 865 |  |  |  |  |  |  | =head2 install_rooted_dir( $dir ) | 
| 866 |  |  |  |  |  |  |  | 
| 867 |  |  |  |  |  |  | Returns $dir, or catdir($INSTALL_ROOT,$dir) if $INSTALL_ROOT | 
| 868 |  |  |  |  |  |  | is defined. | 
| 869 |  |  |  |  |  |  |  | 
| 870 |  |  |  |  |  |  | =end _undocumented | 
| 871 |  |  |  |  |  |  |  | 
| 872 |  |  |  |  |  |  | =cut | 
| 873 |  |  |  |  |  |  |  | 
| 874 |  |  |  |  |  |  | sub install_rooted_file { | 
| 875 | 34 | 50 |  | 34 | 1 | 90 | if (defined $INSTALL_ROOT) { | 
| 876 | 0 |  |  |  |  | 0 | File::Spec->catfile($INSTALL_ROOT, $_[0]); | 
| 877 |  |  |  |  |  |  | } else { | 
| 878 | 34 |  |  |  |  | 197 | $_[0]; | 
| 879 |  |  |  |  |  |  | } | 
| 880 |  |  |  |  |  |  | } | 
| 881 |  |  |  |  |  |  |  | 
| 882 |  |  |  |  |  |  |  | 
| 883 |  |  |  |  |  |  | sub install_rooted_dir { | 
| 884 | 36 | 50 |  | 36 | 1 | 150 | if (defined $INSTALL_ROOT) { | 
| 885 | 0 |  |  |  |  | 0 | File::Spec->catdir($INSTALL_ROOT, $_[0]); | 
| 886 |  |  |  |  |  |  | } else { | 
| 887 | 36 |  |  |  |  | 209 | $_[0]; | 
| 888 |  |  |  |  |  |  | } | 
| 889 |  |  |  |  |  |  | } | 
| 890 |  |  |  |  |  |  |  | 
| 891 |  |  |  |  |  |  | =begin _undocumented | 
| 892 |  |  |  |  |  |  |  | 
| 893 |  |  |  |  |  |  | =head2 forceunlink( $file, $tryhard ) | 
| 894 |  |  |  |  |  |  |  | 
| 895 |  |  |  |  |  |  | Tries to delete a file. If $tryhard is true then we will use whatever | 
| 896 |  |  |  |  |  |  | devious tricks we can to delete the file. Currently this only applies to | 
| 897 |  |  |  |  |  |  | Win32 in that it will try to use Win32API::File to schedule a delete at | 
| 898 |  |  |  |  |  |  | reboot. A wrapper for _unlink_or_rename(). | 
| 899 |  |  |  |  |  |  |  | 
| 900 |  |  |  |  |  |  | =end _undocumented | 
| 901 |  |  |  |  |  |  |  | 
| 902 |  |  |  |  |  |  | =cut | 
| 903 |  |  |  |  |  |  |  | 
| 904 |  |  |  |  |  |  | sub forceunlink { | 
| 905 | 2 |  |  | 2 | 1 | 44 | my ( $file, $tryhard )= @_; #XXX OS-SPECIFIC | 
| 906 | 2 |  |  |  |  | 57 | _unlink_or_rename( $file, $tryhard, not("installing") ); | 
| 907 |  |  |  |  |  |  | } | 
| 908 |  |  |  |  |  |  |  | 
| 909 |  |  |  |  |  |  | =begin _undocumented | 
| 910 |  |  |  |  |  |  |  | 
| 911 |  |  |  |  |  |  | =head2 directory_not_empty( $dir ) | 
| 912 |  |  |  |  |  |  |  | 
| 913 |  |  |  |  |  |  | Returns 1 if there is an .exists file somewhere in a directory tree. | 
| 914 |  |  |  |  |  |  | Returns 0 if there is not. | 
| 915 |  |  |  |  |  |  |  | 
| 916 |  |  |  |  |  |  | =end _undocumented | 
| 917 |  |  |  |  |  |  |  | 
| 918 |  |  |  |  |  |  | =cut | 
| 919 |  |  |  |  |  |  |  | 
| 920 |  |  |  |  |  |  | sub directory_not_empty ($) { | 
| 921 | 0 |  |  | 0 | 1 | 0 | my($dir) = @_; | 
| 922 | 0 |  |  |  |  | 0 | my $files = 0; | 
| 923 | 0 |  |  |  |  | 0 | require File::Find; | 
| 924 |  |  |  |  |  |  | File::Find::find(sub { | 
| 925 | 0 | 0 |  | 0 |  | 0 | return if $_ eq ".exists"; | 
| 926 | 0 | 0 |  |  |  | 0 | if (-f) { | 
| 927 | 0 |  |  |  |  | 0 | $File::Find::prune++; | 
| 928 | 0 |  |  |  |  | 0 | $files = 1; | 
| 929 |  |  |  |  |  |  | } | 
| 930 | 0 |  |  |  |  | 0 | }, $dir); | 
| 931 | 0 |  |  |  |  | 0 | return $files; | 
| 932 |  |  |  |  |  |  | } | 
| 933 |  |  |  |  |  |  |  | 
| 934 |  |  |  |  |  |  | =head2 install_default | 
| 935 |  |  |  |  |  |  |  | 
| 936 |  |  |  |  |  |  | I | 
| 937 |  |  |  |  |  |  |  | 
| 938 |  |  |  |  |  |  | install_default(); | 
| 939 |  |  |  |  |  |  | install_default($fullext); | 
| 940 |  |  |  |  |  |  |  | 
| 941 |  |  |  |  |  |  | Calls install() with arguments to copy a module from blib/ to the | 
| 942 |  |  |  |  |  |  | default site installation location. | 
| 943 |  |  |  |  |  |  |  | 
| 944 |  |  |  |  |  |  | $fullext is the name of the module converted to a directory | 
| 945 |  |  |  |  |  |  | (ie. Foo::Bar would be Foo/Bar).  If $fullext is not specified, it | 
| 946 |  |  |  |  |  |  | will attempt to read it from @ARGV. | 
| 947 |  |  |  |  |  |  |  | 
| 948 |  |  |  |  |  |  | This is primarily useful for install scripts. | 
| 949 |  |  |  |  |  |  |  | 
| 950 |  |  |  |  |  |  | B This function is not really useful because of the hard-coded | 
| 951 |  |  |  |  |  |  | install location with no way to control site vs core vs vendor | 
| 952 |  |  |  |  |  |  | directories and the strange way in which the module name is given. | 
| 953 |  |  |  |  |  |  | Consider its use discouraged. | 
| 954 |  |  |  |  |  |  |  | 
| 955 |  |  |  |  |  |  | =cut | 
| 956 |  |  |  |  |  |  |  | 
| 957 |  |  |  |  |  |  | sub install_default { | 
| 958 | 0 | 0 |  | 0 | 1 | 0 | @_ < 2 or _croak("install_default should be called with 0 or 1 argument"); | 
| 959 | 0 | 0 |  |  |  | 0 | my $FULLEXT = @_ ? shift : $ARGV[0]; | 
| 960 | 0 | 0 |  |  |  | 0 | defined $FULLEXT or die "Do not know to where to write install log"; | 
| 961 | 0 |  |  |  |  | 0 | my $INST_LIB = File::Spec->catdir($Curdir,"blib","lib"); | 
| 962 | 0 |  |  |  |  | 0 | my $INST_ARCHLIB = File::Spec->catdir($Curdir,"blib","arch"); | 
| 963 | 0 |  |  |  |  | 0 | my $INST_BIN = File::Spec->catdir($Curdir,'blib','bin'); | 
| 964 | 0 |  |  |  |  | 0 | my $INST_SCRIPT = File::Spec->catdir($Curdir,'blib','script'); | 
| 965 | 0 |  |  |  |  | 0 | my $INST_MAN1DIR = File::Spec->catdir($Curdir,'blib','man1'); | 
| 966 | 0 |  |  |  |  | 0 | my $INST_MAN3DIR = File::Spec->catdir($Curdir,'blib','man3'); | 
| 967 |  |  |  |  |  |  |  | 
| 968 | 0 |  |  |  |  | 0 | my @INST_HTML; | 
| 969 | 0 | 0 |  |  |  | 0 | if($Config{installhtmldir}) { | 
| 970 | 0 |  |  |  |  | 0 | my $INST_HTMLDIR = File::Spec->catdir($Curdir,'blib','html'); | 
| 971 | 0 |  |  |  |  | 0 | @INST_HTML = ($INST_HTMLDIR => $Config{installhtmldir}); | 
| 972 |  |  |  |  |  |  | } | 
| 973 |  |  |  |  |  |  |  | 
| 974 |  |  |  |  |  |  | install({ | 
| 975 |  |  |  |  |  |  | read => "$Config{sitearchexp}/auto/$FULLEXT/.packlist", | 
| 976 |  |  |  |  |  |  | write => "$Config{installsitearch}/auto/$FULLEXT/.packlist", | 
| 977 |  |  |  |  |  |  | $INST_LIB => (directory_not_empty($INST_ARCHLIB)) ? | 
| 978 |  |  |  |  |  |  | $Config{installsitearch} : | 
| 979 |  |  |  |  |  |  | $Config{installsitelib}, | 
| 980 |  |  |  |  |  |  | $INST_ARCHLIB => $Config{installsitearch}, | 
| 981 |  |  |  |  |  |  | $INST_BIN => $Config{installbin} , | 
| 982 |  |  |  |  |  |  | $INST_SCRIPT => $Config{installscript}, | 
| 983 |  |  |  |  |  |  | $INST_MAN1DIR => $Config{installman1dir}, | 
| 984 |  |  |  |  |  |  | $INST_MAN3DIR => $Config{installman3dir}, | 
| 985 | 0 | 0 |  |  |  | 0 | @INST_HTML, | 
| 986 |  |  |  |  |  |  | },1,0,0); | 
| 987 |  |  |  |  |  |  | } | 
| 988 |  |  |  |  |  |  |  | 
| 989 |  |  |  |  |  |  |  | 
| 990 |  |  |  |  |  |  | =head2 uninstall | 
| 991 |  |  |  |  |  |  |  | 
| 992 |  |  |  |  |  |  | uninstall($packlist_file); | 
| 993 |  |  |  |  |  |  | uninstall($packlist_file, $verbose, $dont_execute); | 
| 994 |  |  |  |  |  |  |  | 
| 995 |  |  |  |  |  |  | Removes the files listed in a $packlist_file. | 
| 996 |  |  |  |  |  |  |  | 
| 997 |  |  |  |  |  |  | If $verbose is true, will print out each file removed.  Default is | 
| 998 |  |  |  |  |  |  | false. | 
| 999 |  |  |  |  |  |  |  | 
| 1000 |  |  |  |  |  |  | If $dont_execute is true it will only print what it was going to do | 
| 1001 |  |  |  |  |  |  | without actually doing it.  Default is false. | 
| 1002 |  |  |  |  |  |  |  | 
| 1003 |  |  |  |  |  |  | =cut | 
| 1004 |  |  |  |  |  |  |  | 
| 1005 |  |  |  |  |  |  | sub uninstall { | 
| 1006 | 0 |  |  | 0 | 1 | 0 | my($fil,$verbose,$dry_run) = @_; | 
| 1007 | 0 |  | 0 |  |  | 0 | $verbose ||= 0; | 
| 1008 | 0 |  | 0 |  |  | 0 | $dry_run  ||= 0; | 
| 1009 |  |  |  |  |  |  |  | 
| 1010 | 0 | 0 |  |  |  | 0 | die _estr "ERROR: no packlist file found: '$fil'" | 
| 1011 |  |  |  |  |  |  | unless -f $fil; | 
| 1012 |  |  |  |  |  |  | # my $my_req = $self->catfile(qw(auto ExtUtils Install forceunlink.al)); | 
| 1013 |  |  |  |  |  |  | # require $my_req; # Hairy, but for the first | 
| 1014 | 0 |  |  |  |  | 0 | require ExtUtils::Packlist; | 
| 1015 | 0 |  |  |  |  | 0 | my ($packlist) = ExtUtils::Packlist->new($fil); | 
| 1016 | 0 |  |  |  |  | 0 | foreach (sort(keys(%$packlist))) { | 
| 1017 | 0 |  |  |  |  | 0 | chomp; | 
| 1018 | 0 | 0 |  |  |  | 0 | print "unlink $_\n" if $verbose; | 
| 1019 | 0 | 0 |  |  |  | 0 | forceunlink($_,'tryhard') unless $dry_run; | 
| 1020 |  |  |  |  |  |  | } | 
| 1021 | 0 | 0 |  |  |  | 0 | print "unlink $fil\n" if $verbose; | 
| 1022 | 0 | 0 |  |  |  | 0 | forceunlink($fil, 'tryhard') unless $dry_run; | 
| 1023 | 0 |  |  |  |  | 0 | _do_cleanup($verbose); | 
| 1024 |  |  |  |  |  |  | } | 
| 1025 |  |  |  |  |  |  |  | 
| 1026 |  |  |  |  |  |  | =begin _undocumented | 
| 1027 |  |  |  |  |  |  |  | 
| 1028 |  |  |  |  |  |  | =head2 inc_uninstall($filepath,$libdir,$verbose,$dry_run,$ignore,$results) | 
| 1029 |  |  |  |  |  |  |  | 
| 1030 |  |  |  |  |  |  | Remove shadowed files. If $ignore is true then it is assumed to hold | 
| 1031 |  |  |  |  |  |  | a filename to ignore. This is used to prevent spurious warnings from | 
| 1032 |  |  |  |  |  |  | occurring when doing an install at reboot. | 
| 1033 |  |  |  |  |  |  |  | 
| 1034 |  |  |  |  |  |  | We now only die when failing to remove a file that has precedence over | 
| 1035 |  |  |  |  |  |  | our own, when our install has precedence we only warn. | 
| 1036 |  |  |  |  |  |  |  | 
| 1037 |  |  |  |  |  |  | $results is assumed to contain a hashref which will have the keys | 
| 1038 |  |  |  |  |  |  | 'uninstall' and 'uninstall_fail' populated with  keys for the files | 
| 1039 |  |  |  |  |  |  | removed and values of the source files they would shadow. | 
| 1040 |  |  |  |  |  |  |  | 
| 1041 |  |  |  |  |  |  | =end _undocumented | 
| 1042 |  |  |  |  |  |  |  | 
| 1043 |  |  |  |  |  |  | =cut | 
| 1044 |  |  |  |  |  |  |  | 
| 1045 |  |  |  |  |  |  | sub inc_uninstall { | 
| 1046 | 8 |  |  | 8 | 1 | 115 | my($filepath,$libdir,$verbose,$dry_run,$ignore,$results) = @_; | 
| 1047 | 8 |  |  |  |  | 29 | my($dir); | 
| 1048 | 8 |  | 50 |  |  | 153 | $ignore||=""; | 
| 1049 | 8 |  |  |  |  | 619 | my $file = (File::Spec->splitpath($filepath))[2]; | 
| 1050 | 8 |  |  |  |  | 41 | my %seen_dir = (); | 
| 1051 |  |  |  |  |  |  |  | 
| 1052 |  |  |  |  |  |  | my @PERL_ENV_LIB = split $Config{path_sep}, defined $ENV{'PERL5LIB'} | 
| 1053 | 8 | 50 | 0 |  |  | 660 | ? $ENV{'PERL5LIB'} : $ENV{'PERLLIB'} || ''; | 
| 1054 |  |  |  |  |  |  |  | 
| 1055 |  |  |  |  |  |  | my @dirs=( @PERL_ENV_LIB, | 
| 1056 |  |  |  |  |  |  | @INC, | 
| 1057 | 8 |  |  |  |  | 470 | @Config{qw(archlibexp | 
| 1058 |  |  |  |  |  |  | privlibexp | 
| 1059 |  |  |  |  |  |  | sitearchexp | 
| 1060 |  |  |  |  |  |  | sitelibexp)}); | 
| 1061 |  |  |  |  |  |  |  | 
| 1062 |  |  |  |  |  |  | #warn join "\n","---",@dirs,"---"; | 
| 1063 | 8 |  |  |  |  | 45 | my $seen_ours; | 
| 1064 | 8 |  |  |  |  | 71 | foreach $dir ( @dirs ) { | 
| 1065 | 64 |  |  |  |  | 321 | my $canonpath = _Is_VMS ? $dir : File::Spec->canonpath($dir); | 
| 1066 | 64 | 100 |  |  |  | 179 | next if $canonpath eq $Curdir; | 
| 1067 | 62 | 100 |  |  |  | 366 | next if $seen_dir{$canonpath}++; | 
| 1068 | 44 |  |  |  |  | 431 | my $targetfile = File::Spec->catfile($canonpath,$libdir,$file); | 
| 1069 | 44 | 100 |  |  |  | 1312 | next unless -f $targetfile; | 
| 1070 |  |  |  |  |  |  |  | 
| 1071 |  |  |  |  |  |  | # The reason why we compare file's contents is, that we cannot | 
| 1072 |  |  |  |  |  |  | # know, which is the file we just installed (AFS). So we leave | 
| 1073 |  |  |  |  |  |  | # an identical file in place | 
| 1074 | 10 |  |  |  |  | 42 | my $diff = _compare($filepath,$targetfile); | 
| 1075 |  |  |  |  |  |  |  | 
| 1076 | 10 | 50 | 66 |  |  | 901 | print "#$file and $targetfile differ\n" if $diff && $verbose > 1; | 
| 1077 |  |  |  |  |  |  |  | 
| 1078 | 10 | 100 | 66 |  |  | 96 | if (!$diff or $targetfile eq $ignore) { | 
| 1079 | 4 |  |  |  |  | 14 | $seen_ours = 1; | 
| 1080 | 4 |  |  |  |  | 18 | next; | 
| 1081 |  |  |  |  |  |  | } | 
| 1082 | 6 | 50 |  |  |  | 47 | if ($dry_run) { | 
| 1083 | 0 |  |  |  |  | 0 | $results->{uninstall}{$targetfile} = $filepath; | 
| 1084 | 0 | 0 |  |  |  | 0 | if ($verbose) { | 
| 1085 | 0 |  | 0 |  |  | 0 | $Inc_uninstall_warn_handler ||= ExtUtils::Install::Warn->new(); | 
| 1086 | 0 |  |  |  |  | 0 | $libdir =~ s|^\./||s ; # That's just cosmetics, no need to port. It looks prettier. | 
| 1087 | 0 |  |  |  |  | 0 | $Inc_uninstall_warn_handler->add( | 
| 1088 |  |  |  |  |  |  | File::Spec->catfile($libdir, $file), | 
| 1089 |  |  |  |  |  |  | $targetfile | 
| 1090 |  |  |  |  |  |  | ); | 
| 1091 |  |  |  |  |  |  | } | 
| 1092 |  |  |  |  |  |  | # if not verbose, we just say nothing | 
| 1093 |  |  |  |  |  |  | } else { | 
| 1094 | 6 | 50 |  |  |  | 37 | print "Unlinking $targetfile (shadowing?)\n" if $verbose; | 
| 1095 |  |  |  |  |  |  | eval { | 
| 1096 | 6 | 50 | 66 |  |  | 344 | die "Fake die for testing" | 
| 1097 |  |  |  |  |  |  | if $ExtUtils::Install::Testing and | 
| 1098 |  |  |  |  |  |  | ucase(File::Spec->canonpath($ExtUtils::Install::Testing)) eq ucase($targetfile); | 
| 1099 | 2 |  |  |  |  | 105 | forceunlink($targetfile,'tryhard'); | 
| 1100 | 2 |  |  |  |  | 34 | $results->{uninstall}{$targetfile} = $filepath; | 
| 1101 | 2 |  |  |  |  | 42 | 1; | 
| 1102 | 6 | 100 |  |  |  | 29 | } or do { | 
| 1103 | 4 |  |  |  |  | 72 | $results->{fail_uninstall}{$targetfile} = $filepath; | 
| 1104 | 4 | 100 |  |  |  | 36 | if ($seen_ours) { | 
| 1105 | 2 |  |  |  |  | 82 | warn "Failed to remove probably harmless shadow file '$targetfile'\n"; | 
| 1106 |  |  |  |  |  |  | } else { | 
| 1107 | 2 |  |  |  |  | 153 | die "$@\n"; | 
| 1108 |  |  |  |  |  |  | } | 
| 1109 |  |  |  |  |  |  | }; | 
| 1110 |  |  |  |  |  |  | } | 
| 1111 |  |  |  |  |  |  | } | 
| 1112 |  |  |  |  |  |  | } | 
| 1113 |  |  |  |  |  |  |  | 
| 1114 |  |  |  |  |  |  | =begin _undocumented | 
| 1115 |  |  |  |  |  |  |  | 
| 1116 |  |  |  |  |  |  | =head2 run_filter($cmd,$src,$dest) | 
| 1117 |  |  |  |  |  |  |  | 
| 1118 |  |  |  |  |  |  | Filter $src using $cmd into $dest. | 
| 1119 |  |  |  |  |  |  |  | 
| 1120 |  |  |  |  |  |  | =end _undocumented | 
| 1121 |  |  |  |  |  |  |  | 
| 1122 |  |  |  |  |  |  | =cut | 
| 1123 |  |  |  |  |  |  |  | 
| 1124 |  |  |  |  |  |  | sub run_filter { | 
| 1125 | 0 |  |  | 0 | 1 | 0 | my ($cmd, $src, $dest) = @_; | 
| 1126 | 0 |  |  |  |  | 0 | local(*CMD, *SRC); | 
| 1127 | 0 | 0 |  |  |  | 0 | open(CMD, "|$cmd >$dest") || die "Cannot fork: $!"; | 
| 1128 | 0 | 0 |  |  |  | 0 | open(SRC, $src)           || die "Cannot open $src: $!"; | 
| 1129 | 0 |  |  |  |  | 0 | my $buf; | 
| 1130 | 0 |  |  |  |  | 0 | my $sz = 1024; | 
| 1131 | 0 |  |  |  |  | 0 | while (my $len = sysread(SRC, $buf, $sz)) { | 
| 1132 | 0 |  |  |  |  | 0 | syswrite(CMD, $buf, $len); | 
| 1133 |  |  |  |  |  |  | } | 
| 1134 | 0 |  |  |  |  | 0 | close SRC; | 
| 1135 | 0 | 0 |  |  |  | 0 | close CMD or die "Filter command '$cmd' failed for $src"; | 
| 1136 |  |  |  |  |  |  | } | 
| 1137 |  |  |  |  |  |  |  | 
| 1138 |  |  |  |  |  |  | =head2 pm_to_blib | 
| 1139 |  |  |  |  |  |  |  | 
| 1140 |  |  |  |  |  |  | pm_to_blib(\%from_to); | 
| 1141 |  |  |  |  |  |  | pm_to_blib(\%from_to, $autosplit_dir); | 
| 1142 |  |  |  |  |  |  | pm_to_blib(\%from_to, $autosplit_dir, $filter_cmd); | 
| 1143 |  |  |  |  |  |  |  | 
| 1144 |  |  |  |  |  |  | Copies each key of %from_to to its corresponding value efficiently. | 
| 1145 |  |  |  |  |  |  | If an $autosplit_dir is provided, all .pm files will be autosplit into it. | 
| 1146 |  |  |  |  |  |  | Any destination directories are created. | 
| 1147 |  |  |  |  |  |  |  | 
| 1148 |  |  |  |  |  |  | $filter_cmd is an optional shell command to run each .pm file through | 
| 1149 |  |  |  |  |  |  | prior to splitting and copying.  Input is the contents of the module, | 
| 1150 |  |  |  |  |  |  | output the new module contents. | 
| 1151 |  |  |  |  |  |  |  | 
| 1152 |  |  |  |  |  |  | You can have an environment variable PERL_INSTALL_ROOT set which will | 
| 1153 |  |  |  |  |  |  | be prepended as a directory to each installed file (and directory). | 
| 1154 |  |  |  |  |  |  |  | 
| 1155 |  |  |  |  |  |  | By default verbose output is generated, setting the PERL_INSTALL_QUIET | 
| 1156 |  |  |  |  |  |  | environment variable will silence this output. | 
| 1157 |  |  |  |  |  |  |  | 
| 1158 |  |  |  |  |  |  | =cut | 
| 1159 |  |  |  |  |  |  |  | 
| 1160 |  |  |  |  |  |  | sub pm_to_blib { | 
| 1161 | 6 |  |  | 6 | 1 | 17830 | my($fromto,$autodir,$pm_filter) = @_; | 
| 1162 |  |  |  |  |  |  |  | 
| 1163 | 6 |  |  |  |  | 30 | my %dirs; | 
| 1164 | 6 | 100 |  |  |  | 34 | _mkpath($autodir,0,0755) if defined $autodir; | 
| 1165 | 6 |  |  |  |  | 42 | while(my($from, $to) = each %$fromto) { | 
| 1166 | 6 | 50 | 66 |  |  | 300 | if( -f $to && -s $from == -s $to && -M $to < -M $from ) { | 
|  |  |  | 66 |  |  |  |  | 
| 1167 | 0 | 0 |  |  |  | 0 | print "Skip $to (unchanged)\n" unless $INSTALL_QUIET; | 
| 1168 | 0 |  |  |  |  | 0 | next; | 
| 1169 |  |  |  |  |  |  | } | 
| 1170 |  |  |  |  |  |  |  | 
| 1171 |  |  |  |  |  |  | # When a pm_filter is defined, we need to pre-process the source first | 
| 1172 |  |  |  |  |  |  | # to determine whether it has changed or not.  Therefore, only perform | 
| 1173 |  |  |  |  |  |  | # the comparison check when there's no filter to be ran. | 
| 1174 |  |  |  |  |  |  | #    -- RAM, 03/01/2001 | 
| 1175 |  |  |  |  |  |  |  | 
| 1176 | 6 |  | 33 |  |  | 36 | my $need_filtering = defined $pm_filter && length $pm_filter && | 
| 1177 |  |  |  |  |  |  | $from =~ /\.pm$/; | 
| 1178 |  |  |  |  |  |  |  | 
| 1179 | 6 | 100 | 66 |  |  | 36 | if (!$need_filtering && !_compare($from,$to)) { | 
| 1180 | 3 | 50 |  |  |  | 651 | print "Skip $to (unchanged)\n" unless $INSTALL_QUIET; | 
| 1181 | 3 |  |  |  |  | 40 | next; | 
| 1182 |  |  |  |  |  |  | } | 
| 1183 | 3 | 50 |  |  |  | 37 | if (-f $to){ | 
| 1184 |  |  |  |  |  |  | # we wont try hard here. its too likely to mess things up. | 
| 1185 | 0 |  |  |  |  | 0 | forceunlink($to); | 
| 1186 |  |  |  |  |  |  | } else { | 
| 1187 | 3 |  |  |  |  | 112 | my $dirname = dirname($to); | 
| 1188 | 3 | 50 |  |  |  | 26 | if (!$dirs{$dirname}++) { | 
| 1189 | 3 |  |  |  |  | 12 | _mkpath($dirname,0,0755); | 
| 1190 |  |  |  |  |  |  | } | 
| 1191 |  |  |  |  |  |  | } | 
| 1192 | 3 | 50 |  |  |  | 17 | if ($need_filtering) { | 
| 1193 | 0 |  |  |  |  | 0 | run_filter($pm_filter, $from, $to); | 
| 1194 | 0 |  |  |  |  | 0 | print "$pm_filter <$from >$to\n"; | 
| 1195 |  |  |  |  |  |  | } else { | 
| 1196 | 3 |  |  |  |  | 14 | _copy( $from, $to ); | 
| 1197 | 3 | 50 |  |  |  | 1115 | print "cp $from $to\n" unless $INSTALL_QUIET; | 
| 1198 |  |  |  |  |  |  | } | 
| 1199 | 3 |  |  |  |  | 91 | my($mode,$atime,$mtime) = (stat $from)[2,8,9]; | 
| 1200 | 3 |  |  |  |  | 53 | utime($atime,$mtime+_Is_VMS,$to); | 
| 1201 | 3 | 50 |  |  |  | 32 | _chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$to); | 
| 1202 | 3 | 50 |  |  |  | 46 | next unless $from =~ /\.pm$/; | 
| 1203 | 3 | 50 |  |  |  | 18 | _autosplit($to,$autodir) if defined $autodir; | 
| 1204 |  |  |  |  |  |  | } | 
| 1205 |  |  |  |  |  |  | } | 
| 1206 |  |  |  |  |  |  |  | 
| 1207 |  |  |  |  |  |  | =begin _private | 
| 1208 |  |  |  |  |  |  |  | 
| 1209 |  |  |  |  |  |  | =head2 _autosplit | 
| 1210 |  |  |  |  |  |  |  | 
| 1211 |  |  |  |  |  |  | From 1.0307 back, AutoSplit will sometimes leave an open filehandle to | 
| 1212 |  |  |  |  |  |  | the file being split.  This causes problems on systems with mandatory | 
| 1213 |  |  |  |  |  |  | locking (ie. Windows).  So we wrap it and close the filehandle. | 
| 1214 |  |  |  |  |  |  |  | 
| 1215 |  |  |  |  |  |  | =end _private | 
| 1216 |  |  |  |  |  |  |  | 
| 1217 |  |  |  |  |  |  | =cut | 
| 1218 |  |  |  |  |  |  |  | 
| 1219 |  |  |  |  |  |  | sub _autosplit { #XXX OS-SPECIFIC | 
| 1220 | 3 |  |  | 3 |  | 1267 | require AutoSplit; | 
| 1221 | 3 |  |  |  |  | 10129 | my $retval = AutoSplit::autosplit(@_); | 
| 1222 | 3 | 50 |  |  |  | 2042 | close *AutoSplit::IN if defined *AutoSplit::IN{IO}; | 
| 1223 |  |  |  |  |  |  |  | 
| 1224 | 3 |  |  |  |  | 25 | return $retval; | 
| 1225 |  |  |  |  |  |  | } | 
| 1226 |  |  |  |  |  |  |  | 
| 1227 |  |  |  |  |  |  |  | 
| 1228 |  |  |  |  |  |  | package ExtUtils::Install::Warn; | 
| 1229 |  |  |  |  |  |  |  | 
| 1230 | 0 |  |  | 0 |  |  | sub new { bless {}, shift } | 
| 1231 |  |  |  |  |  |  |  | 
| 1232 |  |  |  |  |  |  | sub add { | 
| 1233 | 0 |  |  | 0 |  |  | my($self,$file,$targetfile) = @_; | 
| 1234 | 0 |  |  |  |  |  | push @{$self->{$file}}, $targetfile; | 
|  | 0 |  |  |  |  |  |  | 
| 1235 |  |  |  |  |  |  | } | 
| 1236 |  |  |  |  |  |  |  | 
| 1237 |  |  |  |  |  |  | sub DESTROY { | 
| 1238 | 0 | 0 |  | 0 |  |  | unless(defined $INSTALL_ROOT) { | 
| 1239 | 0 |  |  |  |  |  | my $self = shift; | 
| 1240 | 0 |  |  |  |  |  | my($file,$i,$plural); | 
| 1241 | 0 |  |  |  |  |  | foreach $file (sort keys %$self) { | 
| 1242 | 0 | 0 |  |  |  |  | $plural = @{$self->{$file}} > 1 ? "s" : ""; | 
|  | 0 |  |  |  |  |  |  | 
| 1243 | 0 |  |  |  |  |  | print "## Differing version$plural of $file found. You might like to\n"; | 
| 1244 | 0 |  |  |  |  |  | for (0..$#{$self->{$file}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 1245 | 0 |  |  |  |  |  | print "rm ", $self->{$file}[$_], "\n"; | 
| 1246 | 0 |  |  |  |  |  | $i++; | 
| 1247 |  |  |  |  |  |  | } | 
| 1248 |  |  |  |  |  |  | } | 
| 1249 | 0 | 0 |  |  |  |  | $plural = $i>1 ? "all those files" : "this file"; | 
| 1250 |  |  |  |  |  |  | my $inst = (_invokant() eq 'ExtUtils::MakeMaker') | 
| 1251 | 0 | 0 | 0 |  |  |  | ? ( $Config::Config{make} || 'make' ).' install' | 
| 1252 |  |  |  |  |  |  | . ( ExtUtils::Install::_Is_VMS ? '/MACRO="UNINST"=1' : ' UNINST=1' ) | 
| 1253 |  |  |  |  |  |  | : './Build install uninst=1'; | 
| 1254 | 0 |  |  |  |  |  | print "## Running '$inst' will unlink $plural for you.\n"; | 
| 1255 |  |  |  |  |  |  | } | 
| 1256 |  |  |  |  |  |  | } | 
| 1257 |  |  |  |  |  |  |  | 
| 1258 |  |  |  |  |  |  | =begin _private | 
| 1259 |  |  |  |  |  |  |  | 
| 1260 |  |  |  |  |  |  | =head2 _invokant | 
| 1261 |  |  |  |  |  |  |  | 
| 1262 |  |  |  |  |  |  | Does a heuristic on the stack to see who called us for more intelligent | 
| 1263 |  |  |  |  |  |  | error messages. Currently assumes we will be called only by Module::Build | 
| 1264 |  |  |  |  |  |  | or by ExtUtils::MakeMaker. | 
| 1265 |  |  |  |  |  |  |  | 
| 1266 |  |  |  |  |  |  | =end _private | 
| 1267 |  |  |  |  |  |  |  | 
| 1268 |  |  |  |  |  |  | =cut | 
| 1269 |  |  |  |  |  |  |  | 
| 1270 |  |  |  |  |  |  | sub _invokant { | 
| 1271 | 0 |  |  | 0 |  |  | my @stack; | 
| 1272 | 0 |  |  |  |  |  | my $frame = 0; | 
| 1273 | 0 |  |  |  |  |  | while (my $file = (caller($frame++))[1]) { | 
| 1274 | 0 |  |  |  |  |  | push @stack, (File::Spec->splitpath($file))[2]; | 
| 1275 |  |  |  |  |  |  | } | 
| 1276 |  |  |  |  |  |  |  | 
| 1277 | 0 |  |  |  |  |  | my $builder; | 
| 1278 | 0 |  |  |  |  |  | my $top = pop @stack; | 
| 1279 | 0 | 0 | 0 |  |  |  | if ($top =~ /^Build/i || exists($INC{'Module/Build.pm'})) { | 
| 1280 | 0 |  |  |  |  |  | $builder = 'Module::Build'; | 
| 1281 |  |  |  |  |  |  | } else { | 
| 1282 | 0 |  |  |  |  |  | $builder = 'ExtUtils::MakeMaker'; | 
| 1283 |  |  |  |  |  |  | } | 
| 1284 | 0 |  |  |  |  |  | return $builder; | 
| 1285 |  |  |  |  |  |  | } | 
| 1286 |  |  |  |  |  |  |  | 
| 1287 |  |  |  |  |  |  | =head1 ENVIRONMENT | 
| 1288 |  |  |  |  |  |  |  | 
| 1289 |  |  |  |  |  |  | =over 4 | 
| 1290 |  |  |  |  |  |  |  | 
| 1291 |  |  |  |  |  |  | =item B | 
| 1292 |  |  |  |  |  |  |  | 
| 1293 |  |  |  |  |  |  | Will be prepended to each install path. | 
| 1294 |  |  |  |  |  |  |  | 
| 1295 |  |  |  |  |  |  | =item B | 
| 1296 |  |  |  |  |  |  |  | 
| 1297 |  |  |  |  |  |  | Will prevent the automatic use of INSTALL.SKIP as the install skip file. | 
| 1298 |  |  |  |  |  |  |  | 
| 1299 |  |  |  |  |  |  | =item B | 
| 1300 |  |  |  |  |  |  |  | 
| 1301 |  |  |  |  |  |  | If there is no INSTALL.SKIP file in the make directory then this value | 
| 1302 |  |  |  |  |  |  | can be used to provide a default. | 
| 1303 |  |  |  |  |  |  |  | 
| 1304 |  |  |  |  |  |  | =item B | 
| 1305 |  |  |  |  |  |  |  | 
| 1306 |  |  |  |  |  |  | If this environment variable is true then normal install processes will | 
| 1307 |  |  |  |  |  |  | always overwrite older identical files during the install process. | 
| 1308 |  |  |  |  |  |  |  | 
| 1309 |  |  |  |  |  |  | Note that the alias EU_ALWAYS_COPY will be supported if EU_INSTALL_ALWAYS_COPY | 
| 1310 |  |  |  |  |  |  | is not defined until at least the 1.50 release. Please ensure you use the | 
| 1311 |  |  |  |  |  |  | correct EU_INSTALL_ALWAYS_COPY. | 
| 1312 |  |  |  |  |  |  |  | 
| 1313 |  |  |  |  |  |  | =back | 
| 1314 |  |  |  |  |  |  |  | 
| 1315 |  |  |  |  |  |  | =head1 AUTHOR | 
| 1316 |  |  |  |  |  |  |  | 
| 1317 |  |  |  |  |  |  | Original author lost in the mists of time.  Probably the same as Makemaker. | 
| 1318 |  |  |  |  |  |  |  | 
| 1319 |  |  |  |  |  |  | Production release currently maintained by demerphq C, | 
| 1320 |  |  |  |  |  |  | extensive changes by Michael G. Schwern. | 
| 1321 |  |  |  |  |  |  |  | 
| 1322 |  |  |  |  |  |  | Send bug reports via http://rt.cpan.org/.  Please send your | 
| 1323 |  |  |  |  |  |  | generated Makefile along with your report. | 
| 1324 |  |  |  |  |  |  |  | 
| 1325 |  |  |  |  |  |  | =head1 LICENSE | 
| 1326 |  |  |  |  |  |  |  | 
| 1327 |  |  |  |  |  |  | This program is free software; you can redistribute it and/or | 
| 1328 |  |  |  |  |  |  | modify it under the same terms as Perl itself. | 
| 1329 |  |  |  |  |  |  |  | 
| 1330 |  |  |  |  |  |  | See L | 
| 1331 |  |  |  |  |  |  |  | 
| 1332 |  |  |  |  |  |  |  | 
| 1333 |  |  |  |  |  |  | =cut | 
| 1334 |  |  |  |  |  |  |  | 
| 1335 |  |  |  |  |  |  | 1; |