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

📄 pgpkeydb.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
	PGPKeySetRef
PGPPeekKeyDBRootKeySet( PGPKeyDBRef keyDB )
{
	if( ! pgpKeyDBIsValid( keyDB ) )
		return kInvalidPGPKeySetRef;
		
	pgpEnterZeroFunction();

	return pgpKeyDBPeekRootSet( keyDB );
}

	PGPError
pgpKeyDBError( PGPKeyDB *kdb )
{
	pgpa(pgpaPGPKeyDBValid(kdb));
	return kdb->err;
}

	void
pgpKeyDBSetError( PGPKeyDB *kdb, PGPError err )
{
	pgpa(pgpaPGPKeyDBValid(kdb));
	kdb->err = err;
}


	PGPError
PGPFlushKeyDB(PGPKeyDBRef keydb)
{
	PGPValidateKeyDB( keydb );

	pgpEnterPGPErrorFunction();

	return pgpKeyDBFlushInternal( keydb );
}


	PGPError
PGPCountKeysInKeyDB(
	PGPKeyDBRef 	keydb,
	PGPUInt32 *		numKeys )
{
	PGPKeyDBObj *	key;
	PGPUInt32		count = 0;
	PGPError		err	= kPGPError_NoErr;
	
	PGPValidatePtr( numKeys );
	*numKeys	= 0;
	PGPValidateKeyDB( keydb );

	pgpEnterPGPErrorFunction();

	for (key = keydb->firstKeyInDB; key; key = key->next)
	{
		if( pgpKeyDBObjIsReal(key) )
			count++;
	}
	 
	*numKeys = count;

	return( err );
}


	static PGPError
sMatchingKeyDB (PGPContextRef context,
	PFLFileSpecRef pubFileRef, PFLFileSpecRef privFileRef,
	PGPKeyDBRef *keydb )
{
	PGPKeyDBRef		kdb;
	PGPBoolean		match = FALSE;

	*keydb = NULL;

	for( kdb=pgpContextGetFirstKeyDB(context); IsntNull(kdb); kdb=kdb->next )
	{
		if( pgpFrontEndKeyDB( kdb ) )
			continue;

		if( IsNull( kdb->privFileRef )  &&  IsNull( kdb->pubFileRef ) )
			continue;

		if( IsNull(kdb->privFileRef) || IsNull(privFileRef) )
			match = (kdb->privFileRef == privFileRef);
		else
			match = PFLFileSpecsEqual( kdb->privFileRef, privFileRef );
		match &= PFLFileSpecsEqual( kdb->pubFileRef, pubFileRef );

		if( match )
			break;
	}

	if( match )
	{
		pgpAssert( IsntNull( kdb ) );
		++kdb->refCount;
		*keydb = kdb;
	}

	return kPGPError_NoErr;
}


/****************************  Notifications  **************************/

	void
pgpSetPendingNotify( PGPKeySetRef changeset, PGPKeyDBObjRef changeobj,
	PGPKeySetRef newset, PGPKeyDBObjRef newobj )
{
	PGPKeyDB *db = NULL;
	PGPContextRef context;
	PGPNotification *nt;
	PGPConnectRef id = kPGPConnectRef_Null;

	if( IsntNull( changeset ) || IsntNull( newset ) )
	{
		db = PGPPeekKeySetKeyDB( IsntNull(changeset)?changeset:newset );
	} else {
		pgpAssert( IsntNull(changeobj) || IsntNull(newobj) );
		db = PGPPeekKeyDBObjKeyDB( IsntNull(changeobj)?changeobj:newobj );
	}
	context = PGPPeekKeyDBContext( db );
	id = pgpContextGetConnectRef( context );
	for( nt = db->notifies; IsntNull( nt ); nt = nt->next )
	{
		if( pgpConnectRefEqual( nt->id, id ) )
			continue;
		if( IsntNull( changeset ) )
			PGPAddKeys( changeset, nt->changeSet );
		if( IsntNull( newset ) )
			PGPAddKeys( newset, nt->newSet );
		if( IsntNull( changeobj ) )
			PGPAddKey( changeobj, nt->changeSet );
		if( IsntNull( newobj ) )
			PGPAddKey( newobj, nt->newSet );
	}

#if PGP_WIN32 || PGP_OSX
/* Add support for other hosts that do notification */
	if( IsntNull( db ) )
	{
		for( nt = db->notifies; IsntNull( nt ); nt = nt->next )
		{
			if( pgpConnectRefEqual( nt->id, id ) )
				continue;
			if( ( !pgpKeySetIsEmpty( nt->changeSet ) )
				|| !pgpKeySetIsEmpty( nt->newSet ) )
			{
				pgpNotifyClient( nt->id, kPGPNotification_KeyDBChanged );
			}
		}
	}
#endif
}

	PGPError
