📄 pgpnetlog.c
字号:
(*plogRef)->logFileSpec = NULL;
(*plogRef)->logIO = NULL;
(*plogRef)->recLength = sizeof(PGPnetLogEvent);
/* to be changed? */
(*plogRef)->numRecords = kPGPnetLogMaxNumberOfEvents;
(*plogRef)->dataLength = (*plogRef)->numRecords *
(*plogRef)->recLength;
(*plogRef)->fileLength = (*plogRef)->dataLength +
kPGPNetLogHeaderLength;
(*plogRef)->currentFilePosition = 0;
err = PFLCopyFileSpec (logFileSpec, &((*plogRef)->logFileSpec));
if (IsPGPError (err))
{
sFreeLog (*plogRef);
*plogRef = NULL;
return err;
}
#if PGP_WIN32
(*plogRef)->pszEventDirPath = eventfolder;
err = pgpGetEventDirFullPath((*plogRef)->pszEventDirPath, eventDirLen);
#elif PGP_OSX
(*plogRef)->pszEventDirPath = eventfolder;
#endif
/* Create the file if it does not exist or
if it is a different version and we have write access */
err = sCheckForCurrentLogFile (*plogRef, bWriteAccess);
if ((err == kPGPError_FileNotFound) ||
(IsPGPError (err) && bWriteAccess))
{
PGPnetLogFileHeader header;
if( err == kPGPError_FileNotFound )
{
PFLFileSpecCreate ((*plogRef)->logFileSpec);
#if PGP_OSX
{
/* Change the permissions to rw-r--r-- so non-root can at least *read* the file */
char * logFileName = NULL;
if( IsntPGPError( PFLGetFullPathFromFileSpec( (*plogRef)->logFileSpec, &logFileName ) ) )
chmod( logFileName, 0644 );
if( IsntNull( logFileName ) )
PGPFreeData( logFileName );
}
#endif
}
err = PGPSetFileSize ((*plogRef)->logFileSpec,
(*plogRef)->fileLength);
if (IsntPGPError (err))
{
err = PGPOpenFileSpec((*plogRef)->logFileSpec,
kPFLFileOpenFlags_ReadWrite,
(PGPFileIORef*)(&((*plogRef)->logIO)));
if (IsntPGPError (err))
{
/* initialize header and write it */
pgpClearMemory (&header, sizeof(header));
header.logfileFormatVersion = kPGPnetLogFileFormatVersion;
header.recordLengthBytes = sizeof(PGPnetLogEvent);
header.fileLengthRecords = (*plogRef)->numRecords;
PGPIOSetPos ((*plogRef)->logIO, 0);
err = PGPIOWrite ((*plogRef)->logIO,
kPGPNetLogHeaderLength, &header);
/* we will need to wipe the entire file */
bZeroOutFile = TRUE;
}
}
PGPFreeIO ((*plogRef)->logIO);
}
pgpAssertNoErr (err);
if (IsPGPError (err))
{
sFreeLog (*plogRef);
*plogRef = NULL;
return err;
}
/* open the file */
if (bWriteAccess)
err = PGPOpenFileSpec( (*plogRef)->logFileSpec,
kPFLFileOpenFlags_ReadWrite,
(PGPFileIORef*)(&((*plogRef)->logIO)));
else
err = PGPOpenFileSpec( (*plogRef)->logFileSpec,
kPFLFileOpenFlags_ReadOnly,
(PGPFileIORef*)(&((*plogRef)->logIO)));
if (IsPGPError(err))
{
sFreeLog (*plogRef);
*plogRef = NULL;
return err;
}
pgpAssert (PGPIOIsValid ((*plogRef)->logIO));
if (!PGPIOIsValid ((*plogRef)->logIO))
{
sFreeLog (*plogRef);
*plogRef = NULL;
return kPGPError_OutOfMemory;
}
/* zero-out file */
if (bZeroOutFile)
PGPnetClearLogFile (*plogRef);
/* otherwise find starting position */
else
{
PGPUInt32 currPos = kPGPNetLogHeaderLength;
PGPTime timeOfPrevEvent;
PGPIOSetPos ((*plogRef)->logIO, kPGPNetLogHeaderLength);
event.timeOfEvent = 0;
do {
timeOfPrevEvent = event.timeOfEvent;
err = sIOReadEvent ((*plogRef)->logIO, &event);
if (IsPGPError (err))
return err;
currPos += sizeof(PGPnetLogEvent);
} while ((event.timeOfEvent != 0) &&
(event.timeOfEvent >= timeOfPrevEvent) &&
(currPos < (*plogRef)->fileLength));
if (currPos >= (*plogRef)->fileLength)
currPos = kPGPNetLogHeaderLength;
else
currPos -= sizeof(PGPnetLogEvent);
PGPIOSetPos ((*plogRef)->logIO, currPos);
(*plogRef)->currentFilePosition = currPos;
}
return err;
}
/*____________________________________________________________________________
Writes a PGPnetLogEvent to the event log.
Before writing the new event to disk, we read in the previous entry, attempt
to perform any necessary garbage collection, then, if everything is cool, we
write the new event to disk.
____________________________________________________________________________*/
PGPError
PGPnetLogEventToFile (
PGPnetLogRef logRef,
PGPnetLogEvent* pevent)
{
PGPError err;
PGPFileOffset currPos;
PGPIORef newIORef;
PGPValidateLog (logRef);
PGPValidatePtr (pevent);
if (logRef)
{
if (pevent->timeOfEvent == 0)
pevent->timeOfEvent = PGPGetTime ();
/*
sDeleteOldEventFile will read from the log, and delete any lingering
files associated with the about-to-be-overwritten event. Before calling
sDeleteOldEventFile, we make note of the current file position so that
we can seek back to it after sDeleteOldEventFile is done.
*/
PGPIOGetPos(logRef->logIO, &currPos);
err = sDeleteOldEventFile(logRef);
if (IsntPGPError(err))
{
/*
Note: This is a workaround for an irritating nuance in Microsoft's
stdio fread/fwrite implementation. The symptoms are that after
doing an fread from a file, the internal (FILE*)->_flag gets |=
with _IOREAD. In some cases, this doesn't pose a problem for fwrite,
but in most of our circumstances, fwrite calls flsbuf. flsbuf makes
the assumption that if _IOREAD is set (without looking at _IORW),
that there is an error.
This can easily be hacked with (FILE*)->_flag &= ~_IOREAD, but the
more platform independent solution seems to be to reopen the file.
*/
PGPFreeIO(logRef->logIO);
err = PGPOpenFileSpec(logRef->logFileSpec,
kPFLFileOpenFlags_ReadWrite,
(PGPFileIORef*)&newIORef);
if (IsntPGPError(err))
{
/* Free the old PGPIORef, and point logRef->logIO to the new one */
logRef->logIO = newIORef;
PGPIOSetPos(logRef->logIO, currPos);
err = sIOWriteEvent (logRef->logIO, pevent);
PGPIOFlush(logRef->logIO);
if (IsPGPError (err))
return err;
logRef->currentFilePosition += sizeof(PGPnetLogEvent);
if (logRef->currentFilePosition >= logRef->fileLength)
{
logRef->currentFilePosition = kPGPNetLogHeaderLength;
PGPIOSetPos (logRef->logIO, kPGPNetLogHeaderLength);
}
}
}
return err;
}
else
return kPGPError_BadParams;
}
PGPError
PGPnetCloseLogFile (
PGPnetLogRef logRef)
{
PGPValidateLog (logRef);
if (logRef)
{
sFreeLog (logRef);
return kPGPError_NoErr;
}
else
return kPGPError_BadParams;
}
PGPError
PGPnetReadLogData (
PGPnetLogRef logRef,
PGPSize* pnumberEvents,
void** ppEventBuffer)
{
PGPUInt32 currPos = kPGPNetLogHeaderLength;
PGPUInt32 startPos = kPGPNetLogHeaderLength;
PGPUInt32 endPos = kPGPNetLogHeaderLength;
PGPUInt32 bufferPos = 0;
PGPSize sizeBuffer;
PGPByte* pBuffer;
PGPnetLogEvent event;
PGPTime timeOfPrevEvent;
PGPError err;
PGPValidatePtr (pnumberEvents);
PGPValidatePtr (ppEventBuffer);
*pnumberEvents = 0;
*ppEventBuffer = NULL;
PGPValidateLog (logRef);
if (!logRef)
return kPGPError_BadParams;
PGPIOSetPos (logRef->logIO, kPGPNetLogHeaderLength);
/* search for decreasing time, marking end of log data */
event.timeOfEvent = 0;
do {
timeOfPrevEvent = event.timeOfEvent;
err = sIOReadEvent (logRef->logIO, &event);
if (IsPGPError (err))
return err;
currPos += sizeof(PGPnetLogEvent);
} while ((event.timeOfEvent != 0) &&
(event.timeOfEvent >= timeOfPrevEvent) &&
(currPos < logRef->fileLength));
if (event.timeOfEvent == 0)
{
startPos = kPGPNetLogHeaderLength;
endPos = currPos;
}
else if (event.timeOfEvent < timeOfPrevEvent)
{
currPos -= sizeof(PGPnetLogEvent);
startPos = currPos;
endPos = currPos;
}
else
{
startPos = kPGPNetLogHeaderLength;
endPos = kPGPNetLogHeaderLength;
}
/* calculate size of buffer needed and allocate it */
if (startPos < endPos)
sizeBuffer = endPos - startPos - sizeof(PGPnetLogEvent);
else
sizeBuffer = logRef->numRecords * sizeof(PGPnetLogEvent);
if (sizeBuffer == 0)
return kPGPError_NoErr;
pBuffer = (PGPByte *)PGPNewData (logRef->memoryMgr,
sizeBuffer,
kPGPMemoryMgrFlags_Clear);
/* read the data from the file */
PGPIOSetPos (logRef->logIO, startPos);
currPos = startPos;
while (bufferPos < sizeBuffer)
{
err = sIOReadEvent (logRef->logIO,
(PGPnetLogEvent*)&pBuffer[bufferPos]);
if (IsPGPError (err))
return err;
(*pnumberEvents)++;
bufferPos += sizeof(PGPnetLogEvent);
currPos += sizeof(PGPnetLogEvent);
if (currPos >= logRef->fileLength)
{
PGPIOSetPos (logRef->logIO, kPGPNetLogHeaderLength);
currPos = kPGPNetLogHeaderLength;
}
}
*ppEventBuffer = pBuffer;
return kPGPError_NoErr;
}
PGPError
PGPnetFreeLogData (
void* pData)
{
PGPValidatePtr (pData);
PGPFreeData (pData);
return kPGPError_NoErr;
}
#if PGP_MACINTOSH
#include "MacStrings.h"
// Called just like FindFolder()
// except the folder is always created if not present.
OSStatus
FindPGPnetLogEventDataFolder(
short vRefNum,
short *foundVRefNum,
long *foundDirID)
{
OSStatus err;
FSSpec folderSpec;
pgpAssertAddrValid( foundVRefNum, short );
pgpAssertAddrValid( foundDirID, long );
err = FindPGPPreferencesFolder( vRefNum, &folderSpec.vRefNum, &folderSpec.parID );
if( IsntErr( err ) )
{
CInfoPBRec cpb;
*foundVRefNum = folderSpec.vRefNum;
// This string should _not_ be internationalized.
CopyPString( "\pPGPnet Log Event Data", folderSpec.name );
err = FSpGetCatInfo( &folderSpec, &cpb );
if( IsntErr( err ) )
{
if( cpbIsFolder( &cpb ) )
{
*foundDirID = cpb.dirInfo.ioDrDirID;
}
else
{
pgpDebugMsg( "PGPnet Log Event Data is a file!" );
err = dupFNErr;
}
}
else
{
err = FSpDirCreate( &folderSpec, smSystemScript, foundDirID );
}
}
return( err );
}
#endif
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -