if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) && (ret = __db_apprec(dbenv, LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))) != 0) goto err;
db_appinit(db_home, db_config, dbenv, flags)	const char *db_home;	char * const *db_config;	DB_ENV *dbenv;	int flags;{	FILE *fp;	int ret;	char * const *p;	char *lp, buf[MAXPATHLEN * 2];	/* Validate arguments. */	if (dbenv == NULL)		return (EINVAL);#ifdef HAVE_SPINLOCKS#define	OKFLAGS								\   (DB_CREATE | DB_NOMMAP | DB_THREAD | DB_INIT_LOCK | DB_INIT_LOG |	\    DB_INIT_MPOOL | DB_INIT_TXN | DB_MPOOL_PRIVATE | DB_RECOVER |	\    DB_RECOVER_FATAL | DB_TXN_NOSYNC | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)#else#define	OKFLAGS								\   (DB_CREATE | DB_NOMMAP | DB_INIT_LOCK | DB_INIT_LOG |		\    DB_INIT_MPOOL | DB_INIT_TXN | DB_MPOOL_PRIVATE | DB_RECOVER |	\    DB_RECOVER_FATAL | DB_TXN_NOSYNC | DB_USE_ENVIRON | DB_USE_ENVIRON_ROOT)#endif	if ((ret = __db_fchk(dbenv, "db_appinit", flags, OKFLAGS)) != 0)		return (ret);#define	RECOVERY_FLAGS (DB_CREATE | DB_INIT_TXN | DB_INIT_LOG)	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) &&	    LF_ISSET(RECOVERY_FLAGS) != RECOVERY_FLAGS)		return (__db_ferr(dbenv, "db_appinit", 1));	/* Convert the db_appinit(3) flags. */	if (LF_ISSET(DB_THREAD))		F_SET(dbenv, DB_ENV_THREAD);	fp = NULL;	/* Set the database home. */	if ((ret = __db_home(dbenv, db_home, flags)) != 0)		goto err;	/* Parse the config array. */	for (p = db_config; p != NULL && *p != NULL; ++p)		if ((ret = __db_parse(dbenv, *p)) != 0)			goto err;	/*	 * Parse the config file.	 *	 * XXX	 * Don't use sprintf(3)/snprintf(3) -- the former is dangerous, and	 * the latter isn't standard, and we're manipulating strings handed	 * us by the application.	 */	if (dbenv->db_home != NULL) {#define	CONFIG_NAME	"/DB_CONFIG"		if (strlen(dbenv->db_home) +		    strlen(CONFIG_NAME) + 1 > sizeof(buf)) {			ret = ENAMETOOLONG;			goto err;		}		(void)strcpy(buf, dbenv->db_home);		(void)strcat(buf, CONFIG_NAME);		if ((fp = fopen(buf, "r")) != NULL) {			while (fgets(buf, sizeof(buf), fp) != NULL) {				if ((lp = strchr(buf, '\n')) != NULL)					*lp = '\0';				if ((ret = __db_parse(dbenv, buf)) != 0)					goto err;			}			(void)fclose(fp);			fp = NULL;		}	}	/* Set up the tmp directory path. */	if (dbenv->db_tmp_dir == NULL &&	    (ret = __db_tmp_dir(dbenv, flags)) != 0)		goto err;	/* Indicate that the path names have been set. */	F_SET(dbenv, DB_ENV_APPINIT);	/*	 * If we are doing recovery, remove all the regions.	 */	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) {		/* Remove all the old shared memory regions.  */		if ((ret = log_unlink(NULL, 1 /* force */, dbenv)) != 0)			goto err;		if ((ret = memp_unlink(NULL, 1 /* force */, dbenv)) != 0)			goto err;		if ((ret = lock_unlink(NULL, 1 /* force */, dbenv)) != 0)			goto err;		if ((ret = txn_unlink(NULL, 1 /* force */, dbenv)) != 0)			goto err;	}	/* Transactions imply logging. */	if (LF_ISSET(DB_INIT_TXN))		LF_SET(DB_INIT_LOG);	/* Default permissions are 0660. */#undef	DB_DEFPERM#define	DB_DEFPERM	(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)	/* Initialize the subsystems. */	if (LF_ISSET(DB_INIT_LOCK) && (ret = lock_open(NULL,	    LF_ISSET(DB_CREATE | DB_THREAD),	    DB_DEFPERM, dbenv, &dbenv->lk_info)) != 0)		goto err;	if (LF_ISSET(DB_INIT_LOG) && (ret = log_open(NULL,	    LF_ISSET(DB_CREATE | DB_THREAD),	    DB_DEFPERM, dbenv, &dbenv->lg_info)) != 0)		goto err;	if (LF_ISSET(DB_INIT_MPOOL) && (ret = memp_open(NULL,	    LF_ISSET(DB_CREATE | DB_MPOOL_PRIVATE | DB_NOMMAP | DB_THREAD),	    DB_DEFPERM, dbenv, &dbenv->mp_info)) != 0)		goto err;	if (LF_ISSET(DB_INIT_TXN) && (ret = txn_open(NULL,	    LF_ISSET(DB_CREATE | DB_THREAD | DB_TXN_NOSYNC),	    DB_DEFPERM, dbenv, &dbenv->tx_info)) != 0)		goto err;	/* Initialize recovery. */	if (LF_ISSET(DB_INIT_TXN)) {		if ((ret = __bam_init_recover(dbenv)) != 0)			goto err;		if ((ret = __db_init_recover(dbenv)) != 0)			goto err;		if ((ret = __ham_init_recover(dbenv)) != 0)			goto err;		if ((ret = __log_init_recover(dbenv)) != 0)			goto err;		if ((ret = __txn_init_recover(dbenv)) != 0)			goto err;	}	/* Run recovery if necessary. */	if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL) && (ret =	    __db_apprec(dbenv, LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL))) != 0)		goto err;	return (ret);err:	if (fp != NULL)		(void)fclose(fp);	(void)db_appexit(dbenv);	return (ret);}