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