xref: /openbsd-src/gnu/usr.bin/perl/installperl (revision a4afd6dad3fba28f80e70208181c06c482259988)
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