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

📄 pgpmacfile.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    rts
#endif
}

#else

static ushort CalcCRC16Contin(ushort crc, const void *data, long len)
{
	const char *dp=(const char *)data;
	short i;

	while(len--)
	{
		crc ^= (ushort)(*dp++) << 8;
		for (i = 0; i < 8; ++i)
		{
			if (crc & 0x8000)
				crc = (crc << 1) ^ 0x1021;
			else
				crc <<= 1;
		}
	}
	return(crc);
}

static uchar CalcChecksum8Contin(uchar start, const void *data, long len)
{
	const char *dp=(char *)data;

	while(len--)
		start+=*dp++;
	return start;
}

static ulong CalcCRC32(const void *data, register long len)
{
	const ulong *dp=(const ulong *)data;
	ulong crc=0, x;
	long len2;
	ulong highSet;

	len2=len;
	len>>=2;
	while(--len>=0)
	{
		highSet=(crc & 0x80000000);
		crc<<=1;
		if(highSet)
			crc|=1;
		crc+=*dp++;
	}
	x=3;
	len2 &=x;
	len2<<=x;
	x=0;
	x=~x;
	x>>=len2;
	x=~x;
	x &= *dp;
	highSet=(crc & 0x80000000);
	crc<<=1;
	if(highSet)
		crc|=1;
	crc+=x;
	return crc;
}

#endif

static uchar CalcChecksum8(const void *data, long len)
{
	return CalcChecksum8Contin(0, data, len);
}

static ushort CalcCRC16(const void *data, long len)
{
	return CalcCRC16Contin(0, data, len);
}

/*
 * This routine is called each time before writing to an actual fork.  If
 * the kPGPCheckMacBin flag is set, it determines whether or not it's a
 * valid MacBinary header.  If so, it creates the file and opens both the
 * data and resource forks.  Otherwise it creates and opens the data fork,
 * and writes false header information to the data fork, using whatever
 * hints it can find to create the file with the correct type and creator.
 */
	static PGPError
PrepareToWrite(
	PGPFile *		file,
	PGPBoolean		autoMapMacTypes )
{
	MacFile *		mf = (MacFile *)file->priv;
	FSSpec			spec;
	PGPError		err = kPGPError_NoErr;
	OSErr			macResult;
	long			length;

	pgpAssert( (mf->flags & kPGPMacWrite) != 0 );
	if (!(mf->flags & kPGPMacWrite))
		return kPGPError_NoErr;

	if (mf->flags & kPGPCheckMacBin)
	{
		mf->flags &= ~(kPGPMacBinMode | kPGPCheckMacBin);
		if (mf->totalSize >= 126 && mf->macBinHeader.oldVersion == 0 &&
					mf->macBinHeader.minimumVersion <= 129 &&
					(mf->macBinHeader.info1.fdFlags & 0xFF) == 0 &&
					mf->macBinHeader.zero1 == 0 &&
					mf->macBinHeader.name[0] < 64)
		{
			ushort		crc;

			pgpAssert(sizeof(crc) == 2);
			pgpCopyMemory(&mf->macBinHeader.crc1, &crc, sizeof(crc));
			if (crc == CalcCRC16((uchar *)&mf->macBinHeader + 1, 124)
					|| ((mf->flags & kPGPNoMacBinCRCOkay) && crc == 0))
			{
				mf->flags 		|= kPGPMacBinMode;
				file->dataType 	= kPGPFileDataType_Binary;
			}
		}
	}

	if (mf->dataRef != 0)
		return kPGPError_NoErr;

	if ((err = PFLGetFSSpecFromFileSpec(mf->fileRef, &spec)) != kPGPError_NoErr)
		goto error;

	if (mf->flags & kPGPMacBinMode)
	{
		/* XXX Reconsider using a different file type for this */
		macResult = FSpCreate( &spec,
			pgpGetMacFileCreatorFromPGPFileType( kPGPFileTypeDecryptedBin ),
			pgpGetMacFileTypeFromPGPFileType( kPGPFileTypeDecryptedBin ),
			smSystemScript);
		if ( IsPGPError( macResult ) )
			goto macError;

		if ((macResult = FSpOpenDF(&spec, fsWrPerm, &mf->dataRef)) != noErr)
			goto macError;

		if ((macResult = FSpOpenRF(&spec, fsWrPerm, &mf->resRef)) != noErr)
			goto macError;

		mf->dataOffset = 128;
		mf->resOffset = mf->dataOffset +
						(mf->macBinHeader.dLength + 127) & ~127L;
		mf->totalSize = mf->resOffset +
						(mf->macBinHeader.rLength + 127) & ~127L;
	}
	else
	{
		OSType			creator;
		OSType			type;

		if ( autoMapMacTypes )
		{
			err	= pgpMapFileNameToMacCreatorType( spec.name,
					&creator, &type );
						
			if ( IsPGPError( err ) )
			{
				err	= pgpMapFileDataToMacCreatorType(
							((uchar *)&mf->macBinHeader) + 1,
							&creator, &type );
			}
		}

		if ( IsPGPError( err ) || ! autoMapMacTypes )
		{
			/* if no mapping, use default types */
			creator	= pgpGetMacFileCreatorFromPGPFileType( mf->fileType );
			type	= pgpGetMacFileTypeFromPGPFileType( mf->fileType );
			err		= noErr;
		}

		macResult = FSpCreate( &spec, creator,
					type, smSystemScript);
		if ( IsPGPError( macResult ) )
			goto macError;

		if ((macResult = FSpOpenDF(&spec, fsWrPerm, &mf->dataRef)) != noErr)
			goto macError;

		mf->dataOffset = mf->resOffset = 0;

		length = mf->totalSize;
		if ((macResult = FSWrite(mf->dataRef, &length,
								(Ptr)&mf->macBinHeader + 1)) != noErr)
			goto macError;
	}

	return kPGPError_NoErr;
macError:
	err = pgpErrorFromMacError(macResult, kPGPError_FileOpFailed);
error:
	macSetError(file, err);
	return err;
}

