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

📄 pgpgroups.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
	
	pgpEnterPGPErrorFunction();

	err	= sFindGroupByID( set, id, (PGPGroup **)&group );
	if ( IsntPGPError( err ) )
	{
		info->id		= id;
		strcpy( info->name, group->name );
		strcpy( info->description, group->description );
		info->userValue	= group->userValue;
	}
	
	return( err );
}


	PGPError
PGPSetGroupName(
	PGPGroupSetRef	set,
	PGPGroupID		id,
	const char *	name )
{
	PGPError		err	= kPGPError_NoErr;
	PGPGroup *		group	= NULL;
	
	PGPValidatePtr( name );
	PGPValidateGroupSet( set );
	PGPValidateParam( strlen( name ) <= kPGPMaxGroupNameLength );
	
	pgpEnterPGPErrorFunction();

	err	= sFindGroupByID( set, id, &group );
	if ( IsntPGPError( err ) )
	{
		strcpy( group->name, name );
		set->hasBeenModified	= TRUE;
	}
	
	return( err );
}


	PGPError
PGPSetGroupDescription(
	PGPGroupSetRef	set,
	PGPGroupID		id,
	const char *	description )
{
	PGPError		err	= kPGPError_NoErr;
	PGPGroup *		group	= NULL;
	
	PGPValidatePtr( description );
	PGPValidateParam( strlen( description ) <= kPGPMaxGroupDescriptionLength );
	PGPValidateGroupSet( set );
	
	pgpEnterPGPErrorFunction();

	err	= sFindGroupByID( set, id, &group );
	if ( IsntPGPError( err ) )
	{
		strcpy( group->description, description );
		set->hasBeenModified	= TRUE;
	}
	
	return( err );
}


	PGPError
PGPSetGroupUserValue(
	PGPGroupSetRef	set,
	PGPGroupID		id,
	PGPUserValue	userValue )
{
	PGPError		err	= kPGPError_NoErr;
	PGPGroup *		group	= NULL;
	
	PGPValidateGroupSet( set );
	
	pgpEnterPGPErrorFunction();

	err	= sFindGroupByID( set, id, &group );
	if ( IsntPGPError( err ) )
	{
		group->userValue	= userValue;
	}
	
	return( err );
}





/*____________________________________________________________________________
	Return TRUE if group1 contains group 2, either directly or in a subgroup.
____________________________________________________________________________*/
	static PGPBoolean
sGroupContainsGroup(
	PGPGroupSetRef	set,
	PGPGroupID		mainGroupID,
	PGPGroupID		subGroup )
{
	PGPError			err	= kPGPError_NoErr;
	PGPGroup  *			mainGroup	= NULL;
	PGPBoolean			containsGroup	= FALSE;
	PGPUInt32			index;
	
	err	= sFindGroupByID( set, mainGroupID, &mainGroup );
	pgpAssertNoErr( err );
	if ( IsPGPError( err ) )
		return( FALSE );
	if ( mainGroupID == subGroup )
	{
		/* can't add a group to itself */
		return( TRUE );
	}
	
	for( index = 0; index < mainGroup->numItems; ++index )
	{
		PGPGroupItem const *	item;
		
		item	= &mainGroup->itemsArray[ index ];
		if ( item->type == kPGPGroupItem_Group )
		{
			if ( item->u.groupID == subGroup )
			{
				containsGroup	= TRUE;
				break;
			}
			else if ( sGroupContainsGroup( set, item->u.groupID, subGroup ) )
			{
				containsGroup	= TRUE;
				break;
			}
		}
	}
	
	return( containsGroup );
}


/*____________________________________________________________________________
	Add an item to the group.  Caller must completely fill in the item
	before adding.
____________________________________________________________________________*/
	PGPError
PGPAddItemToGroup(
	PGPGroupSetRef			set,
	PGPGroupItem const *	item,
	PGPGroupID				id )
{
	PGPError		err	= kPGPError_NoErr;
	PGPGroup *		group	= NULL;
	PGPUInt32		index;
	
	PGPValidateGroupSet( set );
	PGPValidatePtr( item );
	PGPValidateParam( item->type == kPGPGroupItem_KeyID ||
		item->type == kPGPGroupItem_Group );

	pgpEnterPGPErrorFunction();

	/* verify that the group being added to exists */
	err	= sFindGroupByID( set, id, &group );
	if ( IsPGPError( err ) )
		return( err );
	
	if ( item->type == kPGPGroupItem_Group )
	{
		/* verify that if the group being added that exists */
		PGPGroup *	itemGroup;
		err	= sFindGroupByID( set, item->u.groupID, &itemGroup );
		if ( IsPGPError( err ) )
			return( err );
	}
	
	/* verify that the group doesn't already contain this item */
	if ( sIsGroupMember( group, item, &index )  )
		return( kPGPError_ItemAlreadyExists );
	
	/* verify that a cycle won't be created by adding */
	if ( item->type == kPGPGroupItem_Group &&
		sGroupContainsGroup( set, item->u.groupID, id ) )
	{
		return( kPGPError_BadParams );
	}
	
	/* OK, all verification is now done */
	
	if ( IsntPGPError( err ) )
	{
		PGPContextRef	context	= set->context;
		PGPSize			newSize;
		
		newSize	= ( group->numItems + 1 ) * sizeof( PGPGroupItem );
		/* add the new item */
		err	= pgpContextMemRealloc( context, (void **) &group->itemsArray,
				newSize, 0);
		
		if ( IsntPGPError( err ) )
		{
			(group->itemsArray)[ group->numItems ]	= *item;
			group->numItems++;
			set->hasBeenModified	= TRUE;
		}
	}
	
	return( err );
}
				

/*____________________________________________________________________________
	This can't use an iterator, because it is used to create an iterator.
____________________________________________________________________________*/
	PGPError
PGPCountGroupItems(
	PGPGroupSetRef		set,
	PGPGroupID 			id,
	PGPBoolean			recursive,
	PGPUInt32 *			outNumKeys,
	PGPUInt32 *			outTotal )
{
	PGPError	err	= kPGPError_NoErr;
	PGPGroup *	group	= NULL;
	PGPUInt32	numItems	= 0;
	PGPUInt32	numKeys		= 0;
	
	if ( IsntNull( outNumKeys ) )
		*outNumKeys	= 0;
	if ( IsntNull( outTotal ) )
		*outTotal	= 0;
	PGPValidateGroupSet( set );
	
	pgpEnterPGPErrorFunction();

	err	= sFindGroupByID( set, id, &group);
	if ( IsntPGPError( err ) )
	{
		PGPUInt32	index;
			
		/* account for all items in this group right here */
		numItems	+= group->numItems;
		
		for (index = 0; index < group->numItems; ++index )
		{
			PGPGroupItem const *item;
			
			item	= &group->itemsArray[ index ];
			if ( item->type == kPGPGroupItem_KeyID )
			{
				++numKeys;
			}
			else if ( recursive && item->type == kPGPGroupItem_Group )
			{
				PGPUInt32	tempTotal;
				PGPUInt32	tempKeys;
				
				err	= PGPCountGroupItems( set, item->u.groupID, TRUE,
					&tempKeys, &tempTotal );
				if ( IsPGPError( err ) )
					break;
				numKeys		+= tempKeys;
				numItems	+= tempTotal;
			}
		}
	}
	
	if ( IsntPGPError( err ) )
	{
		if ( IsntNull( outTotal ) )
			*outTotal	= numItems;
			
		if ( IsntNull( outNumKeys ) )
			*outNumKeys	= numKeys;
	}
	
	return( err );
}




	PGPError
PGPGetIndGroupItem(
	PGPGroupSetRef	set,
	PGPGroupID			id,
	PGPUInt32			index,
	PGPGroupItem *		item )
{
	PGPError		err	= kPGPError_NoErr;
	PGPGroup *		group	= NULL;
	
	PGPValidatePtr( item );
	pgpClearMemory( item, sizeof( *item ) );
	PGPValidateGroupSet( set );
	
	pgpEnterPGPErrorFunction();

	err	= sFindGroupByID( set, id, &group);
	if ( IsntPGPError( err ) )
	{
		if ( index < group->numItems )
		{
			*item	= group->itemsArray[ index ];
		}
		else
		{
			err	= kPGPError_BadParams;
		}
	}
	
	return( err );
}


	PGPError
PGPSetIndGroupItemUserValue(
	PGPGroupSetRef	set,
	PGPGroupID		id,
	PGPUInt32		index,
	PGPUserValue	userValue )
{
	PGPError		err	= kPGPError_NoErr;
	PGPGroup *		group	= NULL;
	
	PGPValidateGroupSet( set );
	
	pgpEnterPGPErrorFunction();

	err	= sFindGroupByID( set, id, &group);
	if ( IsntPGPError( err ) )
	{
		if ( index < group->numItems )
		{
			group->itemsArray[ index ].userValue	= userValue;
		}
		else
		{
			err	= kPGPError_BadParams;
		}
	}
	
	return( err );
}

/*____________________________________________________________________________
	An iterator is implemented by creating an array of pointers to the
	elements to be iterated.  This uses a modest amount of memory relative
	to the overall structure, and results in very fast iteration.
	
	Its drawbacks include the inability to change the overall structure
	while iterating (at least in this implementation).
____________________________________________________________________________*/

typedef struct PGPGroupIter	PGPGroupIter;
struct PGPGroupIter
{
	PGPGroupSetRef			set;
	const PGPGroupItem  **	items;
	#define kBeforeFirstItemIndex	0xFFFFFFFF
	PGPUInt32				curIndex;
	PGPUInt32				numItems;
};


/*____________________________________________________________________________
	Fill the iter->items array with pointers to all items in the group.
____________________________________________________________________________*/
	static PGPUInt32
sCollectPointersForIter(
	PGPGroupIter *	iter,
	PGPGroupID		id,
	PGPBoolean		recursive,
	PGPFlags		flags,
	PGPUInt32		startSlot )
{
	PGPUInt32			nextSlot	= startSlot;
	PGPUInt32			index;
	PGPGroup const *	group	= NULL;
	PGPError			err	= kPGPError_NoErr;
	
	pgpAssert( IsntNull( iter ) );
	
	if ( startSlot >= iter->numItems )
	{
		/* if we've found all the items we could be pointing after 
		the end of the array, but we shouldn't find any more items
		of the desired kind, so no point in continuing */
		return( startSlot );
	}
	
	err	= sFindGroupByID( iter->set, id, (PGPGroup **)&group );
	pgpAssertNoErr( err );
	
	for( index = 0; index < group->numItems; ++index )
	{
		const PGPGroupItem *	item;
		
		item	= &group->itemsArray[ index ];
		if ( item->type == kPGPGroupItem_KeyID )
		{
			if ( ( flags & kPGPGroupIterFlags_Keys) != 0 )
			{
				iter->items[ nextSlot ]	= item;
				++nextSlot;
			}
		}
		else
		{
			pgpAssert( item->type == kPGPGroupItem_Group );
			if ( ( flags & kPGPGroupIterFlags_Groups) != 0 )
			{
				iter->items[ nextSlot ]	= item;
				++nextSlot;
			}
		
			if ( recursive )
			{
				nextSlot	= sCollectPointersForIter( iter,
								item->u.groupID, TRUE, flags, nextSlot );
			}
		}
	}
	
	return( nextSlot );
}



	static PGPError
sInitIter(
	PGPGroupSetRef		set,
	PGPGroupID			id,
	PGPFlags			flags,
	PGPGroupIter *		iter )
{
	PGPError	err	= kPGPError_NoErr;
	PGPUInt32	numKeys;
	PGPUInt32	numItems;
	PGPBoolean	recursive;
	PGPGroupID	actualID	= id;
	
	recursive	= (flags & kPGPGroupIterFlags_Recursive) != 0;
	
	pgpClearMemory( iter, sizeof( *iter ) );
	
	if ( IsntPGPError( err ) )
	{
		iter->set		= set;
		iter->items		= NULL;
		iter->curIndex	= kBeforeFirstItemIndex;
		err	= PGPCountGroupItems( set, actualID,
				recursive, &numKeys, &numItems );
		if ( IsntPGPError( err ) )
		{
			iter->numItems	= 0;
			if ( ( flags & kPGPGroupIterFlags_Keys) != 0 )
				iter->numItems	+= numKeys;
			if ( ( flags & kPGPGroupIterFlags_Groups) != 0 )
				iter->numItems	+= (numItems - numKeys);
			
			/* create an array of pointers to the items */
			iter->items	= (const PGPGroupItem **)pgpContextMemAlloc(
							set->context,
							iter->numItems * sizeof( iter->items[ 0 ] ),
							0);
			if ( IsNull( iter->items ) )
				err	= kPGPError_OutOfMemory;
		}
		
		if ( IsntPGPError( err ) )
		{
			PGPUInt32	nextSlot;
			
			/* collect all the pointers we need */
			nextSlot	= sCollectPointersForIter( iter,
							actualID, recursive, flags, 0);
			pgpAssert( nextSlot == iter->numItems ||
					nextSlot == iter->numItems + 1);
		}
	}
	
	return( err );
}


	PGPError
PGPNewGroupItemIter(
	PGPGroupSetRef			set,
	PGPGroupID				id,
	PGPFlags				flags,
	PGPGroupItemIterRef *	iterOut )
{
	PGPError			err	= kPGPError_NoErr;
	PGPGroupIter *		iter	= NULL;
	
	PGPValidatePtr( iterOut );
	*iterOut	= NULL;
	PGPValidateGroupSet( set );
	PGPValidateParam( (flags & kPGPGroupIterFlags_AllItems) != 0 );
	PGPValidateParam( (flags & ~ kPGPGroupIterFlags_AllRecursive) == 0 );
	
	pgpEnterPGPErrorFunction();

	iter	= (PGPGroupIter *)pgpContextMemAlloc( set->context,
			sizeof( *iter ), kPGPMemoryMgrFlags_Clear );
	if ( IsNull( iter ) )
		err	= kPGPError_OutOfMemory;
	if ( IsntPGPError( err ) )
	{
		err	= sInitIter( set, id, flags, iter );
		if ( IsPGPError( err ) )
		{
			pgpContextMemFree( set->context, iter );
			iter	= NULL;
		}
	}
	
	*iterOut	= iter;
	return( err );
}


	PGPError
PGPFreeGroupItemIter( PGPGroupItemIterRef iter )
{
	PGPError	err	= kPGPError_NoErr;
	
	PGPValidateParam( IsntNull( iter ) );

	pgpEnterPGPErrorFunction();

	if ( IsntNull( iter->items ) )
	{
		err	= pgpContextMemFree( iter->set->context,
				(void *) iter->items );
		iter->items	= NULL;
	}
	
	if ( IsntPGPError( err ) )
	{
		err	= pgpContextMemFree( iter->set->context, iter );
	}
	
	return( err );
}




/*____________________________________________________________________________
	Returns kPGPError_EndOfIteration when done
____________________________________________________________________________*/
	PGPError
PGPGroupItemIterNext(
	PGPGroupItemIterRef	iter,
	PGPGroupItem *		item )
{
	PGPError	err	= kPGPError_NoErr;
	
	PGPValidatePtr( item );
	PGPValidateParam( IsntNull( iter ) );
	PGPValidateGroupSet( iter->set );

⌨️ 快捷键说明

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