⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpmacfile.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.

	$Id: pgpMacFile.c,v 1.59 1999/03/10 02:53:02 heller Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"

#include <Devices.h>
#include <Files.h>
#include <Script.h>

#include <errno.h>
#include <stdio.h>

#if PGP_MACINTOSH /* [ */

#include <Errors.h>

#include "MacStrings.h"
#include "MacFiles.h"
#include "pgpTypes.h"
#include "pgpFile.h"
#include "pgpMacFile.h"
#include "pgpMacUtils.h"
#include "pgpFileRef.h"
#include "pgpFileSpec.h"
#include "pgpFileMod.h"
#include "pgpCFB.h"
#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpUsuals.h"
#include "pgpContext.h"
#include "pgpMacFileMapping.h"



/* XXX Is this stuff still necessary? */
#define CHANGED		0x0200	/* ---- --1- ---- ---- */

#define kFinderFlagsIgnore	(kIsOnDesk | kHasBeenInited | CHANGED )

#if PRAGMA_ALIGN_SUPPORTED
#pragma options align=mac68k
#endif

typedef struct MacBinaryHeader
{
	uchar	filler;
	uchar	oldVersion;			/* 000: Must be zero for compatibility */
	uchar	name[64];			/* 001: Pascal string */
	FInfo	info1;				/* 065: Original Finder info: */
								/*		File type (long) */
								/*		File creator (long) */
								/*		Flags (word, low byte must be zero) */
								/*		File's location (Point) */
								/*		File's window (short) */
	uchar	protectedBit;		/* 081: Low order bit */
	uchar	zero1;				/* 082: Must be zero for compatibility */
	long	dLength;			/* 083: Data fork length (in bytes) */
	long	rLength;			/* 087: Resource fork length (in bytes) */
	ulong	creationDate;		/* 091: Creation date */
	ulong	modificationDate;	/* 095: Modification date */
	short	getInfoLength;		/* 099:	Get info length */
	uchar	info2;				/* 101: Finder flags, low byte */
	uchar	dummy1;
	uchar	dummy2[18];			/* 103: Not used */
	uchar	dummy3;
	uchar	newVersion;			/* 122: Uploading program version number */
	uchar	minimumVersion;		/* 123: Minimum version number needed */
	uchar	crc1;
	uchar	crc2;
	uchar	endFiller[2];		/* To pad out to 128 bytes */

	DEBUG_STRUCT_CONSTRUCTOR( MacBinaryHeader )
} MacBinaryHeader;

#if PRAGMA_ALIGN_SUPPORTED
#pragma options align=reset
#endif

/*____________________________________________________________________________
	A MacFileTypeEntry maps a pgp file type to a mac creator/type pair.
____________________________________________________________________________*/
typedef struct MacFileTypeEntry
{
	PGPFileType		pgpFileType;
	OSType			creator;
	OSType			type;
} MacFileTypeEntry;

static MacFileTypeEntry	sMacFileTypeTable[kPGPFileTypeNumTypes] =
{
	{ kPGPFileTypePrefs,
		kPGPMacFileCreator_Keys, kPGPMacFileType_Preferences },
		
	{ kPGPFileTypePubRing,
		kPGPMacFileCreator_Keys, kPGPMacFileType_PubRing },
		
	{ kPGPFileTypePrivRing,
		kPGPMacFileCreator_Keys, kPGPMacFileType_PrivRing },
		
	{ kPGPFileTypeDetachedSig,
		kPGPMacFileCreator_Tools, kPGPMacFileType_DetachedSig },
		
	{ kPGPFileTypeRandomSeed,
		kPGPMacFileCreator_Keys, kPGPMacFileType_RandomSeed },
		
	{ kPGPFileTypeArmorFile,
		kPGPMacFileCreator_Tools, kPGPMacFileType_ArmorFile },
		
	{ kPGPFileTypeEncryptedData,
		kPGPMacFileCreator_Tools, kPGPMacFileType_EncryptedData },

	{ kPGPFileTypeGroups,
		kPGPMacFileCreator_Keys, kPGPMacFileType_Groups },

	/* XXX: The below should be user preferences */
	/* but these are the defaults */
	{ kPGPFileTypeDecryptedText,
		kPGPMacFileCreator_DecryptedText, kPGPMacFileType_DecryptedText },
		
	{ kPGPFileTypeDecryptedBin,
		kPGPMacFileCreator_DecryptedBinary, kPGPMacFileType_DecryptedBinary },
		
	{ kPGPFileTypeSignedData,
		kPGPMacFileCreator_Tools, kPGPMacFileType_SignedData },

	{ kPGPFileTypeExported509Keys,
		kPGPMacFileCreator_Keys, kPGPMacFileType_Exported509Keys }
		
};
#define kNumMacFileTypeEntries	\
	( sizeof( sMacFileTypeTable ) / sizeof( sMacFileTypeTable[ 0 ] ) )





