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

📄 pgpfiledb.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (rdb->rsfrozen) {
		ringSetDestroy (rdb->rsfrozen);
		rdb->rsfrozen = 0;
	}
	rdb->rsimmut = 0;
	ringSetDestroy (rdb->rsmut);
	rdb->rsmut = 0;
		ringFileClose (rdb->rfile);
	rdb->rfile = 0;
	pgpFileClose (rdb->pfile);
	rdb->pfile = 0;
	if (rdb->bfreebuf && rdb->membuf){
		pgpMemFree (rdb->membuf);
	}
	return PGPERR_OK;
}




/******************** Virtual Functions ************************/


static Boolean
rdbIsMutable (PGPKeyDB *kdb) {
	RingDB *rdb = (RingDB *)kdb->private;

	return rdb->bwriteable;
}

static Boolean
rdbObjIsMutable (PGPKeyDB *kdb, RingObject *testObj)
{	
	RingDB *rdb = (RingDB *)kdb->private;

	return rdb->bwriteable && ringSetIsMember (rdb->rsmut, testObj);
}

static Boolean
rdbIsDirty (PGPKeyDB *kdb) {
	RingDB *rdb = (RingDB *)kdb->private;

	return rdb->bdirty;
}

/* Mark as dirty */
static void
rdbDirty (RingDB *rdb)
{
	rdb->bdirty = TRUE;
	if (rdb->rsfrozen) {
		ringSetDestroy (rdb->rsfrozen);
		rdb->rsfrozen = 0;
	}
}

static RingSet *
rdbGetRingSet (PGPKeyDB *kdb) {
	RingDB *rdb = (RingDB *)kdb->private;
	RingSet *rset;

	if (!(rset = rdb->rsfrozen)) {
		rset = ringSetCreate (ringSetPool (rdb->rsmut));
		ringSetAddSet (rset, rdb->rsmut);
		ringSetFreeze (rset);
		rdb->rsfrozen = rset;
	}
	return rset;
}

static PGPError
rdbAdd (PGPKeyDB *kdb, RingSet *toAdd) {
	RingDB *rdb = (RingDB *)kdb->private;
	RingIterator *riAdd;		/* Iterator over toAdd set */
	RingObject *robj;	 	/* Object we are adding */
	int level;		/* Level of iterator in hierarchy */
	int				type;		 /* Type of robj */
	int added;		/* Number of objects added */
	int skipped;	/* Number of objects skipped */
	int				skipparts; /* True if skipping, obj not for us */

	if (!rdb->bwriteable)
		return PGPERR_KEYDB_KEYDBREADONLY;

	riAdd = ringIterCreate (toAdd);
	if (!riAdd) {
		return PGPERR_NOMEM;
}

added = 0;
skipped = 0;
skipparts = 0;

	while ((level = ringIterNextObjectAnywhere(riAdd)) > 0) {
		robj = ringIterCurrentObject (riAdd, level);
		type = ringObjectType (robj);
		if (type==RINGTYPE_KEY) {
				/*
			* If key lacks secret object, put it only on the public
			* ring, and if key comes only from a source where it is a
			* secret key, put it only on the secret ring
				*/
			if (rdb->bprivate) {
				skipparts = !ringKeyIsSec (toAdd, robj);
			} else {
				skipparts = ringKeyIsSecOnly (toAdd, robj);
			}
		}
		/* Signatures only go to public keyrings, secrets to private */
		if (skipparts ||
			((type==RINGTYPE_SIG)&&rdb->bprivate) ||
			((type==RINGTYPE_SEC)&&!rdb->bprivate)) {
			skipped += 1;
		} else {
			ringSetAddObject (rdb->rsmut, robj);
			added += 1;
		}
	}
	ringIterDestroy (riAdd);

	rdbDirty (rdb);
	return PGPERR_OK;
}


static PGPError
rdbRemove (PGPKeyDB *kdb, RingObject *toRemove)
{
	RingDB *rdb = (RingDB *)kdb->private;

	if (!rdb->bwriteable)
		return PGPERR_KEYDB_KEYDBREADONLY;

	if (ringSetIsMember (rdb->rsmut, toRemove))
		rdbDirty (rdb);
	return ringSetRemObject (rdb->rsmut, toRemove);
}

