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