/*
 * This routine is called after closing a MacBinary file for writing.  It
 * sets the finder information including type and creator.
 */
	static PGPError
SetFileInfo(
	PGPFile *		file)
{
	const MacFile *	mf = (MacFile *)file->priv;
	FSSpec			spec;
	CInfoPBRec		cpb;
	FInfo			fInfo;

	if (!(mf->flags & kPGPMacWrite) || !(mf->flags & kPGPMacBinMode))
		return kPGPError_NoErr;

	if (PFLGetFSSpecFromFileSpec(mf->fileRef, &spec) != kPGPError_NoErr)
		goto error;

	cpbCreationDate( &cpb )		= mf->macBinHeader.creationDate;
	cpbModificationDate( &cpb )	= mf->macBinHeader.modificationDate;

	fInfo				= mf->macBinHeader.info1;
	fInfo.fdFlags 		&= 0xFF00;
	fInfo.fdFlags 		|= mf->macBinHeader.info2;
	fInfo.fdFlags		&= ~kFinderFlagsIgnore;
	fInfo.fdLocation.h	= 0;
	fInfo.fdLocation.v	= 0;
	fInfo.fdFldr 		= 0;
	cpbFInfo( &cpb )	= fInfo;
	if ( FSpSetCatInfo( &spec, &cpb ) != noErr)
		goto error;

	return kPGPError_NoErr;

error:
	/* XXX Improve error reporting */
	macSetError(file, kPGPError_FileOpFailed);
	return kPGPError_FileOpFailed;
}

/*
 * It should be noted that writing to MacBinary files won't work if seeking
 * is used in certain ways.  The MacBinary header only interpreted the first
 * time data is written past the first 128 bytes, and then the fork lengths
 * and offsets are fixed and immutable.  This could be fixed at some point,
 * but there's no need for it now.
 *
 * The filename used to create the file is always the <fileRef> passed in,
 * not the name in the MacBinary header.
 */
	PGPFile *
pgpFileRefMacWriteOpen(
	PGPContextRef			cdkContext,
	PFLConstFileSpecRef		fileRef,
	PGPFileType			fileType,
	PGPFileOpenFlags	flags,
	PGPError *			errorCode)
{
	PGPFile *		file = NULL;
	MacFile *		mf = NULL;
	FSSpec			spec;
	PGPError		err = kPGPError_NoErr;
	PGPMemoryMgrRef	memoryMgr	= pgpGetFileRefMemoryMgr( fileRef );

	if ((file = (PGPFile *)PGPNewData( memoryMgr,
		sizeof(*file), kPGPMemoryMgrFlags_Clear)) == NULL)
	{
		err = kPGPError_OutOfMemory;
		goto error;
	}
	file->context	= cdkContext;
	file->dataType 	= kPGPFileDataType_Unknown;

	if ((mf = (MacFile *)PGPNewData( memoryMgr,
		sizeof(*mf), kPGPMemoryMgrFlags_Clear)) == NULL)
	{
		PGPFreeData( file );
		err = kPGPError_OutOfMemory;
		goto error;
	}

	err = PFLCopyFileSpec(fileRef, &mf->fileRef );
	if ((err = PFLGetFSSpecFromFileSpec(mf->fileRef, &spec)) != kPGPError_NoErr)
		goto error;
	mf->fileType = fileType;

	/* Try to delete the file first, in case it already exists */
	/* XXX Maybe we should check the error, and/or truncate the file instead */
	FSpDelete( &spec );

	pgpAssert(sizeof(mf->macBinHeader) >= 129);
	pgpAssert((flags & kPGPFileOpenLocalEncodeHashOnly) == 0);

	mf->flags = kPGPMacWrite;

	if (flags & (kPGPFileOpenMaybeLocalEncode | kPGPFileOpenForceLocalEncode))
	{
		mf->flags |= kPGPCheckMacBin;
		if (flags & kPGPFileOpenNoMacBinCRCOkay)
			mf->flags |= kPGPNoMacBinCRCOkay;
		mf->dataOffset = mf->resOffset = 128;
	}
	else
		mf->dataOffset = mf->resOffset = 0;

	mf->dataRef = mf->resRef = 0;
	mf->totalSize = 0;
	mf->filePos = 0;

	file->priv = mf;
	file->read			= macFileRead;
	file->write			= macFileWrite;
	file->flush			= macFileFlush;
	file->close			= macFileClose;
	file->tell			= macFileTell;
	file->seek			= macFileSeek;
	file->eof			= macFileEof;
	file->sizeAdvise	= macFileSizeAdvise;
	file->error			= macFileError;
	file->clearError	= macFileClearError;
	file->write2read	= macFileWrite2Read;
	file->cfb			= macFileCfb;

	if ( !( mf->flags & kPGPCheckMacBin) )
	{
		if ((err = PrepareToWrite(file, FALSE )) != kPGPError_NoErr)
			goto error;
	}

	return file;
error:
	if (mf != NULL)
	{
		if (mf->fileRef != NULL)
			PFLFreeFileSpec(mf->fileRef);
		pgpContextMemFree( cdkContext, mf);
	}
	if (file != NULL)
		pgpContextMemFree( cdkContext, file);
	if (errorCode != NULL)
	{
		pgpAssertAddrValid(errorCode, PGPError);
		*errorCode = err;
	}
	return NULL;
}

	PGPFile *
pgpFileRefMacReadOpen(
	PGPContextRef	cdkContext,
	PFLConstFileSpecRef		fileRef,
	PGPFileOpenFlags	flags,
	PGPError *			errorCode)
{
	PGPFile *		file = NULL;
	MacFile *		mf = NULL;
	FSSpec			spec;
	CInfoPBRec		cpb;
	ushort			crc;
	OSErr			macResult;
	PGPError		result = kPGPError_NoErr;

	pgpAssert( pgpContextIsValid( cdkContext ) );

	if ((file = (PGPFile *)pgpContextMemAlloc( cdkContext,
		sizeof(*file), kPGPMemoryMgrFlags_Clear)) == NULL)
	{
		result = kPGPError_OutOfMemory;
		goto error;
	}
	file->context	= cdkContext;
	file->dataType 	= kPGPFileDataType_Unknown;
	
	if ((mf = (MacFile *)pgpContextMemAlloc( cdkContext,
		sizeof(*mf), kPGPMemoryMgrFlags_Clear)) == NULL)
	{
		pgpContextMemFree( cdkContext, file );
		result = kPGPError_OutOfMemory;
		goto error;
	}

	result = PFLCopyFileSpec(fileRef, &mf->fileRef);
	if ( result != noErr )
		goto error;

	result = PFLGetFSSpecFromFileSpec(mf->fileRef, &spec);
	if ( IsPGPError( result ) )
		goto error;
	mf->fileType = kPGPFileTypeNone;

	macResult	= FSpGetCatInfo( &spec, &cpb );
	if ( macResult != noErr )
		goto macError;

	pgpAssert(sizeof(mf->macBinHeader) >= 129);
	pgpClearMemory(&mf->macBinHeader, sizeof(mf->macBinHeader));
	CopyPString(spec.name, mf->macBinHeader.name);
	mf->macBinHeader.info2 = cpbFInfo( &cpb ).fdFlags & 0x00FF;
	cpbFInfo( &cpb ).fdFlags &= 0xFF00;
	cpbFInfo( &cpb ).fdLocation.h = 0;
	cpbFInfo( &cpb ).fdLocation.v = 0;
	cpbFInfo( &cpb ).fdFldr = 0;
	mf->macBinHeader.info1				= cpbFInfo( &cpb );
	mf->macBinHeader.dLength			= cpbDataForkSize( &cpb );
	mf->macBinHeader.rLength			= cpbResForkSize( &cpb );
	mf->macBinHeader.creationDate		= cpbCreationDate( &cpb );
	mf->macBinHeader.modificationDate	= cpbModificationDate( &cpb );
	mf->macBinHeader.newVersion			= 129;
	mf->macBinHeader.minimumVersion		= 129;
	crc = CalcCRC16((const uchar *)&mf->macBinHeader + 1, 124);
	pgpAssert(sizeof(crc) == 2);
	pgpCopyMemory(&crc, &mf->macBinHeader.crc1, sizeof(crc));

	mf->flags = kPGPMacRead;
	if ( flags & kPGPFileOpenForceLocalEncode)
	{
		mf->flags 		|= kPGPMacBinMode;
		file->dataType 	= kPGPFileDataType_Binary;
	}
	else if (flags & kPGPFileOpenMaybeLocalEncode)
	{
		if ( pgpOKToEncodeFSSpecWithoutMacBinary( &spec ) )
		{
			mf->flags	&= ~ kPGPMacBinMode;
		}
		else
		{
			mf->flags		|= kPGPMacBinMode;
			file->dataType 	= kPGPFileDataType_Binary;
		}
	}
	

	if ((macResult = FSpOpenDF(&spec, fsRdPerm, &mf->dataRef)) != noErr)
		goto macError;

	if (mf->flags & kPGPMacBinMode)
	{
		if ((macResult = FSpOpenRF(&spec, fsRdPerm, &mf->resRef)) != noErr)
			goto macError;

		mf->dataOffset = 128;
		mf->resOffset =
			mf->dataOffset + (cpbDataForkSize( &cpb ) + 127) & ~127L;
		mf->totalSize = mf->resOffset + (cpbResForkSize( &cpb ) + 127) & ~127L;
		if (flags & kPGPFileOpenLocalEncodeHashOnly)
		{
			mf->flags |= kPGPMacBinHashOnly;
			/* Clear the finder flags */
			mf->macBinHeader.info1.fdFlags = 0;
			mf->macBinHeader.info2 = 0;
			/* Clear the creation and modification dates */
			mf->macBinHeader.creationDate = 0;
			mf->macBinHeader.modificationDate = 0;
			/* Clear the filename */
			pgpClearMemory(mf->macBinHeader.name,
				sizeof(mf->macBinHeader.name));
			/*
			 * Clear the CRC so that if this output gets used to
			 * recreate a file (which it shouldn't), it won't work
			 * properly and someone will notice the problem.
			 */
			pgpClearMemory(&mf->macBinHeader.crc1, sizeof(crc));
		}
	}
	else
	{
		mf->resRef = 0;
		mf->dataOffset = 0;
		mf->totalSize = mf->resOffset = cpbDataForkSize( &cpb );
	}

	mf->filePos = 0;

	file->priv = mf;
	file->read = macFileRead;
	file->write = macFileWrite;
	file->flush = macFileFlush;
	file->close = macFileClose;
	file->tell = macFileTell;
	file->seek = macFileSeek;
	file->eof = macFileEof;
	file->sizeAdvise = macFileSizeAdvise;
	file->error = macFileError;
	file->clearError = macFileClearError;
	file->write2read = macFileWrite2Read;
	file->cfb = macFileCfb;
	return file;

macError:
	result = pgpErrorFromMacError(macResult, kPGPError_CantOpenFile);

error:
	if (mf != NULL)
	{
		if (mf->fileRef != NULL)
			PFLFreeFileSpec(mf->fileRef);
		pgpContextMemFree( cdkContext, mf);
	}
	if (file != NULL)
		pgpContextMemFree( cdkContext, file);
	if (errorCode != NULL)
	{
		pgpAssertAddrValid(errorCode, PGPError);
		*errorCode = result;
	}
	return NULL;
}

	PGPError
