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

📄 log_get.c

📁 这是国外的resip协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1996-2004 *	Sleepycat Software.  All rights reserved. * * $Id: log_get.c,v 11.110 2004/09/17 22:00:31 mjc Exp $ */#include "db_config.h"#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <string.h>#endif#include "db_int.h"#include "dbinc/crypto.h"#include "dbinc/db_page.h"#include "dbinc/hmac.h"#include "dbinc/log.h"#include "dbinc/hash.h"typedef enum { L_ALREADY, L_ACQUIRED, L_NONE } RLOCK;static int __log_c_close_pp __P((DB_LOGC *, u_int32_t));static int __log_c_get_pp __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t));static int __log_c_get_int __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t));static int __log_c_hdrchk __P((DB_LOGC *, DB_LSN *, HDR *, int *));static int __log_c_incursor __P((DB_LOGC *, DB_LSN *, HDR *, u_int8_t **));static int __log_c_inregion __P((DB_LOGC *,	       DB_LSN *, RLOCK *, DB_LSN *, HDR *, u_int8_t **));static int __log_c_io __P((DB_LOGC *,	       u_int32_t, u_int32_t, void *, size_t *, int *));static int __log_c_ondisk __P((DB_LOGC *,	       DB_LSN *, DB_LSN *, u_int32_t, HDR *, u_int8_t **, int *));static int __log_c_set_maxrec __P((DB_LOGC *, char *));static int __log_c_shortread __P((DB_LOGC *, DB_LSN *, int));/* * __log_cursor_pp -- *	DB_ENV->log_cursor * * PUBLIC: int __log_cursor_pp __P((DB_ENV *, DB_LOGC **, u_int32_t)); */int__log_cursor_pp(dbenv, logcp, flags)	DB_ENV *dbenv;	DB_LOGC **logcp;	u_int32_t flags;{	int rep_check, ret;	PANIC_CHECK(dbenv);	ENV_REQUIRES_CONFIG(dbenv,	    dbenv->lg_handle, "DB_ENV->log_cursor", DB_INIT_LOG);	/* Validate arguments. */	if ((ret = __db_fchk(dbenv, "DB_ENV->log_cursor", flags, 0)) != 0)		return (ret);	rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0;	if (rep_check)		__env_rep_enter(dbenv);	ret = __log_cursor(dbenv, logcp);	if (rep_check)		__env_db_rep_exit(dbenv);	return (ret);}/* * __log_cursor -- *	Create a log cursor. * * PUBLIC: int __log_cursor __P((DB_ENV *, DB_LOGC **)); */int__log_cursor(dbenv, logcp)	DB_ENV *dbenv;	DB_LOGC **logcp;{	DB_LOGC *logc;	int ret;	*logcp = NULL;	/* Allocate memory for the cursor. */	if ((ret = __os_calloc(dbenv, 1, sizeof(DB_LOGC), &logc)) != 0)		return (ret);	logc->bp_size = DB_LOGC_BUF_SIZE;	/*	 * Set this to something positive.	 */	logc->bp_maxrec = MEGABYTE;	if ((ret = __os_malloc(dbenv, logc->bp_size, &logc->bp)) != 0) {		__os_free(dbenv, logc);		return (ret);	}	logc->dbenv = dbenv;	logc->close = __log_c_close_pp;	logc->get = __log_c_get_pp;	*logcp = logc;	return (0);}/* * __log_c_close_pp -- *	DB_LOGC->close pre/post processing. */static int__log_c_close_pp(logc, flags)	DB_LOGC *logc;	u_int32_t flags;{	DB_ENV *dbenv;	int rep_check, ret;	dbenv = logc->dbenv;	PANIC_CHECK(dbenv);	if ((ret = __db_fchk(dbenv, "DB_LOGC->close", flags, 0)) != 0)		return (ret);	rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0;	if (rep_check)		__env_rep_enter(dbenv);	ret = __log_c_close(logc);	if (rep_check)		__env_db_rep_exit(dbenv);	return (ret);}/* * __log_c_close -- *	DB_LOGC->close. * * PUBLIC: int __log_c_close __P((DB_LOGC *)); */int__log_c_close(logc)	DB_LOGC *logc;{	DB_ENV *dbenv;	dbenv = logc->dbenv;	if (logc->c_fhp != NULL) {		(void)__os_closehandle(dbenv, logc->c_fhp);		logc->c_fhp = NULL;	}	if (logc->c_dbt.data != NULL)		__os_free(dbenv, logc->c_dbt.data);	__os_free(dbenv, logc->bp);	__os_free(dbenv, logc);	return (0);}/* * __log_c_get_pp -- *	DB_LOGC->get pre/post processing. */static int__log_c_get_pp(logc, alsn, dbt, flags)	DB_LOGC *logc;	DB_LSN *alsn;	DBT *dbt;	u_int32_t flags;{	DB_ENV *dbenv;	int rep_check, ret;	dbenv = logc->dbenv;	PANIC_CHECK(dbenv);	/* Validate arguments. */	switch (flags) {	case DB_CURRENT:	case DB_FIRST:	case DB_LAST:	case DB_NEXT:	case DB_PREV:		break;	case DB_SET:		if (IS_ZERO_LSN(*alsn)) {			__db_err(dbenv, "DB_LOGC->get: invalid LSN: %lu/%lu",			    (u_long)alsn->file, (u_long)alsn->offset);			return (EINVAL);		}		break;	default:		return (__db_ferr(dbenv, "DB_LOGC->get", 1));	}	rep_check = IS_ENV_REPLICATED(dbenv) ? 1 : 0;	if (rep_check)		__env_rep_enter(dbenv);	ret = __log_c_get(logc, alsn, dbt, flags);	if (rep_check)		__env_db_rep_exit(dbenv);	return (ret);}/* * __log_c_get -- *	DB_LOGC->get. * * PUBLIC: int __log_c_get __P((DB_LOGC *, DB_LSN *, DBT *, u_int32_t)); */int__log_c_get(logc, alsn, dbt, flags)	DB_LOGC *logc;	DB_LSN *alsn;	DBT *dbt;	u_int32_t flags;{	DB_ENV *dbenv;	DB_LSN saved_lsn;	int ret;	dbenv = logc->dbenv;	/*	 * On error, we take care not to overwrite the caller's LSN.  This	 * is because callers looking for the end of the log loop using the	 * DB_NEXT flag, and expect to take the last successful lsn out of	 * the passed-in structure after DB_LOGC->get fails with DB_NOTFOUND.	 *	 * !!!	 * This line is often flagged an uninitialized memory read during a	 * Purify or similar tool run, as the application didn't initialize	 * *alsn.  If the application isn't setting the DB_SET flag, there is	 * no reason it should have initialized *alsn, but we can't know that	 * and we want to make sure we never overwrite whatever the application	 * put in there.	 */	saved_lsn = *alsn;	/*	 * If we get one of the log's header records as a result of doing a	 * DB_FIRST, DB_NEXT, DB_LAST or DB_PREV, repeat the operation, log	 * file header records aren't useful to applications.	 */	if ((ret = __log_c_get_int(logc, alsn, dbt, flags)) != 0) {		*alsn = saved_lsn;		return (ret);	}	if (alsn->offset == 0 && (flags == DB_FIRST ||	    flags == DB_NEXT || flags == DB_LAST || flags == DB_PREV)) {		switch (flags) {		case DB_FIRST:			flags = DB_NEXT;			break;		case DB_LAST:			flags = DB_PREV;			break;		case DB_NEXT:		case DB_PREV:		default:			break;		}		if (F_ISSET(dbt, DB_DBT_MALLOC)) {			__os_free(dbenv, dbt->data);			dbt->data = NULL;		}		if ((ret = __log_c_get_int(logc, alsn, dbt, flags)) != 0) {			*alsn = saved_lsn;			return (ret);		}	}	return (0);}/* * __log_c_get_int -- *	Get a log record; internal version. */static int__log_c_get_int(logc, alsn, dbt, flags)	DB_LOGC *logc;	DB_LSN *alsn;	DBT *dbt;	u_int32_t flags;{	DB_CIPHER *db_cipher;	DB_ENV *dbenv;	DB_LOG *dblp;	DB_LSN last_lsn, nlsn;	HDR hdr;	LOG *lp;	RLOCK rlock;	logfile_validity status;	u_int32_t cnt;	u_int8_t *rp;	int eof, is_hmac, ret;	dbenv = logc->dbenv;	dblp = dbenv->lg_handle;	lp = dblp->reginfo.primary;	is_hmac = 0;	/*	 * We don't acquire the log region lock until we need it, and we	 * release it as soon as we're done.	 */	rlock = F_ISSET(logc, DB_LOG_LOCKED) ? L_ALREADY : L_NONE;	nlsn = logc->c_lsn;	switch (flags) {	case DB_NEXT:				/* Next log record. */		if (!IS_ZERO_LSN(nlsn)) {			/* Increment the cursor by the cursor record size. */			nlsn.offset += logc->c_len;			break;		}		flags = DB_FIRST;		/* FALLTHROUGH */	case DB_FIRST:				/* First log record. */		/* Find the first log file. */		if ((ret = __log_find(dblp, 1, &cnt, &status)) != 0)			goto err;		/*		 * DB_LV_INCOMPLETE:		 *	Theoretically, the log file we want could be created		 *	but not yet written, the "first" log record must be		 *	in the log buffer.		 * DB_LV_NORMAL:		 * DB_LV_OLD_READABLE:		 *	We found a log file we can read.		 * DB_LV_NONEXISTENT:		 *	No log files exist, the "first" log record must be in		 *	the log buffer.		 * DB_LV_OLD_UNREADABLE:		 *	No readable log files exist, we're at the cross-over		 *	point between two versions.  The "first" log record		 *	must be in the log buffer.		 */		switch (status) {		case DB_LV_INCOMPLETE:			DB_ASSERT(lp->lsn.file == cnt);			/* FALLTHROUGH */		case DB_LV_NORMAL:		case DB_LV_OLD_READABLE:			nlsn.file = cnt;			break;		case DB_LV_NONEXISTENT:			nlsn.file = 1;			DB_ASSERT(lp->lsn.file == nlsn.file);			break;		case DB_LV_OLD_UNREADABLE:			nlsn.file = cnt + 1;			DB_ASSERT(lp->lsn.file == nlsn.file);			break;		}		nlsn.offset = 0;		break;	case DB_CURRENT:			/* Current log record. */		break;	case DB_PREV:				/* Previous log record. */		if (!IS_ZERO_LSN(nlsn)) {			/* If at start-of-file, move to the previous file. */			if (nlsn.offset == 0) {				if (nlsn.file == 1) {					ret = DB_NOTFOUND;					goto err;				}				if ((!lp->db_log_inmemory &&				    (__log_valid(dblp, nlsn.file - 1, 0, NULL,				    0, &status) != 0 ||				    (status != DB_LV_NORMAL &&				    status != DB_LV_OLD_READABLE)))) {					ret = DB_NOTFOUND;					goto err;				}				--nlsn.file;			}			nlsn.offset = logc->c_prev;			break;		}		/* FALLTHROUGH */	case DB_LAST:				/* Last log record. */		if (rlock == L_NONE) {			rlock = L_ACQUIRED;			R_LOCK(dbenv, &dblp->reginfo);

⌨️ 快捷键说明

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