$VERSION
=
substr
q$Revision: 1.28 $
, 10;
use
vars
qw(@ISA @EXPORT $VERSION)
;
@ISA
= (
'Exporter'
);
@EXPORT
= (
'install'
,
'uninstall'
,
'pm_to_blib'
,
'install_default'
);
$Is_VMS
= $^O eq
'VMS'
;
my
$splitchar
= $^O eq
'VMS'
?
'|'
: ($^O eq
'os2'
|| $^O eq
'dos'
) ?
';'
:
':'
;
my
@PERL_ENV_LIB
=
split
$splitchar
,
defined
$ENV
{
'PERL5LIB'
} ?
$ENV
{
'PERL5LIB'
} :
$ENV
{
'PERLLIB'
} ||
''
;
my
$Inc_uninstall_warn_handler
;
sub
forceunlink {
chmod
0666,
$_
[0];
unlink
$_
[0] or Carp::croak(
"Cannot forceunlink $_[0]: $!"
)
}
sub
install {
my
(
$hash
,
$verbose
,
$nonono
,
$inc_uninstall
) =
@_
;
$verbose
||= 0;
$nonono
||= 0;
my
(
%hash
) =
%$hash
;
my
(
%pack
,
$dir
,
$warn_permissions
);
my
(
$packlist
) = ExtUtils::Packlist->new();
$warn_permissions
++
if
$^O eq
'MSWin32'
;
local
(
*DIR
);
for
(
qw/read write/
) {
$pack
{
$_
}=
$hash
{
$_
};
delete
$hash
{
$_
};
}
my
(
$source_dir_or_file
);
foreach
$source_dir_or_file
(
sort
keys
%hash
) {
opendir
DIR,
$source_dir_or_file
or
next
;
for
(
readdir
DIR) {
next
if
$_
eq
"."
||
$_
eq
".."
||
$_
eq
".exists"
;
if
(-w
$hash
{
$source_dir_or_file
} ||
mkpath(
$hash
{
$source_dir_or_file
})) {
last
;
}
else
{
warn
"Warning: You do not have permissions to "
.
"install into $hash{$source_dir_or_file}"
unless
$warn_permissions
++;
}
}
closedir
DIR;
}
$packlist
->
read
(
$pack
{
"read"
})
if
(-f
$pack
{
"read"
});
my
$cwd
= cwd();
my
$umask
=
umask
0
unless
$Is_VMS
;
my
(
$source
);
MOD_INSTALL:
foreach
$source
(
sort
keys
%hash
) {
my
$targetroot
=
$hash
{
$source
};
if
(
$source
eq
"blib/lib"
and
exists
$hash
{
"blib/arch"
} and
directory_not_empty(
"blib/arch"
)) {
$targetroot
=
$hash
{
"blib/arch"
};
print
"Files found in blib/arch --> Installing files in "
.
"blib/lib into architecture dependend library tree!\n"
;
}
chdir
(
$source
) or
next
;
find(
sub
{
my
(
$dev
,
$ino
,
$mode
,
$nlink
,
$uid
,
$gid
,
$rdev
,
$size
,
$atime
,
$mtime
,
$ctime
,
$blksize
,
$blocks
) =
stat
;
return
unless
-f _;
return
if
$_
eq
".exists"
;
my
$targetdir
= MY->catdir(
$targetroot
,
$File::Find::dir
);
my
$targetfile
= MY->catfile(
$targetdir
,
$_
);
my
$diff
= 0;
if
( -f
$targetfile
&& -s _ ==
$size
) {
$diff
= compare(
$_
,
$targetfile
);
}
else
{
print
"$_ differs\n"
if
$verbose
>1;
$diff
++;
}
if
(
$diff
){
if
(-f
$targetfile
){
forceunlink(
$targetfile
)
unless
$nonono
;
}
else
{
mkpath(
$targetdir
,0,0755)
unless
$nonono
;
print
"mkpath($targetdir,0,0755)\n"
if
$verbose
>1;
}
copy(
$_
,
$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
) {
}
elsif
(
$inc_uninstall
== 0){
inc_uninstall(
$_
,
$File::Find::dir
,
$verbose
,1);
}
else
{
inc_uninstall(
$_
,
$File::Find::dir
,
$verbose
,0);
}
$packlist
->{
$targetfile
}++;
},
"."
);
chdir
(
$cwd
) or Carp::croak(
"Couldn't chdir to $cwd: $!"
);
}
umask
$umask
unless
$Is_VMS
;
if
(
$pack
{
'write'
}) {
$dir
= dirname(
$pack
{
'write'
});
mkpath(
$dir
,0,0755);
print
"Writing $pack{'write'}\n"
;
$packlist
->
write
(
$pack
{
'write'
});
}
}
sub
directory_not_empty ($) {
my
(
$dir
) =
@_
;
my
$files
= 0;
find(
sub
{
return
if
$_
eq
".exists"
;
if
(-f) {
$File::Find::prune
++;
$files
= 1;
}
},
$dir
);
return
$files
;
}
sub
install_default {
@_
< 2 or
die
"install_default should be called with 0 or 1 argument"
;
my
$FULLEXT
=
@_
?
shift
:
$ARGV
[0];
defined
$FULLEXT
or
die
"Do not know to where to write install log"
;
my
$INST_LIB
= MM->catdir(MM->curdir,
"blib"
,
"lib"
);
my
$INST_ARCHLIB
= MM->catdir(MM->curdir,
"blib"
,
"arch"
);
my
$INST_BIN
= MM->catdir(MM->curdir,
'blib'
,
'bin'
);
my
$INST_SCRIPT
= MM->catdir(MM->curdir,
'blib'
,
'script'
);
my
$INST_MAN1DIR
= MM->catdir(MM->curdir,
'blib'
,
'man1'
);
my
$INST_MAN3DIR
= MM->catdir(MM->curdir,
'blib'
,
'man3'
);
install({
read
=>
"$Config{sitearchexp}/auto/$FULLEXT/.packlist"
,
write
=>
"$Config{installsitearch}/auto/$FULLEXT/.packlist"
,
$INST_LIB
=> (directory_not_empty(
$INST_ARCHLIB
)) ?
$Config
{installsitearch} :
$Config
{installsitelib},
$INST_ARCHLIB
=>
$Config
{installsitearch},
$INST_BIN
=>
$Config
{installbin} ,
$INST_SCRIPT
=>
$Config
{installscript},
$INST_MAN1DIR
=>
$Config
{installman1dir},
$INST_MAN3DIR
=>
$Config
{installman3dir},
},1,0,0);
}
sub
uninstall {
my
(
$fil
,
$verbose
,
$nonono
) =
@_
;
die
"no packlist file found: $fil"
unless
-f
$fil
;
my
(
$packlist
) = ExtUtils::Packlist->new(
$fil
);
foreach
(
sort
(
keys
(
%$packlist
))) {
chomp
;
print
"unlink $_\n"
if
$verbose
;
forceunlink(
$_
)
unless
$nonono
;
}
print
"unlink $fil\n"
if
$verbose
;
close
P;
forceunlink(
$fil
)
unless
$nonono
;
}
sub
inc_uninstall {
my
(
$file
,
$libdir
,
$verbose
,
$nonono
) =
@_
;
my
(
$dir
);
my
%seen_dir
= ();
foreach
$dir
(
@INC
,
@PERL_ENV_LIB
,
@Config
{
qw(archlibexp
privlibexp
sitearchexp
sitelibexp)
}) {
next
if
$dir
eq
"."
;
next
if
$seen_dir
{
$dir
}++;
my
(
$targetfile
) = MY->catfile(
$dir
,
$libdir
,
$file
);
next
unless
-f
$targetfile
;
my
$diff
= 0;
if
( -f
$targetfile
&& -s _ == -s
$file
) {
$diff
= compare(
$file
,
$targetfile
);
}
else
{
print
"#$file and $targetfile differ\n"
if
$verbose
>1;
$diff
++;
}
next
unless
$diff
;
if
(
$nonono
) {
if
(
$verbose
) {
$Inc_uninstall_warn_handler
||= new ExtUtils::Install::Warn;
$libdir
=~ s|^\./|| ;
$Inc_uninstall_warn_handler
->add(
"$libdir/$file"
,
$targetfile
);
}
}
else
{
print
"Unlinking $targetfile (shadowing?)\n"
;
forceunlink(
$targetfile
);
}
}
}
sub
pm_to_blib {
my
(
$fromto
,
$autodir
) =
@_
;
if
(!
ref
(
$fromto
) && -r
$fromto
)
{
open
(FROMTO,
"<$fromto"
) or
die
"Cannot open $fromto:$!"
;
my
$str
=
'$fromto = {qw{'
.
join
(
''
,<FROMTO>).
'}}'
;
eval
$str
;
close
(FROMTO);
}
my
$umask
=
umask
0022
unless
$Is_VMS
;
mkpath(
$autodir
,0,0755);
foreach
(
keys
%$fromto
) {
next
if
-f
$fromto
->{
$_
} && -M
$fromto
->{
$_
} < -M
$_
;
unless
(compare(
$_
,
$fromto
->{
$_
})){
print
"Skip $fromto->{$_} (unchanged)\n"
;
next
;
}
if
(-f
$fromto
->{
$_
}){
forceunlink(
$fromto
->{
$_
});
}
else
{
mkpath(dirname(
$fromto
->{
$_
}),0,0755);
}
copy(
$_
,
$fromto
->{
$_
});
my
(
$mode
,
$atime
,
$mtime
) = (
stat
)[2,8,9];
utime
(
$atime
,
$mtime
+
$Is_VMS
,
$fromto
->{
$_
});
chmod
(0444 | (
$mode
& 0111 ? 0111 : 0 ),
$fromto
->{
$_
});
print
"cp $_ $fromto->{$_}\n"
;
next
unless
/\.pm$/;
autosplit(
$fromto
->{
$_
},
$autodir
);
}
umask
$umask
unless
$Is_VMS
;
}
sub
new {
bless
{},
shift
}
sub
add {
my
(
$self
,
$file
,
$targetfile
) =
@_
;
push
@{
$self
->{
$file
}},
$targetfile
;
}
sub
DESTROY {
my
$self
=
shift
;
my
(
$file
,
$i
,
$plural
);
foreach
$file
(
sort
keys
%$self
) {
$plural
= @{
$self
->{
$file
}} > 1 ?
"s"
:
""
;
print
"## Differing version$plural of $file found. You might like to\n"
;
for
(0..$
print
"rm "
,
$self
->{
$file
}[
$_
],
"\n"
;
$i
++;
}
}
$plural
=
$i
>1 ?
"all those files"
:
"this file"
;
print
"## Running 'make install UNINST=1' will unlink $plural for you.\n"
;
}
1;