#define kPGPMacRead			0x01L
#define kPGPMacWrite		0x02L
#define kPGPMacBinMode		0x04L
/* For write mode only: whether we should check */
#define kPGPCheckMacBin		0x08L
/* Strip out volatile information for detached sig */
#define kPGPMacBinHashOnly	0x10L
/* CRC 0 in MacBin header is okay */
#define kPGPNoMacBinCRCOkay	0x20L

/* This is the private data for macfiles */
typedef struct MacFile
{
	ulong			flags;
	short			dataRef, resRef;
	long			dataOffset, resOffset, totalSize;
	long			filePos;
	PGPFileError	err;
	PGPError		error;
	PFLFileSpecRef		fileRef;
	PGPFileType		fileType;
	MacBinaryHeader	macBinHeader;
	DEBUG_STRUCT_CONSTRUCTOR( MacFile )
} MacFile;

static PGPError PrepareToWrite(PGPFile *file, PGPBoolean autoMapMacTypes );
static PGPError SetFileInfo( PGPFile *file);

	static void
macSetError(
	PGPFile *		file,
	PGPError		code)
{
	MacFile *	mf = (MacFile *)file->priv;

	pgpAssert( pgpContextIsValid( file->context ) );

	mf->err.f = file;
	mf->err.fpos = mf->filePos;
	mf->error = mf->err.error = code;
	mf->err.syserrno = 0;
}

	static OSErr
macFileReadFork(
	PGPFile *		file,
	short			refNum,
	long			forkOffset,
	long			forkEnd,
	long *			sizeLeftPtr,
	void **			ptrPtr)
{
	MacFile *	mf = (MacFile *)file->priv;
	long		chunkSize;
	OSErr		err = noErr;

	pgpAssert( pgpContextIsValid( file->context ) );

	if (mf->filePos >= forkOffset &&
		(chunkSize = pgpMin(*sizeLeftPtr, forkEnd - mf->filePos)) > 0)
	{
		UInt32	actualCount;

		err	= FSReadAtOffset( refNum, mf->filePos - forkOffset,
					chunkSize, *ptrPtr, &actualCount, FALSE );

		mf->filePos		+= actualCount;
		*(Ptr *)ptrPtr	+= actualCount;
		*sizeLeftPtr	-= actualCount;
		if ((mf->flags & kPGPMacBinMode) && err == eofErr)
		{
			/*
			 * Clear any memory which was beyond the EOF.  This is expected
			 * in MacBinary because each fork is padded to a multiple of
			 * 128-bytes.
			 */
			chunkSize	-= actualCount;
			pgpClearMemory((uchar *)*ptrPtr, chunkSize);
			mf->filePos += chunkSize;
			*(Ptr *)ptrPtr += chunkSize;
			*sizeLeftPtr -= chunkSize;
			err = noErr;
		}
		else if (err != noErr)
			macSetError(file, kPGPError_FileOpFailed);
	}
	return err;
}

	static size_t
macFileRead(
	void *			ptr,
	size_t			size,
	PGPFile *		file)
{
	MacFile *	mf = (MacFile *)file->priv;
	long		sizeLeft = (long)size;
	long		chunkSize;
	OSErr		result = noErr;

	pgpAssert(mf->filePos >= 0);

	if (!(mf->flags & kPGPMacRead))
	{
		macSetError(file, kPGPError_IllegalFileOp);
		return 0;
	}

	/* Handle portion in the MacBinary header, if any */
	chunkSize	= pgpMin(sizeLeft, mf->dataOffset - mf->filePos);
	if ( chunkSize > 0 )
	{
		pgpCopyMemory( ((uchar *)&mf->macBinHeader) + 1 + mf->filePos,
						ptr, chunkSize);
		mf->filePos += chunkSize;
		ptr = (void *)((Ptr)ptr + chunkSize);
		sizeLeft -= chunkSize;
	}

	/* Handle portion in the data fork, if any */
	if (result == noErr && sizeLeft > 0)
		result = macFileReadFork(file, mf->dataRef, mf->dataOffset,
								mf->resOffset, &sizeLeft, &ptr);

	/*
	 * Handle zeroing the first 128 bytes of the resource fork,
	 * but only if kPGPMacBinHashOnly is set.
	 */
	chunkSize = pgpMin(sizeLeft,
			pgpMin(mf->resOffset + 128, mf->totalSize) - mf->filePos);
	if (result == noErr
			&& (mf->flags & kPGPMacBinMode) && (mf->flags & kPGPMacBinHashOnly)
			&& ( chunkSize > 0 ))
	{
		pgpClearMemory(ptr, chunkSize);
		mf->filePos += chunkSize;
		ptr = (void *)((Ptr)ptr + chunkSize);
		sizeLeft -= chunkSize;
	}

	/* Handle portion in the resource fork, if any */
	if (result == noErr && sizeLeft > 0 && (mf->flags & kPGPMacBinMode))
		result = macFileReadFork(file, mf->resRef, mf->resOffset,
								mf->totalSize, &sizeLeft, &ptr);

	return (size_t)(size - sizeLeft);
}

	static OSErr
