1 # Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # All rights reserved. |
|
3 # This component and the accompanying materials are made available |
|
4 # under the terms of "Eclipse Public License v1.0" |
|
5 # which accompanies this distribution, and is available |
|
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 # |
|
8 # Initial Contributors: |
|
9 # Nokia Corporation - initial contribution. |
|
10 # |
|
11 # Contributors: |
|
12 # |
|
13 # Description: |
|
14 # This module implements Build environment logging |
|
15 # It collects versions of various tools and Windows hotfixes and writes them to the specified XML file |
|
16 # |
|
17 # |
|
18 |
|
19 package buildenv; |
|
20 |
|
21 use strict; |
|
22 use Carp; |
|
23 use lib "$FindBin::Bin/lib"; |
|
24 |
|
25 # Module Win32::TieRegistry - Set delimiter to forward slash to avoid doubling all the backslashes! |
|
26 # Do not ask for ArrayValues sice we are only reading data, not changing/editing anything. |
|
27 use Win32::TieRegistry( Delimiter=>"/" ); |
|
28 |
|
29 # Main |
|
30 # |
|
31 # Inputs |
|
32 # - $iHostName - Name of host computer (to be written into the XML file) |
|
33 # - $iXMLfilePathname - Full pathname of output .XML file |
|
34 # |
|
35 # note: XML file will have been named after the hostname that |
|
36 # the script was run on. See BuildEnv.pl. |
|
37 # |
|
38 # Description |
|
39 # Collects OS information and versions of know tools. |
|
40 # Writes resulting build environment info to specified XML file |
|
41 # |
|
42 sub Main |
|
43 { |
|
44 my ($iHostName, $iXMLfilePathname) = @_; |
|
45 my (%iToolList) = &buildenv::GetToolInfo(); |
|
46 my ($iWinEnvVer, %iHotFixList) = &buildenv::GetWinInfo(); |
|
47 |
|
48 # write the same info in xml - useful for future tools |
|
49 &WriteXMLFormat($iHostName, $iXMLfilePathname, $iWinEnvVer, \%iHotFixList, \%iToolList); |
|
50 } |
|
51 |
|
52 # WriteXMLFormat |
|
53 # |
|
54 # Description |
|
55 # Writes build environment info to XML file |
|
56 # |
|
57 # Inputs |
|
58 # - $iWinVer - scalar with info on windows version |
|
59 # - $iHotFixRef - ref to hash containing hotfix info |
|
60 # - $iToolListRef - ref to hash containing tool info |
|
61 # |
|
62 # Outputs |
|
63 # Writes XML file |
|
64 # |
|
65 sub WriteXMLFormat |
|
66 { |
|
67 use IO; |
|
68 use XML::Writer; |
|
69 |
|
70 # get one scalar and 2 refs to hashes |
|
71 my ($iHostName, $iXMLfilePathname, $iWinVer, $iHotFixListRef, $iToolListRef) = @_; |
|
72 |
|
73 my $DTD = " |
|
74 <!DOCTYPE machine_config [ |
|
75 <!ELEMENT machine_config (operating_sys,tool*)> |
|
76 <!ATTLIST machine_config |
|
77 name CDATA #REQUIRED |
|
78 > |
|
79 <!ELEMENT operating_sys (hotfix*)> |
|
80 <!ATTLIST operating_sys |
|
81 name CDATA #REQUIRED |
|
82 version CDATA #REQUIRED |
|
83 servicepack CDATA #REQUIRED |
|
84 buildnumber CDATA #REQUIRED |
|
85 > |
|
86 <!ELEMENT hotfix EMPTY> |
|
87 <!ATTLIST hotfix |
|
88 name CDATA #REQUIRED |
|
89 installdate CDATA #REQUIRED |
|
90 > |
|
91 <!ELEMENT tool EMPTY> |
|
92 <!ATTLIST tool |
|
93 name CDATA #REQUIRED |
|
94 version CDATA #REQUIRED |
|
95 > |
|
96 ]> "; |
|
97 |
|
98 my $output = new IO::File("> $iXMLfilePathname"); |
|
99 my $writer = new XML::Writer( OUTPUT => $output, DATA_MODE => 'true', DATA_INDENT => 2 ); |
|
100 |
|
101 $writer->xmlDecl( 'UTF-8' ); |
|
102 print $output $DTD; |
|
103 $writer->comment( 'machine_config at ' . localtime() ); |
|
104 $writer->startTag( 'machine_config', 'name' => $iHostName); |
|
105 |
|
106 # breakdown the winversion string to its component parts: |
|
107 $iWinVer =~ m/Microsoft Windows(.*)ver(.*)Service Pack(.*)Build(.*)/; |
|
108 $writer->startTag( 'operating_sys', 'name' => 'Microsoft Windows'.$1, |
|
109 'version' => $2, |
|
110 'servicepack'=> $3, |
|
111 'buildnumber'=> $4); |
|
112 |
|
113 foreach my $fixnum (sort keys %$iHotFixListRef) |
|
114 { |
|
115 $writer->startTag( 'hotfix', name => $fixnum, 'installdate' => $iHotFixListRef->{$fixnum} ); |
|
116 $writer->endTag( ); |
|
117 } |
|
118 $writer->endTag( ); # operating_sys |
|
119 foreach my $toolname (sort {uc $a cmp uc $b} keys %$iToolListRef) |
|
120 { |
|
121 $writer->startTag( 'tool', name => $toolname, 'version' => $iToolListRef->{$toolname}{'version'} ); |
|
122 # Look for modules supporting the current tool (e.g Perl modules) |
|
123 if (defined $iToolListRef->{$toolname}{'modules'}) |
|
124 { |
|
125 foreach my $modulename (sort {uc $a cmp uc $b} keys %{$iToolListRef->{$toolname}{'modules'}}) |
|
126 { |
|
127 $writer->startTag( 'module', name => $modulename, 'version' => $iToolListRef->{$toolname}{'modules'}{$modulename} ); |
|
128 $writer->endTag( ); |
|
129 } |
|
130 } |
|
131 # Look for other versions of the current tool for which files exist but are not reached via default PATH (e.g ARM RVCT) |
|
132 if (defined $iToolListRef->{$toolname}{'multiver'}) |
|
133 { |
|
134 foreach my $multiverdirectory (sort {uc $a cmp uc $b} keys %{$iToolListRef->{$toolname}{'multiver'}}) |
|
135 { |
|
136 $writer->startTag( 'multiversion', name => $multiverdirectory, 'version' => $iToolListRef->{$toolname}{'multiver'}{$multiverdirectory} ); |
|
137 $writer->endTag( ); |
|
138 } |
|
139 } |
|
140 $writer->endTag( ); |
|
141 } |
|
142 $writer->endTag( ); # machine_config |
|
143 $writer->end( ); |
|
144 } |
|
145 |
|
146 # GetWinInfo |
|
147 # |
|
148 # Description |
|
149 # Gets Windows version. Collects information on Windows hotfixes (patches) |
|
150 # |
|
151 # Inputs - None |
|
152 # |
|
153 # Returns |
|
154 # $iWinEnv - Windows version, SP# and build |
|
155 # %iHotFixList - Installed Hotfix patch installation dates |
|
156 # |
|
157 sub GetWinInfo |
|
158 { |
|
159 |
|
160 my %iHotFixList; |
|
161 my $iWinEnv = 'Windows : Unknown version'; |
|
162 |
|
163 # Extract information from the Windows Registry - First get the OS name and version |
|
164 my %iValues; |
|
165 my $iRegKey = 'LMachine/SOFTWARE/Microsoft/Windows NT/CurrentVersion'; |
|
166 # Get data from hash set up by Win32::TieRegistry |
|
167 my $iHashRef = $Registry->{$iRegKey} or return ($iWinEnv, %iHotFixList); |
|
168 # Check that hash element exists before referencing data. Otherwise TieRegistry will think that we want to create a new key/value |
|
169 my $iProd = (defined $iHashRef->{'/ProductName'})? $iHashRef->{'/ProductName'}: ''; |
|
170 my $iVer = (defined $iHashRef->{'/CurrentVersion'})? $iHashRef->{'/CurrentVersion'}: ''; |
|
171 my $iSPVer = (defined $iHashRef->{'/CSDVersion'})? $iHashRef->{'/CSDVersion'}: ''; |
|
172 my $iBuild = (defined $iHashRef->{'/CurrentBuildNumber'})? $iHashRef->{'/CurrentBuildNumber'}: ''; |
|
173 |
|
174 $iWinEnv =$iProd .' ver ' . $iVer . ' ' . $iSPVer . ' Build ' . $iBuild . "\n"; |
|
175 |
|
176 # Next get the list of patches - First assume "Windows 2003" then "Windows 2000" |
|
177 $iRegKey = 'LMachine/SOFTWARE/Microsoft/Updates/Windows Server 2003'; |
|
178 $iHashRef = $Registry->{$iRegKey}; |
|
179 unless (defined $iHashRef) |
|
180 { |
|
181 $iRegKey = 'LMachine/SOFTWARE/Microsoft/Updates/Windows 2000'; |
|
182 $iHashRef = $Registry->{$iRegKey}; |
|
183 unless (defined $iHashRef) |
|
184 { |
|
185 return ($iWinEnv, %iHotFixList); |
|
186 } |
|
187 } |
|
188 foreach my $iKey0 (sort keys %$iHashRef) # Key = service pack identifier; e.g. 'SP-1/', 'SP2/' ... Note trailing delimiter! |
|
189 { |
|
190 my $iHashRef1 = $iHashRef->{$iKey0}; |
|
191 unless (ref($iHashRef1)) { next; } # Skip occasional data item. Reference Type (if any) is 'Win32::TieRegistry' |
|
192 foreach my $iKey1 (sort keys %$iHashRef1) # Key = hotfix reference; e.g. 'Q816093/' etc. Note trailing delimiter! |
|
193 { |
|
194 my $iHashRef2 = $iHashRef1->{$iKey1}; |
|
195 unless (ref($iHashRef2)) { next; } # Skip occasional data item. Reference Type (if any) is 'Win32::TieRegistry' |
|
196 foreach my $iKey2 (sort keys %$iHashRef2) # Key = hotfix property; e.g. '/InstalledDate' etc. Note leading delimiter! |
|
197 { |
|
198 if ($iKey2 =~ m/^\/InstalledDate/) |
|
199 { |
|
200 $iKey0 =~ s/\/$//; # Remove trailing delimiter (slash) from service pack identifier |
|
201 $iKey1 =~ s/\/$//; # Remove trailing delimiter (slash) from hotfix reference |
|
202 $iHotFixList{"$iKey0 $iKey1"}= $iHashRef2->{$iKey2}; |
|
203 } |
|
204 } |
|
205 } |
|
206 } |
|
207 |
|
208 return ($iWinEnv, %iHotFixList); |
|
209 } |
|
210 |
|
211 # GetToolInfo |
|
212 # |
|
213 # Description |
|
214 # Collects OS information and versions of known tools. |
|
215 # |
|
216 # Inputs - None |
|
217 # |
|
218 # Returns |
|
219 # %iToolList - Tool versions |
|
220 # |
|
221 sub GetToolInfo |
|
222 { |
|
223 my %iToolList; |
|
224 my $iToolName; |
|
225 |
|
226 GetPerlInfo(\%iToolList); |
|
227 |
|
228 GetMetrowerksInfo(\%iToolList); |
|
229 |
|
230 GetArmInfo(\%iToolList); |
|
231 |
|
232 GetJavaInfo(\%iToolList); |
|
233 |
|
234 # Location of reltools is assumed to be C:\Apps\RelTools\ |
|
235 $iToolName = 'RelTools'; |
|
236 my $iRelToolsVerTxt = 'C:\\Apps\\RelTools\\Version.txt'; |
|
237 $iToolList{$iToolName}{'version'} = 'Unknown'; |
|
238 |
|
239 if (-e $iRelToolsVerTxt) |
|
240 { |
|
241 my @iReltools = `type $iRelToolsVerTxt 2>&1`; |
|
242 # Get RelTools version (must start with numeric value). Assumed to be in first line of file |
|
243 if ($iReltools[0] =~ m/(^[0-9]{0,2}[0-9]{0,2}.*)(\n$)/) { |
|
244 $iToolList{$iToolName}{'version'} = $1; |
|
245 } |
|
246 } |
|
247 |
|
248 # Perforce Client (Typical output "Rev. P4/NTX86/2003.2/56831 (2004/04/13).") |
|
249 my $iToolNameVer = 'Perforce version'; |
|
250 my $iToolNameRel = 'Perforce release'; |
|
251 my @iP4Env = `P4 -V 2>&1`; |
|
252 $iToolList{$iToolNameVer}{'version'} = 'Unknown'; |
|
253 $iToolList{$iToolNameRel}{'version'} = 'Unknown'; |
|
254 foreach (@iP4Env) |
|
255 { |
|
256 if (m/Rev\.\s+(\S+)\s+\((.+)\)/) |
|
257 { |
|
258 $iToolList{$iToolNameVer}{'version'} = $1; |
|
259 $iToolList{$iToolNameRel}{'version'} = $2; |
|
260 } |
|
261 } |
|
262 |
|
263 # NSIS Compiler |
|
264 $iToolName = 'NSIS version'; |
|
265 my @iNSIS_ver = `MakeNSIS.exe /VERSION 2>&1`; |
|
266 $iToolList{$iToolName}{'version'} = 'Unknown'; |
|
267 if ($iNSIS_ver[0] =~ m/v(\d+\.\d+)/i) |
|
268 { |
|
269 $iToolList{$iToolName}{'version'} = $1; |
|
270 } |
|
271 |
|
272 # PsKill utility (SysInternals) |
|
273 # PsKill v1.11 - Terminates processes on local or remote systems |
|
274 $iToolName = 'PsKill'; |
|
275 my @iPSKillVer = `PsKill 2>&1`; |
|
276 $iToolList{$iToolName}{'version'} = 'Unknown'; |
|
277 foreach (@iPSKillVer) |
|
278 { |
|
279 if (m/PsKill v(\d+\.\d+)/) { $iToolList{$iToolName}{'version'} = $1; last;} |
|
280 } |
|
281 |
|
282 GetSophosInfo(\%iToolList); # Sophos Anti-virus |
|
283 |
|
284 GetMcAfeeInfo(\%iToolList); # McAfee Anti-virus |
|
285 |
|
286 GetGPGInfo(\%iToolList); # GPG (Command line encryption program) |
|
287 |
|
288 GetWinTapInfo(\%iToolList); # Win-TAP |
|
289 |
|
290 return %iToolList; |
|
291 } |
|
292 |
|
293 # GetPerlInfo |
|
294 # |
|
295 # Description |
|
296 # Gets Perl Version (currently usually 5.6.1 or, on a few special machines, 5.8.7) |
|
297 # If Perl is found, we go on to list Perl Modules using "PPM query" but under Perl Version |
|
298 # |
|
299 # Inputs - Reference to Tool List hash (for return of data) |
|
300 # |
|
301 # Outputs - Data returned via supplied hashref |
|
302 # |
|
303 sub GetPerlInfo |
|
304 { |
|
305 my $iToolList = shift; |
|
306 # Typical output from "Perl -v" |
|
307 # This is perl, v5.6.1 built for MSWin32-x86-multi-thread |
|
308 # (with 1 registered patch, see perl -V for more detail) |
|
309 # |
|
310 # Copyright 1987-2001, Larry Wall |
|
311 # |
|
312 # Binary build 635 provided by ActiveState Corp. http://www.ActiveState.com |
|
313 # Built 15:34:21 Feb 4 2003 |
|
314 # |
|
315 my $iToolName = 'Perl'; |
|
316 my $iVersion; |
|
317 my $iBuildNum; |
|
318 my @iRetData = `perl -v 2>&1`; |
|
319 $iToolList->{$iToolName}{'version'} = 'Unknown'; |
|
320 foreach (@iRetData) |
|
321 { # Analyse output from "Perl -v" |
|
322 if (m/ (version\s+|v)([0-9]{0,2}\.[0-9]{0,3}[_\.][0-9]{0,2})/) |
|
323 { |
|
324 if ($iVersion) { print "ERROR: Perl Version redefined as $2.\n"; last; } # Error? Can't have version defined twice!? |
|
325 $iVersion = $2; |
|
326 my $iMatchStr = '^([-\\w]+)\\s+\\[([.\\d]+)\\s*\\]'; |
|
327 my @iRetData = `ppm query 2>&1`; # Ask PPM for a list of modules |
|
328 if ($iRetData[0] =~ m/No query result sets -- provide a query term\./i) # This is the response from Perl v5.8.7. Try new-style query! |
|
329 { |
|
330 $iMatchStr = '([\\-\\w]+)\\s+\\[([\\.\\d]+\w?)([\\~\\]])'; |
|
331 `ppm set fields \"name version\" 2>&1`; # Specified required fields. CAUTION: PPM remembers settings from previous "PPM query" call |
|
332 @iRetData = `ppm query * 2>&1`; # Ask PPM for a list of modules |
|
333 } |
|
334 foreach (@iRetData) |
|
335 { # Analyse list of modules |
|
336 if (m/$iMatchStr/) |
|
337 { |
|
338 $iToolList->{$iToolName}{'modules'}{$1} = ($3 eq '~')? $2 . $3: $2; |
|
339 } |
|
340 } |
|
341 # Check for Inline-Java (which somehow escapes the attention of PPM |
|
342 my $iModuleName = 'Inline-Java'; |
|
343 $iToolList->{$iToolName}{'modules'}{$iModuleName} = GetPerlModuleInfo($iModuleName); |
|
344 # Check for XML-DOM (earlier installations also escaped PPM) |
|
345 $iModuleName = 'XML-DOM'; |
|
346 unless (defined $iToolList->{$iToolName}{'modules'}{$iModuleName}) |
|
347 { |
|
348 $iToolList->{$iToolName}{'modules'}{$iModuleName} = GetPerlModuleInfo($iModuleName); |
|
349 } |
|
350 } |
|
351 elsif (m/Binary\s+build\s+(\d+)/i) |
|
352 { |
|
353 if ($iBuildNum) { print "ERROR: Perl Build Number redefined as $1.\n"; last; } # Error? Can't have build defined twice!? |
|
354 $iBuildNum = $1; |
|
355 } |
|
356 } # End foreach (@iRetData) |
|
357 # We have already set $iToolList->{$iToolName}{'version'} = 'Unknown'; |
|
358 # So if $iVersion is still undefined, leave well alone! Eventually return 'Unknown'. |
|
359 if ($iVersion) # Found version. Have we got a Build Number? |
|
360 { |
|
361 unless($iBuildNum) { $iBuildNum = 'Build unknown'; } |
|
362 $iToolList->{$iToolName}{'version'} = "$iVersion [$iBuildNum]"; |
|
363 } |
|
364 # Next look for "Multiple Versions" |
|
365 # For example "\\LON-ENGBUILD54\C$\Apps\Perl.5.10.0" |
|
366 my $iAppsRoot = 'C:\Apps'; |
|
367 my $iPerlExe = 'bin\Perl.exe'; |
|
368 my $iAppsDirs = ReadDirectory($iAppsRoot); # Get arrayref |
|
369 unless (defined $iAppsDirs) |
|
370 { |
|
371 print "ERROR: Failed to read Apps Directory.\n"; |
|
372 return; |
|
373 } |
|
374 foreach my $iAppsDir (@$iAppsDirs) |
|
375 { |
|
376 if ($iAppsDir =~ m/^Perl\.(\d.*)/i) |
|
377 { |
|
378 my $iMultiVer = $1; |
|
379 $iAppsDir = uc $iAppsDir; # Source is a Windows directory name, which could be in any case |
|
380 $iToolList->{$iToolName}{'multiver'}{$iMultiVer} = 'Unknown'; |
|
381 $iVersion = ''; |
|
382 $iBuildNum = ''; |
|
383 my @iPerlExeRet = `$iAppsRoot\\$iAppsDir\\$iPerlExe -v`; |
|
384 foreach (@iPerlExeRet) |
|
385 { |
|
386 if (m/ (version\s+|v)([0-9]{0,2}\.[0-9]{0,3}[_\.][0-9]{0,2})/) |
|
387 { |
|
388 if ($iVersion) { print "ERROR: Perl Version redefined as $2.\n"; last; } # Error? Can't have version defined twice!? |
|
389 $iVersion = $2; |
|
390 } |
|
391 elsif (m/Binary\s+build\s+(\d+)/i) |
|
392 { |
|
393 if ($iBuildNum) { print "ERROR: Perl Build Number redefined as $1.\n"; last; } # Error? Can't have build defined twice!? |
|
394 $iBuildNum = $1; |
|
395 } |
|
396 } |
|
397 # We have already set $iToolList->{$iToolName}{'multiver'}{$iMultiVer} = 'Unknown'; |
|
398 # So if $iVersion is still undefined, leave well alone! Eventually return 'Unknown'. |
|
399 if ($iVersion) # Found version. Have we got a Build Number? |
|
400 { |
|
401 unless($iBuildNum) { $iBuildNum = 'Build unknown'; } |
|
402 $iToolList->{$iToolName}{'multiver'}{$iMultiVer} = "$iVersion [$iBuildNum]"; |
|
403 } |
|
404 } |
|
405 } # End foreach my $iAppsDir (@$iAppsDirs) |
|
406 } |
|
407 |
|
408 # GetPerlModuleInfo |
|
409 # |
|
410 # Description |
|
411 # Gets Version for the specified Perl Module |
|
412 # |
|
413 # Inputs - Name of Module |
|
414 # |
|
415 # Retuens - Version text |
|
416 # |
|
417 sub GetPerlModuleInfo |
|
418 { |
|
419 my $iModuleName = shift; |
|
420 my $iVerTxt = 'Unknown'; |
|
421 $iModuleName =~ s/-/::/; |
|
422 if (eval "require $iModuleName;") |
|
423 { |
|
424 no strict 'refs'; |
|
425 $iVerTxt = ${$iModuleName . "::VERSION"}; |
|
426 use strict; |
|
427 } |
|
428 return $iVerTxt; |
|
429 } |
|
430 |
|
431 # GetMetrowerksInfo |
|
432 # |
|
433 # Description |
|
434 # Gets Metrowerks Compiler and Linker Versions |
|
435 # |
|
436 # Inputs - Reference to Tool List hash (for return of data) |
|
437 # |
|
438 # Outputs - Data returned via supplied hashref |
|
439 # |
|
440 sub GetMetrowerksInfo |
|
441 { |
|
442 |
|
443 |
|
444 my $iToolList = shift; |
|
445 |
|
446 # First get the version of the default Compiler (MWCCSym2), as located by the "permanent" PATH etc. |
|
447 my $iToolNameCC = 'Metrowerks Compiler'; |
|
448 $iToolList->{$iToolNameCC}{'version'} = 'Unknown'; |
|
449 my @iCCRet = `mwccsym2 -version 2>&1`; |
|
450 foreach (@iCCRet) |
|
451 { |
|
452 if (m/Version(.*)(\n$)/) |
|
453 { |
|
454 $iToolList->{$iToolNameCC}{'version'} = $1; |
|
455 last; |
|
456 } |
|
457 } |
|
458 |
|
459 # Now get the version of the default Linker (MWLDSym2), as located by the "permanent" PATH etc. |
|
460 my $iToolNameLD = 'Metrowerks Linker'; |
|
461 my @iLDEnv = `mwldsym2 -version 2>&1`; |
|
462 $iToolList->{$iToolNameLD}{'version'} = 'Unknown'; |
|
463 foreach (@iLDEnv) |
|
464 { |
|
465 if (m/Version(.*)(\n$)/) |
|
466 { |
|
467 $iToolList->{$iToolNameLD}{'version'} = $1; |
|
468 last; |
|
469 } |
|
470 } |
|
471 |
|
472 # Next look for "Multiple Versions" |
|
473 # For example "\\LON-ENGBUILD54\C$\Apps\Metrowerks\OEM3.1.1\Symbian_Tools\Command_Line_Tools\mwccsym2.exe" |
|
474 my $iMWksRoot = 'C:\Apps\Metrowerks'; |
|
475 my $iMWksCC = 'Symbian_Tools\Command_Line_Tools\mwccsym2.exe'; |
|
476 my $iMWksLD = 'Symbian_Tools\Command_Line_Tools\mwldsym2.exe'; |
|
477 my $iMWksDirs = ReadDirectory($iMWksRoot); # Get arrayref |
|
478 unless (defined $iMWksDirs) |
|
479 { |
|
480 print "ERROR: Failed to read Metrowerks Root Directory.\n"; |
|
481 return; |
|
482 } |
|
483 foreach my $iMWksDir (@$iMWksDirs) |
|
484 { |
|
485 if ($iMWksDir =~ m/^OEM\d+\.\d+/i) |
|
486 { |
|
487 $iMWksDir = uc $iMWksDir; # Source is a Windows directory name, which could be in any case |
|
488 my @iMWksCCRet = `$iMWksRoot\\$iMWksDir\\$iMWksCC`; |
|
489 $iToolList->{$iToolNameCC}{'multiver'}{$iMWksDir} = 'Unknown'; |
|
490 foreach my $iLine(@iMWksCCRet) |
|
491 { |
|
492 if ($iLine =~ m/Version(.*)(\n$)/i) |
|
493 { |
|
494 $iToolList->{$iToolNameCC}{'multiver'}{$iMWksDir} = $1; |
|
495 last; |
|
496 } |
|
497 } |
|
498 my @iMWksLDRet = `$iMWksRoot\\$iMWksDir\\$iMWksLD`; |
|
499 $iToolList->{$iToolNameLD}{'multiver'}{$iMWksDir} = 'Unknown'; |
|
500 foreach my $iLine(@iMWksLDRet) |
|
501 { |
|
502 if ($iLine =~ m/Version(.*)(\n$)/i) |
|
503 { |
|
504 $iToolList->{$iToolNameLD}{'multiver'}{$iMWksDir} = $1; |
|
505 last; |
|
506 } |
|
507 } |
|
508 } |
|
509 } # End foreach my $iMWksDir (@$iMWksDirs) |
|
510 |
|
511 } |
|
512 |
|
513 # GetArmInfo |
|
514 # |
|
515 # Description |
|
516 # Looks for directories below C:\Apps\ARM which might contain versions of RVCT compiler etc. |
|
517 # |
|
518 # Inputs - Reference to Tool List hash (for return of data) |
|
519 # |
|
520 # Outputs - Data returned via supplied hashref |
|
521 # |
|
522 sub GetArmInfo |
|
523 { |
|
524 my $iToolList = shift; |
|
525 my $iToolName = 'Arm CC'; |
|
526 |
|
527 # First get the version of the default ARMCC, as located by the "permanent" PATH etc. |
|
528 $iToolList->{$iToolName}{'version'} = 'Unknown'; |
|
529 my @iArmCCRet = `armcc --vsn 2>&1`; |
|
530 foreach (@iArmCCRet) |
|
531 { |
|
532 if (m/RVCT(.*)(\n$)/) |
|
533 { |
|
534 $iToolList->{$iToolName}{'version'} = $1; |
|
535 last; |
|
536 } |
|
537 } |
|
538 # Next look for "Multiple Versions" |
|
539 # For example "\\LON-ENGBUILD51\C$\Apps\ARM\RVCT2.2[435]\RVCT\Programs\2.2\349\win_32-pentium\armcc.exe" |
|
540 my $iRVCTRoot = 'C:\Apps\ARM'; |
|
541 my $iRVCTCC2 = 'RVCT\Programs\2.2\349\win_32-pentium\armcc.exe'; # Applies to RVCT Version 2.x |
|
542 my $iRVCTCC3 = 'bin\armcc.exe'; # Applies to RVCT Version 3.x |
|
543 my $iRVCTDirs = ReadDirectory($iRVCTRoot); # Get arrayref |
|
544 unless (defined $iRVCTDirs) |
|
545 { |
|
546 print "ERROR: Failed to read ARM Root Directory.\n"; |
|
547 return; |
|
548 } |
|
549 foreach my $iRVCTDir (@$iRVCTDirs) # Applies to RVCT Version 2.x |
|
550 { |
|
551 $iRVCTDir = uc $iRVCTDir; # Source is a Windows directory name, which could be in any case |
|
552 if ($iRVCTDir =~ m/^RVCT2\.\d+/i) |
|
553 { |
|
554 $iToolList->{$iToolName}{'multiver'}{$iRVCTDir} = GetArmVersion("$iRVCTRoot\\$iRVCTDir\\$iRVCTCC2"); |
|
555 } |
|
556 elsif ($iRVCTDir =~ m/^RVCT\d+\.\d+/i) # Applies to RVCT Version 3.x (and above, until we know otherwise!!) |
|
557 { |
|
558 $iToolList->{$iToolName}{'multiver'}{$iRVCTDir} = GetArmVersion("$iRVCTRoot\\$iRVCTDir\\$iRVCTCC3"); |
|
559 } |
|
560 } |
|
561 |
|
562 } |
|
563 |
|
564 # GetArmVersion |
|
565 # |
|
566 # Description |
|
567 # Gets Arm Compiler Version for a specified instance. |
|
568 # |
|
569 # Inputs - Full pathname of compiler (ARMCC.EXE) |
|
570 # |
|
571 # Outputs - Version (as text) or 'Unknown' if not determined |
|
572 # |
|
573 sub GetArmVersion |
|
574 { |
|
575 my $iRVCTCC = shift; # Full pathname of compiler (ARMCC.EXE) |
|
576 my @iArmCCEnv = `$iRVCTCC --vsn 2>&1`; |
|
577 foreach my $iLine(@iArmCCEnv) |
|
578 { |
|
579 if ($iLine =~ m/RVCT(.*)(\n$)/i) |
|
580 { |
|
581 return $1; |
|
582 } |
|
583 } |
|
584 return 'Unknown'; |
|
585 } |
|
586 |
|
587 # GetJavaInfo |
|
588 # |
|
589 # Description |
|
590 # Gets Java Runtime Compiler Version |
|
591 # |
|
592 # Inputs - Reference to Tool List hash (for return of data) |
|
593 # |
|
594 # Outputs - Data returned via supplied hashref |
|
595 # |
|
596 sub GetJavaInfo |
|
597 { |
|
598 my $iToolList = shift; |
|
599 my $iToolName = 'Java'; |
|
600 |
|
601 # First get the version of the default Java installation as located by the "permanent" PATH etc. |
|
602 # This probably means running |
|
603 my @iJavaReturn = `java -version 2>&1`; |
|
604 $iToolList->{$iToolName}{'version'} = 'Unknown'; |
|
605 foreach my $iLine (@iJavaReturn) |
|
606 { |
|
607 if ($iLine =~ m/version.*(\"{1})(.*)(\"{1})/i) |
|
608 { |
|
609 $iToolList->{$iToolName}{'version'} = $2; |
|
610 last; |
|
611 } |
|
612 } |
|
613 |
|
614 # Next look for "Multiple Versions" - Assumed to be in directories matching 'C:\Apps\JRE*' |
|
615 # For example "C:\Apps\JRE1.5.0_13\bin\java.exe" |
|
616 my $iJRERoot = 'C:\Apps'; |
|
617 my $iJREEXE = 'bin\java.exe'; |
|
618 my $iJREDirs = ReadDirectory($iJRERoot); # Get arrayref (list of sub-directories |
|
619 unless (defined $iJREDirs) |
|
620 { |
|
621 print "ERROR: Failed to read JRE Root Directory: $iJRERoot.\n"; |
|
622 return; |
|
623 } |
|
624 foreach my $iJREDir (@$iJREDirs) |
|
625 { |
|
626 if ($iJREDir =~ m/^JRE\d+\.\d+/i) |
|
627 { |
|
628 $iJREDir = uc $iJREDir; # Source is a Windows directory name, which could be in any case |
|
629 my @iJREReturn = `$iJRERoot\\$iJREDir\\$iJREEXE -version 2>&1`; |
|
630 $iToolList->{$iToolName}{'multiver'}{$iJREDir} = 'Unknown'; |
|
631 foreach my $iLine(@iJREReturn) |
|
632 { |
|
633 if ($iLine =~ m/version.*(\"{1})(.*)(\"{1})/i) |
|
634 { |
|
635 $iToolList->{$iToolName}{'multiver'}{$iJREDir} = $2; |
|
636 last; |
|
637 } |
|
638 } |
|
639 } |
|
640 } |
|
641 |
|
642 } |
|
643 |
|
644 # GetSophosInfo |
|
645 # |
|
646 # Description |
|
647 # Gets Sophos Version |
|
648 # |
|
649 # Inputs - Reference to Tool List hash (for return of data) |
|
650 # |
|
651 # Outputs - Data returned via supplied hashref |
|
652 # |
|
653 sub GetSophosInfo |
|
654 { |
|
655 my $iToolList = shift; |
|
656 # Sophos Anti-virus |
|
657 # Typical output from "sav32cli.exe -v" |
|
658 # Sophos Anti-Virus |
|
659 # Copyright (c) 1989-2005 Sophos Plc, www.sophos.com |
|
660 # System time 11:58:18, System date 04 April 2005 |
|
661 # Product version : 3.92.0 |
|
662 # Engine version : 2.28.10 |
|
663 # Virus data version : 3.92 |
|
664 # User interface version : 2.03.048 |
|
665 # Platform : Win32/Intel |
|
666 # Released : 04 April 2005 |
|
667 # Total viruses (with IDEs) : 102532 |
|
668 my $iSophosExe='C:\Program Files\Sophos SWEEP for NT\sav32cli.exe'; |
|
669 $iToolList->{'Sophos product'}{'version'} = 'Unknown'; |
|
670 $iToolList->{'Sophos data'}{'version'} = 'Unknown'; |
|
671 $iToolList->{'Sophos release'}{'version'} = 'Unknown'; |
|
672 if (-e $iSophosExe) |
|
673 { |
|
674 my @iSophosVer = `\"$iSophosExe\" -v`; |
|
675 |
|
676 # Get Sophos versions |
|
677 foreach my $iLine (@iSophosVer) |
|
678 { |
|
679 if ($iLine =~ m/Product\s+version\s+:\s+(\S+)/) |
|
680 { |
|
681 $iToolList->{'Sophos product'}{'version'} = $1; |
|
682 next; |
|
683 } |
|
684 if ($iLine =~ m/Virus\s+data\s+version\s+:\s+(\S+)/) |
|
685 { |
|
686 $iToolList->{'Sophos data'}{'version'} = $1; |
|
687 next; |
|
688 } |
|
689 if ($iLine =~ m/Released\s+:\s+(.+)/) |
|
690 { |
|
691 $iToolList->{'Sophos release'}{'version'} = $1; |
|
692 next; |
|
693 } |
|
694 } |
|
695 } |
|
696 |
|
697 } |
|
698 |
|
699 # GetMcAfeeInfo |
|
700 # |
|
701 # Description |
|
702 # Gets McAfee Versions (Software and data) |
|
703 # |
|
704 # Inputs - Reference to Tool List hash (for return of data) |
|
705 # |
|
706 # Outputs - Data returned via supplied hashref |
|
707 # |
|
708 sub GetMcAfeeInfo |
|
709 { |
|
710 my $iToolList = shift; |
|
711 # McAfee Anti-virus |
|
712 # Revision March 2007 - Get Versions from Registry in the following location (for Version 8.000?): |
|
713 # HKEY_LOCAL_MACHINE\SOFTWARE\Network Associates\ePolicy Orchestrator\Application Plugins\VIRUSCAN8000 |
|
714 $iToolList->{'McAfee VirusScan'}{'version'} = 'Unknown'; |
|
715 $iToolList->{'McAfee VirusData'}{'version'} = 'Unknown'; |
|
716 |
|
717 my $iRegKey = 'LMachine/SOFTWARE/Network Associates/ePolicy Orchestrator/Application Plugins'; |
|
718 # Get data from hash set up by Win32::TieRegistry |
|
719 my $iHashRef = $Registry->{$iRegKey}; |
|
720 unless (defined $iHashRef) { print "WARNING: Failed to read McAfee version from Registry\n"; return; } |
|
721 my @iValidHashKeys; |
|
722 foreach my $iHashKey (sort %$iHashRef) |
|
723 { |
|
724 if ($iHashKey =~ m/^VIRUSCAN\d+/i) |
|
725 { |
|
726 push @iValidHashKeys,$iHashKey; |
|
727 } |
|
728 } |
|
729 unless (scalar @iValidHashKeys) |
|
730 { |
|
731 return; # No valid sub-key |
|
732 } |
|
733 if ((scalar @iValidHashKeys) > 1) |
|
734 { |
|
735 print "WARNING: Duplicate McAfee Versions.\n"; |
|
736 } |
|
737 |
|
738 @iValidHashKeys = sort @iValidHashKeys; |
|
739 my $iVersionKey = pop @iValidHashKeys; # In the unlikely event of there being more than one, get the last one! |
|
740 |
|
741 # Check that hash element exists before referencing data. Otherwise TieRegistry will think that we want to create a new key/value |
|
742 if (defined $iHashRef->{$iVersionKey}{'/Version'}) { $iToolList->{'McAfee VirusScan'}{'version'} = $iHashRef->{$iVersionKey}{'/Version'}; } |
|
743 if (defined $iHashRef->{$iVersionKey}{'/DATVersion'}) { $iToolList->{'McAfee VirusData'}{'version'} = $iHashRef->{$iVersionKey}{'/DATVersion'}; } |
|
744 } |
|
745 |
|
746 # GetGPGInfo |
|
747 # |
|
748 # Description |
|
749 # Gets GPG Version (currently usually |
|
750 # |
|
751 # Inputs - Reference to Tool List hash (for return of data) |
|
752 # |
|
753 # Outputs - Data returned via supplied hashref |
|
754 # |
|
755 sub GetGPGInfo |
|
756 { |
|
757 my $iToolList = shift; |
|
758 |
|
759 # Typical output from 'GPG -h' |
|
760 # gpg (GnuPG) 1.4.4 |
|
761 # Copyright (C) 2006 Free Software Foundation, Inc. |
|
762 # This program comes with ABSOLUTELY NO WARRANTY. |
|
763 # This is free software, and you are welcome to redistribute it |
|
764 # under certain conditions. See the file COPYING for details. |
|
765 |
|
766 my $iToolName = 'GnuPG'; |
|
767 my @iRetData = `GPG -h 2>&1`; |
|
768 $iToolList->{$iToolName}{'version'} = 'Unknown'; |
|
769 foreach (@iRetData) |
|
770 { |
|
771 if (m/^\s*gpg\s+\(GnuPG\)\s*(\d+\.\d+\.\d+)/i) |
|
772 { |
|
773 $iToolList->{$iToolName}{'version'} = $1; |
|
774 last; |
|
775 } |
|
776 } |
|
777 } |
|
778 |
|
779 # GetWinTapInfo |
|
780 # |
|
781 # Description |
|
782 # Gets WinTap Version |
|
783 # |
|
784 # Inputs - Reference to Tool List hash (for return of data) |
|
785 # |
|
786 # Outputs - Data returned via supplied hashref |
|
787 # |
|
788 sub GetWinTapInfo |
|
789 { |
|
790 my $iToolList = shift; |
|
791 |
|
792 # Typical output from 'IPCONFIG /ALL' |
|
793 # Ethernet adapter TAP-Win32: |
|
794 # Connection-specific DNS Suffix . : |
|
795 # Description . . . . . . . . . . . : TAP-Win32 Adapter V8 |
|
796 my $iToolName = 'WinTAP'; |
|
797 my @iRetData = `IPCONFIG /ALL 2>&1`; |
|
798 $iToolList->{$iToolName}{'version'} = 'Unknown'; |
|
799 foreach (@iRetData) |
|
800 { |
|
801 if (m/Description.+TAP-Win32\s+Adapter\s+(V.+)/i) |
|
802 { |
|
803 $iToolList->{$iToolName}{'version'} = $1; |
|
804 last; |
|
805 } |
|
806 } |
|
807 } |
|
808 |
|
809 # ReadDirectory |
|
810 # |
|
811 # Read specified directory. Remove '.' and '..' entries (Windows speciality!) |
|
812 # |
|
813 # Input: Directory name |
|
814 # |
|
815 # Return: Array of subdirectory names, or undef if open fails. |
|
816 # |
|
817 sub ReadDirectory |
|
818 { |
|
819 my $iDirName = shift; |
|
820 |
|
821 unless (opendir DIRECTORY, $iDirName) |
|
822 { |
|
823 print ("ERROR: Failed to open directory: $iDirName\nERROR: $!\n"); |
|
824 return undef; |
|
825 } |
|
826 my @iSubDirs = readdir(DIRECTORY); |
|
827 closedir DIRECTORY; |
|
828 |
|
829 # Remove '.' and '..' from list |
|
830 for (my $iIndx = 0; $iIndx < (scalar @iSubDirs); ) |
|
831 { |
|
832 if ($iSubDirs[$iIndx] =~ m/^\.{1,2}/) |
|
833 { |
|
834 splice @iSubDirs, $iIndx, 1; |
|
835 } |
|
836 else |
|
837 { |
|
838 ++$iIndx; |
|
839 } |
|
840 } |
|
841 |
|
842 return \@iSubDirs; |
|
843 } |
|
844 |
|
845 1; |
|