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

📄 db_vrfyutil.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * However, we also need to make sure that when walking the list	 * of children, we encounter them in the order they're referenced	 * on a page.  (This permits us, for example, to verify the	 * prev_pgno/next_pgno chain of Btree leaf pages.)	 *	 * Check the child database to make sure that this page isn't	 * already a child of the specified page number.  If it's not,	 * put it at the end of the duplicate set.	 */	if ((ret = __db_vrfy_childcursor(vdp, &cc)) != 0)		return (ret);	for (ret = __db_vrfy_ccset(cc, pgno, &oldcip); ret == 0;	    ret = __db_vrfy_ccnext(cc, &oldcip))		if (oldcip->pgno == cip->pgno) {			/*			 * Found a matching child.  Increment its reference			 * count--we've run into it again--but don't put it			 * again.			 */			if ((ret = __db_vrfy_childinc(cc, oldcip)) != 0 ||			    (ret = __db_vrfy_ccclose(cc)) != 0)				return (ret);			return (0);		}	if (ret != DB_NOTFOUND) {		(void)__db_vrfy_ccclose(cc);		return (ret);	}	if ((ret = __db_vrfy_ccclose(cc)) != 0)		return (ret);	cip->refcnt = 1;	data.data = cip;	data.size = sizeof(VRFY_CHILDINFO);	return (__db_put(cdbp, NULL, &key, &data, 0));}/* * __db_vrfy_childinc -- *	Increment the refcount of the VRFY_CHILDINFO struct that the child * cursor is pointing to.  (The caller has just retrieved this struct, and * passes it in as cip to save us a get.) */static int__db_vrfy_childinc(dbc, cip)	DBC *dbc;	VRFY_CHILDINFO *cip;{	DBT key, data;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	cip->refcnt++;	data.data = cip;	data.size = sizeof(VRFY_CHILDINFO);	return (__db_c_put(dbc, &key, &data, DB_CURRENT));}/* * __db_vrfy_ccset -- *	Sets a cursor created with __db_vrfy_childcursor to the first *	child of the given pgno, and returns it in the third arg. * * PUBLIC: int __db_vrfy_ccset __P((DBC *, db_pgno_t, VRFY_CHILDINFO **)); */int__db_vrfy_ccset(dbc, pgno, cipp)	DBC *dbc;	db_pgno_t pgno;	VRFY_CHILDINFO **cipp;{	DBT key, data;	int ret;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	key.data = &pgno;	key.size = sizeof(db_pgno_t);	if ((ret = __db_c_get(dbc, &key, &data, DB_SET)) != 0)		return (ret);	DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO));	*cipp = (VRFY_CHILDINFO *)data.data;	return (0);}/* * __db_vrfy_ccnext -- *	Gets the next child of the given cursor created with *	__db_vrfy_childcursor, and returns it in the memory provided in the *	second arg. * * PUBLIC: int __db_vrfy_ccnext __P((DBC *, VRFY_CHILDINFO **)); */int__db_vrfy_ccnext(dbc, cipp)	DBC *dbc;	VRFY_CHILDINFO **cipp;{	DBT key, data;	int ret;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	if ((ret = __db_c_get(dbc, &key, &data, DB_NEXT_DUP)) != 0)		return (ret);	DB_ASSERT(data.size == sizeof(VRFY_CHILDINFO));	*cipp = (VRFY_CHILDINFO *)data.data;	return (0);}/* * __db_vrfy_ccclose -- *	Closes the cursor created with __db_vrfy_childcursor. * *	This doesn't actually do anything interesting now, but it's *	not inconceivable that we might change the internal database usage *	and keep the interfaces the same, and a function call here or there *	seldom hurts anyone. * * PUBLIC: int __db_vrfy_ccclose __P((DBC *)); */int__db_vrfy_ccclose(dbc)	DBC *dbc;{	return (__db_c_close(dbc));}/* * __db_vrfy_pageinfo_create -- *	Constructor for VRFY_PAGEINFO;  allocates and initializes. */static int__db_vrfy_pageinfo_create(dbenv, pgipp)	DB_ENV *dbenv;	VRFY_PAGEINFO **pgipp;{	VRFY_PAGEINFO *pgip;	int ret;	/*	 * pageinfo structs are sometimes allocated here and sometimes	 * allocated by fetching them from a database with DB_DBT_MALLOC.	 * There's no easy way for the destructor to tell which was	 * used, and so we always allocate with __os_umalloc so we can free	 * with __os_ufree.	 */	if ((ret = __os_umalloc(dbenv, sizeof(VRFY_PAGEINFO), &pgip)) != 0)		return (ret);	memset(pgip, 0, sizeof(VRFY_PAGEINFO));	DB_ASSERT(pgip->pi_refcount == 0);	*pgipp = pgip;	return (0);}/* * __db_salvage_init -- *	Set up salvager database. * * PUBLIC: int  __db_salvage_init __P((VRFY_DBINFO *)); */int__db_salvage_init(vdp)	VRFY_DBINFO *vdp;{	DB *dbp;	int ret;	if ((ret = db_create(&dbp, NULL, 0)) != 0)		return (ret);	if ((ret = __db_set_pagesize(dbp, 1024)) != 0)		goto err;	if ((ret = __db_open(dbp,	    NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0, PGNO_BASE_MD)) != 0)		goto err;	vdp->salvage_pages = dbp;	return (0);err:	(void)__db_close(dbp, NULL, 0);	return (ret);}/* * __db_salvage_destroy -- *	Close salvager database. * PUBLIC: void  __db_salvage_destroy __P((VRFY_DBINFO *)); */void__db_salvage_destroy(vdp)	VRFY_DBINFO *vdp;{	(void)__db_close(vdp->salvage_pages, NULL, 0);}/* * __db_salvage_getnext -- *	Get the next (first) unprinted page in the database of pages we need to *	print still.  Delete entries for any already-printed pages we encounter *	in this search, as well as the page we're returning. * * PUBLIC: int __db_salvage_getnext * PUBLIC:     __P((VRFY_DBINFO *, db_pgno_t *, u_int32_t *)); */int__db_salvage_getnext(vdp, pgnop, pgtypep)	VRFY_DBINFO *vdp;	db_pgno_t *pgnop;	u_int32_t *pgtypep;{	DB *dbp;	DBC *dbc;	DBT key, data;	int ret;	u_int32_t pgtype;	dbp = vdp->salvage_pages;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	if ((ret = __db_cursor(dbp, NULL, &dbc, 0)) != 0)		return (ret);	while ((ret = __db_c_get(dbc, &key, &data, DB_NEXT)) == 0) {		DB_ASSERT(data.size == sizeof(u_int32_t));		memcpy(&pgtype, data.data, sizeof(pgtype));		if ((ret = __db_c_del(dbc, 0)) != 0)			goto err;		if (pgtype != SALVAGE_IGNORE)			goto found;	}	/* No more entries--ret probably equals DB_NOTFOUND. */	if (0) {found:		DB_ASSERT(key.size == sizeof(db_pgno_t));		DB_ASSERT(data.size == sizeof(u_int32_t));		*pgnop = *(db_pgno_t *)key.data;		*pgtypep = *(u_int32_t *)data.data;	}err:	(void)__db_c_close(dbc);	return (ret);}/* * __db_salvage_isdone -- *	Return whether or not the given pgno is already marked *	SALVAGE_IGNORE (meaning that we don't need to print it again). * *	Returns DB_KEYEXIST if it is marked, 0 if not, or another error on *	error. * * PUBLIC: int __db_salvage_isdone __P((VRFY_DBINFO *, db_pgno_t)); */int__db_salvage_isdone(vdp, pgno)	VRFY_DBINFO *vdp;	db_pgno_t pgno;{	DBT key, data;	DB *dbp;	int ret;	u_int32_t currtype;	dbp = vdp->salvage_pages;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	currtype = SALVAGE_INVALID;	data.data = &currtype;	data.ulen = sizeof(u_int32_t);	data.flags = DB_DBT_USERMEM;	key.data = &pgno;	key.size = sizeof(db_pgno_t);	/*	 * Put an entry for this page, with pgno as key and type as data,	 * unless it's already there and is marked done.	 * If it's there and is marked anything else, that's fine--we	 * want to mark it done.	 */	ret = __db_get(dbp, NULL, &key, &data, 0);	if (ret == 0) {		/*		 * The key's already here.  Check and see if it's already		 * marked done.  If it is, return DB_KEYEXIST.  If it's not,		 * return 0.		 */		if (currtype == SALVAGE_IGNORE)			return (DB_KEYEXIST);		else			return (0);	} else if (ret != DB_NOTFOUND)		return (ret);	/* The pgno is not yet marked anything; return 0. */	return (0);}/* * __db_salvage_markdone -- *	Mark as done a given page. * * PUBLIC: int __db_salvage_markdone __P((VRFY_DBINFO *, db_pgno_t)); */int__db_salvage_markdone(vdp, pgno)	VRFY_DBINFO *vdp;	db_pgno_t pgno;{	DBT key, data;	DB *dbp;	int pgtype, ret;	u_int32_t currtype;	pgtype = SALVAGE_IGNORE;	dbp = vdp->salvage_pages;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	currtype = SALVAGE_INVALID;	data.data = &currtype;	data.ulen = sizeof(u_int32_t);	data.flags = DB_DBT_USERMEM;	key.data = &pgno;	key.size = sizeof(db_pgno_t);	/*	 * Put an entry for this page, with pgno as key and type as data,	 * unless it's already there and is marked done.	 * If it's there and is marked anything else, that's fine--we	 * want to mark it done, but db_salvage_isdone only lets	 * us know if it's marked IGNORE.	 *	 * We don't want to return DB_KEYEXIST, though;  this will	 * likely get passed up all the way and make no sense to the	 * application.  Instead, use DB_VERIFY_BAD to indicate that	 * we've seen this page already--it probably indicates a	 * multiply-linked page.	 */	if ((ret = __db_salvage_isdone(vdp, pgno)) != 0)		return (ret == DB_KEYEXIST ? DB_VERIFY_BAD : ret);	data.size = sizeof(u_int32_t);	data.data = &pgtype;	return (__db_put(dbp, NULL, &key, &data, 0));}/* * __db_salvage_markneeded -- *	If it has not yet been printed, make note of the fact that a page *	must be dealt with later. * * PUBLIC: int __db_salvage_markneeded * PUBLIC:     __P((VRFY_DBINFO *, db_pgno_t, u_int32_t)); */int__db_salvage_markneeded(vdp, pgno, pgtype)	VRFY_DBINFO *vdp;	db_pgno_t pgno;	u_int32_t pgtype;{	DB *dbp;	DBT key, data;	int ret;	dbp = vdp->salvage_pages;	memset(&key, 0, sizeof(DBT));	memset(&data, 0, sizeof(DBT));	key.data = &pgno;	key.size = sizeof(db_pgno_t);	data.data = &pgtype;	data.size = sizeof(u_int32_t);	/*	 * Put an entry for this page, with pgno as key and type as data,	 * unless it's already there, in which case it's presumably	 * already been marked done.	 */	ret = __db_put(dbp, NULL, &key, &data, DB_NOOVERWRITE);	return (ret == DB_KEYEXIST ? 0 : ret);}/* * __db_vrfy_prdbt -- *	Print out a DBT data element from a verification routine. * * PUBLIC: int __db_vrfy_prdbt __P((DBT *, int, const char *, void *, * PUBLIC:     int (*)(void *, const void *), int, VRFY_DBINFO *)); */int__db_vrfy_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno, vdp)	DBT *dbtp;	int checkprint;	const char *prefix;	void *handle;	int (*callback) __P((void *, const void *));	int is_recno;	VRFY_DBINFO *vdp;{	if (vdp != NULL) {		/*		 * If vdp is non-NULL, we might be the first key in the		 * "fake" subdatabase used for key/data pairs we can't		 * associate with a known subdb.		 *		 * Check and clear the SALVAGE_PRINTHEADER flag;  if		 * it was set, print a subdatabase header.		 */		if (F_ISSET(vdp, SALVAGE_PRINTHEADER))			(void)__db_prheader(			    NULL, "__OTHER__", 0, 0, handle, callback, vdp, 0);		F_CLR(vdp, SALVAGE_PRINTHEADER);		F_SET(vdp, SALVAGE_PRINTFOOTER);		/*		 * Even if the printable flag wasn't set by our immediate		 * caller, it may be set on a salvage-wide basis.		 */		if (F_ISSET(vdp, SALVAGE_PRINTABLE))			checkprint = 1;	}	return (	    __db_prdbt(dbtp, checkprint, prefix, handle, callback, is_recno));}

⌨️ 快捷键说明

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