windows-nt/Source/XPSP1/NT/admin/admt/migdrvr/scanlog.cpp
2020-09-26 16:20:57 +08:00

384 lines
13 KiB
C++

/*---------------------------------------------------------------------------
File: ScanLog.cpp
Comments: Routines to scan the dispatch log for the DCT agents
(c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
Proprietary and confidential to Mission Critical Software, Inc.
REVISION LOG ENTRY
Revision By: Christy Boles
Revised on 03/15/99 13:29:18
---------------------------------------------------------------------------
*/
#include "StdAfx.h"
#include "Common.hpp"
#include "UString.hpp"
#include "TNode.hpp"
#include "ServList.hpp"
#include "Globals.h"
#include "Monitor.h"
#include "FParse.hpp"
#include "afxdao.h"
#include "errDct.hpp"
#define AR_Status_Created (0x00000001)
#define AR_Status_Replaced (0x00000002)
#define AR_Status_AlreadyExisted (0x00000004)
#define AR_Status_RightsUpdated (0x00000008)
#define AR_Status_DomainChanged (0x00000010)
#define AR_Status_Rebooted (0x00000020)
#define AR_Status_Warning (0x40000000)
#define AR_Status_Error (0x80000000)
#define BYTE_ORDER_MARK (0xFEFF)
void ParseInputFile(const WCHAR * filename);
DWORD __stdcall LogReaderFn(void * arg)
{
WCHAR logfile[MAX_PATH];
BOOL bDone;
long nSeconds;
CoInitialize(NULL);
gData.GetLogPath(logfile);
gData.GetDone(&bDone);
gData.GetWaitInterval(&nSeconds);
while ( ! bDone )
{
ParseInputFile(logfile);
Sleep(nSeconds * 1000);
gData.GetDone(&bDone);
gData.GetWaitInterval(&nSeconds);
}
CoUninitialize();
return 0;
}
BOOL
TErrorLogParser::ScanFileEntry(
WCHAR * string, // in - line from TError log file
WCHAR * timestamp, // out- timestamp from this line
int * pSeverity, // out- severity level of this message
int * pSourceLine, // out- the source line for this message
WCHAR * msgtext // out- the textual part of the message
)
{
BOOL bSuccess = TRUE;
WCHAR cSeverity;
WCHAR cNumber;
int severity = 0;
(*pSeverity) = 0;
(*pSourceLine) = 0;
// extract the timestamp
if ( string[0] == BYTE_ORDER_MARK )
{
string++;
}
UStrCpy(timestamp,string,20);
cSeverity = string[20];
cNumber = string[21];
severity = 0;
switch ( cSeverity )
{
case L'I' :
break;
case L'W':
if ( cNumber == L'1' ) severity = 1;
break;
case L'E':
if ( cNumber == L'2' ) severity = 2;
break;
case L'S':
if ( cNumber == L'3' ) severity = 3;
break;
case L'V':
if ( cNumber == L'4' ) severity = 4;
break;
case L'U':
if ( cNumber == L'5' ) severity = 5;
break;
case L'X':
if ( cNumber == L'6' ) severity = 6;
break;
};
if ( severity )
{
WCHAR temp[10];
UStrCpy(temp,string+22,5);
(*pSourceLine) = _wtoi(temp);
UStrCpy(msgtext,string+28);
}
else
{
UStrCpy(msgtext,string+20);
}
(*pSeverity) = severity;
if ( bSuccess )
{
msgtext[UStrLen(msgtext)-2] = 0;
}
return bSuccess;
}
BOOL GetServerFromMessage(WCHAR const * msg,WCHAR * server)
{
BOOL bSuccess = FALSE;
int ndx = 0;
for ( ndx = 0 ; msg[ndx] ; ndx++ )
{
if ( msg[ndx] == L'\\' && msg[ndx+1] == L'\\' )
{
bSuccess = TRUE;
break;
}
}
if ( bSuccess )
{
int i = 0;
ndx+=2; // strip of the backslashes
for ( i=0; msg[ndx] && msg[ndx] != L'\\' && msg[ndx]!= L' ' && msg[ndx] != L',' && msg[ndx] != L'\t' && msg[ndx] != L'\n' ; i++,ndx++)
{
server[i] = msg[ndx];
}
server[i] = 0;
}
else
{
server[0] = 0;
}
return bSuccess;
}
void ParseInputFile(WCHAR const * gLogFile)
{
FILE * pFile = 0;
WCHAR server[200];
int nRead = 0;
int count = 0;
HWND lWnd = NULL;
long totalRead;
BOOL bNeedToCheckResults = FALSE;
TErrorLogParser parser;
TErrorDct edct;
parser.Open(gLogFile);
gData.GetLinesRead(&totalRead);
if ( parser.IsOpen() )
{
// scan the file
while ( ! parser.IsEof() )
{
if ( parser.ScanEntry() )
{
nRead++;
if ( nRead < totalRead )
continue;
// the first three lines each have their own specific format
if ( nRead == 1 )
{
// first comes the name of the human-readable log file
gData.SetReadableLogFile(parser.GetMessage());
}
else if ( nRead == 2 )
{
// next, the name and location of the result share - this is needed to look for the result files
WCHAR const * dirName = parser.GetMessage();
WCHAR const * colon = wcsrchr(dirName+3,':');
if ( colon )
{
WCHAR const * sharename = colon+2;
WCHAR const * netname = wcschr(sharename+2,L'\\');
if ( netname )
{
gData.SetResultShare(netname+1);
WCHAR directory[MAX_PATH];
// UStrCpy(directory,dirName,(colon - dirName ));
UStrCpy(directory,dirName,(int)(colon - dirName ));
gData.SetResultDir(directory);
}
}
continue;
}
else if ( nRead == 3 )
{
// now the count of computers being dispatched to
count = _wtoi(parser.GetMessage());
ComputerStats cStat;
gData.GetComputerStats(&cStat);
cStat.total = count;
gData.SetComputerStats(&cStat);
continue;
}
else // all other message have the following format: COMPUTER<tab>Action<tab>RetCode
{
WCHAR action[50];
WCHAR const * pAction = wcschr(parser.GetMessage(),L'\t');
WCHAR const * retcode = wcsrchr(parser.GetMessage(),L'\t');
TServerNode * pServer = NULL;
if ( GetServerFromMessage(parser.GetMessage(),server)
&& pAction
&& retcode
&& pAction != retcode
)
{
// UStrCpy(action,pAction+1,retcode - pAction);
UStrCpy(action,pAction+1,(int)(retcode - pAction));
// add the server to the list, if it isn't already there
gData.Lock();
pServer = gData.GetUnsafeServerList()->FindServer(server);
if ( ! pServer )
pServer = gData.GetUnsafeServerList()->AddServer(server);
gData.Unlock();
retcode++;
DWORD rc = _wtoi(retcode);
if ( pServer )
{
if ( UStrICmp(pServer->GetTimeStamp(),parser.GetTimestamp()) < 0 )
{
pServer->SetTimeStamp(parser.GetTimestamp());
}
if ( !UStrICmp(action,L"WillInstall") )
{
pServer->SetIncluded(TRUE);
}
else if (! UStrICmp(action,L"JobFile") )
{
pServer->SetJobPath(retcode);
}
else if (! UStrICmp(action,L"Install") )
{
if ( rc )
{
if ( ! *pServer->GetMessageText() )
{
TErrorDct errTemp;
WCHAR text[2000];
errTemp.ErrorCodeToText(rc,DIM(text),text);
pServer->SetMessageText(text);
}
pServer->SetSeverity(2);
pServer->SetFailed();
pServer->SetIncluded(TRUE);
gData.GetListWindow(&lWnd);
// SendMessage(lWnd,DCT_ERROR_ENTRY,NULL,(long)pServer);
SendMessage(lWnd,DCT_ERROR_ENTRY,NULL,(LPARAM)pServer);
}
else
{
pServer->SetInstalled();
pServer->SetIncluded(TRUE);
gData.GetListWindow(&lWnd);
// SendMessage(lWnd,DCT_UPDATE_ENTRY,NULL,(long)pServer);
SendMessage(lWnd,DCT_UPDATE_ENTRY,NULL,(LPARAM)pServer);
}
}
else if ( ! UStrICmp(action,L"Start") )
{
if ( rc )
{
if ( ! *pServer->GetMessageText() )
{
TErrorDct errTemp;
WCHAR text[2000];
errTemp.ErrorCodeToText(rc,DIM(text),text);
pServer->SetMessageText(text);
}
pServer->SetSeverity(2);
pServer->SetFailed();
pServer->SetIncluded(TRUE);
gData.GetListWindow(&lWnd);
// SendMessage(lWnd,DCT_ERROR_ENTRY,NULL,(long)pServer);
SendMessage(lWnd,DCT_ERROR_ENTRY,NULL,(LPARAM)pServer);
}
else
{
// extract the filename and GUID from the end of the message
WCHAR filename[MAX_PATH];
WCHAR guid[100];
WCHAR * comma1 = wcschr(parser.GetMessage(),L',');
WCHAR * comma2 = NULL;
if ( comma1 )
{
comma2 = wcschr(comma1 + 1,L',');
if ( comma2 )
{
// UStrCpy(filename,comma1+1,(comma2-comma1)); // skip the comma & space before the filename
UStrCpy(filename,comma1+1,(int)(comma2-comma1)); // skip the comma & space before the filename
safecopy(guid,comma2+1); // skip the comma & space before the guid
pServer->SetJobID(guid);
pServer->SetJobFile(filename);
pServer->SetStarted();
bNeedToCheckResults = TRUE;
}
gData.GetListWindow(&lWnd);
// SendMessage(lWnd,DCT_UPDATE_ENTRY,NULL,(long)pServer);
SendMessage(lWnd,DCT_UPDATE_ENTRY,NULL,(LPARAM)pServer);
}
}
}
else if ( ! UStrICmp(action,L"Finished") )
{
SendMessage(lWnd,DCT_UPDATE_ENTRY,NULL,NULL);
}
}
}
else
{
// if dispatcher finished dispatching agents set log done
LPCWSTR psz = parser.GetMessage();
if (wcsstr(psz, L"All") && wcsstr(psz, L"Finished"))
{
gData.SetLogDone(TRUE);
}
}
}
}
}
// if we don't have the handle from the list window, we couldn't really send the messages
// in that case we must read the lines again next time, so that we can resend the messages.
if ( lWnd )
{
// if we have sent the messages, we don't need to send them again
gData.SetLinesRead(nRead);
}
gData.SetFirstPassDone(TRUE);
parser.Close();
}
}