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

📄 pgprpcpacker.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpRPCPacker.c,v 1.9 2002/08/06 20:10:16 dallen Exp $
____________________________________________________________________________*/

#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include "pgpMem.h"
#include "pgpMemoryMgr.h"
#include "pgpPubTypes.h"
#include "pgpUtilities.h"
#include "pgpRPCPacker.h"

#define CKERR		if( IsPGPError( err ) ) goto done
#define CKNULL(x)	do { if( IsNull( x ) ) { err = kPGPError_OutOfMemory; goto done; } } while(0)
#define RETERR(x)	do { err = x; goto done; } while(0)


static PGPUInt32
sGetNeededSize(
	const char *	fmt,
	va_list			args )
{
	PGPUInt32	neededSize	= 0;
	PGPUInt32	i			= 0;
	PGPUInt32	uVal		= 0;
	PGPUInt64	ullVal		= 0;
	PGPInt32	iVal		= 0;
	char *		szVal		= NULL;
	PGPByte *	bufVal		= NULL;
	PGPUInt32	bufSize		= 0;

	for( i = 0; fmt[i] != '\0'; i++ )
	{
		switch( fmt[i] )
		{
			case 'i':
				iVal = va_arg( args, PGPInt32 );
				neededSize += sizeof( PGPInt32 );
				break;

			case 'u':
			case 'b':
				uVal = va_arg( args, PGPUInt32 );
				neededSize += sizeof( PGPUInt32 );
				break;
				
			case 'U':
				ullVal = va_arg( args, PGPUInt64 );
				neededSize += sizeof( PGPUInt64 );
				break;

			case 's':
				szVal = va_arg( args, char * );
				if( IsNull( szVal ) )
					szVal = "";
				neededSize += strlen( szVal ) + 1;
				break;

			case 'B':
				bufVal = va_arg( args, PGPByte * );
				bufSize = va_arg( args, PGPUInt32 );
				neededSize += bufSize + sizeof( bufSize );
				break;

			default:
				break;
		}
	}
	return neededSize;
}

	static PGPError
sPGPrpcPackInternal(
	PGPContextRef	context,
	PGPUInt32		msgType,
	PGPByte **		pBuf,
	PGPSize *		pLen,
	const char *	fmt,
	va_list			args )
{
	PGPUInt32		neededSize	= 0;
	PGPrpcMessage *	msg			= NULL;
	PGPUInt32		i			= 0;
	PGPUInt32		uVal		= 0;
	PGPUInt64		ullVal		= 0;
	PGPInt32		iVal		= 0;
	char *			szVal		= NULL;
	PGPByte *		bufVal		= NULL;
	PGPUInt32		bufSize		= 0;
	PGPByte *		buf			= NULL;

	neededSize = sGetNeededSize( fmt, args );

	*pBuf = PGPNewData( PGPPeekContextMemoryMgr( context ),
		neededSize + sizeof( msgType ) + sizeof( PGPUInt32 ),
		kPGPMemoryMgrFlags_Clear );
	if( IsNull( *pBuf ) )
		return kPGPError_OutOfMemory;
		
	buf = *pBuf;

	/* Add message type and message length to packed message */
	msg = (PGPrpcMessage *) buf;
	msg->msgType = msgType;
	msg->msgSize = neededSize;
	
	buf = msg->msgData;
		
	/* Now add the bulk of the data */
	for( i = 0; fmt[i] != '\0'; i++ )
	{
		switch( fmt[i] )
		{
			case 'i':
				iVal = va_arg( args, PGPInt32 );
				pgpCopyMemory( &iVal, buf, sizeof( iVal ) );
				buf += sizeof( iVal );
				break;

			case 'u':
			case 'b':
				uVal = va_arg( args, PGPUInt32 );
				pgpCopyMemory( &uVal, buf, sizeof( uVal ) );
				buf += sizeof( uVal );
				break;
			
			case 'U':
				ullVal = va_arg( args, PGPUInt64 );
				pgpCopyMemory( &ullVal, buf, sizeof( ullVal ) );
				buf += sizeof( ullVal );
				break;
			
			case 's':
				szVal = va_arg( args, char * );
				if( IsNull( szVal ) )
					szVal = "";
				pgpCopyMemory( szVal, buf, strlen( szVal ) + 1 );
				buf += strlen( szVal ) + 1;
				break;

			case 'B':
				bufVal = va_arg( args, PGPByte * );
				if( IsNull( bufVal ) )
					bufVal = "";
				bufSize = va_arg( args, PGPUInt32 );
				pgpCopyMemory( &bufSize, buf, sizeof( bufSize ) );
				buf += sizeof( bufSize );
				pgpCopyMemory( bufVal, buf, bufSize );
				buf += bufSize;
				break;

			default:
				break;
		}
	}

	*pLen = buf - *pBuf;

	return kPGPError_NoErr;
}

	PGPError