macFileWriteFork(
	PGPFile *		file,
	short			refNum,
	long			forkOffset,
	long			forkEnd,	/* Ignored unless kPGPMacBinMode flag set */
	long			forkLen,	/* Ignored unless kPGPMacBinMode flag set */
	long *			sizeLeftPtr,
	void const **	ptrPtr)
{
	MacFile *	mf = (MacFile *)file->priv;
	long		chunkSize;
	OSErr		result = noErr;

	chunkSize = *sizeLeftPtr;
	if (mf->flags & kPGPMacBinMode)
		chunkSize = pgpMin(chunkSize, forkEnd - mf->filePos);

	if (mf->filePos >= forkOffset && chunkSize > 0)
	{
		IOParam		pb;

		pb.ioRefNum		= refNum;
		pb.ioBuffer		= (Ptr)*ptrPtr;
		pb.ioPosMode	= fsFromStart;
		pb.ioPosOffset	= mf->filePos - forkOffset;
		pb.ioReqCount	= chunkSize;
		if (mf->flags & kPGPMacBinMode)
			pb.ioReqCount = pgpMin(pb.ioReqCount, forkLen - pb.ioPosOffset);
		result	= PBWriteSync((ParmBlkPtr)&pb);
		mf->filePos		+= chunkSize;
		*(Ptr *)ptrPtr	+= chunkSize;
		*sizeLeftPtr	-= chunkSize;
		if (result != noErr)
			macSetError(file, kPGPError_FileOpFailed);
	}
	if (mf->totalSize < mf->filePos)
		mf->totalSize = mf->filePos;
	return result;
}

	static size_t
macFileWrite(
	void const *	ptr,
	size_t			size,
	PGPFile *		file)
{
	MacFile *	mf = (MacFile *)file->priv;
	long		sizeLeft = (long)size;
	long		chunkSize;
	OSErr		macErr = noErr;

	pgpAssert(mf->filePos >= 0);
	pgpAssert( ( mf->flags & kPGPMacWrite) != 0 );
	if (!(mf->flags & kPGPMacWrite))
	{
		macSetError(file, kPGPError_FileLocked);
		return 0;
	}

	/* Handle portion in the MacBinary header, if any */
	chunkSize	= pgpMin(sizeLeft, mf->dataOffset - mf->filePos);
	if ( chunkSize > 0)
	{
		pgpAssert(mf->filePos + chunkSize <= 128);
		pgpCopyMemory(ptr, ((uchar *)&mf->macBinHeader) + 1 + mf->filePos,
						chunkSize);
		mf->filePos += chunkSize;
		ptr = (void *)((Ptr)ptr + chunkSize);
		sizeLeft -= chunkSize;
		if (mf->totalSize < mf->filePos)
			mf->totalSize = mf->filePos;
	}

	/* Handle portion in the data fork, if any */
	if (macErr == noErr && sizeLeft > 0)
	{
		if ( IsPGPError( PrepareToWrite(file, TRUE ) ) )
			return( 0 );
			
		macErr = macFileWriteFork(file, mf->dataRef, mf->dataOffset,
								mf->resOffset, mf->macBinHeader.dLength,
								&sizeLeft, &ptr);
	}

	/* Handle portion in the resource fork, if any */
	if (macErr == noErr &&
		sizeLeft > 0 &&
		(mf->flags & kPGPMacBinMode))
	{
		macErr = macFileWriteFork(file, mf->resRef, mf->resOffset,
								mf->totalSize, mf->macBinHeader.rLength,
								&sizeLeft, &ptr);
	}

	return (size_t)(size - sizeLeft);
}

	static PGPError
macFileFlush(
	PGPFile *		file)
{
	MacFile *	mf = (MacFile *)file->priv;
	IOParam		pb;

	pb.ioRefNum = mf->dataRef;
	PBFlushFileSync((ParmBlkPtr)&pb);
	pb.ioRefNum = mf->resRef;
	PBFlushFileSync((ParmBlkPtr)&pb);
	return kPGPError_NoErr;
}

	static PGPError