pgpUpdateKeyDB_internal( PGPKeyDB *db, PGPKeySetRef newSet,
						 PGPKeySetRef changeSet )
{
	PGPNotification *nt;
	PGPContextRef context;
	PGPConnectRef id;
	PGPError err = kPGPError_NoErr;

	context = PGPPeekKeyDBContext( db );
	id = pgpContextGetConnectRef( context );

	for( nt = db->notifies; IsntNull( nt ); nt = nt->next )
	{
		if( pgpConnectRefEqual( nt->id, id ) )
		{
			err = PGPAddKeys( nt->newSet, newSet );
			if( IsPGPError( err ) )
				break;
			err = PGPAddKeys( nt->changeSet, changeSet );
			if( IsPGPError( err ) )
				break;
			PGPFreeKeySet( nt->newSet );
			PGPFreeKeySet( nt->changeSet );
			nt->newSet = nt->changeSet = NULL;
			err = PGPNewEmptyKeySet( db, &nt->newSet );
			if( IsPGPError( err ) )
				break;
			err = PGPNewEmptyKeySet( db, &nt->changeSet );
			if( IsPGPError( err ) )
				break;
			break;
		}
	}
	return err;
}

	void
pgpSetBackendUpdateNeeded()
{
	PGPContextRef	ctx;

	ctx = NULL;
	while( IsntNull( ctx = pgpContextNextContext( ctx ) ) )
	{
		pgpContextSetUpdateNeeded( ctx, TRUE );
		++sBackendUpdatesNeeded;
	}
}


	void
pgpKeyDBBackendUpdate( )
{
	PGPContextRef	ctx;
	PGPKeyDBRef		kdb;
	PGPError		err;
	PGPUInt32		numNewKeys;
	PGPUInt32 *		newKeyArray;
	PGPSize			newKeyArraySize;
	PGPUInt32 *		changelist;
	PGPSize			changelistsize;
	PGPBoolean		firstContext = TRUE;

	if (!pgpRPCEnabled())
		return;
	if( sBackendUpdatesNeeded > 0 )
	{
		ctx = NULL;
		while( IsntNull( ctx = pgpContextNextContext( ctx ) ) &&
			   pgpContextGetUpdateNeeded( ctx ) )
		{
#if PGP_WIN32
			/*
			 * Only handle contexts associated with current thread;
			 * or if there is only one context we assume that the clients
			 * are managing multiple thread usage of that context properly
			 * so we will update them too.
			 */
			if( GetCurrentThreadId() != pgpContextGetThreadID(ctx) &&
				! (firstContext && pgpContextNextContext(ctx) == NULL) )
				continue;
#endif
			/* Dec counter and clear flag before processing; we may reenter */
			--sBackendUpdatesNeeded;
			pgpContextSetUpdateNeeded( ctx, FALSE );

			for( kdb=pgpContextGetFirstKeyDB(ctx); IsntNull(kdb);
				 								kdb=kdb->next )
			{
				err = pgpUpdateKeyDB_back( ctx, kdb->id, &numNewKeys,
										   &newKeyArray, &newKeyArraySize,
										   &changelist, &changelistsize );
				if( IsPGPError( err ) )
					continue;
				err = pgpAddFromKeyArray( kdb, NULL, newKeyArray, numNewKeys,
										  FALSE );
				if( IsntNull( newKeyArray ) )
					PGPFreeData( newKeyArray );
				err = pgpKeyRefreshFromList( kdb, changelist, changelistsize );
			}
			firstContext = FALSE;
		}
	}
}

/* External function to poll for whether keydb has been changed in backend */
/* Intended for use on architectures where callbacks can't be done */
	PGPError
PGPKeyDBIsUpdated( PGPKeyDBRef kdb, PGPBoolean *updated )
{
	PGPError		err;
	PGPUInt32		numNewKeys;
	PGPUInt32 *		newKeyArray;
	PGPSize			newKeyArraySize;
	PGPUInt32 *		changelist;
	PGPSize			changelistsize;
	PGPContextRef	context;

	PGPValidatePtr( updated );
	*updated	= FALSE;
	PGPValidateKeyDB( kdb );

	pgpEnterPGPErrorFunction();

	context = kdb->context;
	err = pgpUpdateKeyDB_back( context, kdb->id, &numNewKeys,
							   &newKeyArray, &newKeyArraySize,
							   &changelist, &changelistsize );
	if( IsPGPError( err ) )
		return err;

	/* Return with updated as false if nothing to do */
	if( newKeyArraySize == 0 && changelistsize == 0 )
	{
		if( IsntNull( newKeyArray ) )
			PGPFreeData( newKeyArray );
		if( IsntNull( changelist ) )
			PGPFreeData( changelist );
		return kPGPError_NoErr;
	}

	err = pgpAddFromKeyArray( kdb, NULL, newKeyArray, numNewKeys,
							  FALSE );
	if( IsntNull( newKeyArray ) )
		PGPFreeData( newKeyArray );
	err = pgpKeyRefreshFromList( kdb, changelist, changelistsize );

	if( IsntPGPError( err ) )
		*updated = TRUE;

	return err;
}

	static void
sAddNotification( PGPKeyDB *db )
{
	PGPContextRef context;
	PGPConnectRef id;
	PGPConnectRef nullId = kPGPConnectRef_Null;
	PGPNotification *nt;

	context = PGPPeekKeyDBContext( db );
	id = pgpContextGetConnectRef( context );

	if( !pgpConnectRefEqual( id, nullId ) )
	{
		nt = (PGPNotification *) pgpContextMemAlloc( context, sizeof(*nt), 0 );
		PGPNewEmptyKeySet( db, &nt->newSet );
		PGPNewEmptyKeySet( db, &nt->changeSet );
		nt->id = id;
		nt->next = db->notifies;
		db->notifies = nt;
	}
}

	static void
sRemoveNotification( PGPKeyDB *db )
{
	PGPContextRef context;
	PGPConnectRef id;
	PGPConnectRef nullId = kPGPConnectRef_Null;
	PGPNotification *nt, *ntprev;

	context = PGPPeekKeyDBContext( db );
	id = pgpContextGetConnectRef( context );
	if( pgpConnectRefEqual( id, nullId ) )
		return;

	ntprev = NULL;
	for( nt=db->notifies; IsntNull( nt ); ntprev = nt, nt = nt->next )
	{
		if( pgpConnectRefEqual( nt->id, id ) )
		{
			if( ntprev == NULL )
			{
				db->notifies = nt->next;
			} else {
				ntprev->next = nt->next;
			}
			PGPFreeKeySet( nt->newSet );
			PGPFreeKeySet( nt->changeSet );
			PGPFreeData( nt );
			return;
		}
	}
	pgpAssert( 0 );
}
	


/****************************  Constructors  **************************/

	PGPKeyDBRef 
pgpCreateKeyDBFromKeyRings (PGPContextRef context,
	PFLFileSpecRef pubFileRef, PFLFileSpecRef privFileRef,
	PGPFlags openFlags, PGPError *error)
{
	PGPKeyDBRef    kdb;

	*error = kPGPError_NoErr;

	/* See if we have a matching keydb already */
	*error = sMatchingKeyDB( context, pubFileRef, privFileRef, &kdb );
	if( IsPGPError( *error ) )
		return NULL;

	if( IsntNull( kdb ) )
	{
		sAddNotification( kdb );
		if( openFlags & kPGPOpenKeyDBFileOptions_Mutable )
			kdb->bmutable = TRUE;
		return kdb;
	}

	kdb = (PGPKeyDB *)pgpContextMemAlloc( context, sizeof(PGPKeyDB),
										  kPGPMemoryMgrFlags_Clear);
	if (kdb == NULL)
	{
		*error = kPGPError_OutOfMemory;
		return NULL;
	}

	pgpKeyDBInit( context, kdb );

	if( IsPGPError( *error = PFLCopyFileSpec(pubFileRef, &kdb->pubFileRef) ) )
	{
		pgpKeyDBDestroyInternal( kdb );
		return NULL;
	}
	if(	IsntNull( privFileRef ) &&
		IsPGPError( *error = PFLCopyFileSpec(privFileRef, &kdb->privFileRef )))
	{
		pgpKeyDBDestroyInternal( kdb );
		return NULL;
	}
	kdb->openFlags = openFlags;
	*error = sOpenKeyRings ( kdb );
	if (*error)
	{
		pgpKeyDBDestroyInternal( kdb );
		return NULL;
	}

	return kdb;
}

	PGPKeyDBRef 
pgpCreateKeyDBFromMemory (PGPContextRef context,
	const void *buf, PGPSize buflen, PGPError *error)
{
	PGPKeyDBRef		kdb;

	*error = kPGPError_NoErr;
	kdb = (PGPKeyDB *)pgpContextMemAlloc( context, sizeof(PGPKeyDB),
										  kPGPMemoryMgrFlags_Clear);
	if (kdb == NULL)
	{
		*error = kPGPError_OutOfMemory;
		return NULL;
	}

	pgpKeyDBInit( context, kdb );

	/* Memfile keydb's are immutable */
	kdb->bmutable = FALSE;

	kdb->pubFile = pgpFileMemOpen ( context, buf, buflen );
	if (!kdb->pubFile)
	{
		pgpKeyDBDestroyInternal( kdb );
		*error = kPGPError_OutOfMemory;
		return NULL;
	}

	*error = pgpReadKeyFile( kdb, kdb->pubFile, FALSE );
	if (*error)
	{
		pgpKeyDBDestroyInternal( kdb );
		return NULL;
	}

	return kdb;
}


/* Create a new, empty keydb, of the memory type */
	PGPError
pgpNewKeyDB_internal( PGPContextRef context, PGPKeyDBRef *keydb )
{
	PGPKeyDBRef		kdb;

	*keydb	= NULL;

	kdb = (PGPKeyDB *)pgpContextMemAlloc( context, sizeof(PGPKeyDB),
										  kPGPMemoryMgrFlags_Clear);
	if (kdb == NULL)
		return kPGPError_OutOfMemory;

	pgpKeyDBInit( context, kdb );

	/* Memfile keydb's are immutable */
	kdb->bmutable = FALSE;

	*keydb = kdb;
	return kPGPError_NoErr;
}


/* Create a new, empty keydb, of the memory type */
	PGPError
PGPNewKeyDB( PGPContextRef context, PGPKeyDBRef *keydb )
{
	PGPUInt32		kdbid;
	PGPError		err;

	PGPValidatePtr( keydb );
	*keydb	= NULL;
	PGPValidateContext( context );
	
	pgpEnterPGPErrorFunction();

	/* In production mode, if no server, don't use double data structs */
#if !PGP_FORCEBACKEND
	if( !pgpRPCEnabled() )
	{
		return pgpNewKeyDB_internal( context, keydb );
	}
#endif

	err = pgpNewKeyDB_back( context, &kdbid );
	if( IsPGPError( err ) )
		return err;

	return pgpNewFrontEndKeyDB( context,  kdbid, NULL, 0, keydb );
}


/* Create a new keydb for the front end, from the given key array */
	PGPError
pgpNewFrontEndKeyDB( PGPContextRef context, PGPUInt32 kdbid,
	PGPUInt32 *keyArray, PGPUInt32 keyCount, PGPKeyDBRef *keydb )
{
	PGPKeyDB *kdb;
	PGPError err = kPGPError_NoErr;

	PGPValidatePtr( keydb );
	*keydb	= NULL;
	PGPValidateContext( context );
	
	kdb = (PGPKeyDB *)pgpContextMemAlloc( context, sizeof(PGPKeyDB),
										  kPGPMemoryMgrFlags_Clear);
	if (kdb == NULL)
		return kPGPError_OutOfMemory;

	pgpKeyDBInit( context, kdb );
	kdb->id = kdbid;

	err = pgpAddFromKeyArray( kdb, NULL, keyArray, keyCount, TRUE );
	
	if( IsPGPError( err ) )
		pgpKeyDBDestroyInternal( kdb );
	else
		*keydb = kdb;

	return err;
}
	




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

⌨️ 快捷键说明

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