📄 pgprpcpacker.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 + -