1#!perl 2 3# Initialisation code and subroutines shared between installperl and installman 4# Probably installhtml needs to join the club. 5 6use strict; 7use vars qw($Is_VMS $Is_W32 $Is_OS2 $Is_Cygwin $Is_Darwin $Is_NetWare $Is_AmigaOS 8 %opts $packlist); 9use subs qw(unlink link chmod chown); 10require File::Path; 11require File::Copy; 12 13BEGIN { 14 require Config; 15 if ($Config::Config{userelocatableinc}) { 16 # This might be a considered a hack. Need to get information about the 17 # configuration from Config.pm *before* Config.pm expands any .../ 18 # prefixes. 19 # 20 # So we set $^X to pretend that we're the already installed perl, so 21 # Config.pm does its ... expansion off that location. 22 23 my $location = $Config::Config{initialinstalllocation}; 24 die <<'OS' unless defined $location; 25$Config{initialinstalllocation} is not defined - can't install a relocatable 26perl without this. 27OS 28 $^X = "$location/perl"; 29 # And then remove all trace of ever having loaded Config.pm, so that 30 # it will reload with the revised $^X 31 undef %Config::; 32 delete $INC{"Config.pm"}; 33 delete $INC{"Config_heavy.pl"}; 34 delete $INC{"Config_git.pl"}; 35 # You never saw us. We weren't here. 36 37 require Config; 38 } 39 Config->import; 40} 41 42if ($Config{d_umask}) { 43 umask(022); # umasks like 077 aren't that useful for installations 44} 45 46$Is_VMS = $^O eq 'VMS'; 47$Is_W32 = $^O eq 'MSWin32'; 48$Is_OS2 = $^O eq 'os2'; 49$Is_Cygwin = $^O eq 'cygwin'; 50$Is_Darwin = $^O eq 'darwin'; 51$Is_NetWare = $Config{osname} eq 'NetWare'; 52$Is_AmigaOS = $^O eq 'amigaos'; 53 54sub unlink { 55 my(@names) = @_; 56 my($cnt) = 0; 57 58 return scalar(@names) if $Is_VMS; 59 60 foreach my $name (@names) { 61 next unless -e $name; 62 chmod 0777, $name if ($Is_OS2 || $Is_W32 || $Is_Cygwin || $Is_NetWare || $Is_AmigaOS); 63 print " unlink $name\n" if $opts{verbose}; 64 ( CORE::unlink($name) and ++$cnt 65 or warn "Couldn't unlink $name: $!\n" ) unless $opts{notify}; 66 } 67 return $cnt; 68} 69 70sub link { 71 my($from,$to) = @_; 72 my($success) = 0; 73 74 my $xfrom = $from; 75 $xfrom =~ s/^\Q$opts{destdir}\E// if $opts{destdir}; 76 my $xto = $to; 77 $xto =~ s/^\Q$opts{destdir}\E// if $opts{destdir}; 78 print $opts{verbose} ? " ln $xfrom $xto\n" : " $xto\n" 79 unless $opts{silent}; 80 my $link = $Is_AmigaOS ? \&CORE::symlink : \&CORE::link; 81 eval { 82 $link->($from, $to) 83 ? $success++ 84 : ($from =~ m#^/afs/# || $to =~ m#^/afs/#) 85 ? die "AFS" # okay inside eval {} 86 : die "Couldn't link $from to $to: $!\n" 87 unless $opts{notify}; 88 $packlist->{$xto} = { from => $xfrom, type => 'link' }; 89 }; 90 if ($@) { 91 warn "Replacing link() with File::Copy::copy(): $@"; 92 print $opts{verbose} ? " cp $from $xto\n" : " $xto\n" 93 unless $opts{silent}; 94 print " creating new version of $xto\n" 95 if $Is_VMS and -e $to and !$opts{silent}; 96 unless ($opts{notify} or File::Copy::copy($from, $to) and ++$success) { 97 # Might have been that F::C::c can't overwrite the target 98 warn "Couldn't copy $from to $to: $!\n" 99 unless -f $to and (chmod(0666, $to), unlink $to) 100 and File::Copy::copy($from, $to) and ++$success; 101 } 102 if (defined($opts{uid}) || defined($opts{gid})) { 103 chown($opts{uid}, $opts{gid}, $to) if $success; 104 } 105 $packlist->{$xto} = { type => 'file' }; 106 } 107 $success; 108} 109 110sub chmod { 111 my($mode,$name) = @_; 112 113 return if ($^O eq 'dos'); 114 printf " chmod %o %s\n", $mode, $name if $opts{verbose}; 115 CORE::chmod($mode,$name) 116 || warn sprintf("Couldn't chmod %o %s: $!\n", $mode, $name) 117 unless $opts{notify}; 118} 119 120sub chown { 121 my($uid,$gid,$name) = @_; 122 123 return if ($^O eq 'dos'); 124 printf " chown %s:%s %s\n", $uid, $gid, $name if $opts{verbose}; 125 CORE::chown($uid,$gid,$name) 126 || warn sprintf("Couldn't chown %s:%s %s: $!\n", $uid, $gid, $name) 127 unless $opts{notify}; 128} 129 130sub samepath { 131 my($p1, $p2) = @_; 132 133 return (lc($p1) eq lc($p2)) if ($Is_W32 || $Is_NetWare); 134 135 return 1 136 if $p1 eq $p2; 137 138 my ($dev1, $ino1) = stat $p1; 139 return 0 140 unless defined $dev1; 141 my ($dev2, $ino2) = stat $p2; 142 143 return $dev1 == $dev2 && $ino1 == $ino2; 144} 145 146sub safe_rename { 147 my($from,$to) = @_; 148 if (-f $to and not unlink($to)) { 149 my($i); 150 for ($i = 1; $i < 50; $i++) { 151 last if rename($to, "$to.$i"); 152 } 153 warn("Cannot rename to '$to.$i': $!"), return 0 154 if $i >= 50; # Give up! 155 } 156 link($from,$to) || return 0; 157 unlink($from); 158} 159 160sub mkpath { 161 File::Path::make_path(shift, {owner=>$opts{uid}, group=>$opts{gid}, 162 mode=>0777, verbose=>$opts{verbose}}) unless $opts{notify}; 163} 164 165sub unixtoamiga 166{ 167 my $unixpath = shift; 168 169 my @parts = split("/",$unixpath); 170 my $isdir = 0; 171 $isdir = 1 if substr($unixpath,-1) eq "/"; 172 173 my $first = 1; 174 my $amigapath = ""; 175 176 my $i = 0; 177 178 for($i = 0; $i <= $#parts;$i++) 179 { 180 next if $parts[$i] eq "."; 181 if($parts[$i] eq "..") 182 { 183 $parts[$i] = "/"; 184 } 185 if($i == 0) 186 { 187 if($parts[$i] eq "") 188 { 189 $amigapath .= $parts[$i + 1] . ":"; 190 $i++; 191 next; 192 } 193 } 194 $amigapath .= $parts[$i]; 195 if($i != $#parts) 196 { 197 $amigapath .= "/" unless $parts[$i] eq "/" ; 198 } 199 else 200 { 201 if($isdir) 202 { 203 $amigapath .= "/" unless $parts[$i] eq "/" ; 204 } 205 } 206 } 207 208 return $amigapath; 209} 210 211sub amigaprotect 212{ 213 my ($file,$bits) = @_; 214 print "PROTECT: File $file\n"; 215 system("PROTECT $file $bits") 216 unless $opts{notify}; 217} 218 2191; 220