PGPrpcPack(
	PGPContextRef	context,
	PGPUInt32		msgType,
	PGPByte **		pBuf,
	PGPSize *		pLen,
	const char *	fmt,
	... )
{
	PGPError		err		= kPGPError_NoErr;
	va_list			args;

	va_start( args, fmt );

	err = sPGPrpcPackInternal( context, msgType, pBuf, pLen, fmt, args );
	
	va_end( args );

	return err;
}

	static PGPError
sPGPrpcUnpackInternal(
	PGPContextRef	context,
	PGPByte *		buf,
	PGPSize			len,
	const char *	fmt,
	va_list			args )
{
	PGPError		err			= kPGPError_NoErr;
	PGPrpcMessage *	msg			= NULL;
	PGPUInt32		i			= 0;
	PGPUInt32		uVal		= 0;
	PGPUInt32 *		puVal		= NULL;
	PGPUInt64 *		pullVal		= NULL;
	PGPInt32 *		piVal		= NULL;
	PGPBoolean *	pbVal		= NULL;
	char **			ppszVal		= NULL;
	PGPByte **		pbufVal		= NULL;

	/* Set buf to point to message data */
	msg = (PGPrpcMessage *) buf;
	buf = msg->msgData;
	
	/* Now read the data portion of the message */
	for( i = 0; fmt[i] != '\0'; i++ )
	{
		/* Check that we haven't run over the size of our buffer */
		if( buf - (PGPByte *) msg > len )
			RETERR( kPGPError_CorruptData );

		switch( fmt[i] )
		{
			case 'i':
				piVal = va_arg( args, PGPInt32 * );
				pgpCopyMemory( buf, piVal, sizeof( *piVal ) );
				buf += sizeof( *piVal );
				break;

			case 'u':
				puVal = va_arg( args, PGPUInt32 * );
				pgpCopyMemory( buf, puVal, sizeof( *puVal ) );
				buf += sizeof( *puVal );
				break;
			
			case 'U':
				pullVal = va_arg( args, PGPUInt64 * );
				pgpCopyMemory( buf, pullVal, sizeof( *pullVal ) );
				buf += sizeof( *pullVal );
				break;
			
			case 'b':
				pbVal = va_arg( args, PGPBoolean * );
				pgpCopyMemory( buf, &uVal, sizeof( uVal ) );
				*pbVal = uVal ? TRUE : FALSE;
				buf += sizeof( uVal );
				break;

			case 's':
				ppszVal = va_arg( args, char ** );
				*ppszVal = PGPNewData( PGPPeekContextMemoryMgr( context ),
					strlen( buf ) + 1,
					kPGPMemoryMgrFlags_Clear );
				CKNULL( *ppszVal );
				pgpCopyMemory( buf, *ppszVal, strlen( buf ) + 1 );
				buf += strlen( buf ) + 1;
				break;

			case 'B':
				pbufVal = va_arg( args, PGPByte ** );
				puVal = va_arg( args, PGPUInt32 * );
				pgpCopyMemory( buf, &uVal, sizeof( uVal ) );
				buf += sizeof( uVal );
				*puVal = uVal;
				*pbufVal = PGPNewData( PGPPeekContextMemoryMgr( context ),
					uVal,
					kPGPMemoryMgrFlags_Clear );
				CKNULL( *pbufVal );
				pgpCopyMemory( buf, *pbufVal, uVal );
				buf += uVal;
				break;

			default:
				break;
		}
	}

done:
	return err;
}

	PGPError
PGPrpcUnpack(
	PGPContextRef	context,
	PGPByte *		buf,
	PGPSize			len,
	const char *	fmt,
	... )
{
	PGPError		err		= kPGPError_NoErr;
	va_list			args;

	va_start( args, fmt );

	err = sPGPrpcUnpackInternal( context, buf, len, fmt, args );
	
	va_end( args );

	return err;
}

	PGPError
