CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
	{
	CA_DB *retdb = NULL;
	TXT_DB *tmpdb = NULL;
	BIO *in = BIO_new(BIO_s_file());
	CONF *dbattr_conf = NULL;
	char buf[1][BSIZE];
	long errorline= -1;

	if (in == NULL)
		{
		ERR_print_errors(bio_err);
		goto err;
		}
	if (BIO_read_filename(in,dbfile) <= 0)
		{
		perror(dbfile);
		BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
		goto err;
		}
	if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
		goto err;

#ifndef OPENSSL_SYS_VMS
	BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
#else
	BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
#endif
	dbattr_conf = NCONF_new(NULL);
	if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
		{
		if (errorline > 0)
			{
			BIO_printf(bio_err,
				"error on line %ld of db attribute file '%s'\n"
				,errorline,buf[0]);
			goto err;
			}
		else
			{
			NCONF_free(dbattr_conf);
			dbattr_conf = NULL;
			}
		}

	if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
		{
		fprintf(stderr, "Out of memory\n");
		goto err;
		}

	retdb->db = tmpdb;
	tmpdb = NULL;
	if (db_attr)
		retdb->attributes = *db_attr;
	else
		{
		retdb->attributes.unique_subject = 1;
		}

	if (dbattr_conf)
		{
		char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
		if (p)
			{
#ifdef RL_DEBUG
			BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
#endif
			retdb->attributes.unique_subject = parse_yesno(p,1);
			}
		}

 err:
	if (dbattr_conf) NCONF_free(dbattr_conf);
	if (tmpdb) TXT_DB_free(tmpdb);
	if (in) BIO_free_all(in);
	return retdb;
	}
CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
	{
	CA_DB *retdb = NULL;
	TXT_DB *tmpdb = NULL;
	BIO *in = BIO_new(BIO_s_file());
	CONF *dbattr_conf = NULL;
	char buf[1][BSIZE];
	long errorline= -1;

	if (in == NULL)
		{
		ERR_print_errors(bio_err);
		goto err;
		}
	if (BIO_read_filename(in,dbfile) <= 0)
		{
		perror(dbfile);
		BIO_printf(bio_err,"unable to open '%s'\n",dbfile);
		goto err;
		}
	if ((tmpdb = TXT_DB_read(in,DB_NUMBER)) == NULL)
		goto err;

#ifndef OPENSSL_SYS_VMS
	BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
#else
	BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
#endif
	dbattr_conf = NCONF_new(NULL);
	if (NCONF_load(dbattr_conf,buf[0],&errorline) <= 0)
		{
		if (errorline > 0)
			{
			BIO_printf(bio_err,
				"error on line %ld of db attribute file '%s'\n"
				,errorline,buf[0]);
			goto err;
			}
		else
			{
			NCONF_free(dbattr_conf);
			dbattr_conf = NULL;
			}
		}

	if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL)
		{
		fprintf(stderr, "Out of memory\n");
		goto err;
		}

	retdb->db = tmpdb;
	tmpdb = NULL;
	if (db_attr)
		retdb->attributes = *db_attr;
	else
		{
		retdb->attributes.unique_subject = 1;
		}

	if (dbattr_conf)
		{
		char *p = NCONF_get_string(dbattr_conf,NULL,"unique_subject");
		if (p)
			{
#ifdef RL_DEBUG
			BIO_printf(bio_err, "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
#endif
			retdb->attributes.unique_subject = parse_yesno(p,1);
			}
		}

 err:
	if (dbattr_conf) NCONF_free(dbattr_conf);
	if (tmpdb) TXT_DB_free(tmpdb);
	if (in) BIO_free_all(in);
	return retdb;
	}