1#!./perl 2# $OpenBSD: installperl,v 1.6 1997/07/24 21:18:44 kstailey Exp $ 3# 4# This is hacked up, in order to support DESTDIR and INSTALL_STRIP. 5# 6 7BEGIN { 8 require 5.004; 9 @INC = 'lib'; 10 $ENV{PERL5LIB} = 'lib'; 11} 12 13use File::Find; 14use File::Compare; 15use File::Copy (); 16use File::Path (); 17use Config; 18use subs qw(unlink link chmod cmd); 19 20# override the ones in the rest of the script 21sub mkpath { 22 File::Path::mkpath(@_) unless $nonono; 23} 24 25$mainperldir = "/usr/bin"; 26$exe_ext = $Config{exe_ext}; 27 28while (@ARGV) { 29 $nonono = 1 if $ARGV[0] eq '-n'; 30 $versiononly = 1 if $ARGV[0] eq '-v'; 31 shift; 32} 33 34umask 022; 35 36@scripts = qw( utils/c2ph utils/h2ph utils/h2xs 37 utils/perlbug utils/perldoc utils/pl2pm utils/splain 38 x2p/s2p x2p/find2perl 39 pod/pod2man pod/pod2html pod/pod2latex pod/pod2text); 40 41@pods = (<pod/*.pod>); 42 43%archpms = (Config => 1, FileHandle => 1, overload => 1); 44find(sub { 45 if ("$File::Find::dir/$_" =~ m{^ext/[^/]+/(.*)\.pm$}) { 46 (my $pm = $1) =~ s{^lib/}{}; 47 $archpms{$pm} = 1; 48 } 49 }, 'ext'); 50 51$ver = $]; 52$release = substr($ver,0,3); # Not used presently. 53$patchlevel = substr($ver,3,2); 54die "Patchlevel of perl ($patchlevel)", 55 "and patchlevel of config.sh ($Config{'PATCHLEVEL'}) don't match\n" 56 if $patchlevel != $Config{'PATCHLEVEL'}; 57 58$installdest = $ENV{"DESTDIR"}; 59$installdest =~ s:/+$::; 60if ($installdest ne '') { 61 # Fetch some frequently-used items from %Config, prefixing with DESTDIR. 62 $installbin = "$installdest/$Config{installbin}"; 63 $installscript = "$installdest/$Config{installscript}"; 64 $installprivlib = "$installdest/$Config{installprivlib}"; 65 $installarchlib = "$installdest/$Config{installarchlib}"; 66 $installsitelib = "$installdest/$Config{installsitelib}"; 67 $installsitearch = "$installdest/$Config{installsitearch}"; 68 $installman1dir = "$installdest/$Config{installman1dir}"; 69 # Also whack $mainperldir. 70 $mainperldir = "$installdest/$mainperldir"; 71} else { 72 # Fetch some frequently-used items from %Config 73 $installbin = $Config{installbin}; 74 $installscript = $Config{installscript}; 75 $installprivlib = $Config{installprivlib}; 76 $installarchlib = $Config{installarchlib}; 77 $installsitelib = $Config{installsitelib}; 78 $installsitearch = $Config{installsitearch}; 79 $installman1dir = $Config{installman1dir}; 80} 81 82$man1ext = $Config{man1ext}; 83$libperl = $Config{libperl}; 84# Shared library and dynamic loading suffixes. 85$so = $Config{so}; 86$dlext = $Config{dlext}; 87 88$d_dosuid = $Config{d_dosuid}; 89$binexp = $Config{binexp}; 90 91# Do some quick sanity checks. 92 93if ($d_dosuid && $>) { die "You must run as root to install suidperl\n"; } 94 95 $installbin || die "No installbin directory in config.sh\n"; 96-d $installbin || mkpath($installbin, 1, 0777); 97-d $installbin || $nonono || die "$installbin is not a directory\n"; 98-w $installbin || $nonono || die "$installbin is not writable by you\n" 99 unless $installbin =~ m#^/afs/# || $nonono; 100 101-x 'perl' . $exe_ext || die "perl isn't executable!\n"; 102-x 'suidperl' . $exe_ext|| die "suidperl isn't executable!\n" if $d_dosuid; 103 104-x 't/TEST' || warn "WARNING: You've never run 'make test'!!!", 105 " (Installing anyway.)\n"; 106 107# First we install the version-numbered executables. 108 109if (defined($ENV{"INSTALL"})) { 110 $installcmd = $ENV{"INSTALL"} 111 . " " . $ENV{"INSTALL_COPY"} 112 . " " . $ENV{"INSTALL_STRIP"}; 113} else { 114 $installcmd = "cp"; 115} 116 117safe_unlink("$installbin/perl$ver$exe_ext"); 118cmd("$installcmd perl$exe_ext $installbin/perl$ver$exe_ext"); 119#copy("perl$exe_ext", "$installbin/perl$ver$exe_ext"); 120chmod(0755, "$installbin/perl$ver$exe_ext"); 121 122safe_unlink("$installbin/sperl$ver$exe_ext"); 123if ($d_dosuid) { 124 cmd("$installcmd suidperl$exe_ext $installbin/sperl$ver$exe_ext"); 125 #copy("suidperl$exe_ext", "$installbin/sperl$ver$exe_ext"); 126 chmod(04711, "$installbin/sperl$ver$exe_ext"); 127} 128 129# Install library files. 130 131$do_installarchlib = $do_installprivlib = 0; 132 133mkpath($installprivlib, 1, 0777); 134mkpath($installarchlib, 1, 0777); 135mkpath($installsitelib, 1, 0777) if ($installsitelib); 136mkpath($installsitearch, 1, 0777) if ($installsitearch); 137 138if (chdir "lib") { 139 $do_installarchlib = ! samepath($installarchlib, '.'); 140 $do_installprivlib = ! samepath($installprivlib, '.'); 141 $do_installprivlib = 0 if $versiononly && !($installprivlib =~ m/\Q$]/); 142 143 if ($do_installarchlib || $do_installprivlib) { 144 find(\&installlib, '.'); 145 } 146 chdir ".." || die "Can't cd back to source directory: $!\n"; 147} 148else { 149 warn "Can't cd to lib to install lib files: $!\n"; 150} 151 152# Install header files and libraries. 153mkpath("$installarchlib/CORE", 1, 0777); 154@corefiles = <*.h libperl*.*>; 155# AIX needs perl.exp installed as well. 156push(@corefiles,'perl.exp') if $^O eq 'aix'; 157# If they have built sperl.o... 158push(@corefiles,'sperl.o') if -f 'sperl.o'; 159foreach $file (@corefiles) { 160 # HP-UX (at least) needs to maintain execute permissions 161 # on dynamically-loadable libraries. So we do it for all. 162 copy_if_diff($file,"$installarchlib/CORE/$file") 163 and chmod($file =~ /\.(so|\Q$dlext\E)$/ ? 0555 : 0444, 164 "$installarchlib/CORE/$file"); 165} 166 167# Offer to install perl in a "standard" location 168 169$mainperl_is_instperl = 0; 170 171if (!$versiononly && !$nonono && -t STDIN && -t STDERR 172 && -w $mainperldir && ! samepath($mainperldir, $installbin)) { 173 local($usrbinperl) = "$mainperldir/perl$exe_ext"; 174 local($instperl) = "$installbin/perl$exe_ext"; 175 local($expinstperl) = "$binexp/perl$exe_ext"; 176 177 # First make sure $usrbinperl is not already the same as the perl we 178 # just installed. 179 if (-x $usrbinperl) { 180 # Try to be clever about mainperl being a symbolic link 181 # to binexp/perl if binexp and installbin are different. 182 $mainperl_is_instperl = 183 samepath($usrbinperl, $instperl) || 184 samepath($usrbinperl, $expinstperl) || 185 (($binexp ne $installbin) && 186 (-l $usrbinperl) && 187 ((readlink $usrbinperl) eq $expinstperl)); 188 } 189 if ((! $mainperl_is_instperl) && 190 (yn("Many scripts expect perl to be installed as $usrbinperl.\n" . 191 "Do you wish to have $usrbinperl be the same as\n" . 192 "$expinstperl? [y] "))) 193 { 194 unlink($usrbinperl); 195 eval { CORE::link $instperl, $usrbinperl } || 196 eval { symlink $expinstperl, $usrbinperl } || 197 copy($instperl, $usrbinperl); 198 $mainperl_is_instperl = 1; 199 } 200} 201 202# Make links to ordinary names if installbin directory isn't current directory. 203 204if (! $versiononly && ! samepath($installbin, '.')) { 205 safe_unlink("$installbin/perl$exe_ext", "$installbin/suidperl$exe_ext"); 206 link("$installbin/perl$ver$exe_ext", "$installbin/perl$exe_ext"); 207 link("$installbin/sperl$ver$exe_ext", "$installbin/suidperl$exe_ext") 208 if $d_dosuid; 209} 210 211if (!$versiononly && ! samepath($installbin, 'x2p')) { 212 safe_unlink("$installbin/a2p$exe_ext"); 213 copy("x2p/a2p$exe_ext", "$installbin/a2p$exe_ext"); 214 chmod(0755, "$installbin/a2p$exe_ext"); 215} 216 217# cppstdin is just a script, but it is architecture-dependent, so 218# it can't safely be shared. Place it in $installbin. 219# Note that Configure doesn't build cppstin if it isn't needed, so 220# we skip this if cppstdin doesn't exist. 221if (! $versiononly && (-f 'cppstdin') && (! samepath($installbin, '.'))) { 222 safe_unlink("$installbin/cppstdin"); 223 copy("cppstdin", "$installbin/cppstdin"); 224 chmod(0755, "$installbin/cppstdin"); 225} 226 227# Install scripts. 228 229mkpath($installscript, 1, 0777); 230 231if (! $versiononly) { 232 for (@scripts) { 233 (my $base = $_) =~ s#.*/##; 234 copy($_, "$installscript/$base"); 235 chmod(0755, "$installscript/$base"); 236 } 237} 238 239# pstruct should be a link to c2ph 240 241if (! $versiononly) { 242 safe_unlink("$installscript/pstruct"); 243 link("$installscript/c2ph","$installscript/pstruct"); 244} 245 246# Install pod pages. Where? I guess in $installprivlib/pod. 247 248if (! $versiononly || !($installprivlib =~ m/\Q$]/)) { 249 mkpath("${installprivlib}/pod", 1, 0777); 250 251 # If Perl 5.003's perldiag.pod is there, rename it. 252 if (open POD, "${installprivlib}/pod/perldiag.pod") { 253 read POD, $_, 4000; 254 close POD; 255 # Some of Perl 5.003's diagnostic messages ended with periods. 256 if (/^=.*\.$/m) { 257 my ($from, $to) = ("${installprivlib}/pod/perldiag.pod", 258 "${installprivlib}/pod/perldiag-5.003.pod"); 259 print STDERR " rename $from $to"; 260 rename($from, $to) 261 or warn "Couldn't rename $from to $to: $!\n" 262 unless $nonono; 263 } 264 } 265 266 foreach $file (@pods) { 267 # $file is a name like pod/perl.pod 268 copy_if_diff($file, "${installprivlib}/${file}"); 269 } 270 271 # Link perldiag.pod into archlib 272 my ($from, $to) = ("${installprivlib}/pod/perldiag.pod", 273 "${installarchlib}/pod/perldiag.pod"); 274 if (compare($from, $to) || $nonono) { 275 mkpath("${installarchlib}/pod", 1, 0777); 276 unlink($to); 277 link($from, $to); 278 } 279} 280 281# Check to make sure there aren't other perls around in installer's 282# path. This is probably UNIX-specific. Check all absolute directories 283# in the path except for where public executables are supposed to live. 284# Also skip $mainperl if the user opted to have it be a link to the 285# installed perl. 286 287if (!$versiononly) { 288 289 $dirsep = ($^O eq 'os2') ? ';' : ':' ; 290 ($path = $ENV{"PATH"}) =~ s:\\:/:g ; 291 @path = split(/$dirsep/, $path); 292 @otherperls = (); 293 for (@path) { 294 next unless m,^/,; 295 # Use &samepath here because some systems have other dirs linked 296 # to $mainperldir (like SunOS) 297 next if samepath($_, $binexp); 298 next if ($mainperl_is_instperl && samepath($_, $mainperldir)); 299 push(@otherperls, "$_/perl$exe_ext") 300 if (-x "$_/perl$exe_ext" && ! -d "$_/perl$exe_ext"); 301 } 302 if (@otherperls) { 303 print STDERR "\nWarning: perl appears in your path in the following " . 304 "locations beyond where\nwe just installed it:\n"; 305 for (@otherperls) { 306 print STDERR " ", $_, "\n"; 307 } 308 print STDERR "\n"; 309 } 310 311} 312 313print STDERR " Installation complete\n"; 314 315exit 0; 316 317############################################################################### 318 319sub yn { 320 local($prompt) = @_; 321 local($answer); 322 local($default) = $prompt =~ m/\[([yn])\]\s*$/i; 323 print STDERR $prompt; 324 chop($answer = <STDIN>); 325 $answer = $default if $answer =~ m/^\s*$/; 326 ($answer =~ m/^[yY]/); 327} 328 329sub unlink { 330 local(@names) = @_; 331 my($cnt) = 0; 332 333 foreach $name (@names) { 334 next unless -e $name; 335 chmod 0777, $name if $^O eq 'os2'; 336 print STDERR " unlink $name\n"; 337 ( CORE::unlink($name) and ++$cnt 338 or warn "Couldn't unlink $name: $!\n" ) unless $nonono; 339 } 340 return $cnt; 341} 342 343sub safe_unlink { 344 return if $nonono; 345 local @names = @_; 346 foreach $name (@names) { 347 next unless -e $name; 348 chmod 0777, $name if $^O eq 'os2'; 349 print STDERR " unlink $name\n"; 350 next if CORE::unlink($name); 351 warn "Couldn't unlink $name: $!\n"; 352 if ($! =~ /busy/i) { 353 print STDERR " mv $name $name.old\n"; 354 safe_rename($name, "$name.old") 355 or warn "Couldn't rename $name: $!\n"; 356 } 357 } 358} 359 360sub safe_rename { 361 local($from,$to) = @_; 362 if (-f $to and not unlink($to)) { 363 my($i); 364 for ($i = 1; $i < 50; $i++) { 365 last if rename($to, "$to.$i"); 366 } 367 warn("Cannot rename to `$to.$i': $!"), return 0 368 if $i >= 50; # Give up! 369 } 370 link($from,$to) || return 0; 371 unlink($from); 372} 373 374sub link { 375 my($from,$to) = @_; 376 my($success) = 0; 377 378 print STDERR " ln $from $to\n"; 379 eval { 380 CORE::link($from, $to) 381 ? $success++ 382 : ($from =~ m#^/afs/# || $to =~ m#^/afs/#) 383 ? die "AFS" # okay inside eval {} 384 : warn "Couldn't link $from to $to: $!\n" 385 unless $nonono; 386 }; 387 if ($@) { 388 File::Copy::copy($from, $to) 389 ? $success++ 390 : warn "Couldn't copy $from to $to: $!\n" 391 unless $nonono; 392 } 393 $success; 394} 395 396sub cmd { 397 my($cmd) = @_; 398 print STDERR " $cmd\n"; 399 unless ($nonono) { 400 system $cmd; 401 warn "Command failed!!!\n" if $?; 402 } 403} 404 405sub chmod { 406 local($mode,$name) = @_; 407 408 printf STDERR " chmod %o %s\n", $mode, $name; 409 CORE::chmod($mode,$name) 410 || warn sprintf("Couldn't chmod %o %s: $!\n", $mode, $name) 411 unless $nonono; 412} 413 414sub copy { 415 my($from,$to) = @_; 416 417 print STDERR " cp $from $to\n"; 418 File::Copy::copy($from, $to) 419 || warn "Couldn't copy $from to $to: $!\n" 420 unless $nonono; 421} 422 423sub samepath { 424 local($p1, $p2) = @_; 425 local($dev1, $ino1, $dev2, $ino2); 426 427 if ($p1 ne $p2) { 428 ($dev1, $ino1) = stat($p1); 429 ($dev2, $ino2) = stat($p2); 430 ($dev1 == $dev2 && $ino1 == $ino2); 431 } 432 else { 433 1; 434 } 435} 436 437sub installlib { 438 my $dir = $File::Find::dir; 439 $dir =~ s#^\.(?![^/])/?##; 440 local($depth) = $dir ? "lib/$dir" : "lib"; 441 442 my $name = $_; 443 444 if ($name eq 'CVS' && -d $name) { 445 $File::Find::prune = 1; 446 return; 447 } 448 449 # ignore patch backups and the .exists files. 450 return if $name =~ m{\.orig$|~$|^\.exists}; 451 452 $name = "$dir/$name" if $dir ne ''; 453 454 my $installlib = $installprivlib; 455 if ($dir =~ /^auto/ || 456 ($name =~ /^(.*)\.(?:pm|pod)$/ && $archpms{$1})) { 457 $installlib = $installarchlib; 458 return unless $do_installarchlib; 459 } else { 460 return unless $do_installprivlib; 461 } 462 463 if (-f $_) { 464 if (/\.(?:al|ix)$/ && !($dir =~ m[^auto/(.*)$] && $archpms{$1})) { 465 $installlib = $installprivlib; 466 #We're installing *.al and *.ix files into $installprivlib, 467 #but we have to delete old *.al and *.ix files from the 5.000 468 #distribution: 469 #This might not work because $archname might have changed. 470 unlink("$installarchlib/$name"); 471 } 472 if (compare($_, "$installlib/$name") || $nonono) { 473 unlink("$installlib/$name"); 474 mkpath("$installlib/$dir", 1, 0777); 475 # HP-UX (at least) needs to maintain execute permissions 476 # on dynamically-loaded libraries. 477 copy_if_diff($_, "$installlib/$name") 478 and chmod($name =~ /\.(so|$dlext)$/o ? 0555 : 0444, 479 "$installlib/$name"); 480 } 481 } elsif (-d $_) { 482 mkpath("$installlib/$name", 1, 0777); 483 } 484} 485 486# Copy $from to $to, only if $from is different than $to. 487# Also preserve modification times for .a libraries. 488# On some systems, if you do 489# ranlib libperl.a 490# cp libperl.a /usr/local/lib/perl5/archlib/CORE/libperl.a 491# and then try to link against the installed libperl.a, you might 492# get an error message to the effect that the symbol table is older 493# than the library. 494# Return true if copying occurred. 495 496sub copy_if_diff { 497 my($from,$to)=@_; 498 -f $from || die "$0: $from not found"; 499 if (compare($from, $to) || $nonono) { 500 safe_unlink($to); # In case we don't have write permissions. 501 if ($nonono) { 502 $from = $depth . "/" . $from if $depth; 503 } 504 copy($from, $to); 505 # Restore timestamps if it's a .a library or for OS/2. 506 if (!$nonono && ($^O eq 'os2' || $to =~ /\.a$/)) { 507 my ($atime, $mtime) = (stat $from)[8,9]; 508 utime $atime, $mtime, $to; 509 } 510 1; 511 } 512} 513