PGPrpcWrite(
	PGPInt32		sock,
	PGPByte *		buf,
	PGPSize			len )
{
	PGPInt32		retval			= 0;
	PGPUInt32		bytesWritten	= 0;
	
	do
	{
		retval = write( sock, buf + bytesWritten, len - bytesWritten );
		if( retval < 0 )
			return kPGPError_WriteFailed;
		bytesWritten += retval;
	} while( bytesWritten < len );
	
	return kPGPError_NoErr;
}

	static PGPError
sSetSocketBlocking(
	PGPInt32		sock )
{
	PGPInt32		retval		= 0;
	PGPInt32		flags		= 0;

	flags = fcntl( sock, F_GETFL, 0 );
	retval = fcntl( sock, F_SETFL, flags & ~O_NONBLOCK );
	if( retval < 0 )
		return kPGPError_UnknownError;
	
	return kPGPError_NoErr;
}

	PGPError
PGPrpcRead(
	PGPContextRef	context,
	PGPInt32		sock,
	PGPByte **		outBuf,
	PGPSize *		outLen )
{
	PGPError		err			= kPGPError_NoErr;
	PGPrpcMessage *	msg			= NULL;
	PGPUInt32		msgType		= 0;
	PGPUInt32		msgSize		= 0;
	PGPByte *		buf			= 0;
	PGPSize			len			= 0;
	PGPInt32		retval		= 0;
	PGPUInt32		bytesRead	= 0;
	
	err = sSetSocketBlocking( sock ); CKERR;
	
	retval = read( sock, &msgType, sizeof( msgType ) );
	if( retval < (PGPInt32) sizeof( msgType ) )
	{
		if( retval > 0 )
			errno = EAGAIN;
		RETERR( kPGPError_UnknownError );
	}
	
	retval = read( sock, &msgSize, sizeof( msgSize ) );
	if( retval < (PGPInt32) sizeof( msgSize ) )
	{
		if( retval > 0 )
			errno = EAGAIN;
		RETERR( kPGPError_UnknownError );
	}
	
	len = sizeof( msgType ) + sizeof( msgSize ) + msgSize;
	buf = PGPNewData( PGPPeekContextMemoryMgr( context ),
		len,
		kPGPMemoryMgrFlags_Clear );
	CKNULL( buf );
	
	msg = (PGPrpcMessage *) buf;
	msg->msgType = msgType;
	msg->msgSize = msgSize;
	
	if( msgSize > 0 )
	{
		do
		{
			retval = read( sock, msg->msgData + bytesRead, msgSize - bytesRead );
			if( retval < 0 )
				RETERR( kPGPError_ReadFailed );
			else if( retval == 0 )
				RETERR( kPGPError_EOF );
			bytesRead += retval;
		} while( bytesRead < msgSize );
	}

	*outBuf = buf;
	*outLen = len;
		
done:
	return err;
}

	PGPError
PGPrpcPackAndWrite(
	PGPContextRef	context,
	PGPInt32		sock,
	PGPUInt32		msgType,
	const char *	fmt,
	... )
{
	PGPError		err		= kPGPError_NoErr;
	va_list			args;
	PGPByte *		buf		= NULL;
	PGPSize			len		= 0;

	va_start( args, fmt );

	err = sPGPrpcPackInternal( context, msgType, &buf, &len, fmt, args ); CKERR;
	err = PGPrpcWrite( sock, buf, len ); CKERR;

done:
	if( IsntNull( buf ) )
		(void) PGPFreeData( buf );
	va_end( args );
	return err;
}


	PGPError
PGPrpcReadAndUnpack(
	PGPContextRef	context,
	PGPInt32		sock,
	PGPUInt32		msgType,
	const char *	fmt,
	... )
{
	PGPError		err		= kPGPError_NoErr;
	va_list			args;
	PGPByte *		buf		= NULL;
	PGPSize			len		= 0;
	PGPrpcMessage *	msg		= NULL;

	va_start( args, fmt );

	err = PGPrpcRead( context, sock, &buf, &len ); CKERR;

	msg = (PGPrpcMessage *) buf;
	if( msg->msgType != msgType )
		RETERR( kPGPError_CorruptData );
		
	err = sPGPrpcUnpackInternal( context, buf, len, fmt, args ); CKERR;
 	
done:
	if( IsntNull( buf ) )
		(void) PGPFreeData( buf );
	va_end( args );
	return err;
}

⌨️ 快捷键说明

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