# --------------------------------------------------------------------------- # Script: symindex.pm # # (c) 2000 Microsoft Corporation. All rights reserved. # # Purpose: symbols server package # # Version: 1.00 (06/14/2000) - dmiura Make international complient #--------------------------------------------------------------------- # Set Package package symindex; # Set the script name $ENV{script_name} = 'symindex.pm'; # Set version $VERSION = '1.00'; # Set required perl version require 5.003; # Use section use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts"; use lib $ENV{RAZZLETOOLPATH}; use GetParams; use LocalEnvEx; use Logmsg; use GetIniSetting; use strict; use File::Basename; no strict 'vars'; # Require section require Exporter; # Global variable section ( $MainSymSrvShare, $OfficialIDXBranch1, $OfficialIDXBranch2 ); $MainSymSrvShare = undef; # if running on idx branch then some paths below will change $OfficialIDXBranch1 = "idx01"; $OfficialIDXBranch2 = "idx02"; sub Main { # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ # Begin Main code section # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ # Return when you want to exit on error # # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ # End Main code section # /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ } # sub IndexSymbols { # get passed arg my( $Language, $BuildName, $LogFileName ) = @_; my( $SymLocation, $LocalSymSrvDir, $ArchType, $RazPath, $Return); if ( ! ( defined ( $ENV{ "OFFICIAL_BUILD_MACHINE" } ) ) ) { # we don't index symbols on non-official machines logmsg( "Non-official build machine, not indexing symbols ..."); return; } # # comment out this code to enable VBLs to index # if ( ! ( defined ( $ENV{ "MAIN_BUILD_LAB_MACHINE" } ) ) ) { # # we don't index symbols yet outside the main build lab # logmsg( "Not a main build lab machine, not indexing symbols yet..."); # return; # } $SymLocation = &GetSymbolsLocation( $Language, $BuildName, $LogFileName ); if ( ! ( defined( $SymLocation ) ) ) { errmsg( "Location of symbols to index can't be determined"); return; } # comment out for now, timing problems may cause indexing to occur before sym copy # if ( ! ( -e $SymLocation ) ) { # errmsg( "Location of symbols $SymLocation doesn't exist"); # return; # } if ( ! ( defined ( $ENV{_NTPostBld} ) ) ) { # if the binaries tree is not there we are toast! errmsg( "unexpected error - binaries tree not present ..."); return; } my( @IniRequest ) = ( "SymIndexServer" ); my( $IniReturn ) = &GetIniSetting::GetSettingEx( $ENV{_BuildBranch}, $Language, @IniRequest ); if ( $IniReturn ) { $MainSymSrvShare = $IniReturn; } else { logmsg( "No symindex server. Exit."); return; } my $altLang = $Language; $altLang = "usa" if( lc $Language eq "cov" ); $LocalSymSrvDir = "$ENV{_NTPostBld}\\symsrv\\$altLang"; if ( ! ( defined( $LocalSymSrvDir ) ) ) { errmsg( "Location of local symsrv directory can't be determined"); return; } logmsg( "Location of symsrv subdirectory is $LocalSymSrvDir"); if ( ! ( -e $LocalSymSrvDir ) ) { errmsg( "Location of symsrv $LocalSymSrvDir doesn't exist"); return; } &AddSymbols( $SymLocation, $LocalSymSrvDir, $BuildName, $LogFileName ); } sub AddSymbols { #create loc files #push newreq (loc, bin, pri, pub) to MainSymServer-AddReq queue #move newreq (bin, pri, pub)to AddWorking #if oldreq in AddFinish move oldreq to MainSymServer-DeleteReq #remove oldreq from AddFinish #Wait for newreq to move to MainSymServer-AddFinish #move newreq to AddFinsh # get passed args my( $SymbolsLoc, $LocalSymSrvDir, $BuildName, $LogFileName ) = @_; my( $FileType, %FileName, $StillWorkingList, %IndexFileName ); my( $Counter, $FinalLocation, $ThisFile, $Return ); my $newMainSymSrvShare; logmsg( "Indexing symbols ..." ); # create the loc files foreach $FileType ( 'bin', 'pri', 'pub' ) { $Return = system( "dir /b $LocalSymSrvDir\\add_requests\\$BuildName.*.$FileType >nul 2>nul" ); if ( $Return != 0 ) { logmsg( "$BuildName\.\*\.$FileType file not found at $LocalSymSrvDir\\add_requests"); } else { chomp($FileName{ $FileType } = `dir /b $LocalSymSrvDir\\add_requests\\$BuildName.*.$FileType`); if ($FileName{ $FileType } !~ /\./) { $FileName{ $FileType } = undef; next; } if ( $FileName{ $FileType } =~ /\S/) { $FinalLocation = $SymbolsLoc; my ($filename, $ext) = (fileparse($FileName{$FileType}, "\.$FileType"))[0,2]; # get filename and its extension, element 1 is path that we don't care here $ext =~ s/^\.//; $IndexFileName{ $FileType } = &getproject() . "_" . $filename . "_" . $ext . ".ssi"; if ( $FileType =~ /pri/i ) { $FinalLocation .= "\\symbols.pri"; } if ( $FileType =~ /pub/i ) { $FinalLocation .= "\\symbols"; } $Return = system( "echo $FinalLocation > $LocalSymSrvDir\\add_requests\\" . $FileName{ $FileType } . "\.loc" ); $Return ||= system("GenSSIFile.cmd -i \"$LocalSymSrvDir\\add_requests\\$IndexFileName{ $FileType }\" -o \"$LocalSymSrvDir\\add_requests\\$IndexFileName{ $FileType }\" -t \"$FinalLocation\" -b \"$SymbolsLoc\"") >> 8; # add error checking to make sure the write of the loc file worked!!!? } else { errmsg( "Undefined dir return! '$FileType' has no value in FileName hash!"); } } } # copy the files over to the main symbols server add request if ( -e $MainSymSrvShare ) { if (lc$MainSymSrvShare eq "\\\\symbols\\build\$") { $newMainSymSrvShare = $MainSymSrvShare . "\\" . getproject(); $newMainSymSrvShare =~ s/build\$/projects/i; } else { $newMainSymSrvShare = $MainSymSrvShare; } # make these into loops over $FileName{ $FileType } foreach $FileType ( 'bin', 'pri', 'pub' ) { # now, copy the loc file over to the symbols server (this must be done before the non-loc file per BarbKess) if ( defined ( $FileName{ $FileType } )) { $Return = system( "copy $LocalSymSrvDir\\add_requests\\" . $IndexFileName{ $FileType } . " $newMainSymSrvShare\\add_requests >nul 2>nul" ); if ( $Return != 0 ) { errmsg( "Failed to copy $IndexFileName{ $FileType } file to $newMainSymSrvShare\\add_requests ..."); } } } #if any files in add finished then move to main symbol server delete request (but only if add requests is not empty) $Return = system( "dir /b $LocalSymSrvDir\\add_requests\\*_$BuildName.* >nul 2>nul" ); if ( $Return == 0 ) { # get branch name $BranchName = &GetBuildBranch( $BuildName ); if ( ! ( defined( $BranchName ) ) ) { errmsg( "Failed to find branch name..."); return; } #only move to main symbol server delete request if we are not in a fork branch # if ( !($BranchName =~ /$OfficialIDXBranch1/i || $BranchName =~ /$OfficialIDXBranch2/i) ) { # $Return = system( "copy $LocalSymSrvDir\\add_finished\\\*\.\* $MainSymSrvShare\\del_requests >nul 2>nul" ); # if ( $Return != 0 ) { errmsg( "Failed to copy $LocalSymSrvDir\\add_finished\\\*\.\*to $MainSymSrvShare\\del_requests\\..."); } # $Return = system( "del \/q $LocalSymSrvDir\\add_finished\\\*\.\*" ); # if ( $Return != 0 ) { logmsg( "Failed to delete $LocalSymSrvDir\\add_finished\\\*\.\*..."); } # } # move files from add requests to add finished foreach $FileType ( 'bin', 'pri', 'pub' ) { if ( defined ( $FileName{ $FileType } )) { if ( !($BranchName =~ /$OfficialIDXBranch1/i || $BranchName =~ /$OfficialIDXBranch2/i) ) { $Return = system( "copy $LocalSymSrvDir\\add_finished\\\*\_$FileType\.ssi $newMainSymSrvShare\\del_requests >nul 2>nul" ); $Return = system( "del \/q $LocalSymSrvDir\\add_finished\\\*\_$FileType\.ssi" ); $Return = system( "del \/q $LocalSymSrvDir\\add_finished\\\*\.$FileType" ); } $Return = system( "move \"$LocalSymSrvDir\\add_requests\\$FileName{ $FileType }\" \"$LocalSymSrvDir\\add_finished\\$FileName{ $FileType }\"" ); if ( $Return != 0 ) { errmsg( "Failed to move $FileName{ $FileType } to $LocalSymSrvDir\\add_finished\\..."); } $Return = system( "move \"$LocalSymSrvDir\\add_requests\\$IndexFileName{ $FileType }\" \"$LocalSymSrvDir\\add_finished\\$IndexFileName{ $FileType }\"" ); if ( $Return != 0 ) { errmsg( "Failed to move $IndexFileName{ $FileType } to $LocalSymSrvDir\\add_finished\\..."); } } } } } else { # matches if ( -e $MainSymSrvShare ) { errmsg( "Couldn't see the symbols server $MainSymSrvShare ..."); } } sub GetRelSvrFromRelRules { # get passed args my( $Language, $BranchName, $ArchType, $LogFileName ) = @_; my( $RazPath, $RelRulesFile, @RelRulesLines, $FoundTag, $Line, $Junk, $ThisLang, $FirstMachine ); $RazPath = $ENV{ "RazzleToolPath" }; $RelRulesFile = "$RazPath\\PostBuildScripts\\RelRules.$BranchName"; if ( ! ( -e $RelRulesFile ) ) { logmsg( "No relrules file found, assuming not archiving on release server ..."); return( undef ); } # parse the relrules file unless ( open( INFILE, $RelRulesFile ) ) { errmsg( "Failed to open $RelRulesFile for reading."); return( undef ); } @RelRulesLines = ; close( INFILE ); $FoundTag = "FALSE"; foreach $Line ( @RelRulesLines ) { chomp( $Line ); if ( $Line =~ /^\#/ ) { next; } # skip comments if ( length( $Line ) == 0 ) { next; } # skip blank lines if ( $Line =~ /^(.+?)\:$/ ) { # parse tag lines $FoundTag = "FALSE"; if ( $1 =~ /$ArchType/ ) { $FoundTag = "TRUE"; } # look for "$ArchType": tag, where $ArchType is x86fre... } elsif ( $FoundTag eq "TRUE" ) { # parse non-tag lines ( $Junk, $Junk, $ThisLang, $FirstMachine ) = split( /\, /, $Line ); if ( $ThisLang !~ /$Language/i ) { next; } # skip other language specs return( $FirstMachine ); # return the first release server listed } } # if we're here, we didn't find ourselves in RelRules. logmsg( "No $ArchType release server found, assuming not archiving on release server ..."); return( undef ); } sub GetSymbolsLocation { # get passed args my( $Language, $BuildName, $LogFileName ) = @_; my( $BranchName, $BuildReleaseShare, $SymFarmShare, $Location, $ArchType, $RelSrv, $Return ); # get branch name $BranchName = &GetBuildBranch( $BuildName ); if ( ! ( defined( $BranchName ) ) ) { errmsg( "Failed to find branch name."); return; } undef( $Location ); # find the symbols farm name for this branch if it exists my( @IniRequest ) = ( "SymFarm" ); my( $IniReturn ) = &GetIniSetting::GetSettingEx( $ENV{_BuildBranch}, $Language, @IniRequest ); if ( $IniReturn ) { $SymFarmShare = $IniReturn; } if ( defined( $SymFarmShare ) ) { $Location = "$SymFarmShare\\$Language\\$BuildName"; logmsg( "Symbols Location for build machine with sym farm is $Location"); return( $Location ); # symbols are on the symbols farm } # parse args from the build name $ArchType = &GetArchType( $BuildName, $LogFileName ); if ( ! ( defined( $ArchType ) ) ) { errmsg( "Failed to get valid ArchType from Build Name $BuildName."); return; } # find the release server name for this branch if it exists $RelSrv = GetRelSvrFromRelRules($Language, $BranchName, $ArchType, $LogFileName ); if ( defined( $RelSrv ) ) { $Location = "\\\\$RelSrv\\release\\$Language\\$BuildName"; logmsg( "Symbols Location for build machine with release server is $Location"); return( $Location ); # symbols are on a release server } # symbols location being determined for build machine with no sym farm or release servers"); # set up build release share name ( @IniRequest ) = ( "AlternateReleaseDir" ); ( $IniReturn ) = &GetIniSetting::GetSettingEx( $BranchName, $Language, @IniRequest ); if ( $IniReturn ) { $BuildReleaseShare = $IniReturn; } else { $BuildReleaseShare = "release"; } if ($Language =~ /usa/i ) { $Location = "\\\\" . $ENV{ 'COMPUTERNAME' } . "\\$BuildReleaseShare\\$BuildName"; } else { $Location = "\\\\" . $ENV{ 'COMPUTERNAME' } . "\\$BuildReleaseShare\\$Language\\$BuildName"; } logmsg( "Symbols Location for build machine only is $Location"); return( $Location ); # symbols are on a build machine } sub GetArchType { # GetArchType # # GetArchType will return the archtype found in the given BuildName, # or undef if an invalid archtype is given. # get passed args my( $BuildName, $LogFileName ) = @_; my( $Junk, $ArchType ); ( $Junk, $ArchType, $Junk ) = split( /\./, $BuildName ); # validate we have a real arch type if ( ( $ArchType =~ /ia64fre/i ) || ( $ArchType =~ /ia64chk/i ) || ( $ArchType =~ /amd64fre/i ) || ( $ArchType =~ /amd64chk/i ) || ( $ArchType =~ /x86fre/i ) || ( $ArchType =~ /x86chk/i ) ) { return( $ArchType ); } else { errmsg( "Failed to parse a valid arch type '$ArchType' from" . "the given build name '$BuildName' ..."); return; } } sub GetBuildBranch { # GetBuildBranch # # GetBuildBranch will return the branch name contained in the passed BuildName # get passed args my( $BuildName ) = @_; my( $Junk, $BranchName ); ( $Junk, $Junk, $BranchName, $Junk ) = split( /\./, $BuildName ); return( $BranchName ); } sub getproject { my $value; $value = &GetIniSetting::GetSettingQuietEx($ENV{_BuildBranch}, $ENV{Lang}, 'DFSAlternateBranchName'); $value = $ENV{_BuildBranch} if (!defined $value); $value =~ s/\_.+//; return "Win" . $value; } # # GetShareDir # # sub GetShareDir { my( $ShareName, $LogFile ) = @_; my( @NetShareReturn, $Return, $NetShareLine ); my( $FieldName, $FieldValue ); $Return = system( "net share $ShareName >nul 2>nul" ); if ( $Return != 0 ) { errmsg( "No $ShareName share found."); return; } @NetShareReturn = `net share $ShareName`; # note that i'm using the second line of the net share return # to get this data. if this changes, it'll break. $NetShareLine = $NetShareReturn[1]; # logmsg( "NetShareLine is $NetShareLine"); chomp( $NetShareLine ); ( $FieldName, $FieldValue ) = split( /\s+/, $NetShareLine ); if ( $FieldName ne "Path" ) { errmsg( "Second line of net share does not start with " . "\'Path\' -- possibly another language?"); } # logmsg( "FieldValue for $ShareName share path is $FieldValue"); return( $FieldValue ); } sub ValidateParams { # } # sub Usage { print < &GetParams ('-o', 'l:', '-p', 'lang', @ARGV); # Include local environment extensions &LocalEnvEx::localenvex('initialize'); # Set lang from the environment $lang=$ENV{lang}; # Validate the option given as parameter. &ValidateParams; # Step 4: Call the main function &symindex::Main(); # End local environment extensions. &LocalEnvEx::localenvex('end'); } # ------------------------------------------------------------------------------------------- # Script: template_script.pm # Purpose: Template perl perl script for the NT postbuild environment # SD Location: %sdxroot%\tools\postbuildscripts # # (1) Code section description: # CmdMain - Developer code section. This is where your work gets done. # - Developer subs code section. This is where you write subs. # # (2) Reserved Variables - # $ENV{HELP} - Flag that specifies usage. # $ENV{lang} - The specified language. Defaults to USA. # $ENV{logfile} - The path and filename of the logs file. # $ENV{logfile_bak} - The path and filename of the logfile. # $ENV{errfile} - The path and filename of the error file. # $ENV{tmpfile} - The path and filename of the temp file. # $ENV{errors} - The scripts errorlevel. # $ENV{script_name} - The script name. # $ENV{_NTPostBld} - Abstracts the language from the files path that # postbuild operates on. # # (3) Reserved Subs - # Usage - Use this sub to discribe the scripts usage. # ValidateParams - Use this sub to verify the parameters passed to the script. # # (4) Call other executables or command scripts by using: # system "foo.exe"; # Note that the executable/script you're calling with system must return a # non-zero value on errors to make the error checking mechanism work. # # Example # if (system("perl.exe foo.pl -l $lang")){ # errmsg("perl.exe foo.pl -l $lang failed."); # # If you need to terminate function's execution on this error # goto End; # } # # (5) Log non-error information by using: # logmsg ""; # and log error information by using: # errmsg ""; # # (6) Have your changes reviewed by a member of the US build team (ntbusa) and # by a member of the international build team (ntbintl). # # ------------------------------------------------------------------------------------------- =head1 NAME B - What this package for =head1 SYNOPSIS =head1 DESCRIPTION =head1 INSTANCES =head2 =head1 METHODS =head2 =head1 SEE ALSO =head1 AUTHOR > =cut 1;