Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

723 lines
18 KiB

  1. ####################################################################################
  2. # SpawnProcess()
  3. # Spawns a new instance of specified application in param1, with arguments in param2
  4. # return Process Object on success, 0 on failure
  5. # a-jbilas, 06/01/99 - created
  6. ####################################################################################
  7. sub SpawnProcess
  8. {
  9. local($sTheApp, $sTheArgs) = @_;
  10. local($pTheApp) = 0;
  11. if ($sTheApp !~ /(\/|\\)/)
  12. {
  13. my($sTheAppWithPath) = FindOnPath($sTheApp);
  14. if ($sTheAppWithPath)
  15. {
  16. $sTheApp = $sTheAppWithPath;
  17. }
  18. }
  19. if (!-e $sTheApp)
  20. {
  21. PrintToLogErr("Cannot spawn process, '$sTheApp' does not exist\n");
  22. }
  23. else
  24. {
  25. PrintToLog(" - Spawning new instance of '$sTheApp $sTheArgs'\n");
  26. if (!Win32::Process::Create($pTheApp,
  27. $sTheApp,
  28. RemovePath($sTheApp)." ".$sTheArgs,
  29. 0,
  30. NORMAL_PRIORITY_CLASS,
  31. "."))
  32. {
  33. PrintToLogErr("SpawnProcess() Error: ".Win32::FormatMessage(Win32::GetLastError()));
  34. $pTheApp = 0;
  35. }
  36. }
  37. return($pTheApp);
  38. }
  39. ####################################################################################
  40. # GetFiles()
  41. # When passed a directory, it will return a list of all absolute path filenames contained
  42. # within. Returns an empty list upon failure (either to open dir or find subdirs)
  43. # if no dir passed as argument, will assume current directory and do relative path filenames
  44. # adding a non-null second argument will recurse subdirectories (to recurse current
  45. # directory subdirectories, pass either "" (relative paths) or cwd() (absolute paths)
  46. # as first argument). subdirs .. and . are ignored
  47. # a-jbilas, 07/08/99 - created
  48. # a-jbilas, 07/16/99 - added recurse option
  49. ####################################################################################
  50. sub GetFiles
  51. {
  52. my(@lFiles) = ();
  53. my($sRelDir) = (($_[0] eq "") ? "" : $_[0]."\\");
  54. opendir(SRCDIR, (($_[0] eq "") ? cwd() : $_[0]));
  55. foreach $file (readdir(SRCDIR))
  56. {
  57. if (!-d $sRelDir.$file)
  58. {
  59. push(@lFiles, $sRelDir.$file);
  60. }
  61. elsif ((-d $sRelDir.$file) && ($_[1] ne "") && ($file !~ /^\.\.?$/))
  62. {
  63. push(@lFiles, GetFiles($sRelDir.$file, 1));
  64. }
  65. }
  66. closedir(SRCDIR);
  67. if ($DEBUG && (@lFiles == ()) && ($_[1] eq ""))
  68. {
  69. PrintToLogErr("GetFiles() Warning: no files found in ".(($_[0] eq "") ? cwd() : $_[0])."\n");
  70. }
  71. return(@lFiles);
  72. }
  73. ####################################################################################
  74. # GetSubdirs()
  75. # When passed a directory, it will return a list of all absolute path subdirs contained
  76. # within. Returns an empty list upon failure (either to open dir or find subdirs)
  77. # if no dir passed as argument, will assume current directory and do relative paths
  78. # adding a non-null second argument will recurse subdirectories (to recurse current
  79. # directory subdirectories, pass either "" for relative paths or cwd() for absolute paths
  80. # as first argument). subdirs .. and . are ignored
  81. # a-jbilas, 07/08/99 - created
  82. # a-jbilas, 07/16/99 - added recurse option
  83. ####################################################################################
  84. sub GetSubdirs
  85. {
  86. my(@lDirs) = ();
  87. my($sRelDir) = (($_[0] eq "") ? "" : $_[0]."\\");
  88. opendir(SRCDIR, (($_[0] eq "") ? cwd() : $_[0]));
  89. foreach $dir (readdir(SRCDIR))
  90. {
  91. if ((-d $sRelDir.$dir) && ($dir !~ /^\.\.?$/))
  92. {
  93. push(@lDirs, $sRelDir.$dir);
  94. if ($_[1] ne "")
  95. {
  96. push(@lDirs, GetSubdirs($sRelDir.$dir, 1));
  97. }
  98. }
  99. }
  100. closedir(SRCDIR);
  101. if ($DEBUG && (@lDirs == ()) && ($_[1] eq ""))
  102. {
  103. PrintToLogErr("GetSubdirs() Warning: no subdirs found in ".(($_[0] eq "") ? cwd() : $_[0])."\n");
  104. }
  105. return(@lDirs);
  106. }
  107. ####################################################################################
  108. # GrabCookie()
  109. # Grabs the cookie -- when passed r (read) or w (write) string as parameter, if cookie
  110. # grab fails, will wait 10 minutes before trying another grab. If cookie could not be
  111. # grabbed after 30 attempts (5 hours), function returns 0, it otherwise returns 1
  112. # a-jbilas, 07/14/99 - created
  113. ####################################################################################
  114. sub GrabCookie
  115. {
  116. my($rc) = 1;
  117. my($nMaxAttempts) = 30;
  118. my($bCookieGrabbed) = 0;
  119. if (($_[0] ne "r") && ($_[0] ne "w"))
  120. {
  121. carp("Usage: GrabCookie(r/w) ");
  122. $rc = 0;
  123. }
  124. else
  125. {
  126. PrintToLog("Attempting to obtain a ".$_[0]." lock on cookie\n");
  127. for ($nAttempt = 1 ; (!$bCookieGrabbed && ($nAttempt <= $nMaxAttempts)) ; ++$nAttempt)
  128. {
  129. if (Execute('cookie -v'.$_[0].'c "Locked for the '.$PROCESSOR_ARCHITECTURE.' build"'))
  130. {
  131. PrintToLog("Cookie successfully grabbed\n");
  132. $bCookieGrabbed = 1;
  133. }
  134. elsif ($nAttempt != 30)
  135. {
  136. PrintToLog("Cookie grab failed, waiting 10 minutes for cookie to be freed ");
  137. for ($time = 1 ; $time <= 10 ; ++$time) #sleep ten minutes
  138. {
  139. print(".");
  140. sleep(60);
  141. }
  142. PrintToLog("\n");
  143. }
  144. }
  145. }
  146. if (!$bCookieGrabbed)
  147. {
  148. PrintToLogErr("GrabCookie() Error: Cookie could not be obtained\n");
  149. $rc = 0;
  150. }
  151. return($rc);
  152. }
  153. #### DougP 7/19/99
  154. #### return full path of a program found on the path.
  155. sub FindOnPath
  156. {
  157. my ($strProgram) = @_;
  158. foreach $dir (split (';', $ENV{"PATH"}))
  159. {
  160. my $strFullPath = $dir."\\".$strProgram;
  161. if (-e $strFullPath)
  162. {
  163. return $strFullPath;
  164. }
  165. }
  166. print "couldn't find path for $strProgram\n";
  167. return 0;
  168. }
  169. ####################################################################################
  170. # NLP3CleanAll()
  171. # traverse all of nlp3 project and delnode directories with names match arguments
  172. # passed to function (if no args, use function defaults)
  173. # returns number of files deleted
  174. # a-jbilas, 07/21/99 - created
  175. ####################################################################################
  176. sub NLP3CleanAll
  177. {
  178. local(@lCleanDirs) = @_;
  179. if (@lCleanDirs == ())
  180. {
  181. # this is the default
  182. @lCleanDirs = ("DEBUG", "RELEASE", "PROFILE", "ENGLISH", "ENGLISH_S", "JAPANESE",
  183. "SPANISH", "FRENCH", "GERMAN", "ENGLISH-INIT", "ENGLISH-C");
  184. }
  185. my($nTotalFiles) = 0;
  186. if (PushD($SAPIROOT))
  187. {
  188. foreach $dir (GetSubdirs())
  189. {
  190. $dir = lc($dir);
  191. $nTotalFiles += DelOld(cwd()."\\".$dir, *lCleanDirs);
  192. }
  193. PopD(); # $SAPIROOT
  194. }
  195. return($nTotalFiles);
  196. }
  197. ####################################################################################
  198. # PrintToMsg()
  199. # Outputs 1st string parameter to $strBuildMsg with optional additional string
  200. # parameters output as subsets to 1st string (all properly formatted)
  201. # a-jbilas, 07/22/99 - created
  202. ####################################################################################
  203. sub PrintToMsg
  204. {
  205. local(@lOutput) = @_;
  206. if ($lOutput[0] =~ /fail/i)
  207. {
  208. PrintToLogErr($lOutput[0]);
  209. }
  210. else
  211. {
  212. PrintToLog($lOutput[0]);
  213. }
  214. $lOutput[0] =~ s/(failed|succeeded|succeeds)/<bold>$1<\/bold>/gi;
  215. $strBuildMsg .= "<dd>".$lOutput[0]."\n";
  216. shift(@lOutput);
  217. if ($lOutput)
  218. {
  219. $strBuildMsg .= "<dl compact><em>\n";
  220. foreach $msg (@lOutput)
  221. {
  222. PrintToLog($msg);
  223. $msg =~ s/\n/<BR>\n/g;
  224. $strBuildMsg .= "<dd>".$msg;
  225. }
  226. $strBuildMsg .= "<\/dl><\/em>\n";
  227. }
  228. }
  229. ####################################################################################
  230. # GlobalReplaceInFile()
  231. # Performs a global string replacement in file specified
  232. # a-jbilas, 07/26/99 - created
  233. ####################################################################################
  234. sub GlobalReplaceInFile($$$)
  235. {
  236. # NOTE: entire file buffered in memory, not for use w/ extremely large files
  237. my($sFileName, $sSrc, $sTgt) = @_;
  238. my($buf) = "";
  239. my($acc) = "";
  240. my($bFound) = 0;
  241. my($fhIn) = OpenFile($sFileName, "read");
  242. if (!$fhIn)
  243. {
  244. return(0);
  245. }
  246. else
  247. {
  248. while (!$fhIn->eof())
  249. {
  250. $buf = $fhIn->getline();
  251. if (!$bFound && ($buf =~ /$sSrc/))
  252. {
  253. $bFound = 1;
  254. }
  255. $buf =~ s/$sSrc/$sTgt/g;
  256. $acc .= $buf;
  257. }
  258. CloseFile($fhIn);
  259. if ($bFound)
  260. {
  261. unlink($fhIn);
  262. my($fhOut) = OpenFile($sFileName, "write");
  263. $fhOut->print($acc);
  264. CloseFile($fhOut);
  265. return(1);
  266. }
  267. }
  268. }
  269. sub Isx86()
  270. {
  271. return(lc($PROCESSOR_ARCHITECTURE) eq "x86");
  272. }
  273. sub IsAlpha()
  274. {
  275. return(lc($PROCESSOR_ARCHITECTURE) eq "alpha");
  276. }
  277. # two routines to track disk space
  278. # return the space left on a directory (in Mb)
  279. # DougP 7/6/99
  280. sub SpaceLeft
  281. {
  282. my ($strDir) = @_;
  283. open (FPIN, "dir /-C $strDir |");
  284. my $iSpace = -1;
  285. while (<FPIN>)
  286. {
  287. if (/(\d+) bytes free/)
  288. {
  289. $iSpace = $1;
  290. }
  291. }
  292. close (FPIN);
  293. $iSpace /= (1 << 20); # convert to Mb
  294. return int $iSpace;
  295. }
  296. # return an html message if disk space available is below the set limit (in Mb)
  297. # warning if below 5 times set limit
  298. # DougP 7/6/99
  299. sub SpaceLeftAlarm
  300. {
  301. my ($strDir, $iAlarmLevel) = @_;
  302. my $iSpaceLeft = SpaceLeft $strDir;
  303. print "Space left on $strDir is ${iSpaceLeft}M\n";
  304. if ($iSpaceLeft < $iAlarmLevel)
  305. {
  306. return "<strong><font color=red>Space left on $strDir is ${iSpaceLeft}M</font></strong><br>\n";
  307. }
  308. if ($iSpaceLeft < 5*$iAlarmLevel)
  309. {
  310. return "<font color=orange>Space left on $strDir is ${iSpaceLeft}M</font><br>\n";
  311. }
  312. return "";
  313. }
  314. ####################################################################################
  315. # PrintL()
  316. # multi-option print, options listed with constants at top of library
  317. # Input: output string as first var, options as second var
  318. # (if null, PL_NORMAL assumed)
  319. # a-jbilas, 08/08/99 - created
  320. ####################################################################################
  321. sub PrintL
  322. {
  323. my($sMsg, $sModifiers) = @_;
  324. my($sHead) = "";
  325. my($sFoot) = "";
  326. # skip rest of function if just printing to console and log
  327. if (($sModifiers eq "") || ($sModifiers == PL_NORMAL))
  328. {
  329. print(STDOUT $sMsg);
  330. if ($fhBuildLog)
  331. {
  332. my($tmp) = $sMsg;
  333. $tmp =~ s/\n/<br>\n/g;
  334. $fhBuildLog->print($tmp);
  335. }
  336. return();
  337. }
  338. # color modifiers
  339. if ($sModifiers & PL_RED)
  340. {
  341. $sHead = '<font color="red">'.$sHead;
  342. $sFoot = $sFoot.'</font>';
  343. }
  344. elsif ($sModifiers & PL_BLUE)
  345. {
  346. $sHead = '<font color="blue">'.$sHead;
  347. $sFoot = $sFoot.'</font>';
  348. }
  349. elsif ($sModifiers & PL_GREEN)
  350. {
  351. $sHead = '<font color="green">'.$sHead;
  352. $sFoot = $sFoot.'</font>';
  353. }
  354. elsif ($sModifiers & PL_PURPLE)
  355. {
  356. $sHead = '<font color="purple">'.$sHead;
  357. $sFoot = $sFoot.'</font>';
  358. }
  359. elsif ($sModifiers & PL_ORANGE)
  360. {
  361. $sHead = '<font color="orange">'.$sHead;
  362. $sFoot = $sFoot.'</font>';
  363. }
  364. # font modifiers
  365. if ($sModifiers & PL_LARGE)
  366. {
  367. $sHead = '<font size="4">'.$sHead;
  368. $sFoot = $sFoot.'</font>';
  369. }
  370. if ($sModifiers & PL_BOLD)
  371. {
  372. $sHead = '<b>'.$sHead;
  373. $sFoot = $sFoot.'</b>';
  374. }
  375. if ($sModifiers & PL_ITALIC)
  376. {
  377. $sHead = '<i>'.$sHead;
  378. $sFoot = $sFoot.'</i>';
  379. }
  380. if (defined $strBuildMsg)
  381. {
  382. if ($sModifiers & PL_BOOKMARK)
  383. {
  384. $strBuildMsg .= Bookmark($sHead.$sMsg.$sFoot);
  385. }
  386. elsif ($sModifiers & PL_MSG)
  387. {
  388. $strBuildMsg .= $sHead.$sMsg.$sFoot."\n";
  389. }
  390. }
  391. if ($fhBuildLog && !($sModifiers & PL_NOLOG))
  392. {
  393. my($tmp) = $sMsg;
  394. $tmp =~ s/\n/<br>\n/g;
  395. $fhBuildLog->print($sHead.$tmp.$sFoot);
  396. }
  397. if (!($sModifiers & PL_NOSTD))
  398. {
  399. if ($sModifiers & PL_NOTAG)
  400. {
  401. $sMsg =~ s/<[^>]*>//g;
  402. }
  403. if ($sModifiers & PL_STDERR)
  404. {
  405. print(STDERR $sMsg);
  406. }
  407. else
  408. {
  409. print(STDOUT $sMsg);
  410. }
  411. }
  412. if ($sModifiers & PL_FLUSH)
  413. {
  414. if (defined $fhBuildLog && !($sModifiers & PL_NOLOG))
  415. {
  416. $fhBuildLog->flush();
  417. }
  418. if (!($sModifiers & PL_NOSTD))
  419. {
  420. if ($sModifiers & PL_STDERR)
  421. {
  422. # TODO: how to flush STDERR?
  423. }
  424. else
  425. {
  426. # TODO: how to flush STDOUT?
  427. }
  428. }
  429. }
  430. }
  431. sub PrintMsgBlock
  432. {
  433. my($lineNum) = 0;
  434. my($maxReached) = 0;
  435. PrintL("<dl compact>", PL_MSG | PL_NOSTD | PL_NOLOG);
  436. foreach $line (@_)
  437. {
  438. if ((!defined $nMaxErrLines) || (!$maxReached && ($lineNum < $nMaxErrLines)))
  439. {
  440. PrintL("<dd>".$line."\n", PL_ITALIC | PL_MSG | PL_NOSTD | PL_NOLOG);
  441. }
  442. elsif (!$maxReached)
  443. {
  444. PrintL("<dd>Too many errors to display, click link to view continuation\n",
  445. PL_ITALIC | PL_MSG | PL_NOSTD | PL_NOLOG | PL_RED | PL_BOLD | PL_NOTAG);
  446. }
  447. }
  448. PrintL("</dl>", PL_MSG | PL_NOSTD | PL_NOLOG);
  449. }
  450. sub IsDirectory($)
  451. {
  452. local($rc) = 0;
  453. if (Win32::File::GetAttributes($_[0], $rc))
  454. {
  455. return($rc & DIRECTORY);
  456. }
  457. else
  458. {
  459. return(0);
  460. }
  461. }
  462. sub IsReadOnly($)
  463. {
  464. local($rc) = 0;
  465. if (Win32::File::GetAttributes($_[0], $rc))
  466. {
  467. return($rc & READONLY);
  468. }
  469. else
  470. {
  471. return(0);
  472. }
  473. }
  474. sub SetReadOnly($$)
  475. {
  476. local($attr) = 0;
  477. if (Win32::File::GetAttributes($_[0], $attr))
  478. {
  479. if ($_[1] && !($attr & READONLY))
  480. {
  481. $attr = $attr | READONLY;
  482. return(Win32::File::SetAttributes($_[0], $attr));
  483. }
  484. elsif (!$_[1] && ($attr & READONLY))
  485. {
  486. $attr = $attr - READONLY;
  487. return(Win32::File::SetAttributes($_[0], $attr));
  488. }
  489. else
  490. {
  491. return(1);
  492. }
  493. }
  494. else
  495. {
  496. return(0);
  497. }
  498. }
  499. sub GetDayRange
  500. {
  501. my($nNow) = time();
  502. my($x, $nDay, $nMon, $nYear);
  503. ($x, $x, $x, $nDay, $nMon, $nYear, $x, $x, $x) = localtime($nNow);
  504. my ($retVal) = ($nMon + 1).'/'.$nDay.'/'.$nYear;
  505. if (!$_[0])
  506. {
  507. return($retVal);
  508. }
  509. ($x, $x, $x, $nDay, $nMon, $nYear, $x, $x, $x) = localtime($nNow - $_[0] * 24 * 60 * 60);
  510. return(($nMon + 1).'/'.$nDay.'/'.$nYear);
  511. }
  512. sub GetSLMLog
  513. {
  514. my($strArg) = "";
  515. my($dir) = "";
  516. my($time) = "";
  517. my(%log) = "";
  518. foreach $i (@_)
  519. {
  520. if ($i eq "today")
  521. {
  522. my($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
  523. $strArg .= " -t ".($mon + 1)."/$mday/$year";
  524. }
  525. elsif ($i eq "user")
  526. {
  527. $strArg .= " -u $ENV{COMPUTERNAME}";
  528. }
  529. else
  530. {
  531. $strArg .= " $i";
  532. }
  533. }
  534. open(FPIN, 'log "-rfvi&" '.$strArg.' |');
  535. while (<FPIN>)
  536. {
  537. if (/^time/ || /^log : warning: /)
  538. {
  539. # skip header and warnings
  540. }
  541. elsif (/Log for (.*):/)
  542. {
  543. $dir = $1.$2;
  544. #print "Directory is ".$dir."\n";
  545. }
  546. elsif (/^(\d\d)-(\d\d)-(\d\d)\@(\d\d):(\d\d):(\d\d)\b(.*)$/)
  547. {
  548. $time = "$3/$1/$2 $4:$5:$6 ";
  549. my($day, $who, $what, $file, $ver1, $comment) = split ' ', $7, 6;
  550. if ($who =~ /^spgbldALPHA2(.+)/)
  551. { # fix up the running together of this long name and the operation
  552. $comment = $ver1.' '.$comment;
  553. $file = $what;
  554. $what = $1;
  555. $who = "spgbldALPHA2";
  556. }
  557. if ($file =~ /.+\\([\w.]+)/)
  558. {
  559. $file = "$dir\\$1";
  560. }
  561. if ($comment =~ /I\d+ +(.*)/)
  562. {
  563. $comment = $1;
  564. }
  565. if ($what ne "release")
  566. {
  567. $log{"$time $who $what $file"} = " - $comment\n";
  568. }
  569. }
  570. #else
  571. #{
  572. # print "X on $_";
  573. #}
  574. }
  575. close(FPIN);
  576. my($retVal) = "";
  577. foreach $k (reverse sort keys %log)
  578. {
  579. $retVal .= $k.$log{$k};
  580. }
  581. return($retVal);
  582. }
  583. sub FormatLogAsHTML($)
  584. {
  585. if ($_[0] eq "")
  586. {
  587. return('<font size=4><b>No History Available</b></font>');
  588. }
  589. my($result) = "<table border=1><caption><font size=4><b>Recent History</b></font></caption>\n".
  590. "<tr><th>when</th><th>who</th><th>what</th><th>file</th><th>comment</th></tr>\n";
  591. foreach $line (split(/\n/, $_[0]))
  592. {
  593. my($date, $time, $who, $what, $file, $comment) = split(' ', $line, 6);
  594. if ($comment =~ /^- (.*)/)
  595. {
  596. $comment = $1;
  597. }
  598. $result .= "<tr><td>$date $time</td><td>$who</td><td>$what</td><td>$file</td><td>$comment</td></tr>\n";
  599. }
  600. close (FPIN);
  601. return($result."</table>\n");
  602. }
  603. sub CleanUpSAPI()
  604. {
  605. if (PushD($SAPIROOT))
  606. {
  607. local(@lSubdirs) = GetSubdirs();
  608. foreach $i (@lSubdirs)
  609. {
  610. if (lc($i) ne 'bin'
  611. && lc($i) ne 'lib')
  612. {
  613. DelAll($i, 1, 1); #recurse, ignore SLM Ini
  614. }
  615. }
  616. }
  617. PopD(); #$SAPIROOT
  618. }
  619. $__SAPILIBPM = 1;
  620. 1;