286 lines
6.9 KiB
Perl
286 lines
6.9 KiB
Perl
#
|
|
# Converts and xcopy command line into the appropriate binplace
|
|
# command line(s)
|
|
#
|
|
use strict;
|
|
|
|
# GLOBALS
|
|
my $gExcludes="";
|
|
my @all_files=();
|
|
|
|
# Never exit if a single file failed
|
|
my $gFlags ="-e";
|
|
|
|
MAIN: {
|
|
foreach ("_NTTREE","_NTROOT","_NTDRIVE") {
|
|
if (! defined $ENV{$_} ) {
|
|
die("# $0 : Must be run from a Razzle window!\n");
|
|
}
|
|
}
|
|
|
|
my($src, $dst) = ParseArgs(\@ARGV);
|
|
|
|
if ($gExcludes ne "") {
|
|
$gExcludes = "($gExcludes)";
|
|
}
|
|
|
|
my $cwd = `cd`;
|
|
chomp $cwd;
|
|
|
|
my $nttree = $ENV{'_NTTREE'};
|
|
my $ntdrive = $ENV{'_NTDRIVE'};
|
|
my $ntroot = $ENV{'_NTROOT'};
|
|
|
|
# Make placeroot and tempdst
|
|
my $placeroot = $dst;
|
|
my $rootdst;
|
|
|
|
|
|
$placeroot =~ s/^\Q$nttree\E//;
|
|
|
|
$placeroot =~ /.*[^:](\\[^\\]*)/;
|
|
$rootdst = $1;
|
|
$rootdst = "" if (!defined $rootdst);
|
|
$placeroot =~ s/\Q$rootdst\E$//;
|
|
|
|
$placeroot =~ s/^\\//;
|
|
$rootdst =~ s/^\\//;
|
|
$rootdst =~ s/\\$//;
|
|
|
|
$placeroot = "\%_NTTREE\%\\$placeroot";
|
|
|
|
|
|
if ($gExcludes eq "") {
|
|
# No need to do file by file listings, just
|
|
# copy entire directories
|
|
if (-d $src) {
|
|
push(@all_files, "$src\\*");
|
|
RecurseDirectoryTree($src, \&IsDir);
|
|
} else {
|
|
push(@all_files, $src);
|
|
}
|
|
|
|
} else {
|
|
# Need to go file by file so we can exclude
|
|
# files.
|
|
UseExcludes($src);
|
|
if (-d $src) {
|
|
RecurseDirectoryTree($src, \&UseExcludes);
|
|
}
|
|
}
|
|
|
|
|
|
if ($#all_files < 0) {
|
|
die("# $0 : No files to copy found.\n");
|
|
}
|
|
|
|
my $file;
|
|
|
|
foreach $file (@all_files) {
|
|
my $temp = $file;
|
|
|
|
# Translate the src
|
|
$file =~ s/^\Q$ntdrive\E//i;
|
|
$file =~ s/\Q$ntroot\E\\//i;
|
|
|
|
# Translate the dest
|
|
$temp =~ /^\Q$src\E(.*)/;
|
|
$temp = $1;
|
|
|
|
$temp =~ s/\\[^\\]*$//;
|
|
$temp =~ s/^\\//;
|
|
my $dest = ($rootdst eq "") ? (($temp eq "") ? "." : $temp) : "$rootdst\\$temp";
|
|
$dest = ".\\" if $dest eq "";
|
|
##HERE##
|
|
system "binplace $gFlags -R $placeroot -:DEST $dest $file\n";
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
# Add excludes to the global regexp
|
|
sub AddExcludesToGlobals {
|
|
my $exclude_file = shift;
|
|
my $line;
|
|
|
|
if (! open(hFILE, "$exclude_file") ) {
|
|
print("BUILDMSG: $0: Can't open exclude file \"$exclude_file\". Skipping.\n");
|
|
return;
|
|
}
|
|
|
|
while ($line = <hFILE>) {
|
|
chomp $line;
|
|
|
|
if ($line =~ /^\*$/) {
|
|
print("BUILDMSG: $0: Skipping global mask (*) in file $exclude_file.\n");
|
|
next;
|
|
}
|
|
|
|
$line =~ s/\\/\\\\/g; # \ to \\
|
|
$line =~ s/\./\\\./g; # . to \.
|
|
$line =~ s/\?/\./g; # ? to .
|
|
$line =~ s/\*/\.\*/g; # * to .*
|
|
$line =~ s/\{/\\\{/g; # { to \{
|
|
$line =~ s/\}/\\\}/g; # } to \}
|
|
$line =~ s/\(/\\\(/g; # ( to \(
|
|
$line =~ s/\)/\\\)/g; # ) to \)
|
|
|
|
if ($gExcludes ne "") {
|
|
$gExcludes .= "|$line";
|
|
} else {
|
|
$gExcludes = "$line";
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
# Sub to process files not using excludes
|
|
sub IsDir {
|
|
my $file = shift;
|
|
if (-d $file) {
|
|
push(@all_files, "$file\\*");
|
|
}
|
|
}
|
|
|
|
# Parse the command line
|
|
sub ParseArgs {
|
|
my @OPTS_ARRAY = @{$_[0]};
|
|
my $OPT;
|
|
|
|
my $source = "";
|
|
my $dest = "";
|
|
my %options;
|
|
|
|
foreach $OPT (@OPTS_ARRAY) {
|
|
my $switch = uc(substr($OPT,0,1));
|
|
my $value;
|
|
|
|
my $i; # generic loop var
|
|
my $c; # to hold a char
|
|
|
|
# Convert XCopy Flags
|
|
if ( $switch =~ /[-\/]/) {
|
|
$value = substr($OPT, 1);
|
|
|
|
|
|
if ( uc(substr($value,0,8)) eq "EXCLUDE:") {
|
|
# HANDLE EXCLUDES;
|
|
$value = substr($value, 8);
|
|
|
|
my @ExcludeFiles = split(/\+/, $value);
|
|
foreach (@ExcludeFiles) {
|
|
AddExcludesToGlobals($_);
|
|
}
|
|
|
|
} else {
|
|
for ($i=0;$i<length($value);$i++) {
|
|
$c = uc(substr($value, $i, 1));
|
|
|
|
if ($c eq "-") {
|
|
$c .= uc(substr($value, ++$i, 1));
|
|
}
|
|
|
|
if ($c =~ /([FGHLNOPQRTUWXZ]|-Y){1}/ ) {
|
|
# Don't spew this
|
|
# warn("# $0 : Ignoring option /$c.\n");
|
|
next;
|
|
} elsif ($c =~ /[AM]{1}/) {
|
|
$gFlags .= " -:ARC";
|
|
next;
|
|
} elsif ($c =~ /[K]{1}/) {
|
|
$gFlags .= " -k";
|
|
next;
|
|
} elsif ($c =~ /[YVISEC]{1}/) {
|
|
#warn("# $0 : /$c is handled implicitly. Ignoring.\n");
|
|
next;
|
|
} elsif ($c =~ /[ISE]{1}/) {
|
|
# Handled by creating multiple binplace lines
|
|
next;
|
|
} elsif ($c =~ /[D]{1}/) {
|
|
if (substr($value, $i+1, 1) eq ":") {
|
|
while (substr($value, ++$i, 1) =~ /[0-9\-:]{1}/) {
|
|
;
|
|
}
|
|
$i--; # step back one
|
|
if (substr($value, $i, 1) eq "-") {
|
|
$i--; # step back again
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Handle source and dest
|
|
} else {
|
|
if ($source eq "") {
|
|
$source = $OPT;
|
|
} elsif ($dest eq "") {
|
|
$dest = $OPT;
|
|
} else {
|
|
# warn("# $0 : \"$OPT\" was unexpected. Ignoring.\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
return($source, $dest, %options);
|
|
|
|
}
|
|
|
|
# Walk a dir tree calling $Function for
|
|
# each entry (except . and ..) found.
|
|
sub RecurseDirectoryTree {
|
|
|
|
if ($#_ != 1) {
|
|
print("BUILDMSG: $0: Internal erorr 1001.\n");
|
|
return(0);
|
|
}
|
|
|
|
my $TreeRoot = shift;
|
|
$TreeRoot =~ s/\\$//; # cut possible trailing '\'
|
|
|
|
my $Function = shift;
|
|
my $file;
|
|
my @files;
|
|
|
|
local *hDIR;
|
|
|
|
if (!opendir(hDIR, "$TreeRoot") ) {
|
|
print("BUILDMSG: $0: Internal error 1002. Can't open $TreeRoot.\n");
|
|
return(0);
|
|
}
|
|
|
|
while ( $file = readdir(hDIR) ) {
|
|
next if ($file eq ".");
|
|
next if ($file eq "..");
|
|
$file = "$TreeRoot\\$file";
|
|
&$Function("$file");
|
|
if (-d "$file" ){
|
|
RecurseDirectoryTree("$file", \&$Function);
|
|
}
|
|
}
|
|
|
|
closedir(hDIR);
|
|
}
|
|
|
|
# Sub to process files using exludes
|
|
sub UseExcludes {
|
|
my $file = shift;
|
|
|
|
if (-d $file) {
|
|
if ($file =~ /$gExcludes/) {
|
|
# NOTE: This RecurseDirectoryTree to never
|
|
# recurse thru this directory!!
|
|
next;
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ($file !~ /$gExcludes+/) {
|
|
push(@all_files, $file);
|
|
}
|
|
|
|
}
|