summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Koch <kpkoch@mit.edu>2007-03-05 14:07:07 +0000
committerKevin Koch <kpkoch@mit.edu>2007-03-05 14:07:07 +0000
commitc5c0e39a4591077e9eb9b7a55243886476ebabaf (patch)
tree867b7a974a038dee2011fb088bac1c7e99d6eb27
parentd47811aa8c5314097b28c49a47020670f8743133 (diff)
downloadkrb5-c5c0e39a4591077e9eb9b7a55243886476ebabaf.tar.gz
krb5-c5c0e39a4591077e9eb9b7a55243886476ebabaf.tar.xz
krb5-c5c0e39a4591077e9eb9b7a55243886476ebabaf.zip
Automation for building KfW
Target_Version: 1.6.1 Component: KfW git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@19205 dc483132-0cff-0310-8789-dd5450dbe970
-rw-r--r--src/windows/build/BKWconfig.xml70
-rw-r--r--src/windows/build/bkw.pl409
-rw-r--r--src/windows/build/copyfiles.xml221
-rw-r--r--src/windows/build/site-local.sed2
-rw-r--r--src/windows/build/tee.pl79
-rw-r--r--src/windows/build/which.pl69
6 files changed, 850 insertions, 0 deletions
diff --git a/src/windows/build/BKWconfig.xml b/src/windows/build/BKWconfig.xml
new file mode 100644
index 0000000000..7de3df102f
--- /dev/null
+++ b/src/windows/build/BKWconfig.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- BKW: Build Kerberos for Windows -->
+<BKW_Config>
+ <CommandLine>
+ <!-- The most changeable parameters can be specified on the command line.
+ Less changeable params are in section Config, below. -->
+ <Tags>
+ <cvs value="2.6.5 build 1234"/>
+<!-- <svn value="http://anonsvn.mit.edu/foo/bar"/> -->
+ </Tags>
+ <Directories>
+ <!-- Sources will be checked out of repositories into <src>. The structure
+ of the repositories will cause pismere/athena to be created under <src>. -->
+ <src path="C:\MIT-ISDA\KfW\src2" />
+
+ <!-- The sample config distributed as a zip must be unzipped into this directory before running the build: -->
+ <extras path="\auth\krb5\package-extras" /> <!-- Relative to <src>\pismere\athena -->
+
+ <out path="path4" />
+ </Directories>
+ <Options>
+ <debug value="0" />
+ <log value="1" path="bkw_pl.log" />
+ <clean value="0" />
+ <nomake value="0" />
+ <nopackage value="0" />
+ <verbose value="0" />
+ <vverbose value="0" />
+ </Options>
+ </CommandLine>
+ <Config>
+ <CVSROOT name=":kserver:cvs.mit.edu:/cvs/pismere" />
+ <SVNURL name="" />
+ </Config>
+ <Stages>
+ <FetchSources></FetchSources>
+ <Make></Make>
+ <PrePackage>
+ <CopyList>
+ <Config>
+ <!-- Debug and Release build results go in different places.
+ The otherwise identical paths differ in one section. For example:
+ .../target/bin/i386/bin/rel/filename and .../target/bin/i386/dbg/filename.
+ Here we define the two differing sections: -->
+ <DebugArea value="dbg" />
+ <ReleaseArea value="rel" />
+ <!-- Paths in the file list that include <AlwaysTag> will always have the tag replaced
+ with <DebugArea> or <ReleaseArea>, depending on the type of build.
+ Paths that include <DebugTag> (or <ReleaseTag>) will only have the tag substituted
+ and be copied when doing a debug (or release) build. Examples:
+ Will always be copied, from a build-dependent directory:
+ <File name="kfwlogon.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ Will only be copied in debug build:
+ <File name="netidmgr.exe.static.manifest" from="..\target\bin\i386\%debug%\" to="\bin\i386" notrequired="true" />
+ Will always be copied, from a build-independent directory:
+ <File name="des.h" from="auth\krb4\include\" to="\inc\krb4" newname="foo.h"/>
+ -->
+ <AlwaysTag value="%bldtype%" /> <!-- Pick a string that won't appear in a path. -->
+ <DebugTag value="%debug%" /> <!-- Pick a string that won't appear in a path. -->
+ <ReleaseTag value="%release%" /> <!-- Pick a string that won't appear in a path. -->
+ </Config>
+ <Files>
+ <Include path="copyfiles.xml" /> <!-- Relative to location of bkw.pl. -->
+ </Files>
+ </CopyList>
+ </PrePackage>
+ <Package></Package>
+ <PostPackage></PostPackage>
+ </Stages>
+</BKW_Config> \ No newline at end of file
diff --git a/src/windows/build/bkw.pl b/src/windows/build/bkw.pl
new file mode 100644
index 0000000000..a36107ffe4
--- /dev/null
+++ b/src/windows/build/bkw.pl
@@ -0,0 +1,409 @@
+#!perl -w
+
+#use strict;
+use FindBin;
+use File::Spec;
+use File::Basename;
+use lib "$FindBin::Bin/build/lib";
+#use Logger;
+use Getopt::Long;
+use Cwd;
+use XML::Simple;
+use Data::Dumper;
+
+my $BAIL;
+$0 = fileparse($0);
+my $OPT = { logfile => 'bkw.pl.log' };
+my $MAKE = 'NMAKE';
+
+sub get_info
+ {
+ my $cmd = shift || die;
+ my $which = $^X.' which.pl';
+ my $full = `$which $cmd`;
+ return 0 if ($? / 256);
+ chomp($full);
+ $full = "\"".$full."\"";
+ return { cmd => $cmd, full => $full};
+ }
+
+sub usage {
+ print <<USAGE;
+Usage: $0 (-f --config) config-file [options] NMAKE-options
+
+ Options are case insensitive.
+
+ Options:
+ /help /? usage information (what you now see)
+ /srcdir dir Source directory to use. Should contain
+ pismere/athena. If cvstag or svntag is null,
+ the directory should be prepopulated.
+ /cvstag tag \\ For whichever of these tags is specified,
+ /svntag url / a checkout will be done into srcdir
+ /debug Do debug make instead of release make
+ /outdir dir Directory to be created where build results will go
+ /nomake Skip make step
+ /nopackage Skip packaging step
+ /clean Build clean target
+ /verbose Debug mode - verbose output
+ /config path Path to config file
+ /logfile path Where to write output. If omitted, ...
+ Other:
+ NMAKE-options any options you want to pass to NMAKE, which can be:
+ (note: /nologo is always used)
+
+USAGE
+ system("$MAKE /?");
+ }
+
+sub handler {
+ my $sig = shift;
+ my $bailmsg = "Bailing out due to SIG$sig!\n";
+ my $warnmsg = <<EOH;
+*********************************
+* FUTURE BUILDS MAY FAIL UNLESS *
+* BUILD DIRECTORIES ARE CLEANED *
+*********************************
+EOH
+ $BAIL = $bailmsg.$warnmsg;
+}
+
+sub makeDir {
+ my ($path) = @_;
+ if (! -d $path) {
+ mkdir($path) or die "Fatal -- couldn't create $path";
+ print "Debug -- makeDir($path)\n";
+ }
+ else {print "Debug -- makeDir($path) -- directory already exists.\n";}
+ }
+
+sub main {
+ Getopt::Long::Configure('no_bundling', 'no_auto_abbrev',
+ 'no_getopt_compat', 'require_order',
+ 'ignore_case', 'pass_through',
+ 'prefix_pattern=(--|-|\+|\/)',
+ );
+ GetOptions($OPT,
+ 'help|h|?',
+ 'cvstag|c:s',
+ 'svntag|s:s',
+ 'srcdir|r:s',
+ 'outdir|o:s',
+ 'debug|d',
+ 'config|f:s',
+ 'logfile|l:s',
+ 'clean',
+ 'verbose',
+ 'vverbose',
+ 'nomake',
+ 'nopackage',
+ );
+
+ if ( $OPT->{help} ) {
+ usage();
+ exit(0);
+ }
+
+##++ Validate required conditions:
+
+ if ($OPT->{config}) {}
+ else {
+ print "Fatal -- Configuration file must be specified.\n";
+ usage();
+ exit(0);
+ }
+
+# #print Dumper($OPT);
+
+ # List of programs which must be in PATH:
+ my @required_list = ('sed', 'awk', 'which', 'cat', 'rm', 'cvs', 'svn', 'doxygen', 'hhc', 'candle', 'light');
+ my $requirements_met = 1;
+ my $first_missing = 0;
+ my $error_list = "";
+ foreach my $required (@required_list) {
+ if (!get_info($required)) {
+ $requirements_met = 0;
+ if (!$first_missing) {
+ $first_missing = 1;
+ $error_list = "Fatal -- Environment problem! The following program(s) are not in PATH:\n";
+ }
+ $error_list .= "$required\n";
+ }
+ }
+ if (!$requirements_met) {
+ print $error_list;
+ print "Info -- Update PATH or install the programs and try again.\n";
+ exit(0);
+ }
+
+##-- Validate required conditions.
+
+ use Time::gmtime;
+ $ENV{DATE} = gmctime()." GMT";
+ my $originalDir =`cd`;
+ $originalDir =~ s/\n//g;
+
+ my $errorState = 0; ## Cumulative return code. 0 is success.
+
+##++ Assemble configuration from config file and command line:
+
+ my $configfile;
+ $configfile = $OPT->{config};
+
+ print "Info -- Reading configuration from $configfile.\n";
+
+ # Get configuration file:
+ my $xml = new XML::Simple();
+ my $config = $xml->XMLin($configfile);
+
+ # Set up convenience variables:
+ my (@switches, @paths, @tags, @prepackage, @files);
+ @switches = $config->{CommandLine}->{Options};
+ @paths = $config->{CommandLine}->{Directories};
+ @tags = $config->{CommandLine}->{Tags};
+ @prepackage = $config->{Stages}->{PrePackage};
+ @files = $config->{Stages}->{PrePackage}->{CopyList}->{Files};
+
+ # Update the config with overrides from the command line:
+ $tags[0]->{cvs}->{value} = $OPT->{cvstag} if exists $OPT->{cvstag};
+ $tags[0]->{svn}->{value} = $OPT->{svnurl} if exists $OPT->{svnurl};
+ $paths[0]->{src}->{path} = $OPT->{srcdir} if exists $OPT->{srcdir};
+ $paths[0]->{out}->{path} = $OPT->{outdir} if exists $OPT->{outdir};
+ $switches[0]->{debug}->{value} = $OPT->{debug} if exists $OPT->{debug};
+ $switches[0]->{clean}->{value} = 1 if exists $OPT->{clean};
+ $switches[0]->{nomake}->{value} = 1 if exists $OPT->{nomake};
+ $switches[0]->{nopackage}->{value} = 1 if exists $OPT->{nopackage};
+ $switches[0]->{verbose}->{value} = $OPT->{verbose} if exists $OPT->{verbose};
+ $switches[0]->{vverbose}->{value} = $OPT->{verbose} if exists $OPT->{vverbose};
+ if (exists $OPT->{logfile}) {
+ $switches[0]->{log}->{path} = $OPT->{logfile};
+ $switches[0]->{log}->{value} = 1;
+ }
+ my $verbose = $config->{CommandLine}->{Options}->{verbose}->{value};
+ my $vverbose = $config->{CommandLine}->{Options}->{vverbose}->{value};
+
+ if ($switches[0]->{clean}->{value} && !$switches[0]->{nopackage}->{value}) {
+ print "Info -- /clean forces /nopackage.\n";
+ $switches[0]->{nopackage}->{value} = 1;
+ }
+
+ my $i = 0;
+ # See if there is an included file list:
+ if (exists $files[0]->{Include}->{path}) {
+ my $configfile2 = $files[0]->{Include}->{path};
+ print "Info -- Including files to be copied from $configfile2.\n";
+ my $config2 = $xml->XMLin($configfile2);
+ while ($config2->{File}[$i]) {
+ $files[0]->{File}[++$#{$files[0]->{File}}] = $config2->{File}[$i];
+ $i++;
+ }
+ }
+
+ if ($vverbose) {print Dumper($config);}
+
+ # Examples of use:
+ #print "Logfile path: $switches[0]->{log}->{path}\n";
+ #print "src path: $paths[0]->{src}->{path}\n";
+ #print "cvs tag: $tags[0]->{cvs}->{value}\n";
+ #print "CVSROOT: $config->{Config}->{CVSROOT}->{name}\n";
+
+##-- Assemble configuration from config file and command line.
+
+# Begin logging:
+# my $l;
+# if ($OPT->{logfile}) {
+# $l = new Logger $OPT->{logfile} or die "Fatal -- Can't create Logger.";
+# $l->start;
+# }
+
+if (!$switches[0]->{nomake}->{value}) {
+ if ($verbose) {print "Info -- *** Begin fetching sources.\n";}
+
+ my ($wd, $result);
+ $wd = $paths[0]->{src}->{path};
+ chdir($wd) or die "Fatal -- couldn't chdir to $wd\n";
+ if ($verbose) {print "Info -- chdir to $wd\n";}
+
+ #if (! -d "pismere") {print "Warning -- can't find pismere in $wd. It will be created.\n";}
+ #if (! -d "pismere\\athena") {print "Warning -- can't find pismere\\athena in $wd. It will be created.\n";}
+
+ if ($tags[0]->{cvs}->{value}) {
+ # Set up cvs environment variables:
+ print "Warning -- cvs checkout skipped for now.\n";
+ # system("cvs checkout krb") or die "Fatal -- checkout of cvs source failed; return code $?\n";
+ }
+ else {print "Info -- cvs tag not specified; no cvs sources will be checked out.\n";}
+
+ if ($tags[0]->{svn}->{value}) {
+ # Set up svn environment variables:
+ print "Warning -- svn checkout skipped for now.\n";
+ # system("svn checkout krb") or die "Fatal -- checkout of svn source failed; return code $?\n";
+ }
+ else {print "Info -- svn tag not specified; no svn sources will be checked out.\n";}
+
+ if ($verbose) {print "Info -- *** End fetching sources.\n";}
+
+ if ($verbose) {print "Info -- *** Begin preparing for build.\n";}
+
+ my ($path, $destpath);
+
+ # Copy athena\scripts\site\graft\krb5\Makefile.src to athena\auth\krb5:
+ $path = "pismere\\scripts\\site\\graft\\krb5\\Makefile.src";
+ if (!-e $path) {die "Fatal -- Expected file $wd\\$path not found.";}
+ $destpath = "pismere\\athena\\auth\\krb5\\Makefile.src";
+ !system("echo F | xcopy /D $wd\\$path $wd\\$destpath /Y > NUL") or die "Fatal -- Copy of $wd\\$path to $wd\\$destpath failed.";
+ print "Info -- copied $wd\\$path to $wd\\$destpath\n";
+
+ # Add DEBUG_SYMBOL to .../wshelper/Makefile.src:
+ $path = "pismere\\athena\\wshelper\\wshelper\\Makefile.src";
+ if (!-e $path) {die "Fatal -- Expected file $wd\\$path not found.";}
+ if (system("grep DEBUG_SYMBOL $path > NUL") != 0) {
+ !system ("echo DEBUG_SYMBOL=1 >> $wd\\$path") or die "Fatal -- Append line to file failed.\n";
+ print "Info -- Added DEBUG_SYMBOL to $wd\\$path\n";
+ }
+
+ if ($verbose) {print "Info -- *** End preparing for build.\n";}
+
+ my ($buildtarget, $buildtext);
+ if ($switches[0]->{clean}->{value}) {
+ $buildtarget = "clean" ;
+ $buildtext = " clean."
+ }
+ else {
+ $buildtarget = "" ;
+ $buildtext = "."
+ }
+ if ($verbose) {print "Info -- *** Begin build".$buildtext."\n";}
+
+ chdir("pismere/athena") or die "Fatal -- couldn't chdir to source directory $wd\\pismere\\athena\n";
+ if ($verbose) {print "Info -- chdir to $wd\\pismere\\athena\n";}
+ !system("perl ../scripts/build.pl --softdirs $buildtarget") or die "Fatal -- build $buildtarget failed.";
+
+ chdir("..") or die "Fatal -- couldn't chdir to $wd\\pismere.";
+ if ($switches[0]->{clean}->{value}) {
+ if (-d "staging") {
+ !system("rm -rf staging") or die "Fatal -- Couldn't remove pismere/staging.";
+ }
+ }
+
+ if ($verbose) {print "Info -- *** End build".$buildtext."\n";}
+ } ## End make conditional.
+
+if (!$switches[0]->{nopackage}->{value}) {
+ if ($verbose) {print "Info -- *** Begin prepackage.\n";}
+
+ # The build results are copied to a staging area, where the packager expects to find them.
+ # We put the staging area in the fixed area .../pismere/staging.
+ $wd = $paths[0]->{src}->{path}."\\pismere";
+ my $staging_area = "$wd\\staging";
+ chdir($wd) or die "Fatal -- couldn't chdir to $wd\n";
+ if ($verbose) {print "Info -- chdir to $wd\n";}
+ (-e $staging_area) or makeDir($staging_area);
+
+ my $src = $paths[0]->{src}->{path};
+ my $CopyList = $prepackage[0]->{CopyList};
+
+ # A path can contain a variable part, which will be handled here. If the variable part is
+ # the Always or BuildDependent tag, then the variable will be changed to the
+ # build-type-dependent PathFragment.
+ # If the variable part is the IgnoreTag, then the file will not be copied.
+ my ($PathFragment, $BuildDependentTag, $IgnoreTag);
+
+ my $AlwaysTag = $CopyList->{Config}->{AlwaysTag}->{value};
+ if ($switches[0]->{debug}->{value}) { ## Debug build tags:
+ $PathFragment = $CopyList->{Config}->{DebugArea}->{value};
+ $BuildDependentTag = $CopyList->{Config}->{DebugTag}->{value};
+ $IgnoreTag = $CopyList->{Config}->{ReleaseTag}->{value};
+ }
+ else { ## Release build tags:
+ $PathFragment = $CopyList->{Config}->{ReleaseArea}->{value};
+ $BuildDependentTag = $CopyList->{Config}->{ReleaseTag}->{value};
+ $IgnoreTag = $CopyList->{Config}->{DebugTag}->{value};
+ }
+
+ # Copy all the files in the CopyList:
+ $i = 0;
+ my $nfiles = 0;
+ while ($files[0]->{File}[$i]) {
+ my ($name, $newname, $from, $to, $ignore);
+ $name = $files[0]->{File}->[$i]->{name};
+ if (exists $files[0]->{File}->[$i]->{newname}) {$newname = $files[0]->{File}->[$i]->{newname};}
+ else {$newname = $name;}
+ if ($name) {
+ $ignore = 0;
+ $from = "$src\\pismere\\athena\\$files[0]->{File}->[$i]->{from}\\$name";
+ $to = "$src\\pismere\\staging\\$files[0]->{File}->[$i]->{to}\\$newname";
+ if (index($from.$to, $IgnoreTag) <0) { ## Test for IgnoreTag
+ # Apply PathTag substitutions:
+ $from =~ s/$AlwaysTag/$PathFragment/g;
+ $to =~ s/$AlwaysTag/$PathFragment/g;
+ $from =~ s/$BuildDependentTag/$PathFragment/g;
+ $to =~ s/$BuildDependentTag/$PathFragment/g;
+ # We use xcopy instead of copy because it will create directories for us:
+ if (system("echo F | xcopy /D /F /Y $from $to 2>NUL") != 0) {
+ # xcopy failed.
+ if (!exists $files[0]->{File}->[$i]->{notrequired}) {
+ ( -e $from) or die "Fatal -- can't find $from";
+ die "Fatal -- Copy of $from to $to failed";
+ }
+ }
+ else {$nfiles++;}
+ }
+ }
+ $i++;
+ }
+
+ # Copy the extras:
+ print "Info -- Absent a way of scripting unzip, the instructions require manually unzipping into\n";
+ print " the target area $src\\pismere\\staging.\n";
+ # my $extradir = $paths[0]->{extras}->{path};
+ # !system("xcopy /d/f/y/s $src\\pismere\\athena\\$extradir\\* $src\\pismere\\staging") or die "Fatal -- Couldn't copy extras from $src\\pismere\\athena\\$extradir";
+
+ chdir("staging\\install\\wix") or die "Fatal -- Couldn't cd to $wd\\staging\\install\\wix";
+
+ # Correct errors in files.wxi:
+ !system("sed 's/WorkingDirectory=\"\\[dirbin\\]\"/WorkingDirectory=\"dirbin\"/g' files.wxi > a.tmp") or die "Fatal -- Couldn't modify files.wxi.";
+ !system("copy /y a.tmp files.wxi") or die "Fatal -- Couldn't update files.wxi.";
+ !system("del a.tmp") or print "Warning -- Couldn't clean up temporary file $wd\\staging\\installer\\wix\\a.tmp.\n";
+
+ # Update paths in site-local.wxi:
+ my $dblback_originalDir = $originalDir;
+ $dblback_originalDir =~ s/\\/\\\\/g;
+ !system("sed -f $dblback_originalDir\\site-local.sed site-local.wxi > b.tmp") or die "Fatal -- Couldn't modify site-local.wxi.";
+ my $hexback_wd = $wd;
+ $hexback_wd =~ s/\\/\\\\\\\\\\\\/g;
+ !system("sed 's/%%TARGETDIR%%/$hexback_wd\\\\\\staging\\\\\\/' b.tmp > c.tmp") or die "Fatal -- Couldn't modify site-local.wxi temporary file.";
+ !system("sed 's/%%CONFIGDIR%%/$hexback_wd\\\\\\staging\\\\\\sample\\\\\\/' c.tmp > d.tmp") or die "Fatal -- Couldn't modify site-local.wxi temporary file.";
+ !system("copy /y d.tmp site-local.wxi") or die "Fatal -- Couldn't replace site-local.wxi.";
+
+ # Copy krb.conf from ...\athena\auth\krb5\src\config-files to pismere\staging\samples\krb5.ini:
+ !system("echo F | xcopy /D $wd\\athena\\auth\\krb5\\src\\config-files\\krb5.conf $wd\\staging\\sample\\krb5.ini")
+ or die "Fatal -- Couldn't update $wd\\staging\\sample\\krb5.ini.";
+
+ # Sam said to leave these files out, but it is faster to copy them now
+ # than to figure out how to modify the wix configs to ignore them:
+ !system("echo F | xcopy /D $wd\\staging\\kfw-2.5-extra\\sample-config\\*.con $wd\\staging\\sample")
+ or die "Fatal -- Couldn't copy $wd\\staging\\kfw-2.5-extra\\sample-config\\*.con.";
+
+ if ($verbose) {print "Info -- *** End prepackage.\n";}
+
+ # Make the msi:
+ !system("nmake") or die "Fatal -- Couldn't make kfw.msi.";
+
+ if ($verbose) {print "Info -- *** Begin package.\n";}
+ if ($verbose) {print "Info -- *** End package.\n";}
+ } ## End package conditional.
+
+#End logging:
+# if (!$OPT->{nolog}) {
+# $l->stop;
+# }
+
+ return $errorState;
+}
+
+$SIG{'INT'} = \&handler;
+$SIG{'QUIT'} = \&handler;
+
+##exit (0);
+exit(main()); \ No newline at end of file
diff --git a/src/windows/build/copyfiles.xml b/src/windows/build/copyfiles.xml
new file mode 100644
index 0000000000..86efd5fbd1
--- /dev/null
+++ b/src/windows/build/copyfiles.xml
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="utf-8" ?>
+ <Files>
+ <!-- File from paths are relative to <src>\pismere\athena -->
+ <!-- File to paths are relative to <src>\pismere\staging -->
+ <File dummy="foo" /> <!-- Forces XML::Simple behavior -->
+ <!-- Without this, XML::Simple does not make an anonymous array and I can't figure out how to iterate over it. -->
+
+ <!-- Build-dependent files (from release or debug build): -->
+ <File name="netidmgr.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="netidmgr_version.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr"/>
+ <File name="perfstat.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr"/>
+ <File name="utils.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="sync.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="mstring.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="kplugin.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="kmq.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="kmm.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khuidefs.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khtracker.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khrescache.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khremote.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khprops.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khnewcred.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khmsgtypes.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khlist.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khhtlink.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="kherror.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="kherr.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khdefs.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khconfigui.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khalerts.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khactiondef.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="khaction.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="kcreddb.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="kconfig.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="hashtable.h" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\inc\" to="\inc\netidmgr" />
+ <File name="nidmgr32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="xpprof32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="wshelp32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="loadfuncs.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="leashw32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="krbv4w32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="krbcc32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="krb5_32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="krb524.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="kclnt32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="gssapi32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="getopt.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="delaydlls.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="comerr32.lib" from="..\target\lib\i386\%bldtype%\" to="\lib\i386" />
+ <File name="netidmgr.pdb" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\w2k\" to="\bin\i386\w2k" />
+ <File name="nidmgr32.pdb" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\w2k\" to="\bin\i386\w2k" />
+ <File name="kfwcpcc.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kfwlogon.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="netidmgr.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="nidmgr32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb4cred.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb5cred.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="mit2ms.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kdeltkt.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kcpytkt.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="xpprof32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="wshelp32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="ms2mit.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="leashw32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="leash32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+<!-- <File name="leash32.chm" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" /> -->
+ <File name="kpasswd.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kvno.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krbv4w32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krbcc32s.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krbcc32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="k5sprt32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb5_32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb524.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="klist.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kinit.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kdestroy.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kclnt32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="k524init.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gssapi32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gss-server.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gss-client.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gss.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="comerr32.pdb" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="netidmgr.exe" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\w2k\" to="\bin\i386\w2k" />
+ <File name="nidmgr32.dll" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\w2k\" to="\bin\i386\w2k" />
+ <File name="kfwcpcc.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kfwlogon.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="netidmgr.exe.manifest" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" notrequired="true" />
+ <File name="netidmgr.chm" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="netidmgr.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="netiddev.chm" from="..\target\bin\i386\%bldtype%\" to="\doc" />
+ <File name="nidmgr32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb4cred_en_us.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb4cred.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb5cred_en_us.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb5cred.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="mit2ms.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kdeltkt.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kcpytkt.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="xpprof32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="wshelp32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="ms2mit.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="leashw32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+<!-- <File name="leash32.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" /> -->
+<!-- <File name="leash32.chm" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" /> -->
+ <File name="kpasswd.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kvno.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krbv4w32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krbcc32s.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krbcc32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="k5sprt32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb5_32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="krb524.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="klist.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kinit.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kdestroy.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="kclnt32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="k524init.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gssapi32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gss-server.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gss-client.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="gss.exe" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="comerr32.dll" from="..\target\bin\i386\%bldtype%\" to="\bin\i386" />
+ <File name="NetIddev.chm" from="auth\krb5\src\windows\identity\obj\i386\%bldtype%\doc\" to="\doc" newname="netiddev.chm" />
+
+ <!-- Debug build only: -->
+ <File name="khhelp.h" from="auth\krb5\src\windows\identity\obj\i386\%debug%\inc\" to="\inc\netidmgr" />
+ <File name="aklog.pdb" from="..\target\bin\i386\%debug%\" to="\bin\i386" />
+ <File name="netidmgr.exe.static.manifest" from="..\target\bin\i386\%debug%\" to="\bin\i386" notrequired="true" />
+ <File name="aklog.exe" from="..\target\bin\i386\%debug%\" to="\bin\i386" />
+
+ <!-- Build-INdependent files, always copied: -->
+ <File name="relnotes.html" from="..\doc\kerberos\" to="\doc" />
+ <File name="leash_userdoc.pdf" from="auth\leash\help\" to="\doc" />
+ <File name="NetIdMgr.pdf" from="auth\krb5\src\windows\identity\doc\" to="\doc" newname="netidmgr_userdoc.pdf" />
+ <File name="*" from="auth\krb5\src\windows\identity\sample\templates\credprov\" to="\sample\templates\credprov\" />
+ <File name="*" from="auth\krb5\src\windows\identity\sample\templates\credprov\images\" to="\sample\templates\credprov\images" />
+ <File name="*" from="auth\krb5\src\windows\identity\sample\templates\credprov\lang\" to="\sample\templates\credprov\lang" />
+ <File name="*" from="auth\krb5\src\windows\identity\sample\templates\credprov\lang\en_us\" to="\sample\templates\credprov\lang\en_us" />
+ <File name="kclient.h" from="auth\krb4\kclient\include\" to="\inc\kclient" />
+ <File name="kcmacerr.h" from="auth\krb4\kclient\include\" to="\inc\kclient" />
+ <File name="com_err.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="conf-pc.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="conf.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="des.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="kadm_err.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="krb.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="krberr.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="mit_copy.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="osconf.h" from="auth\krb4\include\" to="\inc\krb4" />
+ <File name="com_err.h" from="auth\krb5\src\include\" to="\inc\krb5" />
+ <File name="gssapi.h" from="auth\krb5\src\include\gssapi\" to="\inc\krb5\gssapi" />
+ <File name="gssapi_generic.h" from="auth\krb5\src\include\gssapi\" to="\inc\krb5\gssapi" />
+ <File name="gssapi_krb5.h" from="auth\krb5\src\include\gssapi\" to="\inc\krb5\gssapi" />
+ <File name="des.h" from="auth\krb5\src\include\KerberosIV\" to="\inc\krb5\KerberosIV" />
+ <File name="kadm_err.h" from="auth\krb5\src\include\KerberosIV\" to="\inc\krb5\KerberosIV" />
+ <File name="krb_err.h" from="auth\krb5\src\include\KerberosIV\" to="\inc\krb5\KerberosIV" />
+ <File name="krb.h" from="auth\krb5\src\include\KerberosIV\" to="\inc\krb5\KerberosIV" />
+ <File name="mit-copyright.h" from="auth\krb5\src\include\KerberosIV\" to="\inc\krb5\KerberosIV" />
+ <File name="krb5.h" from="auth\krb5\src\include\" to="\inc\krb5" />
+ <File name="profile.h" from="auth\krb5\src\include\" to="\inc\krb5" />
+ <File name="win-mac.h" from="auth\krb5\src\include\" to="\inc\krb5" />
+ <File name="krb5.h" from="auth\krb5\src\include\krb5\" to="\inc\krb5\krb5" notrequired="true" />
+ <File name="cacheapi.h" from="auth\krbcc\include\" to="\inc\krbcc" />
+ <File name="leasherr.h" from="auth\leash\include\" to="\inc\leash" />
+ <File name="leashinfo.h" from="auth\leash\include\" to="\inc\leash" />
+ <File name="leashwin.h" from="auth\leash\include\" to="\inc\leash" />
+ <File name="loadfuncs-afs.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-afs36.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-com_err.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-krb.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-krb5.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-krb524.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-leash.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-lsa.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-profile.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs-wshelper.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs.c" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="loadfuncs.h" from="util\loadfuncs\" to="\inc\loadfuncs" />
+ <File name="nameser.h" from="wshelper\include\arpa\" to="\inc\wshelper\arpa" />
+ <File name="hesiod.h" from="wshelper\include\" to="\inc\wshelper" />
+ <File name="mitwhich.h" from="wshelper\include\" to="\inc\wshelper" />
+ <File name="resolv.h" from="wshelper\include\" to="\inc\wshelper" />
+ <File name="wshelper.h" from="wshelper\include\" to="\inc\wshelper" />
+ <File name="kfw-fixed.nsi" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="kfw.ico" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="kfw.nsi" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="KfWConfigPage.ini" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="KfWConfigPage2.ini" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="killer.cpp" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="licenses.rtf" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="site-local.nsi" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="utils.nsi" from="auth\krb5\src\windows\installer\nsis\" to="\install\nsis" />
+ <File name="msi-deployment-guide.txt" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="config.wxi" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="features.wxi" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="files.wxi" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="kfw.wxs" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="Makefile" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="property.wxi" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="site-local.wxi" from="auth\krb5\src\windows\installer\wix\" to="\install\wix" />
+ <File name="bannrbmp.bmp" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="completi.ico" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="custicon.ico" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="dlgbmp.bmp" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="exclamic.ico" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="info.bmp" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="insticon.ico" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="new.bmp" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="removico.ico" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="repairic.ico" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="up.bmp" from="auth\krb5\src\windows\installer\wix\Binary\" to="\install\wix\Binary" />
+ <File name="custom.cpp" from="auth\krb5\src\windows\installer\wix\custom\" to="\install\wix\custom" />
+ <File name="custom.h" from="auth\krb5\src\windows\installer\wix\custom\" to="\install\wix\custom" />
+ <File name="config_1033.wxi" from="auth\krb5\src\windows\installer\wix\lang\" to="\install\wix\lang" />
+ <File name="strings_1033.wxl" from="auth\krb5\src\windows\installer\wix\lang\" to="\install\wix\lang" />
+ <File name="ui_1033.wxi" from="auth\krb5\src\windows\installer\wix\lang\" to="\install\wix\lang" />
+ <File name="license.rtf" from="auth\krb5\src\windows\installer\wix\lang\" to="\install\wix\lang" />
+ </Files> \ No newline at end of file
diff --git a/src/windows/build/site-local.sed b/src/windows/build/site-local.sed
new file mode 100644
index 0000000000..34d68ff66c
--- /dev/null
+++ b/src/windows/build/site-local.sed
@@ -0,0 +1,2 @@
+s/<?define TargetDir="c:.temp.*"?>/<?define TargetDir="%%TARGETDIR%%"?>/
+s/<?define ConfigDir="c:.temp.*"?>/<?define ConfigDir="%%CONFIGDIR%%"?>/ \ No newline at end of file
diff --git a/src/windows/build/tee.pl b/src/windows/build/tee.pl
new file mode 100644
index 0000000000..a9c30fb459
--- /dev/null
+++ b/src/windows/build/tee.pl
@@ -0,0 +1,79 @@
+# Usage 'tee filename'
+# Make sure that when using this as a perl pipe you
+# print a EOF char!
+# (This may be a bug in perl 4 for NT)
+#
+# Use it like:
+# open(PIPE, "|$^X tee.pl foo.log") || die "Can't pipe";
+# open(STDOUT, ">&PIPE") || die "Can't dup pipe to stdout";
+# open(STDERR, ">&PIPE") || die "Can't dup pipe to stderr";
+
+use IO::File;
+
+#$SIG{'INT'} = \&handler;
+#$SIG{'QUIT'} = \&handler;
+
+$SIG{'INT'} = 'IGNORE';
+$SIG{'QUIT'} = \&handler;
+
+my $fh = new IO::File;
+
+my $arg = shift;
+my $file;
+my $access = ">";
+
+while ($arg) {
+ if ($arg =~ /-a/) {
+ $access = ">>";
+ } elsif ($arg =~ /-i/) {
+ $SIG{'INT'} = 'IGNORE';
+ $SIG{'QUIT'} = 'IGNORE';
+ } else {
+ $file = $arg;
+ last;
+ }
+ $arg = shift;
+}
+
+STDOUT->autoflush(1);
+
+if ($file) {
+ $fh->open($access.$file) || die "Could not open $file\n";
+ $fh->autoflush(1);
+}
+
+while (<>) {
+ $_ = &logtime.$_;
+ print $_;
+ print $fh $_ if $file;
+}
+
+sub logtime {
+ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
+ $mon = $mon + 1;
+ $year %= 100;
+ sprintf ("[%02d/%02d/%02d %02d:%02d:%02d] ",
+ $year, $mon, $mday,
+ $hour, $min, $sec);
+}
+
+sub handler {
+ my $sig = shift;
+ my $bailmsg = &logtime."Bailing out due to SIG$sig!\n";
+ my $warnmsg = <<EOH;
+*********************************
+* FUTURE BUILDS MAY FAIL UNLESS *
+* BUILD DIRECTORIES ARE CLEANED *
+*********************************
+EOH
+ print $bailmsg, $warnmsg;
+ print $fh $bailmsg, $warnmsg;
+ print "Closing log...";
+ undef $fh if $fh;
+ print "closed!\n";
+ exit(2);
+}
+
+END {
+ undef $fh if $fh;
+}
diff --git a/src/windows/build/which.pl b/src/windows/build/which.pl
new file mode 100644
index 0000000000..1cf89ce571
--- /dev/null
+++ b/src/windows/build/which.pl
@@ -0,0 +1,69 @@
+#!perl -w
+
+use strict;
+use Config;
+use File::Basename;
+use Getopt::Long;
+
+$0 = fileparse($0);
+
+sub main
+{
+ Getopt::Long::Configure('bundling', 'no_auto_abbrev',
+ 'no_getopt_compat', 'require_order',
+ 'ignore_case', 'pass_through',
+ 'prefix_pattern=(--|-|\+|\/)',
+ );
+ my $OPT = {};
+ GetOptions($OPT,
+ 'help|h|?',
+ 'all|a',
+ 'quiet|q',
+ 'debug|d',
+ 'path:s',
+ );
+
+ my $f = shift @ARGV;
+ if ($OPT->{help} || !$f) {
+ usage();
+ exit(0) if $OPT->{help};
+ exit(1);
+ }
+
+ my $p = $OPT->{path} || $ENV{PATH};
+ my $s = $Config{path_sep};
+ my @d = split(/$s/, $p);
+ my @e = split(/$s/, lc($ENV{PATHEXT} || '.bat;.exe;.com'));
+ my @f = ($f, map { $f.$_; } @e);
+ my $found = 0;
+ foreach my $d (@d) {
+ print "(Searching $d)\n" if $OPT->{debug};
+ foreach my $f (@f) {
+ my $df = $d.'\\'.$f; # cannot use $File::Spec->catfile due to UNC.
+ print "(Checking for $df)\n" if $OPT->{debug};
+ if (-f $df) {
+ exit(0) if $OPT->{quiet};
+ print "$df\n";
+ exit(0) if !$OPT->{all};
+ $found = 1;
+ }
+ }
+ }
+ print "Could not find $f\n" if !$found && !$OPT->{quiet};
+ exit($found?0:1);
+}
+
+sub usage
+{
+ print <<USAGE;
+Usage: $0 [options] command
+ command find file executed by this command by looking at PATH
+ -d, --debug debug output
+ -a, --all find all such commands in PATH
+ -q, --quiet no output, exit with non-zero errorcode if not found
+ --path PATHARG search PATHARG instead of the PATH environment variable
+ -?, -H, --help help
+USAGE
+}
+
+main();