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.

285 lines
7.1 KiB

  1. #
  2. # Converts and xcopy command line into the appropriate binplace
  3. # command line(s)
  4. #
  5. use strict;
  6. # GLOBALS
  7. my $gExcludes="";
  8. my @all_files=();
  9. # Never exit if a single file failed
  10. my $gFlags ="-e";
  11. MAIN: {
  12. foreach ("_NTTREE","_NTROOT","_NTDRIVE") {
  13. if (! defined $ENV{$_} ) {
  14. die("# $0 : Must be run from a Razzle window!\n");
  15. }
  16. }
  17. my($src, $dst) = ParseArgs(\@ARGV);
  18. if ($gExcludes ne "") {
  19. $gExcludes = "($gExcludes)";
  20. }
  21. my $cwd = `cd`;
  22. chomp $cwd;
  23. my $nttree = $ENV{'_NTTREE'};
  24. my $ntdrive = $ENV{'_NTDRIVE'};
  25. my $ntroot = $ENV{'_NTROOT'};
  26. # Make placeroot and tempdst
  27. my $placeroot = $dst;
  28. my $rootdst;
  29. $placeroot =~ s/^\Q$nttree\E//;
  30. $placeroot =~ /.*[^:](\\[^\\]*)/;
  31. $rootdst = $1;
  32. $rootdst = "" if (!defined $rootdst);
  33. $placeroot =~ s/\Q$rootdst\E$//;
  34. $placeroot =~ s/^\\//;
  35. $rootdst =~ s/^\\//;
  36. $rootdst =~ s/\\$//;
  37. $placeroot = "\%_NTTREE\%\\$placeroot";
  38. if ($gExcludes eq "") {
  39. # No need to do file by file listings, just
  40. # copy entire directories
  41. if (-d $src) {
  42. push(@all_files, "$src\\*");
  43. RecurseDirectoryTree($src, \&IsDir);
  44. } else {
  45. push(@all_files, $src);
  46. }
  47. } else {
  48. # Need to go file by file so we can exclude
  49. # files.
  50. UseExcludes($src);
  51. if (-d $src) {
  52. RecurseDirectoryTree($src, \&UseExcludes);
  53. }
  54. }
  55. if ($#all_files < 0) {
  56. die("# $0 : No files to copy found.\n");
  57. }
  58. my $file;
  59. foreach $file (@all_files) {
  60. my $temp = $file;
  61. # Translate the src
  62. $file =~ s/^\Q$ntdrive\E//i;
  63. $file =~ s/\Q$ntroot\E\\//i;
  64. # Translate the dest
  65. $temp =~ /^\Q$src\E(.*)/;
  66. $temp = $1;
  67. $temp =~ s/\\[^\\]*$//;
  68. $temp =~ s/^\\//;
  69. my $dest = ($rootdst eq "") ? (($temp eq "") ? "." : $temp) : "$rootdst\\$temp";
  70. $dest = ".\\" if $dest eq "";
  71. ##HERE##
  72. system "binplace $gFlags -R $placeroot -:DEST $dest $file\n";
  73. }
  74. }
  75. # Add excludes to the global regexp
  76. sub AddExcludesToGlobals {
  77. my $exclude_file = shift;
  78. my $line;
  79. if (! open(hFILE, "$exclude_file") ) {
  80. print("BUILDMSG: $0: Can't open exclude file \"$exclude_file\". Skipping.\n");
  81. return;
  82. }
  83. while ($line = <hFILE>) {
  84. chomp $line;
  85. if ($line =~ /^\*$/) {
  86. print("BUILDMSG: $0: Skipping global mask (*) in file $exclude_file.\n");
  87. next;
  88. }
  89. $line =~ s/\\/\\\\/g; # \ to \\
  90. $line =~ s/\./\\\./g; # . to \.
  91. $line =~ s/\?/\./g; # ? to .
  92. $line =~ s/\*/\.\*/g; # * to .*
  93. $line =~ s/\{/\\\{/g; # { to \{
  94. $line =~ s/\}/\\\}/g; # } to \}
  95. $line =~ s/\(/\\\(/g; # ( to \(
  96. $line =~ s/\)/\\\)/g; # ) to \)
  97. if ($gExcludes ne "") {
  98. $gExcludes .= "|$line";
  99. } else {
  100. $gExcludes = "$line";
  101. }
  102. }
  103. }
  104. # Sub to process files not using excludes
  105. sub IsDir {
  106. my $file = shift;
  107. if (-d $file) {
  108. push(@all_files, "$file\\*");
  109. }
  110. }
  111. # Parse the command line
  112. sub ParseArgs {
  113. my @OPTS_ARRAY = @{$_[0]};
  114. my $OPT;
  115. my $source = "";
  116. my $dest = "";
  117. my %options;
  118. foreach $OPT (@OPTS_ARRAY) {
  119. my $switch = uc(substr($OPT,0,1));
  120. my $value;
  121. my $i; # generic loop var
  122. my $c; # to hold a char
  123. # Convert XCopy Flags
  124. if ( $switch =~ /[-\/]/) {
  125. $value = substr($OPT, 1);
  126. if ( uc(substr($value,0,8)) eq "EXCLUDE:") {
  127. # HANDLE EXCLUDES;
  128. $value = substr($value, 8);
  129. my @ExcludeFiles = split(/\+/, $value);
  130. foreach (@ExcludeFiles) {
  131. AddExcludesToGlobals($_);
  132. }
  133. } else {
  134. for ($i=0;$i<length($value);$i++) {
  135. $c = uc(substr($value, $i, 1));
  136. if ($c eq "-") {
  137. $c .= uc(substr($value, ++$i, 1));
  138. }
  139. if ($c =~ /([FGHLNOPQRTUWXZ]|-Y){1}/ ) {
  140. # Don't spew this
  141. # warn("# $0 : Ignoring option /$c.\n");
  142. next;
  143. } elsif ($c =~ /[AM]{1}/) {
  144. $gFlags .= " -:ARC";
  145. next;
  146. } elsif ($c =~ /[K]{1}/) {
  147. $gFlags .= " -k";
  148. next;
  149. } elsif ($c =~ /[YVISEC]{1}/) {
  150. #warn("# $0 : /$c is handled implicitly. Ignoring.\n");
  151. next;
  152. } elsif ($c =~ /[ISE]{1}/) {
  153. # Handled by creating multiple binplace lines
  154. next;
  155. } elsif ($c =~ /[D]{1}/) {
  156. if (substr($value, $i+1, 1) eq ":") {
  157. while (substr($value, ++$i, 1) =~ /[0-9\-:]{1}/) {
  158. ;
  159. }
  160. $i--; # step back one
  161. if (substr($value, $i, 1) eq "-") {
  162. $i--; # step back again
  163. }
  164. }
  165. }
  166. }
  167. }
  168. # Handle source and dest
  169. } else {
  170. if ($source eq "") {
  171. $source = $OPT;
  172. } elsif ($dest eq "") {
  173. $dest = $OPT;
  174. } else {
  175. # warn("# $0 : \"$OPT\" was unexpected. Ignoring.\n");
  176. }
  177. }
  178. }
  179. return($source, $dest, %options);
  180. }
  181. # Walk a dir tree calling $Function for
  182. # each entry (except . and ..) found.
  183. sub RecurseDirectoryTree {
  184. if ($#_ != 1) {
  185. print("BUILDMSG: $0: Internal erorr 1001.\n");
  186. return(0);
  187. }
  188. my $TreeRoot = shift;
  189. $TreeRoot =~ s/\\$//; # cut possible trailing '\'
  190. my $Function = shift;
  191. my $file;
  192. my @files;
  193. local *hDIR;
  194. if (!opendir(hDIR, "$TreeRoot") ) {
  195. print("BUILDMSG: $0: Internal error 1002. Can't open $TreeRoot.\n");
  196. return(0);
  197. }
  198. while ( $file = readdir(hDIR) ) {
  199. next if ($file eq ".");
  200. next if ($file eq "..");
  201. $file = "$TreeRoot\\$file";
  202. &$Function("$file");
  203. if (-d "$file" ){
  204. RecurseDirectoryTree("$file", \&$Function);
  205. }
  206. }
  207. closedir(hDIR);
  208. }
  209. # Sub to process files using exludes
  210. sub UseExcludes {
  211. my $file = shift;
  212. if (-d $file) {
  213. if ($file =~ /$gExcludes/) {
  214. # NOTE: This RecurseDirectoryTree to never
  215. # recurse thru this directory!!
  216. next;
  217. } else {
  218. return;
  219. }
  220. }
  221. if ($file !~ /$gExcludes+/) {
  222. push(@all_files, $file);
  223. }
  224. }