Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
7.2 KiB

  1. #!/tmp/.TheInstallScriptWasNotRunTheInstallScriptWasNotRunTheInstallScriptWasNotRun-perl/bin/perl
  2. =head1 NAME
  3. reloc_perl - relocate a perl installation
  4. =head1 SYNOPSIS
  5. reloc_perl [-a] [-b] [-d] [-e destpath] [-f file] [-i] [-t] [-r] [-v]
  6. topath [frompath]
  7. This tool will move a perl installation wholesale to a new location.
  8. Edits path names in binaries (e.g., a2p, perl, libperl.a) to reflect the
  9. new location, but preserves the size of strings by null padding them as
  10. necessary.
  11. Edits text files by simple substitution.
  12. 'destpath' cannot be longer than 'frompath'.
  13. If 'frompath' is not found in any files, no changes whatsoever are made.
  14. Running the tool without arguments provides more help.
  15. =head1 COPYRIGHT
  16. (c) 1999-2001 ActiveState Tool Corp. All rights reserved.
  17. =cut
  18. use strict;
  19. use Config;
  20. use File::Find;
  21. use File::Path qw(mkpath rmtree);
  22. use Getopt::Std;
  23. use vars qw($opt_a $opt_b $opt_d $opt_e $opt_f $opt_i $opt_t $opt_r $opt_v
  24. *ARGVOUT *OLDERR);
  25. my $logname;
  26. my $is_MSWin32;
  27. BEGIN {
  28. $is_MSWin32 = ($^O eq 'MSWin32');
  29. # on Windows, reloc_perl is usually run via wperl, so we need to
  30. # redirect STDERR to a file to record any mishaps
  31. if ($is_MSWin32) {
  32. # XXX - the following line of code makes poor assumptions such as
  33. # the existance of a c: drive
  34. my $tmp = $ENV{'TEMP'} || $ENV{'tmp'} || "$ENV{'SystemDrive'}/"
  35. || 'c:/temp';
  36. $logname = "$tmp/ActivePerlInstall.log";
  37. # ignore open errors, file may already exist from a previous
  38. # installation by a different user, in which case the error spew
  39. # goes to the regular STDERR
  40. open(OLDERR, ">&STDERR");
  41. open(STDERR, ">> $logname");
  42. }
  43. }
  44. END {
  45. if ($logname) {
  46. open(STDERR, ">&OLDERR");
  47. unlink $logname if -z $logname;
  48. }
  49. }
  50. my $frompath_default
  51. = $is_MSWin32
  52. ? 'D:\p4\main\Apps\ActivePerl\MSI\data\ActivePerl\Perl\\'
  53. # we intend this path to get translated too when reloc_perl is installed :-)
  54. : '/tmp/.TheInstallScriptWasNotRunTheInstallScriptWasNotRunTheInstallScriptWasNotRun-perl';
  55. getopts('abde:f:itrv') or usage('');
  56. my $topath = shift || usage('');
  57. my $destpath = $opt_e || $topath;
  58. my $frompath = shift || $frompath_default;
  59. my $bak = '.~1~';
  60. my $nullpad = length($frompath) - length($destpath);
  61. my $filelist = $opt_f || '';
  62. usage("$destpath is longer than $frompath") if ($nullpad < 0 and ! $opt_a);
  63. if ($nullpad > 0) {
  64. $nullpad = "\0" x $nullpad;
  65. } else {
  66. $nullpad = '';
  67. }
  68. if (-d $topath) {
  69. if (not -d $frompath) {
  70. warn "Will do inplace edit of `$topath'\n";
  71. $opt_i++;
  72. }
  73. }
  74. elsif ($opt_i) {
  75. usage("Directory `$topath' doesn't exist, can't do inplace edit");
  76. }
  77. my(@edit_bin, @edit_txt);
  78. sub usage {
  79. my $msg = shift;
  80. warn <<EOT;
  81. $msg
  82. Usage:
  83. $0 [-a] [-b] [-d] [-e destpath] [-f logfile] [-i] [-t] [-r] [-v]
  84. topath [frompath]
  85. -a allow destpath to be longer than frompath
  86. -b don't delete backups after edit
  87. -d delete source tree after relocation
  88. -e destpath edit files to contain this path instead of `frompath'
  89. (defaults to `topath')
  90. -f logfile creates `logfile' and writes the full path name of
  91. each file that was modified (one line per file)
  92. -i edit perl installation at `topath' insitu
  93. (makes no attempt to move tree, -d is ignored)
  94. -t only edit text files
  95. -r do not run `ranlib' on *.a files that were edited
  96. -v verbose messages
  97. 'destpath' defaults to `topath'
  98. 'frompath' defaults to '$frompath_default'
  99. 'destpath' must be shorter than 'frompath' unless the -a option is
  100. specified
  101. -i is assumed if `topath' exists, is a directory, and `frompath'
  102. doesn't exist.
  103. EOT
  104. exit(1);
  105. }
  106. sub wanted {
  107. if (-l or -d or -z) {
  108. return; # do nothing for symlinks, directories, empty files
  109. }
  110. elsif (-B) {
  111. edit_bin($_) unless $opt_t; # binary file edit
  112. }
  113. elsif (-e && -s && -f) {
  114. edit_txt($_); # text file edit
  115. }
  116. }
  117. sub edit_bin {
  118. my $file = shift;
  119. local(*F, $_);
  120. open(F, "<$file") or die "Can't open `$file': $!";
  121. binmode F;
  122. while (<F>) {
  123. if (/\Q$frompath\E/o) {
  124. push @edit_bin, $File::Find::name;
  125. last;
  126. }
  127. }
  128. close F;
  129. }
  130. sub edit_txt {
  131. my $file = shift;
  132. my $modifier;
  133. local(*F, $_);
  134. open(F, "<$file") or die "Can't open `$file': $!";
  135. $modifier = '(?i)' if $is_MSWin32;
  136. while (<F>) {
  137. if (/$modifier\Q$frompath\E/o) {
  138. push @edit_txt, $File::Find::name;
  139. last;
  140. }
  141. }
  142. close F;
  143. }
  144. # move tree
  145. unless ($opt_i) {
  146. # create parent path to destination
  147. my $toparent = $topath;
  148. $toparent =~ s|^(.*)/.+$|$1|;
  149. $toparent = '/' if $toparent eq '';
  150. mkpath($toparent,1,0755) unless -d $toparent;
  151. # # check if they're on same device and do quick rename
  152. # # XXX not enabled, since doing this is risky (NFS!)
  153. # if ((stat($toparent))[0] == (stat($frompath))[0]) {
  154. # warn "renaming $frompath to $topath\n" if $opt_v;
  155. # rename $frompath, $topath
  156. # or die "rename $frompath $topath failed: $!";
  157. # }
  158. # # must copy
  159. # else
  160. {
  161. # HPUX 11.00 tar gives warnings about uid and gid not existing.
  162. # -o should shut it off (according to the man page), but doesn't,
  163. # so we'll use pre-POSIX tar format on HPUX 11.
  164. my $tar_opts = ($^O eq 'hpux' and $Config{osver} =~ /^11\./)
  165. ? 'cOf' : 'cf';
  166. my $mvdir = "(cd $frompath; tar $tar_opts - .)|(cd $topath; tar xf -)";
  167. unless (-d $topath) {
  168. mkdir $topath, 0755 or die "Can't create `$topath': $!";
  169. }
  170. warn "running system('$mvdir')...\n" if $opt_v;
  171. system($mvdir) == 0 or die "system('$mvdir') failed: $?\n";
  172. if ($opt_d) {
  173. warn "deleting $frompath\n" if $opt_v;
  174. rmtree($frompath,0,0);
  175. }
  176. }
  177. }
  178. find(\&wanted, $topath);
  179. if (@edit_txt or @edit_bin) {
  180. # show affected files
  181. print "Configuring Perl installation at $topath\n";
  182. if ($filelist) {
  183. if (open(LOG, ">$filelist")) {
  184. for (@edit_bin,@edit_txt) {
  185. print LOG "$_\n";
  186. }
  187. close LOG;
  188. }
  189. else {
  190. warn "Can't open $filelist: $!";
  191. }
  192. }
  193. if ($opt_v) {
  194. warn "Translating $frompath to $destpath\n";
  195. for (@edit_bin,@edit_txt) {
  196. warn "editing $_\n";
  197. }
  198. }
  199. # edit files
  200. {
  201. local $^I = $bak;
  202. if (@edit_txt) {
  203. local @ARGV = @edit_txt;
  204. my $modifier;
  205. $modifier = '(?i)' if $is_MSWin32;
  206. while (<>) {
  207. s|$modifier\Q$frompath\E|$destpath|go;
  208. print;
  209. close ARGV if eof;
  210. }
  211. }
  212. if (@edit_bin) {
  213. local @ARGV = @edit_bin;
  214. binmode(ARGV);
  215. binmode(ARGVOUT);
  216. while (<>) {
  217. s|\Q$frompath\E(.*?)\0|$destpath$1$nullpad\0|go;
  218. print;
  219. close ARGV if eof;
  220. }
  221. }
  222. }
  223. # clobber backups
  224. unless ($opt_b) {
  225. warn "cleaning out backups\n" if $opt_v;
  226. for (@edit_bin,@edit_txt) {
  227. unlink "$_$bak";
  228. }
  229. }
  230. # run ranlib, where appropriate
  231. my $ranlib = $Config{ranlib};
  232. $ranlib = '' if $ranlib =~ /^:?\s*$/;
  233. if ($ranlib and !$opt_r) {
  234. for (@edit_bin) {
  235. if (/\Q$Config{_a}\E$/o) {
  236. warn "$ranlib $_\n" if $opt_v;
  237. system("$ranlib $_") == 0 or die "`$ranlib $_' failed: $?\n";
  238. }
  239. }
  240. }
  241. }