/*
* Note that unions don't pass this call down, they take care of it
* themselves
*/
static PGPError
rdbChanged (PGPKeyDB *kdb, RingSet *changedkeys)
{
	RingDB *rdb = (RingDB *)kdb->private;

	if (!rdb->bwriteable)
		return PGPERR_KEYDB_KEYDBREADONLY;

	rdbDirty (rdb);
	return pgpReSortKeys (kdb, changedkeys);
}

static PGPError
rdbCommit (PGPKeyDB *kdb) {
	RingDB *rdb = (RingDB *)kdb->private;
	RingPool	*ringpool = ringSetPool (rdb->rsmut);
	PGPError error;

	if (!rdb->bwriteable)
		return PGPERR_OK;

	/* Don't check for trust changed if untrusted file */
	if (!rdb->bdirty && (!rdb->btrusted ||
				(rdb->btrusted && !ringFileIsTrustChanged(rdb->rfile))))
		return PGPERR_OK;

	/* Must use frozen set for writing */

	ringSetFreeze (rdb->rsmut);
	if (rdb->rsfrozen) {
		ringSetDestroy (rdb->rsfrozen);
		rdb->rsfrozen = 0;
	}
	error = do_write (rdb);

	if (error) {
		/*
		* Sometimes on error we have fixed rdb->rsmut, but possibly it may
		* still be frozen as above. To be safe we will always make a copy
		* here so it is writeable in the future.
*/
		RingSet *rset = ringSetCreate (ringpool);
		pgpAssert (rset);
		pgpAssert (rdb->rsmut);
		ringSetAddSet (rset, rdb->rsmut);
		ringSetDestroy (rdb->rsmut);
		rdb->rsmut = rset;
		return error;
	}

	rdb->rsimmut = ringFileSet (rdb->rfile);
	rdb->rsmut = ringSetCreate (ringpool);
	ringSetAddSet (rdb->rsmut, rdb->rsimmut);
	rdb->bdirty = 0;

return PGPERR_OK;
}


static PGPError
rdbRevert (PGPKeyDB *kdb) {
	RingDB *rdb = (RingDB *)kdb->private;

	if (!rdb->bdirty)
		return PGPERR_OK;
	rdb->bdirty = 0;
	if (rdb->rsmut) {
		ringSetDestroy (rdb->rsmut);
		rdb->rsmut = ringSetCreate (ringSetPool(rdb->rsimmut));
		if (!rdb->rsmut) {
			return PGPERR_NOMEM;
		}
		ringSetAddSet (rdb->rsmut, rdb->rsimmut);
	}
	if (rdb->rsfrozen) {
		ringSetDestroy (rdb->rsfrozen);
		rdb->rsfrozen = 0;
	}
	return PGPERR_OK;
}

static PGPError
rdbReload (PGPKeyDB *kdb) {
	RingDB *rdb = (RingDB *)kdb->private;
	PGPFileRef *fileRef;
	PGPError err;

	if (rdb->membuf)
		return PGPERR_OK;
	if ((fileRef = pgpCopyFileRef(rdb->fileRef)) == NULL)
		return PGPERR_NOMEM;
	err = do_close (rdb);
	if (err) {
		pgpFreeFileRef(fileRef);
		return err;
	}
	err = do_open (fileRef, rdb->btrusted, rdb->bprivate,
		rdb->bwriteable, ringSetPool (rdb->rsimmut), rdb);
	rdb->bdirty = 0;
	if (rdb->rsfrozen) {
		ringSetDestroy (rdb->rsfrozen);
		rdb->rsfrozen = 0;
	}
	pgpFreeFileRef(fileRef);
	return err;
}

static void
rdbDestroy (PGPKeyDB *kdb)
{
	RingDB *rdb = (RingDB *)kdb->private;

	do_close (rdb);
	pgpFreeFileRef (rdb->fileRef);
	pgpMemFree (rdb);
}


/**************************** Constructor **************************/


PGPKeyDB *
pgpCreateFileKeyDB (PGPFileRef const *fileRef, int trusted, int private,
	int writeable, RingPool *ringpool, PGPError *error)
{
	PGPKeyDB *kdb;
	RingDB *rdb;

	*error = 0;
	kdb = pgpKeyDBCreateInternal ();
	if (!kdb) {
		*error = PGPERR_NOMEM;
		return NULL;
	}
	rdb = (RingDB *) pgpMemAlloc (sizeof (RingDB));
	if (!rdb) {
		*error = PGPERR_NOMEM;
		pgpKeyDBDestroyInternal (kdb);
		return NULL;
	}

	memset (rdb, 0, sizeof (*rdb));

	*error = do_open (fileRef, trusted, private, writeable, ringpool, rdb);
	if (*error) {
		pgpMemFree (rdb);
		pgpKeyDBDestroyInternal (kdb);
		return NULL;
}

	kdb->private 	 	= rdb;
	kdb->magic				= PGPKDBFILEMAGIC;
	kdb->isMutable			= rdbIsMutable;
	kdb->objIsMutable	 	= rdbObjIsMutable;
	kdb->isDirty 	 	= rdbIsDirty;
	kdb->getRingSet			= rdbGetRingSet;
	kdb->add 	 	= rdbAdd;
	kdb->remove 		= rdbRemove;
	kdb->changed			= rdbChanged;
	kdb->commit 		= rdbCommit;
	kdb->revert 		= rdbRevert;
	kdb->reload 		= rdbReload;
  kdb->destroy			= rdbDestroy;

	pgpKeyDBInitInternal(kdb);

  return kdb;
}

/*
* Create a File type KeyDB from a memory buffer. This will be an
* immutable KeyDB since we can't save our changes anywhere.
*/
PGPKeyDB *
pgpCreateMemFileKeyDB (byte *buf, size_t length, RingPool *ringpool,
	PGPError *error)
{
	PGPKeyDB *kdb;
	RingDB *rdb;

	*error = 0;
	kdb = pgpKeyDBCreateInternal ();
	if (!kdb) {
 	*error = PGPERR_NOMEM;
		return NULL;
	}
	rdb = (RingDB *) pgpMemAlloc (sizeof (RingDB));
	if (!rdb) {
		*error = PGPERR_NOMEM;
		pgpKeyDBDestroyInternal (kdb);
  	return NULL;
	}

	memset (rdb, 0, sizeof (*rdb));

 rdb->rsmut = ringSetCreate (ringpool);
	if (!rdb->rsmut) {
		pgpMemFree (rdb);
		pgpKeyDBDestroyInternal (kdb);
		*error = PGPERR_NOMEM;
		return NULL;
	}

	rdb->pfile = pgpFileMemReadOpen (buf, length);
	if (!rdb->pfile) {
		ringSetDestroy (rdb->rsmut);
		pgpMemFree (rdb);
		pgpKeyDBDestroyInternal (kdb);
		*error = PGPERR_NOMEM;
		return NULL;
	}

	rdb->rfile = ringFileOpen (ringpool, rdb->pfile, 0, error);
	if (!rdb->rfile) {
		pgpFileClose (rdb->pfile);
		ringSetDestroy (rdb->rsmut);
		pgpMemFree (rdb);
		pgpKeyDBDestroyInternal (kdb);
		return NULL;
	}

	rdb->rsimmut = ringFileSet (rdb->rfile);
	ringSetAddSet (rdb->rsmut, rdb->rsimmut);

	rdb->membuf		= buf;
	rdb->bfreebuf	 = 1;
	rdb->fileRef	= pgpNewFileRefFromFullPath("");

	kdb->private 	 	= rdb;
	kdb->magic				= PGPKDBFILEMAGIC;
	kdb->isMutable			= rdbIsMutable;
	kdb->objIsMutable	 	= rdbObjIsMutable;
	kdb->isDirty 	 	= rdbIsDirty;
	kdb->getRingSet			= rdbGetRingSet;
	kdb->add 	 	= rdbAdd;
	kdb->remove 		= rdbRemove;
	kdb->changed			= rdbChanged;
	kdb->commit 		= rdbCommit;
  kdb->revert 		= rdbRevert;
	kdb->reload 		= rdbReload;
	kdb->destroy			= rdbDestroy;

	pgpKeyDBInitInternal(kdb);

 return kdb;
}

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

⌨️ 快捷键说明

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