macFileClose(
	PGPFile *		file)
{
	MacFile *	mf = (MacFile *)file->priv;
	PGPContextRef	cdkContext;

	pgpAssertAddrValid( file, PGPFile );
	cdkContext	= file->context;
	pgpAssert( pgpContextIsValid( cdkContext ) );

	if ( ( mf->flags & kPGPMacWrite) != 0 )
	{
		PrepareToWrite(file, TRUE );
	}
	
	if (mf->dataRef > 0)
		FSClose(mf->dataRef);
	if (mf->resRef > 0)
		FSClose(mf->resRef);
	SetFileInfo(file);
	PFLFreeFileSpec(mf->fileRef);
	pgpClearMemory((void *)mf, sizeof(*mf));
	pgpContextMemFree( cdkContext, mf);
	pgpContextMemFree( cdkContext, file);
	return kPGPError_NoErr;
}

	static long
macFileTell(
	PGPFile *		file)
{
	MacFile *	mf = (MacFile *)file->priv;

	return mf->filePos;
}

	static PGPError
macFileSeek(
	PGPFile *		file,
	long			offset,
	int				whence)
{
	MacFile *	mf = (MacFile *)file->priv;

	switch (whence)
	{
		case SEEK_SET:
			/* offset is correct, as is */
			break;
		case SEEK_CUR:
			offset += mf->filePos;
			break;
		case SEEK_END:
			offset += mf->totalSize;
			break;
	}

	if (offset < 0 || offset > mf->totalSize)
	{
		macSetError(file, kPGPError_FileOpFailed);
		return kPGPError_FileOpFailed;
	}

	mf->filePos = offset;
	return kPGPError_NoErr;
}

	static PGPBoolean
macFileEof(
	PGPFile const *	file)
{
	MacFile *	mf = (MacFile *)file->priv;

	/*
	 * XXX This will always return TRUE when writing files.
	 *     Is that semantically correct?
	 */
	return mf->filePos >= mf->totalSize;
}

	static long
macFileSizeAdvise(
	PGPFile const *	file)
{
	MacFile *	mf = (MacFile *)file->priv;

	return mf->totalSize;
}

	static PGPFileError const *
macFileError(
	PGPFile const *	file)
{
	MacFile *	mf = (MacFile *)file->priv;

	if (mf->error != kPGPError_NoErr)
		return &mf->err;
	else
		return NULL;
}

	static void
macFileClearError(
	PGPFile *		file)
{
	MacFile *	mf = (MacFile *)file->priv;

	mf->error = kPGPError_NoErr;
}

	static PGPError
macFileWrite2Read(
	PGPFile *		file)
{
	macSetError(file, kPGPError_IllegalFileOp);
	return kPGPError_IllegalFileOp;
}

	static PGPCFBContext *
macFileCfb(
	PGPFile const *	file)
{
	(void)file;	/* Quiet compiler warning */
	/* XXX: I'm not really sure what should be done here */
	return NULL;
}

#ifndef __powerc

static ushort asm CalcCRC16Contin(ushort start, const void *data, long len)
{
	fralloc +
	move.l	D3, -(SP)
	move.w	#0x1021, D3
	clr.l	D0
	move.w	start, D0
	move.l	data, A0
	move.l	len, D2
	bra		Loop1
Loop0:
	move.b	(A0)+, D1
	lsl.w	#8, D1
	eor.w	D1, D0
	moveq	#7, D1
ShiftLoop0:
	lsl.w	#1, D0
	bcc		ShiftLoop1
	eor.w	D3, D0
ShiftLoop1:
	dbra	D1, ShiftLoop0
Loop1:
	dbra	D2, Loop0
	move.l	(SP)+, D3
	frfree
#if GENERATINGCFM || defined(__CFM68K__)
	rtd		#12
#else
    rts
#endif
}

static uchar asm CalcChecksum8Contin(uchar start, const void *data, long len)
{
	FRALLOC	+
	CLR.L	D0
	MOVE.B	start, D0
	MOVE.L	data, A0
	MOVE.L	len, D1
	BRA		Loop1
Loop0:
	ADD.B	(A0)+, D0
Loop1:
	DBRA	D1, Loop0
	FRFREE
#if GENERATINGCFM || defined(__CFM68K__)
	rtd		#12
#else
    rts
#endif
}

static ulong asm CalcCRC32(const void *data, long len)
{
	fralloc	+
	move.l	data, A0
	clr.l	D0
	move.l	len, D1
	lsr.l	#2, D1
	bra		Loop1
Loop0:
	rol.l	#1, D0
	add.l	(A0)+, D0
Loop1:
	dbra	D1, Loop0
	moveq	#3, D2
	move.l	len, D1
	and.l	D2, D1
	lsl.w	D2, D1
	clr.l	D2
	not.l	D2
	lsr.l	D1, D2
	not.l	D2
	and.l	(A0), D2
	rol.l	#1, D0
	add.l	D2, D0
	frfree
#if GENERATINGCFM || defined(__CFM68K__)
	rtd		#8
#else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -