📄 pgpkeyset.c
字号:
error:
if( IsntNull(iter) )
PGPFreeKeyIter (iter);
if( IsntNull(newset) )
PGPFreeKeySet (newset);
return err;
}
/* Add all the objects in the first key set into the second keydb. */
PGPError
PGPCopyKeys (
PGPKeySetRef keysToAdd,
PGPKeyDBRef destdb,
PGPKeySetRef *destKeySet )
{
if( IsntNull( destKeySet ) )
*destKeySet = kInvalidPGPKeySetRef;
PGPValidateKeyDB( destdb );
PGPValidateKeySet( keysToAdd );
pgpEnterPGPErrorFunction();
return pgpCopyKeys_internal( keysToAdd, destdb, destKeySet );
}
/* Like PGPCopyKeys, but just one key */
PGPError
PGPCopyKeyDBObj (
PGPKeyDBObjRef obj,
PGPKeyDBRef keydb,
PGPKeyDBObjRef *destObj)
{
PGPKeySetRef oneset;
PGPKeySetRef newset;
PGPError err = kPGPError_NoErr;
if( IsntNull( destObj ) )
*destObj = kInvalidPGPKeyDBObjRef;
PGPValidateKeyDBObj( obj );
PGPValidateKeyDB( keydb );
pgpEnterPGPErrorFunction();
err = PGPNewOneKeySet( obj, &oneset );
if( IsPGPError( err ) )
return err;
err = PGPCopyKeys( oneset, keydb, (IsntNull(destObj)?&newset:NULL) );
PGPFreeKeySet( oneset );
if( IsntPGPError(err) && IsntNull( destObj ) )
{
*destObj = pgpFirstKeyInKeySet( newset );
PGPFreeKeySet( newset );
}
return err;
}
/* Remove all objects in the set from its keydb */
PGPError
PGPDeleteKeys (
PGPKeySetRef keysToRemove)
{
PGPKeyIter *iter = NULL;
PGPKeyDB *db;
PGPKeyDBObj *obj;
PGPError err = kPGPError_NoErr;
PGPValidateKeySet( keysToRemove );
pgpEnterPGPErrorFunction();
db = PGPPeekKeySetKeyDB( keysToRemove );
err = PGPNewKeyIterFromKeySet( keysToRemove, &iter );
if ( IsPGPError( err ) )
goto error;
while( IsntPGPError( pgpKeyIterNextObject( iter, &obj ) ) ) {
/* May have been deleted when parent was */
if( !pgpKeyDBObjIsDeleted( obj ) )
{
err = pgpKeyDBRemoveObject( db, obj );
if ( IsPGPError( err ) )
goto error;
}
}
pgpKeyDBChanged( db, TRUE );
PGPFreeKeyIter( iter );
iter = NULL;
error:
if (iter)
PGPFreeKeyIter (iter);
return err;
}
PGPError
pgpFreeKeySet(PGPKeySet *keys, PGPBoolean bForce)
{
/* Root set doesn't get refcounted */
if( keys->keyDB->rootSet != keys )
keys->refCount--;
if (keys->refCount <= 0 || bForce)
{
(*keys->destroy)(keys);
keys->magic = ~keys->magic; /* mark as invalid */
if (keys->prevSetInDB)
keys->prevSetInDB->nextSetInDB = keys->nextSetInDB;
else
keys->keyDB->firstSetInDB = keys->nextSetInDB;
if (keys->nextSetInDB)
keys->nextSetInDB->prevSetInDB = keys->prevSetInDB;
pgpAssert(keys->firstListInSet == NULL);
PGPFreeData( keys);
}
return( kPGPError_NoErr );
}
PGPError
PGPFreeKeySet(PGPKeySet *keys)
{
PGPValidateKeySet( keys );
pgpEnterPGPErrorFunction();
return pgpFreeKeySet( keys, FALSE );
}
PGPError
PGPCountKeys(
PGPKeySetRef keys,
PGPUInt32 * numKeys )
{
PGPKeyDBObj * key;
PGPUInt32 count = 0;
PGPError err = kPGPError_NoErr;
PGPValidatePtr( numKeys );
*numKeys = 0;
PGPValidateKeySet( keys );
pgpEnterPGPErrorFunction();
for (key = keys->keyDB->firstKeyInDB; key; key = key->next)
{
pgpa(pgpaPGPKeyValid(key));
if (pgpKeySetIsMember(key, keys))
count++;
}
*numKeys = count;
return( err );
}
PGPBoolean
pgpKeySetIsEmpty(
PGPKeySetRef keys )
{
pgpa(pgpaPGPKeySetValid(keys));
return keys->isEmpty( keys );
}
PGPKeyDBObj *
pgpFirstKeyInKeySet( PGPKeySet const * keySet )
{
PGPKeyDBObj * key;
PGPKeyDB * kdb;
kdb = keySet->keyDB;
for( key = kdb->firstKeyInDB; IsntNull(key); key = key->next )
if( pgpKeySetIsMember( key, (PGPKeySet *)keySet ) )
break;
return key;
}
/* Sort keylist by keyid, only in back end for efficiency */
static int
sCompareKeylistEntry( const void *ent1, const void *ent2 )
{
PGPKeyDBObj * obj1;
PGPKeyDBObj * obj2;
PGPKeyID keyid1, keyid2;
obj1 = *(PGPKeyDBObj **) ent1;
obj2 = *(PGPKeyDBObj **) ent2;
pgpAssert( !pgpFrontEndKey( obj1 ) );
pgpAssert( !pgpFrontEndKey( obj2 ) );
PGPGetKeyID( obj1, &keyid1 );
PGPGetKeyID( obj2, &keyid2 );
return PGPCompareKeyIDs( &keyid1, &keyid2 );
}
static void
sSortKeylist( PGPUInt32 *keylist, PGPSize keylistcount )
{
qsort( keylist, keylistcount, sizeof(PGPUInt32),
sCompareKeylistEntry );
}
/* True if keyset is such that all keys contain all sub objects */
PGPBoolean
pgpKeySetIsFlattenable( PGPKeySet const *set )
{
PGPKeyIter *iter;
PGPKeyDBObj *obj;
PGPBoolean keyinset = FALSE;
PGPError err;
if( IsNull( set ) )
return TRUE;
/* Iterate over all keys in underlying keydb */
if( IsPGPError( err = PGPNewKeyIterFromKeyDB(
PGPPeekKeySetKeyDB((PGPKeySet*)set), &iter ) ) )
return FALSE;
/* If find an obj not in set when key was in set, can't do it */
while( IsntPGPError( pgpKeyIterNextObject( iter, &obj ) ) )
{
/* Skip dummy objects */
if( !pgpKeyDBObjIsReal( obj ) )
continue;
/* Skip if we find a key that is not a member */
if( OBJISTOPKEY( obj ) )
{
keyinset = pgpKeySetIsMember( obj, (PGPKeySet *)set );
} else {
if( keyinset && !pgpKeySetIsMember( obj, (PGPKeySet *)set ) )
{
PGPFreeKeyIter( iter );
return FALSE;
}
}
}
PGPFreeKeyIter( iter );
return TRUE;
}
/* Create a list of all keyids of keys in key set */
PGPError
pgpKeySetFlatten( PGPKeySet const *set, PGPUInt32 **keylist,
PGPSize *keylistsize )
{
PGPKeyIter *iter;
PGPUInt32 *list;
PGPSize size;
PGPUInt32 nkeys;
PGPUInt32 i;
PGPKeyDBObjRef key;
PGPContextRef context;
PGPBoolean front;
PGPError err;
if( IsNull( set ) )
{
*keylist = NULL;
*keylistsize = 0;
return kPGPError_NoErr;
}
front = pgpFrontEndKeyDB( set->keyDB );
PGPCountKeys( (PGPKeySet *)set, &nkeys );
size = nkeys * sizeof(PGPUInt32);
context = PGPPeekKeySetContext( (PGPKeySet *)set );
list = (PGPUInt32 *)pgpContextMemAlloc( context, size, 0 );
if( IsPGPError( err = PGPNewKeyIterFromKeySet( (PGPKeySet *)set, &iter )))
{
PGPFreeData( list );
return err;
}
i = 0;
while( IsntPGPError( PGPKeyIterNextKeyDBObj( iter, kPGPKeyDBObjType_Key,
&key ) ) )
{
list[i++] = front ? pgpKeyDBObjID( key ) : (PGPUInt32)key;
}
PGPFreeKeyIter( iter );
pgpAssert( i == nkeys );
/* Sort lists on back end */
if( !front )
sSortKeylist( list, nkeys );
*keylist = list;
*keylistsize = size;
return kPGPError_NoErr;
}
/* Flatten and free the keyset */
PGPError
pgpKeySetFlattenFree( PGPKeySet *set, PGPUInt32 **keylist,
PGPSize *keylistsize )
{
PGPError err;
err = pgpKeySetFlatten( set, keylist, keylistsize );
if( IsntNull( set ) )
PGPFreeKeySet( set );
return err;
}
/* Create a new keyset from a keylist, which is already sorted by keyid */
PGPError
pgpKeySetUnflatten( PGPKeyDB *db, PGPUInt32 *keylist, PGPSize keylistsize,
PGPKeySetRef *pset)
{
PGPKeySetRef set;
PGPBoolean front;
PGPUInt32 keylistcount;
PGPError err = kPGPError_NoErr;
keylistcount = keylistsize / sizeof(PGPUInt32);
front = pgpFrontEndKeyDB( db );
/* Sort lists on back end */
if( !front )
{
sSortKeylist( keylist, keylistcount );
} else {
/* Translate backend key_ids into key pointers */
PGPUInt32 obj;
PGPUInt32 i;
for( i=0; i<keylistcount; ++i )
{
PGPFindNode( db->idToObj, keylist[i], (PGPUserValue *)&obj );
keylist[i] = obj;
}
}
if( keylistcount == 0 )
err = PGPNewEmptyKeySet( db, &set );
else
err = pgpNewKeyListSet( db, (PGPKeyDBObjRef *)keylist, keylistcount,
&set );
if( IsntPGPError( err ) )
*pset = set;
return err;
}
/* Also free keylist */
PGPError
pgpKeySetUnflattenFree( PGPKeyDB *db, PGPUInt32 *keylist, PGPSize keylistsize,
PGPKeySetRef *pset)
{
PGPError err;
err = pgpKeySetUnflatten( db, keylist, keylistsize, pset );
if( IsntNull( keylist ) )
PGPFreeData( keylist );
return err;
}
/* Refresh key objs in the keyset, i.e. mark them as being obsolete */
PGPError
pgpKeySetRefreshFree( PGPKeySet *set )
{
PGPKeyIter *iter;
PGPKeyDBObjRef key;
PGPError err;
if( IsPGPError( err = PGPNewKeyIterFromKeySet( (PGPKeySet *)set, &iter )))
{
PGPFreeKeySet( set );
return err;
}
while( IsntPGPError( PGPKeyIterNextKeyDBObj( iter, kPGPKeyDBObjType_Key,
&key ) ) )
{
(void) pgpKeyDBObjRefresh( key, TRUE );
}
PGPFreeKeyIter( iter );
PGPFreeKeySet( set );
return kPGPError_NoErr;
}
PGPBoolean
pgpKeySetIsValid( PGPKeySet const * keySet)
{
return( IsntNull( keySet ) && keySet->magic == kPGPKeySetMagic );
}
#if PGP_DEBUG /* [ */
PGPBoolean
pgpaInternalPGPKeySetValid(
pgpaCallPrefixDef,
PGPKeySet const * keySet,
char const * varName)
{
pgpaAddrValid(keySet, PGPKeySet);
pgpaFailIf(keySet->refCount <= 0, (pgpaFmtPrefix, "refCount <= 0"));
pgpaFmtMsg((pgpaFmtPrefix,
"pgpaPGPKeySetValid failed on %s (%p)", varName, keySet));
return pgpaFailed;
}
#endif /* ] PGP_DEBUG */
/*
* Local Variables:
* tab-width: 4
* End:
* vi: ts=4 sw=4
* vim: si
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -