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

📄 db_vrfyutil.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2000-2004 *	Sleepycat Software.  All rights reserved. * * $Id: db_vrfyutil.c,v 11.40 2004/10/11 18:47:50 bostic Exp $ */#include "db_config.h"#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/db_page.h"#include "dbinc/db_verify.h"#include "dbinc/db_am.h"static int __db_vrfy_childinc __P((DBC *, VRFY_CHILDINFO *));static int __db_vrfy_pageinfo_create __P((DB_ENV *, VRFY_PAGEINFO **));/* * __db_vrfy_dbinfo_create -- *	Allocate and initialize a VRFY_DBINFO structure. * * PUBLIC: int __db_vrfy_dbinfo_create * PUBLIC:     __P((DB_ENV *, u_int32_t, VRFY_DBINFO **)); */int__db_vrfy_dbinfo_create(dbenv, pgsize, vdpp)	DB_ENV *dbenv;	u_int32_t pgsize;	VRFY_DBINFO **vdpp;{	DB *cdbp, *pgdbp, *pgset;	VRFY_DBINFO *vdp;	int ret;	vdp = NULL;	cdbp = pgdbp = pgset = NULL;	if ((ret = __os_calloc(NULL, 1, sizeof(VRFY_DBINFO), &vdp)) != 0)		goto err;	if ((ret = db_create(&cdbp, dbenv, 0)) != 0)		goto err;	if ((ret = __db_set_flags(cdbp, DB_DUP)) != 0)		goto err;	if ((ret = __db_set_pagesize(cdbp, pgsize)) != 0)		goto err;	if ((ret = __db_open(cdbp,	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0)		goto err;	if ((ret = db_create(&pgdbp, dbenv, 0)) != 0)		goto err;	if ((ret = __db_set_pagesize(pgdbp, pgsize)) != 0)		goto err;	if ((ret = __db_open(pgdbp,	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) != 0)		goto err;	if ((ret = __db_vrfy_pgset(dbenv, pgsize, &pgset)) != 0)		goto err;	LIST_INIT(&vdp->subdbs);	LIST_INIT(&vdp->activepips);	vdp->cdbp = cdbp;	vdp->pgdbp = pgdbp;	vdp->pgset = pgset;	*vdpp = vdp;	return (0);err:	if (cdbp != NULL)		(void)__db_close(cdbp, NULL, 0);	if (pgdbp != NULL)		(void)__db_close(pgdbp, NULL, 0);	if (vdp != NULL)		__os_free(dbenv, vdp);	return (ret);}/* * __db_vrfy_dbinfo_destroy -- *	Destructor for VRFY_DBINFO.  Destroys VRFY_PAGEINFOs and deallocates *	structure. * * PUBLIC: int __db_vrfy_dbinfo_destroy __P((DB_ENV *, VRFY_DBINFO *)); */int__db_vrfy_dbinfo_destroy(dbenv, vdp)	DB_ENV *dbenv;	VRFY_DBINFO *vdp;{	VRFY_CHILDINFO *c, *d;	int t_ret, ret;	ret = 0;	for (c = LIST_FIRST(&vdp->subdbs); c != NULL; c = d) {		d = LIST_NEXT(c, links);		__os_free(NULL, c);	}	if ((t_ret = __db_close(vdp->pgdbp, NULL, 0)) != 0)		ret = t_ret;	if ((t_ret = __db_close(vdp->cdbp, NULL, 0)) != 0 && ret == 0)		ret = t_ret;	if ((t_ret = __db_close(vdp->pgset, NULL, 0)) != 0 && ret == 0)		ret = t_ret;	DB_ASSERT(LIST_FIRST(&vdp->activepips) == NULL);	if (vdp->extents != NULL)		__os_free(dbenv, vdp->extents);	__os_free(dbenv, vdp);	return (ret);}/* * __db_vrfy_getpageinfo -- *	Get a PAGEINFO structure for a given page, creating it if necessary. * * PUBLIC: int __db_vrfy_getpageinfo * PUBLIC:     __P((VRFY_DBINFO *, db_pgno_t, VRFY_PAGEINFO **)); */int__db_vrfy_getpageinfo(vdp, pgno, pipp)	VRFY_DBINFO *vdp;	db_pgno_t pgno;	VRFY_PAGEINFO **pipp;{	DBT key, data;	DB *pgdbp;	VRFY_PAGEINFO *pip;	int ret;	/*	 * We want a page info struct.  There are three places to get it from,	 * in decreasing order of preference:	 *	 * 1. vdp->activepips.  If it's already "checked out", we're	 *	already using it, we return the same exact structure with a	 *	bumped refcount.  This is necessary because this code is	 *	replacing array accesses, and it's common for f() to make some	 *	changes to a pip, and then call g() and h() which each make	 *	changes to the same pip.  vdps are never shared between threads	 *	(they're never returned to the application), so this is safe.	 * 2. The pgdbp.  It's not in memory, but it's in the database, so	 *	get it, give it a refcount of 1, and stick it on activepips.	 * 3. malloc.  It doesn't exist yet;  create it, then stick it on	 *	activepips.  We'll put it in the database when we putpageinfo	 *	later.	 */	/* Case 1. */	for (pip = LIST_FIRST(&vdp->activepips); pip != NULL;	    pip = LIST_NEXT(pip, links))		if (pip->pgno == pgno)			/* Found it. */			goto found;	/* Case 2. */	pgdbp = vdp->pgdbp;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	F_SET(&data, DB_DBT_MALLOC);	key.data = &pgno;	key.size = sizeof(db_pgno_t);	if ((ret = __db_get(pgdbp, NULL, &key, &data, 0)) == 0) {		/* Found it. */		DB_ASSERT(data.size == sizeof(VRFY_PAGEINFO));		pip = data.data;		DB_ASSERT(pip->pi_refcount == 0);		LIST_INSERT_HEAD(&vdp->activepips, pip, links);		goto found;	} else if (ret != DB_NOTFOUND)	/* Something nasty happened. */		return (ret);	/* Case 3 */	if ((ret = __db_vrfy_pageinfo_create(pgdbp->dbenv, &pip)) != 0)		return (ret);	LIST_INSERT_HEAD(&vdp->activepips, pip, links);found:	pip->pi_refcount++;	*pipp = pip;	DB_ASSERT(pip->pi_refcount > 0);	return (0);}/* * __db_vrfy_putpageinfo -- *	Put back a VRFY_PAGEINFO that we're done with. * * PUBLIC: int __db_vrfy_putpageinfo __P((DB_ENV *, * PUBLIC:     VRFY_DBINFO *, VRFY_PAGEINFO *)); */int__db_vrfy_putpageinfo(dbenv, vdp, pip)	DB_ENV *dbenv;	VRFY_DBINFO *vdp;	VRFY_PAGEINFO *pip;{	DBT key, data;	DB *pgdbp;	VRFY_PAGEINFO *p;	int ret;#ifdef DIAGNOSTIC	int found;	found = 0;#endif	if (--pip->pi_refcount > 0)		return (0);	pgdbp = vdp->pgdbp;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	key.data = &pip->pgno;	key.size = sizeof(db_pgno_t);	data.data = pip;	data.size = sizeof(VRFY_PAGEINFO);	if ((ret = __db_put(pgdbp, NULL, &key, &data, 0)) != 0)		return (ret);	for (p = LIST_FIRST(&vdp->activepips); p != NULL;	    p = LIST_NEXT(p, links))		if (p == pip) {#ifdef DIAGNOSTIC			found++;#endif			DB_ASSERT(p->pi_refcount == 0);			LIST_REMOVE(p, links);			break;		}#ifdef DIAGNOSTIC	DB_ASSERT(found == 1);#endif	DB_ASSERT(pip->pi_refcount == 0);	__os_ufree(dbenv, pip);	return (0);}/* * __db_vrfy_pgset -- *	Create a temporary database for the storing of sets of page numbers. *	(A mapping from page number to int, used by the *_meta2pgset functions, *	as well as for keeping track of which pages the verifier has seen.) * * PUBLIC: int __db_vrfy_pgset __P((DB_ENV *, u_int32_t, DB **)); */int__db_vrfy_pgset(dbenv, pgsize, dbpp)	DB_ENV *dbenv;	u_int32_t pgsize;	DB **dbpp;{	DB *dbp;	int ret;	if ((ret = db_create(&dbp, dbenv, 0)) != 0)		return (ret);	if ((ret = __db_set_pagesize(dbp, pgsize)) != 0)		goto err;	if ((ret = __db_open(dbp,	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600, PGNO_BASE_MD)) == 0)		*dbpp = dbp;	elseerr:		(void)__db_close(dbp, NULL, 0);	return (ret);}/* * __db_vrfy_pgset_get -- *	Get the value associated in a page set with a given pgno.  Return *	a 0 value (and succeed) if we've never heard of this page. * * PUBLIC: int __db_vrfy_pgset_get __P((DB *, db_pgno_t, int *)); */int__db_vrfy_pgset_get(dbp, pgno, valp)	DB *dbp;	db_pgno_t pgno;	int *valp;{	DBT key, data;	int ret, val;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	key.data = &pgno;	key.size = sizeof(db_pgno_t);	data.data = &val;	data.ulen = sizeof(int);	F_SET(&data, DB_DBT_USERMEM);	if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) {		DB_ASSERT(data.size == sizeof(int));	} else if (ret == DB_NOTFOUND)		val = 0;	else		return (ret);	*valp = val;	return (0);}/* * __db_vrfy_pgset_inc -- *	Increment the value associated with a pgno by 1. * * PUBLIC: int __db_vrfy_pgset_inc __P((DB *, db_pgno_t)); */int__db_vrfy_pgset_inc(dbp, pgno)	DB *dbp;	db_pgno_t pgno;{	DBT key, data;	int ret;	int val;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	val = 0;	key.data = &pgno;	key.size = sizeof(db_pgno_t);	data.data = &val;	data.ulen = sizeof(int);	F_SET(&data, DB_DBT_USERMEM);	if ((ret = __db_get(dbp, NULL, &key, &data, 0)) == 0) {		DB_ASSERT(data.size == sizeof(int));	} else if (ret != DB_NOTFOUND)		return (ret);	data.size = sizeof(int);	++val;	return (__db_put(dbp, NULL, &key, &data, 0));}/* * __db_vrfy_pgset_next -- *	Given a cursor open in a pgset database, get the next page in the *	set. * * PUBLIC: int __db_vrfy_pgset_next __P((DBC *, db_pgno_t *)); */int__db_vrfy_pgset_next(dbc, pgnop)	DBC *dbc;	db_pgno_t *pgnop;{	DBT key, data;	db_pgno_t pgno;	int ret;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	/* We don't care about the data, just the keys. */	F_SET(&data, DB_DBT_USERMEM | DB_DBT_PARTIAL);	F_SET(&key, DB_DBT_USERMEM);	key.data = &pgno;	key.ulen = sizeof(db_pgno_t);	if ((ret = __db_c_get(dbc, &key, &data, DB_NEXT)) != 0)		return (ret);	DB_ASSERT(key.size == sizeof(db_pgno_t));	*pgnop = pgno;	return (0);}/* * __db_vrfy_childcursor -- *	Create a cursor to walk the child list with.  Returns with a nonzero *	final argument if the specified page has no children. * * PUBLIC: int __db_vrfy_childcursor __P((VRFY_DBINFO *, DBC **)); */int__db_vrfy_childcursor(vdp, dbcp)	VRFY_DBINFO *vdp;	DBC **dbcp;{	DB *cdbp;	DBC *dbc;	int ret;	cdbp = vdp->cdbp;	if ((ret = __db_cursor(cdbp, NULL, &dbc, 0)) == 0)		*dbcp = dbc;	return (ret);}/* * __db_vrfy_childput -- *	Add a child structure to the set for a given page. * * PUBLIC: int __db_vrfy_childput * PUBLIC:     __P((VRFY_DBINFO *, db_pgno_t, VRFY_CHILDINFO *)); */int__db_vrfy_childput(vdp, pgno, cip)	VRFY_DBINFO *vdp;	db_pgno_t pgno;	VRFY_CHILDINFO *cip;{	DB *cdbp;	DBC *cc;	DBT key, data;	VRFY_CHILDINFO *oldcip;	int ret;	cdbp = vdp->cdbp;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	key.data = &pgno;	key.size = sizeof(db_pgno_t);	/*	 * We want to avoid adding multiple entries for a single child page;	 * we only need to verify each child once, even if a child (such	 * as an overflow key) is multiply referenced.	 *

⌨️ 快捷键说明

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