A great reply, shmem, IMHO
Here's my present workaround based on shmem's suggestion above.
Only the install sub
from ExtUtils::Install is shown (it is the only place in the module file where (at present) any
changes have been made). I'll post a link to a network URI where a patch can be fetched
in a later update.
sub install {
my($from_to,$verbose,$nonono,$inc_uninstall) = @_;
$verbose ||= 0;
$nonono ||= 0;
my $bootstrapped = eval 'use Filesys::Type 0.02 (qw|fstype|); 1;';
+ # CPAN
my $no_colons_in_basenames;
my @DOSish_FSTs = qw(msdos umsdos vfat ntfs iso9660 smb FAT FAT32
+CDFS NTFS);
=for COMMENTARY
# Types of fs that can be returned by Filesys::Type::fstype would
+have been nice
# to have access to without breaking into the module's encapsula
+tion. (this is IMHO
# nonoptimal design; these could/should have been exportable fro
+m the module).
=cut
use Cwd qw(cwd);
use ExtUtils::Packlist;
use File::Basename qw(dirname);
use File::Copy qw(copy);
use File::Find qw(find);
use File::Path qw(mkpath);
use File::Compare qw(compare);
my(%from_to) = %$from_to;
my(%pack, $dir, $warn_permissions);
my($packlist) = ExtUtils::Packlist->new();
# -w doesn't work reliably on FAT dirs
# UHH, FAT-type filesystems can be found on other than MSWin32 OS'
+s. Huh? XXX
$warn_permissions++ if $^O eq 'MSWin32';
local(*DIR);
for (qw/read write/) {
$pack{$_}=$from_to{$_};
delete $from_to{$_};
}
my($source_dir_or_file);
foreach $source_dir_or_file (sort keys %from_to) {
#Check if there are files, and if yes, look if the corresponding
#target directory is writable for us
opendir DIR, $source_dir_or_file or next;
for (readdir DIR) {
next if $_ eq $Curdir || $_ eq $Updir || $_ eq ".exists";
my $targetdir = install_rooted_dir($from_to{$source_dir_or
+_file});
++$no_colons_in_basenames if grep(fstype($targetdir) eq $_
+ , @DOSish_FSTs);
mkpath($targetdir) unless $nonono;
if (!$nonono && !-w $targetdir) {
warn "Warning: You do not have permissions to " .
"install into $from_to{$source_dir_or_file}"
unless $warn_permissions++;
}
}
closedir DIR;
}
my $tmpfile = install_rooted_file($pack{"read"});
$packlist->read($tmpfile) if (-f $tmpfile);
my $cwd = cwd();
MOD_INSTALL: foreach my $source (sort keys %from_to) {
#copy the tree to the target directory without altering
#timestamp and permission and remember for the .packlist
#file. The packlist file contains the absolute paths of the
#install locations. AFS users may call this a bug. We'll have
#to reconsider how to add the means to satisfy AFS users also.
#October 1997: we want to install .pm files into archlib if
#there are any files in arch. So we depend on having ./blib/arch
#hardcoded here.
my $targetroot = install_rooted_dir($from_to{$source});
my $blib_lib = File::Spec->catdir('blib', 'lib');
my $blib_arch = File::Spec->catdir('blib', 'arch');
if ($source eq $blib_lib and
exists $from_to{$blib_arch} and
directory_not_empty($blib_arch)) {
$targetroot = install_rooted_dir($from_to{$blib_arch});
print "Some files found in $blib_arch: we shall therefore
+be "
. "installing files in $blib_lib into the architecture
+ dependent "
. "library tree\n";
}
chdir $source or next;
find(sub {
my ($mode,$size,$atime,$mtime) = (stat)[2,7,8,9];
return unless -f _;
my $origfile = $_;
return if $origfile eq ".exists";
my $targetdir = File::Spec->catdir($targetroot, $File::Find::
+dir);
my $targetfile = File::Spec->catfile($targetdir, $origfile);
my $sourcedir = File::Spec->catdir($source, $File::Find::
+dir);
my $sourcefile = File::Spec->catfile($sourcedir, $origfile
+);
# Cope with installation of man files to FAT type filesyst
+ems (could
# be installing to removable media formatted as vfat/FAT32
+ from a
# UNIX OS, like GNU/Linux or Cygwin or *BSD, for example).
if($sourcedir =~ m{ blib/man[31] }x and $no_colons_in_base
+names) {
my $formername = $targetfile;
$targetfile =~s{::} {.}g;
warn qq|INFO: "$formername"\n => "$targetfile"\n|
, qq|for writing to the target location which is a|
, (' '.fstype($targetdir))
, qq| filesystem (no colons allowed).\n|;
}
my $save_cwd = cwd;
chdir $cwd; # in case the target is relative
# 5.5.3's File::Find missing no_chdir option.
my $diff = 0;
if ( -f $targetfile && -s _ == $size) {
# We have a good chance, we can skip this one
$diff = compare($sourcefile, $targetfile);
} else {
print "$sourcefile differs\n" if $verbose>1;
$diff++;
}
if ($diff){
if (-f $targetfile){
forceunlink($targetfile) unless $nonono;
} else {
mkpath($targetdir) unless $nonono;
print "mkpath($targetdir)\n" if $verbose>1;
}
copy($sourcefile, $targetfile) unless $nonono;
print "Installing $targetfile\n";
utime($atime,$mtime + $Is_VMS,$targetfile) unless $nonono>1;
print "utime($atime,$mtime,$targetfile)\n" if $verbose>1;
$mode = 0444 | ( $mode & 0111 ? 0111 : 0 );
chmod $mode, $targetfile;
print "chmod($mode, $targetfile)\n" if $verbose>1;
} else {
print "Skipping $targetfile (unchanged)\n" if $verbose;
}
if (defined $inc_uninstall) {
inc_uninstall($sourcefile,$File::Find::dir,$verbose,
$inc_uninstall ? 0 : 1);
}
# Record the full pathname.
$packlist->{$targetfile}++;
# File::Find can get confused if you chdir in here.
chdir $save_cwd;
# File::Find seems to always be Unixy except on MacPerl :(
}, $Is_MacPerl ? $Curdir : '.' );
chdir($cwd) or Carp::croak("Couldn't chdir to $cwd: $!");
}
$no_colons_in_basenames = undef; # XXX ?
if ($pack{'write'}) {
$dir = install_rooted_dir(dirname($pack{'write'}));
mkpath($dir,0,0755) unless $nonono;
print "Writing $pack{'write'}\n";
$packlist->write(install_rooted_file($pack{'write'})) unless $nono
+no;
}
}
Soren A / somian / perlspinr / Intrepid
--
Words can be slippery, so consider who speaks as well as
what is said;
know as much as you can about the total context of the speaker's
participation in a forum over time, before deciding that you fully
comprehend the intention behind those words. If in doubt, ask
for clarification before you 'flame'.