pgpMacCalcFileSize(
	PFLConstFileSpecRef		fileRef,
	PGPFileOpenFlags	flags,
	size_t *			fileSize)
{
	FSSpec			spec;
	CInfoPBRec		cpb;
	PGPBoolean		macBinMode;
	PGPError		result = kPGPError_NoErr;

	*fileSize = 0;	/* In case there's an error */

	if ((result = PFLGetFSSpecFromFileSpec(fileRef, &spec)) != kPGPError_NoErr)
		return result;

	if ( (result = FSpGetCatInfo( &spec, &cpb )) != noErr)
		return pgpErrorFromMacError( result, kPGPError_CantOpenFile);

	macBinMode = FALSE;
	if ( flags & kPGPFileOpenForceLocalEncode )
	{
		macBinMode = TRUE;
	}
	else if (flags & kPGPFileOpenMaybeLocalEncode)
	{
		macBinMode	= ! pgpOKToEncodeFSSpecWithoutMacBinary( &spec );
	}

	if (macBinMode)
	{
		*fileSize = 128 +								/* MacBinary header */
					((cpbDataForkSize( &cpb ) + 127) & ~127L) +	/* Data fork */
					((cpbResForkSize( &cpb ) + 127) & ~127L);	/* Res fork */
	}
	else
	{
		*fileSize = cpbDataForkSize( &cpb );
	}

	return kPGPError_NoErr;
}

	static MacFileTypeEntry const *
sFindMacFileTypeEntry( PGPFileType type )
{
	PGPUInt16					index;
	MacFileTypeEntry const *	entry	= NULL;
	
	entry	= &sMacFileTypeTable[ 0 ];
	for( index = 0; index < kNumMacFileTypeEntries; ++index, ++entry )
	{
		if ( entry->pgpFileType == type )
		{
			return( entry );
		}
	}
	
	pgpDebugMsg( "can't find entry for PGPFileType" );
	return( NULL );
}


	OSType
pgpGetMacFileTypeFromPGPFileType( PGPFileType pgpType )
{
	MacFileTypeEntry const *	entry	= NULL;
	
	entry	= sFindMacFileTypeEntry( pgpType );
	if ( IsntNull( entry ) )
		return( entry->type );
	return( 0 );
}

	OSType
pgpGetMacFileCreatorFromPGPFileType( PGPFileType pgpType )
{
	MacFileTypeEntry const *	entry	= NULL;
	
	entry	= sFindMacFileTypeEntry( pgpType );
	if ( IsntNull( entry ) )
		return( entry->creator );
	return( 0 );
}


#endif	/* ] PGP_MACINTOSH */

/*
 * Local Variables:
 * tab-width: 4
 * End:
 * vi: ts=4 sw=4
 * vim: si
 */

⌨️ 快捷键说明

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