Leaked source code of windows server 2003
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.

1079 lines
30 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // File: log.cxx
  4. //
  5. // Contents: The code for the logging servers client logging methods
  6. //
  7. // Functions: Log::Log()
  8. // Log::~Log()
  9. // Log::Info(inc, char *[])
  10. // Log::WriteData(PCHAR)
  11. //
  12. // History: 24-Sep-90 DaveWi Initial Coding
  13. // 11-Mar-94 DaveY Miniature Log.
  14. // 10-Aug-95 ChrisAB Changed fopen()s to _fsopens() for
  15. // proper chicago operation
  16. //
  17. //--------------------------------------------------------------------
  18. #include <comtpch.hxx>
  19. #pragma hdrstop
  20. extern "C"
  21. {
  22. #include <stdarg.h>
  23. #include <string.h>
  24. #include <time.h>
  25. #include <fcntl.h>
  26. #include <sys\types.h>
  27. #include <sys\stat.h>
  28. #include <io.h>
  29. #include <direct.h>
  30. #include <share.h>
  31. }
  32. #include "log.hxx"
  33. #include "log.h"
  34. #define CCH_MAX_CHARS 1024
  35. // Set up a table of the status text values
  36. const char * aStatus[] = { LOG_PASS_TXT,
  37. LOG_FAIL_TXT,
  38. LOG_WARN_TXT,
  39. LOG_ABORT_TXT,
  40. LOG_INFO_TXT,
  41. LOG_START_TXT,
  42. LOG_DONE_TXT };
  43. #ifdef WIN16
  44. #define OutputDebugStringA OutputDebugString
  45. #endif
  46. //+-------------------------------------------------------------------
  47. //
  48. // Member: Log::Log(int, char *[], DWORD)
  49. //
  50. // Synopsis: Log constructor with command line data given
  51. //
  52. // Arguments: [argc] - Argument count
  53. // [argv] - Argument array
  54. // [fUseUnicode] - whether we should use WCHARs
  55. //
  56. // Returns: Results from Info()
  57. //
  58. // History: ??-???-?? ???????? Created
  59. // Jun-11-92 DonCl added line to zero out LogStats struct
  60. //
  61. //--------------------------------------------------------------------
  62. Log :: Log(int argc, char *argv[], DWORD dwCharType) :
  63. fInfoSet(FALSE),
  64. ulLastError(ERROR_SUCCESS)
  65. {
  66. #if defined (_WIN32)
  67. //
  68. // Check the result of the CMutex Contructor and continue if
  69. // it succeeded
  70. //
  71. ulLastError = hMtxSerialize.QueryError();
  72. if (ulLastError == ERROR_SUCCESS)
  73. {
  74. ulLastError = Info(argc, argv);
  75. }
  76. #else
  77. ulLastError = Info(argc, argv);
  78. #endif
  79. }
  80. //+-------------------------------------------------------------------
  81. //
  82. // Member: Log::Log(PCHAR, PCHAR, PCHAR, PCHAR, PCHAR)
  83. //
  84. // Synopsis: Log constructor with internal data given
  85. //
  86. // Arguments: [pszSrvr] - Name of logging server
  87. // [pszTest] - Name of this test
  88. // [pszName] - Name of test runner
  89. // [pszSubPath] - Users log file qualifer
  90. // [pszObject] - Name of invoking object
  91. //
  92. // Returns:
  93. //
  94. // Modifies:
  95. //
  96. // History: ??-???-?? ???????? Created
  97. // Jun-11-92 DonCl added line to zero out LogStats struct
  98. //
  99. // BUGBUG wszName unused - left until all components can co-ordinate
  100. // with this. SarahJ
  101. //--------------------------------------------------------------------
  102. Log :: Log(PCHAR pszSrvr,
  103. PCHAR pszTest,
  104. PCHAR pszName,
  105. PCHAR pszSubPath,
  106. PCHAR pszObject) : ulLastError(ERROR_SUCCESS)
  107. {
  108. #if defined (_WIN32)
  109. //
  110. // Check the result of the CMutex Contructor and continue if
  111. // it succeeded
  112. //
  113. ulLastError = hMtxSerialize.QueryError();
  114. if (ulLastError != ERROR_SUCCESS)
  115. {
  116. return;
  117. }
  118. #endif
  119. InitLogging();
  120. // Print warning if server name given
  121. /* BUGBUG Need to restore this once remote server is supported.
  122. if(NULL != pszSrvr)
  123. {
  124. fprintf(stderr, "Remote server not supported with this version of "
  125. "log.lib. Continuing.\n");
  126. }
  127. */
  128. ulLastError = SetInfo(NULL, pszTest, pszSubPath, pszObject);
  129. if(ulLastError == ERROR_SUCCESS)
  130. {
  131. ulLastError = LogOpen();
  132. if(ulLastError == ERROR_SUCCESS)
  133. {
  134. WriteData("\n*LOG_START*-%s", pszShortLogFileName);
  135. }
  136. }
  137. }
  138. //+-------------------------------------------------------------------
  139. //
  140. // Member: Log::~Log()
  141. //
  142. // Synopsis: Destroy the Log Object
  143. //
  144. // History: ??-???-?? ???????? Created
  145. //
  146. //--------------------------------------------------------------------
  147. Log :: ~Log()
  148. {
  149. if(fInfoSet != FALSE)
  150. {
  151. if(WriteData("\n*LOG_DONE*") != ERROR_SUCCESS)
  152. {
  153. LogPrintf(stderr, "ERROR: Failed to log \"%s\" status\n",
  154. LOG_DONE_TXT);
  155. }
  156. }
  157. SetLoggingDir((PCHAR) NULL);
  158. SetMachineName((PCHAR) NULL);
  159. SetObjectName((PCHAR) NULL);
  160. SetTestName((PCHAR) NULL);
  161. SetPath((PCHAR) NULL);
  162. SetStatus((PCHAR) NULL);
  163. SetLogFileName((PCHAR) NULL);
  164. SetShortLogFileName((PCHAR) NULL);
  165. CloseLogFile();
  166. }
  167. //+-------------------------------------------------------------------
  168. //
  169. // Member: Log::Info(int, char *[])
  170. //
  171. // Synopsis: Parse the command line and set the appropriate member variables
  172. //
  173. // Arguments: [argc] - Argument count
  174. // [argv] - Argument vector
  175. //
  176. // Returns:
  177. //
  178. // Modifies:
  179. //
  180. // History: ??-???-?? ???????? Created
  181. // 30-Oct-92 SarahJ Updated parms to SetInfo
  182. //
  183. //--------------------------------------------------------------------
  184. ULONG Log :: Info(int argc, char *argv[])
  185. {
  186. USHORT usNdx; // Index into cmnd line args
  187. PCHAR pszTest = NULL; // Name of this test
  188. PCHAR pszSubPath = NULL; // Users log file qualifer
  189. PCHAR pszObject = NULL; // Name of invoking object
  190. PCHAR pch; // Temporary pointer into a string
  191. InitLogging();
  192. // All the argv processing is still done in CHARs
  193. if(ulLastError == ERROR_SUCCESS)
  194. {
  195. //
  196. // For every command line switch, check its validity and parse its
  197. // value. This version allows / or - for switches. If there are
  198. // no command line switches, this loop is skipped. This is for the
  199. // case when Log() is called with no messages.
  200. //
  201. for(usNdx = 1; usNdx < (unsigned short) argc; ++usNdx)
  202. {
  203. char *szArg = argv[ usNdx];
  204. pch = szArg;
  205. // check for / -
  206. if(*szArg == '/' || *szArg == '-')
  207. {
  208. register int i = 1;
  209. pch++;
  210. //
  211. // Check if next char is m, ie handed down from manager code.
  212. // If so skip m
  213. //
  214. if (*pch == 'm' || *pch == 'M')
  215. {
  216. pch++;
  217. i++;
  218. }
  219. ++pch; // Skip next char and check for :
  220. if(*pch++ == ':')
  221. {
  222. switch(toupper(szArg[i]))
  223. {
  224. case 'O': // Object name found
  225. pszObject = (PCHAR)pch;
  226. break;
  227. case 'P': // Directory Path switch found
  228. pszSubPath = (PCHAR)pch;
  229. break;
  230. case 'L': // Logging server name found
  231. // BUGBUG We don't want this message spit to debugger
  232. // all the time.
  233. // BUGBUG OutputDebugStringA("Logging server not supported with "
  234. // BUGBUG "this version of log.lib. Continuing.\n");
  235. break;
  236. case 'T': // Test name found
  237. pszTest = (PCHAR)pch;
  238. break;
  239. default: // Skip this unknown argument
  240. break;
  241. }
  242. }
  243. }
  244. }
  245. // If no test name was given, set pszTest to the apps base name.
  246. char szName[_MAX_FNAME];
  247. if(pszTest == NULL || *pszTest == NULLTERM)
  248. {
  249. GetBaseFilename(argv[0], szName);
  250. pszTest = szName;
  251. }
  252. }
  253. ulLastError = SetInfo(NULL, pszTest, pszSubPath, pszObject);
  254. // This was not here before, but it seems the log should be opened by now
  255. if(ERROR_SUCCESS == ulLastError)
  256. {
  257. ulLastError = LogOpen() || WriteData("\n*LOG_START*-%s", pszShortLogFileName);
  258. }
  259. return ulLastError;
  260. }
  261. //+-------------------------------------------------------------------
  262. //
  263. // Member: Log::WriteData(PCHAR, ...)
  264. //
  265. // Synopsis: Write a string to the Log file.
  266. //
  267. // Arguments: [pszFormat] - a printf-like format string
  268. // [...] - The data to print out.
  269. //
  270. // Returns: ERROR_SUCCESS if successful
  271. // Any error code from Log::SetStrData() or Log::LogData
  272. // or CTCLock::QueryError()
  273. //
  274. // Modifies: ulLastError
  275. //
  276. // History: ??-???-?? ???????? Created
  277. // 3-Jul-92 DeanE Modified to call WriteDataList
  278. //
  279. //--------------------------------------------------------------------
  280. ULONG Log :: WriteData(PCHAR psz, ...)
  281. {
  282. CHAR szBuffer[CCH_MAX_CHARS];
  283. va_list varArgs;
  284. #ifndef WIN16
  285. CTCLock clMemLock (hMtxSerialize); // Serialize access to this object
  286. ULONG ulErr = clMemLock.QueryError();
  287. if (ulErr != NO_ERROR)
  288. {
  289. return ulErr;
  290. }
  291. #endif
  292. szBuffer[0] = '\0';
  293. szBuffer[CCH_MAX_CHARS-1] = '\0';
  294. if ((psz != NULL) && (pfLog != NULL))
  295. {
  296. // Print the caller's string to a buffer
  297. va_start(varArgs, psz);
  298. _vsnprintf(szBuffer, CCH_MAX_CHARS-1, psz, varArgs);
  299. va_end(varArgs);
  300. int iRet = fprintf(pfLog, "%s\n", szBuffer);
  301. if (iRet < 0)
  302. {
  303. OutputDebugStringA("CTLOG::Failed to log data string : ");
  304. OutputDebugStringA(szBuffer);
  305. OutputDebugStringA("\n");
  306. }
  307. else
  308. {
  309. fflush(pfLog);
  310. }
  311. }
  312. return(ERROR_SUCCESS);
  313. }
  314. //+-------------------------------------------------------------------
  315. //
  316. // Member: Log::WriteData2(PCHAR)
  317. //
  318. // Synopsis: Write a string to the Log file.
  319. //
  320. // Arguments: [psz] - string to print out
  321. //
  322. // Returns: ERROR_SUCCESS if successful
  323. // Any error code from Log::SetStrData() or Log::LogData
  324. // or CTCLock::QueryError()
  325. //
  326. // Modifies: ulLastError
  327. //
  328. // History: 3-Jul-92 DeanE Modified to call WriteDataList
  329. //
  330. //--------------------------------------------------------------------
  331. ULONG Log :: WriteData2(PCHAR psz)
  332. {
  333. #ifndef WIN16
  334. CTCLock clMemLock (hMtxSerialize); // Serialize access to this object
  335. ULONG ulErr = clMemLock.QueryError();
  336. if (ulErr != NO_ERROR)
  337. {
  338. return ulErr;
  339. }
  340. #endif
  341. if ((psz != NULL) && (pfLog != NULL))
  342. {
  343. int iRet = fprintf(pfLog, "%s", psz);
  344. if (iRet < 0)
  345. {
  346. OutputDebugStringA("CTLOG::Failed to log data string : ");
  347. OutputDebugStringA(psz);
  348. OutputDebugStringA("\n");
  349. }
  350. else
  351. {
  352. fflush(pfLog);
  353. }
  354. }
  355. return(ERROR_SUCCESS);
  356. }
  357. #ifndef WIN16
  358. //+-------------------------------------------------------------------
  359. //
  360. // Member: Log::WriteData2(PWCHAR)
  361. //
  362. // Synopsis: Write a string to the Log file.
  363. //
  364. // Arguments: [pwsz] - string to print out
  365. //
  366. // Returns: ERROR_SUCCESS if successful
  367. // Any error code from Log::SetStrData() or Log::LogData
  368. // or CTCLock::QueryError()
  369. //
  370. // Modifies: ulLastError
  371. //
  372. // History: 3-Jul-92 DeanE Modified to call WriteDataList
  373. //
  374. //--------------------------------------------------------------------
  375. ULONG Log :: WriteData2(PWCHAR pwsz)
  376. {
  377. #ifndef WIN16
  378. CTCLock clMemLock (hMtxSerialize); // Serialize access to this object
  379. ULONG ulErr = clMemLock.QueryError();
  380. if (ulErr != NO_ERROR)
  381. {
  382. return ulErr;
  383. }
  384. #endif
  385. if ((pwsz != NULL) && (pfLog != NULL))
  386. {
  387. int iRet = fprintf(pfLog, "%ls", pwsz);
  388. if (iRet < 0)
  389. {
  390. OutputDebugStringA("CTLOG::Failed to log data string : ");
  391. // Note on Chicago this call will be stubbed out.
  392. OutputDebugStringW(pwsz);
  393. OutputDebugStringA("\n");
  394. }
  395. else
  396. {
  397. fflush(pfLog);
  398. }
  399. }
  400. return(ERROR_SUCCESS);
  401. }
  402. #endif
  403. //+-------------------------------------------------------------------
  404. //
  405. // Member: Log::WriteVar
  406. //
  407. // Synopsis: Write a variation status to the Log file.
  408. //
  409. // Arguments:
  410. //
  411. // Returns: ERROR_SUCCESS if successful
  412. // Any error code from Log::SetStrData() or Log::LogData
  413. // or CTCLock::QueryError()
  414. //
  415. // Modifies: ulLastError
  416. //
  417. // History: ??-???-?? ???????? Created
  418. // 3-Jul-92 DeanE Modified to call WriteDataList
  419. //
  420. //--------------------------------------------------------------------
  421. ULONG Log :: WriteVar(PCHAR pszVariation,
  422. USHORT usStatus,
  423. PCHAR pszStrFmt, ... )
  424. {
  425. CHAR szBuffer[CCH_MAX_CHARS];
  426. va_list varArgs;
  427. #ifndef WIN16
  428. CTCLock clMemLock (hMtxSerialize); // Serialize access to this object
  429. ULONG ulErr = clMemLock.QueryError();
  430. if (ulErr != NO_ERROR)
  431. {
  432. return ulErr;
  433. }
  434. #endif
  435. szBuffer[0] = '\0';
  436. szBuffer[CCH_MAX_CHARS-1] = '\0';
  437. if (pfLog != NULL)
  438. {
  439. int iRet;
  440. if (pszStrFmt != NULL)
  441. {
  442. // Print the caller's string to a buffer
  443. va_start(varArgs, pszStrFmt);
  444. _vsnprintf(szBuffer, CCH_MAX_CHARS-1, pszStrFmt, varArgs);
  445. va_end(varArgs);
  446. iRet = fprintf(pfLog, "%s: %s: %s\n", aStatus[usStatus],
  447. pszVariation, szBuffer);
  448. }
  449. else
  450. {
  451. iRet = fprintf(pfLog, "%s: %s\n", aStatus[usStatus], pszVariation);
  452. }
  453. if (iRet < 0)
  454. {
  455. OutputDebugStringA("CTLOG::Failed to log variation string : ");
  456. OutputDebugStringA(pszVariation);
  457. OutputDebugStringA("\n");
  458. }
  459. else
  460. {
  461. fflush(pfLog);
  462. }
  463. fflush(pfLog);
  464. }
  465. return(ERROR_SUCCESS);
  466. }
  467. //+-------------------------------------------------------------------
  468. //
  469. // Member: Log ::InitLogging(VOID)
  470. //
  471. // Synopsis: Initialize the classes data members.
  472. //
  473. // Modifies:
  474. //
  475. // History: ??-???-?? ???????? Created
  476. //
  477. //--------------------------------------------------------------------
  478. void Log :: InitLogging(VOID)
  479. {
  480. pszLoggingDir = NULL;
  481. pszMachineName = NULL;
  482. pszObjectName = NULL;
  483. pszTestName = NULL;
  484. pszPath = NULL;
  485. pszStatus = NULL;
  486. pszVariation = NULL;
  487. pszLogFileName = NULL;
  488. pszShortLogFileName = NULL;
  489. fInfoSet = FALSE;
  490. pfLog = NULL;
  491. }
  492. //+-------------------------------------------------------------------
  493. //
  494. // Member: Log ::SetLogFile(VOID)
  495. //
  496. // Synopsis: Combine the logging file name components into a full path
  497. // file name. If this new file name is not the same as that
  498. // referenced by element pszLogFileName, switch to log data
  499. // into the file in this new name.
  500. //
  501. // Returns: ERROR_SUCCESS if successful, else
  502. // ERROR_INVALID_PARAMETER
  503. // ERROR_OUTOFMEMORY
  504. // ERROR_CANTOPEN
  505. // Any error from AddComponent, CheckDir, SetLogFileName,
  506. // or SetEventCount
  507. //
  508. // Modifies:
  509. //
  510. // History: ??-???-?? ???????? Created
  511. //
  512. //--------------------------------------------------------------------
  513. ULONG Log :: SetLogFile()
  514. {
  515. if (((pszLoggingDir != (PCHAR) NULL) &&
  516. (strlen(pszLoggingDir) > _MAX_PATH)) ||
  517. ((pszPath != NULL) && (strlen(pszPath) > _MAX_PATH)))
  518. {
  519. return ERROR_INVALID_PARAMETER;
  520. }
  521. PCHAR pszNewFileName = new char[_MAX_PATH + 1];
  522. if(pszNewFileName == NULL)
  523. {
  524. return ERROR_OUTOFMEMORY;
  525. }
  526. //
  527. // No -
  528. // For each component of the new log file path, append it to the
  529. // root logging directory. Make sure only one back-slash exists
  530. // between each appended path component.
  531. //
  532. if(pszLoggingDir != NULL && *pszLoggingDir != NULLTERM)
  533. {
  534. strcpy(pszNewFileName, pszLoggingDir);
  535. }
  536. else
  537. {
  538. *pszNewFileName = NULLTERM;
  539. }
  540. ulLastError =
  541. AddComponent(pszNewFileName, pszPath) ||
  542. AddComponent(pszNewFileName, pszTestName);
  543. //
  544. // The the new file name was successfully built, see if it the same as
  545. // the name of the currently open log file (if one is open). If is not
  546. // the same file name, close the open one (if open) and open the new
  547. // logging file. If the open is successful, save the name of the newly
  548. // opened file for the next time thru here.
  549. //
  550. // A later version of this method could be written to create a LRU queue
  551. // of some max number of open logging files. This version just keeps one
  552. // file open at a time, closing it only to switch to a different log file.
  553. //
  554. if(ulLastError == ERROR_SUCCESS)
  555. {
  556. strcat(pszNewFileName, (const char *)".Log");
  557. ulLastError = SetLogFileName((const char *) pszNewFileName);
  558. if (ulLastError == ERROR_SUCCESS)
  559. {
  560. char szName[_MAX_FNAME];
  561. GetBaseFilename(pszNewFileName, szName);
  562. ulLastError = SetShortLogFileName((const char *) szName);
  563. }
  564. if (ulLastError == ERROR_SUCCESS)
  565. {
  566. // Changed this from fopen() to work on chicago 16 bit
  567. pfLog = _fsopen(pszNewFileName, "a", _SH_DENYNO);
  568. if(pfLog == NULL)
  569. {
  570. ulLastError = ERROR_CANTOPEN;
  571. OutputDebugStringA("CTLOG::Failed to create log file");
  572. OutputDebugStringA(pszNewFileName);
  573. OutputDebugStringA("\n");
  574. }
  575. }
  576. }
  577. delete [] pszNewFileName;
  578. return ulLastError;
  579. }
  580. //+-------------------------------------------------------------------
  581. //
  582. // Member: Log ::AddComponent(PCHAR, PCHAR)
  583. //
  584. // Synopsis: Append a path component to the given string in szNewName.
  585. // Make sure there is one and only one '\' between each
  586. // component and no trailing '\' is present.
  587. //
  588. // Arguments: [szNewName] - Pointer to exist path (must not be NULL)
  589. // [szComponent] - New component to add
  590. //
  591. // Returns: ERROR_SUCCESS if successful
  592. // ERROR_INVALID_PARAMETER
  593. //
  594. // Modifies:
  595. //
  596. // History: ??-???-?? ???????? Created
  597. //
  598. //--------------------------------------------------------------------
  599. ULONG Log :: AddComponent(PCHAR szNewName, PCHAR szComponent)
  600. {
  601. PCHAR pch = NULL;
  602. // Path component provided?
  603. if (szComponent != NULL && *szComponent != NULLTERM)
  604. {
  605. int nLen = strlen((const char *)szComponent);
  606. //
  607. // Trim trailing and leading '\'s from the component to be appended,
  608. // then append the component to the file name.
  609. //
  610. pch = szComponent + nLen;
  611. while (pch > szComponent)
  612. {
  613. if (*pch == SLASH)
  614. {
  615. *pch = NULLTERM;
  616. pch--;
  617. }
  618. else
  619. {
  620. break;
  621. }
  622. }
  623. pch = szComponent;
  624. while (*pch == SLASH)
  625. {
  626. pch++;
  627. }
  628. //
  629. // Append one '\' to the file name then append the given component.
  630. //
  631. if (strlen((const char *)szNewName) + nLen + 1 < _MAX_PATH)
  632. {
  633. nLen = strlen((const char *)szNewName);
  634. if (nLen > 0)
  635. { // Add component separater
  636. szNewName[ nLen++] = SLASH;
  637. }
  638. strcpy(&szNewName[nLen], (const char *)pch);
  639. }
  640. else
  641. {
  642. ulLastError = ERROR_INVALID_PARAMETER;
  643. }
  644. }
  645. return(ulLastError);
  646. }
  647. //+-------------------------------------------------------------------
  648. //
  649. // Member: Log ::LogOpen(VOID)
  650. //
  651. // Synopsis: If we are not in the LogSvr and if logging remotly, try
  652. // to a START record to the server. If not, or if the attempt
  653. // fails, log the data locally. This may require opening the
  654. // local log file.
  655. //
  656. // Returns: ERROR_SUCCESS if successful
  657. // Results from Remote(), SetLogFile(), or OpenLogFile()
  658. //
  659. // Modifies:
  660. //
  661. // History: ??-???-?? ???????? Created
  662. //
  663. //--------------------------------------------------------------------
  664. ULONG Log :: LogOpen()
  665. {
  666. if(pfLog == NULL)
  667. {
  668. //
  669. // Something failed in the remote logging attempt, or this is our
  670. // first call to open the log file, so set up to log locally.
  671. //
  672. ulLastError = SetLogFile();
  673. if(ulLastError != ERROR_SUCCESS)
  674. {
  675. return ulLastError; // Setup failed... Don't go any further.
  676. }
  677. }
  678. return ERROR_SUCCESS;
  679. }
  680. //+-------------------------------------------------------------------
  681. //
  682. // Member: Log ::SetInfo(const char *, const char *,
  683. // const char *, const char *)
  684. //
  685. // Synopsis: Set the logging information about the test being run.
  686. // User is set to pszTest OR logged on username OR MY_NAME in
  687. // that order of preference.
  688. // Machinename is set to computername OR MY_NAME in
  689. // that order of preference.
  690. //
  691. //
  692. // Arguments: [pszSrvr] - Name of logging server
  693. // [pszTest] - Name of the test being run
  694. // [pszSubPath] - Log file path qualifier
  695. // [pszObject] - Name of object logging the data
  696. //
  697. // Returns: USHORT - ERROR_SUCCESS (ERROR_SUCCESS) if successful. Otherwise,
  698. // the return value from SetTestName,
  699. // SetTester, SetPath, or SerObjectName.
  700. //
  701. // Modifies:
  702. //
  703. // History: ??-???-?? ???????? Created
  704. // 09-Feb-92 BryanT Added Win32 support
  705. // 01-Jul-92 Lizch Fixed bug where testername was getting
  706. // overwritten if machinename not set.
  707. // 30-Jul-92 SarahJ Fixed memory trashing bug - SetTester
  708. // & SetmachineName were trashing environment
  709. // variables
  710. // 30-Oct-92 SarahJ Removed all signs of pszTester - it
  711. // was only mis-used
  712. //--------------------------------------------------------------------
  713. ULONG Log :: SetInfo(const char * pszSrvr,
  714. const char * pszTest,
  715. const char * pszSubPath,
  716. const char * pszObject)
  717. {
  718. ulLastError =
  719. SetTestName(pszTest) ||
  720. SetPath(pszSubPath) ||
  721. SetObjectName(pszObject);
  722. if(ulLastError == ERROR_SUCCESS && pszMachineName == NULL)
  723. {
  724. SetMachineName("MyMachineName");
  725. if(pszMachineName == NULL)
  726. {
  727. // ulLastError has been set to error by SetMachineName.
  728. fprintf(stderr, "ERROR! machine name not set\n");
  729. }
  730. }
  731. if(ulLastError == ERROR_SUCCESS)
  732. {
  733. fInfoSet = TRUE; // Note that info has been set
  734. }
  735. return ulLastError;
  736. }
  737. //+-------------------------------------------------------------------
  738. //
  739. // Member: Log ::OpenLogFile(VOID)
  740. //
  741. // Synopsis: Opens log file if not already open.
  742. //
  743. // Returns: ERROR_SUCCESS if successful, else ERROR_CANTOPEN
  744. //
  745. // History: ??-???-?? ???????? Created
  746. //
  747. //--------------------------------------------------------------------
  748. ULONG Log :: OpenLogFile(VOID)
  749. {
  750. ULONG ulErr = ERROR_SUCCESS;
  751. if(pfLog == NULL)
  752. {
  753. // changed this from fopen() to work on chicago 16 bit
  754. pfLog = _fsopen(pszLogFileName, "a", _SH_DENYNO);
  755. if(pfLog == NULL)
  756. {
  757. ulErr = ERROR_CANTOPEN;
  758. }
  759. }
  760. return(ulErr);
  761. }
  762. //+-------------------------------------------------------------------
  763. //
  764. // Member: Log ::CloseLogFile(VOID)
  765. //
  766. // Synopsis: If a logging file is open, write event count to the
  767. // beginning of the file and close the file
  768. //
  769. // Returns: <nothing> - sets ulLastError if there is an error
  770. //
  771. // Modifies:
  772. //
  773. // History: ??-???-?? ???????? Created
  774. //
  775. //--------------------------------------------------------------------
  776. void Log :: CloseLogFile(VOID)
  777. {
  778. if(pfLog != NULL)
  779. {
  780. fclose(pfLog);
  781. pfLog = NULL;
  782. }
  783. // SetLogFileName((PCHAR) NULL);
  784. }
  785. //+-------------------------------------------------------------------
  786. //
  787. //
  788. // Member: Log ::LogPrintf(HANDLE, PCHAR, ...)
  789. //
  790. // Synopsis: This version has a max formared output of STRBUFSIZ
  791. // (see log.h). The only check I know how to make is to
  792. // strlen the format string. It is not fool-proof but it's
  793. // better than nothing. The method allows a printf-like format
  794. // and args to be written to a file opened with 'open()'.
  795. //
  796. // Arguments: [nHandle] - Output File handle
  797. // [pszFmt] - Format string for output
  798. // [...] - Data to pass printf()
  799. //
  800. // Returns: ERROR_SUCCESS if successful
  801. //
  802. // Modifies:
  803. //
  804. // History: ??-???-?? ???????? Created
  805. // 16-Sep-92 SarahJ Changed this function to at most write
  806. // STDSTRBUFSIZ bytes.
  807. //
  808. // Note: I have assumed that LogPrintf does not print > 1K
  809. // and can find no use with more data.
  810. // If I am wrong then the code from SetStrData should be
  811. // copied here.
  812. //
  813. //--------------------------------------------------------------------
  814. int Log :: LogPrintf(FILE *pf, PCHAR pszFmt, ...)
  815. {
  816. return ERROR_SUCCESS;
  817. }
  818. //+-------------------------------------------------------------------
  819. //
  820. // Member: Log ::NewString(PCHAR *, const char *)
  821. //
  822. // Synopsis: This method will delete the existing string if it exists,
  823. // and (if a new string is given) will create and return a
  824. // duplicate string.
  825. // The assumption, here, is that the original pointer was
  826. // properly initialized to NULL prior to calling this method
  827. // the firsttime for that original string.
  828. //
  829. // Arguments: [pszOrig] - The original string
  830. // [pszNewStr] - The new and improved string
  831. //
  832. // Returns: ERROR_SUCCESS if successful, else ERROR_OUTOFMEMORY.
  833. //
  834. // Modifies:
  835. //
  836. // History: ??-???-?? ???????? Created
  837. //
  838. //--------------------------------------------------------------------
  839. ULONG Log :: NewString(PCHAR *pszOrig, const char * pszNewStr)
  840. {
  841. DelString(pszOrig);
  842. // If a new string was given, duplicate it.
  843. if(pszNewStr != NULL)
  844. {
  845. *pszOrig = new char[strlen(pszNewStr) + 1];
  846. if(*pszOrig == NULL)
  847. {
  848. ulLastError = ERROR_OUTOFMEMORY;
  849. }
  850. else
  851. {
  852. strcpy(*pszOrig, pszNewStr);
  853. }
  854. }
  855. return ulLastError;
  856. }
  857. //+-------------------------------------------------------------------
  858. //
  859. // Function: DelString(PCHAR *)
  860. //
  861. // Synopsis: Given a pointer to a string, delete the memory if necessary
  862. // and set the pointer to NULL
  863. //
  864. // Arguments: [pszOrig] Original string to delete
  865. //
  866. // Returns: <nothing>
  867. //
  868. // History: ??-???-?? ???????? Created
  869. //
  870. //--------------------------------------------------------------------
  871. VOID Log :: DelString(PCHAR *pszOrig)
  872. {
  873. if (*pszOrig != NULL)
  874. {
  875. delete *pszOrig;
  876. *pszOrig = NULL;
  877. }
  878. }
  879. //+-------------------------------------------------------------------
  880. //
  881. // Function: GetBaseFilename
  882. //
  883. // Synopsis: Return a filename with it's extension and path
  884. // stripped off
  885. //
  886. // Arguments: [pszFileWithExtension] -- The full filename
  887. // [pszBaseName] -- Where to put the base name
  888. //
  889. // Returns: <nothing>
  890. //
  891. // History: 15-Apr-96 MikeW Created
  892. // 17-Oct-96 EricHans Fixed to return with path stripped
  893. //
  894. //--------------------------------------------------------------------
  895. void Log :: GetBaseFilename(LPSTR pszFileWithExtension, LPSTR pszBaseName)
  896. {
  897. LPSTR pszStartOfExtension;
  898. LPSTR pszLastBackslash;
  899. UINT nCharsInBase;
  900. pszStartOfExtension = strrchr(pszFileWithExtension, '.');
  901. // assume this is a fully qualified path or
  902. // just the filename itself
  903. pszLastBackslash = strrchr(pszFileWithExtension, '\\');
  904. if (NULL == pszStartOfExtension)
  905. {
  906. // find the end of the string
  907. pszStartOfExtension = strchr(pszFileWithExtension, '\0');
  908. }
  909. if (NULL == pszLastBackslash)
  910. {
  911. nCharsInBase = pszStartOfExtension - pszFileWithExtension;
  912. strncpy(pszBaseName, pszFileWithExtension, nCharsInBase);
  913. }
  914. else
  915. {
  916. if (pszLastBackslash > pszStartOfExtension)
  917. {
  918. // boundary condition: there's actually a dot in the path
  919. // find the end of the string instead
  920. pszStartOfExtension = strchr(pszFileWithExtension, '\0');
  921. }
  922. nCharsInBase = (pszStartOfExtension - pszLastBackslash) - 1;
  923. strncpy(pszBaseName, pszLastBackslash + 1, nCharsInBase);
  924. }
  925. pszBaseName[nCharsInBase] = '\0';
  926. }