Module Name:    src
Committed By:   christos
Date:           Fri Nov 29 22:56:19 UTC 2013

Modified Files:
        src/external/bsd/nvi/dist/common: dbinternal.h vi_db.c vi_db.h
        src/external/bsd/nvi/usr.bin/nvi: Makefile config.h port.h
Added Files:
        src/external/bsd/nvi/dist/common: db1.c

Log Message:
Bring back the compatibility db3->db1 code from the old vi.
This is selected with -DUSE_DB1 in the Makefile. By default
use use the db1 specific code from the current nvi which is
enabled using -DUSE_BUNDLED_DB. Unfortunately recovery seems
to be broken for both.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/external/bsd/nvi/dist/common/db1.c
cvs rdiff -u -r1.1 -r1.2 src/external/bsd/nvi/dist/common/dbinternal.h
cvs rdiff -u -r1.4 -r1.5 src/external/bsd/nvi/dist/common/vi_db.c
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/nvi/dist/common/vi_db.h
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/nvi/usr.bin/nvi/Makefile \
    src/external/bsd/nvi/usr.bin/nvi/config.h
cvs rdiff -u -r1.1 -r1.2 src/external/bsd/nvi/usr.bin/nvi/port.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/nvi/dist/common/dbinternal.h
diff -u src/external/bsd/nvi/dist/common/dbinternal.h:1.1 src/external/bsd/nvi/dist/common/dbinternal.h:1.2
--- src/external/bsd/nvi/dist/common/dbinternal.h:1.1	Fri Nov 22 10:52:05 2013
+++ src/external/bsd/nvi/dist/common/dbinternal.h	Fri Nov 29 17:56:19 2013
@@ -1,5 +1,5 @@
-/*	$NetBSD: dbinternal.h,v 1.1 2013/11/22 15:52:05 christos Exp $	*/
-#ifndef db_env_create
+/*	$NetBSD: dbinternal.h,v 1.2 2013/11/29 22:56:19 christos Exp $	*/
+#if !defined(db_env_create) || defined(USE_DB1)
 int db_env_create(DB_ENV **, u_int32_t);
 #endif
 int db_create(DB **, DB_ENV *, u_int32_t);

Index: src/external/bsd/nvi/dist/common/vi_db.c
diff -u src/external/bsd/nvi/dist/common/vi_db.c:1.4 src/external/bsd/nvi/dist/common/vi_db.c:1.5
--- src/external/bsd/nvi/dist/common/vi_db.c:1.4	Wed Nov 27 22:14:28 2013
+++ src/external/bsd/nvi/dist/common/vi_db.c	Fri Nov 29 17:56:19 2013
@@ -23,11 +23,14 @@ static const char sccsid[] = "Id: db.c,v
 #include <limits.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
 
 #include "common.h"
+#include "dbinternal.h"
 #include "../vi/vi.h"
 
-static int append __P((SCR*, db_recno_t, CHAR_T*, size_t, lnop_t, int));
+static int append __P((SCR*, db_recno_t, const CHAR_T*, size_t, lnop_t, int));
 
 /*
  * db_eget --
@@ -87,7 +90,7 @@ db_get(SCR *sp, db_recno_t lno, u_int32_
 	EXF *ep;
 	TEXT *tp;
 	db_recno_t l1, l2;
-	CHAR_T *wp;
+	const CHAR_T *wp;
 	size_t wlen;
 	size_t nlen;
 
@@ -275,12 +278,12 @@ db_delete(SCR *sp, db_recno_t lno)
  *				line
  */
 static int
-append(SCR *sp, db_recno_t lno, CHAR_T *p, size_t len, lnop_t op, int update)
+append(SCR *sp, db_recno_t lno, const CHAR_T *p, size_t len, lnop_t op, int update)
 {
 	DBT data, key;
 	DBC *dbcp_put;
 	EXF *ep;
-	char *fp;
+	const char *fp;
 	size_t flen;
 	int rval;
 
@@ -312,7 +315,7 @@ append(SCR *sp, db_recno_t lno, CHAR_T *
 	    if ((sp->db_error = dbcp_put->c_get(dbcp_put, &key, &data, DB_SET)) != 0) 
 		goto err2;
 
-	    data.data = fp;
+	    data.data = __UNCONST(fp);
 	    data.size = flen;
 	    if ((sp->db_error = dbcp_put->c_put(dbcp_put, &key, &data, DB_AFTER)) != 0) {
 err2:
@@ -329,7 +332,7 @@ err2:
 		if (sp->db_error != DB_NOTFOUND)
 		    goto err2;
 
-		data.data = fp;
+		data.data = __UNCONST(fp);
 		data.size = flen;
 		if ((sp->db_error = ep->db->put(ep->db, NULL, &key, &data, DB_APPEND)) != 0) {
 		    goto err2;
@@ -337,7 +340,7 @@ err2:
 	    } else {
 		key.data = &lno;
 		key.size = sizeof(lno);
-		data.data = fp;
+		data.data = __UNCONST(fp);
 		data.size = flen;
 		if ((sp->db_error = dbcp_put->c_put(dbcp_put, &key, &data, DB_BEFORE)) != 0) {
 		    goto err2;
@@ -419,7 +422,7 @@ db_set(SCR *sp, db_recno_t lno, CHAR_T *
 {
 	DBT data, key;
 	EXF *ep;
-	char *fp;
+	const char *fp;
 	size_t flen;
 
 #if defined(DEBUG) && 0
@@ -446,7 +449,7 @@ db_set(SCR *sp, db_recno_t lno, CHAR_T *
 	key.data = &lno;
 	key.size = sizeof(lno);
 	memset(&data, 0, sizeof(data));
-	data.data = fp;
+	data.data = __UNCONST(fp);
 	data.size = flen;
 	if ((sp->db_error = ep->db->put(ep->db, NULL, &key, &data, 0)) != 0) {
 		msgq(sp, M_DBERR, "006|unable to store line %lu", (u_long)lno);
@@ -514,7 +517,7 @@ db_last(SCR *sp, db_recno_t *lnop)
 	DBC *dbcp;
 	EXF *ep;
 	db_recno_t lno;
-	CHAR_T *wp;
+	const CHAR_T *wp;
 	size_t wlen;
 
 	/* Check for no underlying file. */
@@ -530,8 +533,8 @@ db_last(SCR *sp, db_recno_t *lnop)
 	if (ep->c_nlines != OOBLNO) {
 		*lnop = ep->c_nlines;
 		if (F_ISSET(sp, SC_TINPUT))
-			*lnop += TAILQ_LAST&sp->tiq, _texth)->lno -
-			    TAILQ_FIRST&sp->tiq)->lno;
+			*lnop += TAILQ_LAST(&sp->tiq, _texth)->lno -
+			    TAILQ_FIRST(&sp->tiq)->lno;
 		return (0);
 	}
 
@@ -648,6 +651,8 @@ update_cache(SCR *sp, lnop_t op, db_recn
 			if (lno == scrp->c_lno)
 				scrp->c_lno = OOBLNO;
 			break;
+		case LINE_APPEND:
+			break;
 		}
 
 	if (ep->c_nlines != OOBLNO)
@@ -658,6 +663,9 @@ update_cache(SCR *sp, lnop_t op, db_recn
 		case LINE_DELETE:
 			--ep->c_nlines;
 			break;
+		case LINE_APPEND:
+		case LINE_RESET:
+			break;
 		}
 }
 

Index: src/external/bsd/nvi/dist/common/vi_db.h
diff -u src/external/bsd/nvi/dist/common/vi_db.h:1.2 src/external/bsd/nvi/dist/common/vi_db.h:1.3
--- src/external/bsd/nvi/dist/common/vi_db.h:1.2	Fri Nov 22 10:52:05 2013
+++ src/external/bsd/nvi/dist/common/vi_db.h	Fri Nov 29 17:56:19 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: vi_db.h,v 1.2 2013/11/22 15:52:05 christos Exp $	*/
+/*	$NetBSD: vi_db.h,v 1.3 2013/11/29 22:56:19 christos Exp $ */
 
 #include <db.h>
 
@@ -27,7 +27,7 @@ typedef recno_t db_recno_t;
 
 #else
 
-#if DB_VERSION_MAJOR >= 3 && DB_VERSION_MINOR >= 1
+#if USE_DB1 || (DB_VERSION_MAJOR >= 3 && DB_VERSION_MINOR >= 1)
 #define db_env_open(env,path,flags,mode)				\
     (env)->open(env, path, flags, mode)
 #define db_env_remove(env,path,flags)					\
@@ -65,3 +65,112 @@ extern int   (*nvi_db_create) __P((DB **
 extern int   (*nvi_db_env_create) __P((DB_ENV **, u_int32_t));
 extern char *(*nvi_db_strerror) __P((int));
 #endif
+
+#ifdef USE_DB1
+
+#define DB_AFTER	1
+#define DB_APPEND	2
+#define DB_BEFORE	3
+#define DB_FIRST	7
+#define DB_LAST		15
+#define DB_SET		25
+
+#define DB_NOTFOUND (-30989)
+
+/* DBT emulation */
+typedef DBT DBT_v1;
+#undef DBT
+#define DBT DBT_new
+
+typedef struct {
+	void *data;
+	size_t size;
+
+	u_int32_t ulen;
+
+#define DB_DBT_USERMEM 0x040
+	u_int32_t flags;
+} DBT;
+
+/* DB_ENV emulation */
+struct __db_env_new;
+typedef struct __db_env_new DB_ENV;
+
+struct __db_env_new {
+	int (*close)(DB_ENV *, u_int32_t);
+	int (*open)(DB_ENV *, char *, u_int32_t, int);
+#define DB_INIT_MPOOL	0x004000
+#define DB_PRIVATE	0x200000
+	int (*remove)(DB_ENV *, char *, u_int32_t);
+
+	char *base_path;
+	int mode;
+};
+
+/* DBC emulation */
+
+struct __dbc_new;
+typedef struct __dbc_new DBC;
+
+typedef recno_t db_recno_t;
+#define DB_MAX_RECORDS MAX_REC_NUMBER
+
+#define DB_UNKNOWN (-1)
+
+/* DB emulation */
+typedef DB DB_old;
+#undef DB
+#define DB DB_new
+typedef struct __db_new DB;
+
+#undef DB_TXN
+typedef void DB_TXN;
+
+#undef DB_LSN
+typedef struct {
+	int dummy;
+} DB_LSN;
+
+struct __db_new {
+	DB_old *actual_db;
+
+	int type;
+
+	int (*close)(DB *, u_int32_t);
+#define	DB_NOSYNC	26		/* close() */
+
+	int (*open)(DB *, const char *, const char *, DBTYPE, u_int32_t, int);
+#define	DB_CREATE	0x000001	/* Create file as necessary. */
+#define	DB_TRUNCATE	0x004000	/* Discard existing DB (O_TRUNC) */
+
+	int (*sync)(DB *, u_int32_t);
+	int (*get)(DB *, DB_TXN *, DBT *, DBT *, u_int32_t);
+	int (*put)(DB *, DB_TXN *, DBT *, DBT *, u_int32_t);
+	int (*del)(DB *, DB_TXN *, DBT *, u_int32_t);
+
+	int (*cursor)(DB *, DB_TXN *, DBC **, u_int32_t);
+
+	int (*set_flags)(DB *, u_int32_t);
+#define	DB_RENUMBER	0x0008		/* Recno: renumber on insert/delete. */
+#define	DB_SNAPSHOT	0x0020		/* Recno: snapshot the input. */
+
+	int (*set_pagesize)(DB *, u_int32_t);
+
+	int (*set_re_delim)(DB *, int);
+	int (*set_re_source)(DB *, const char *);
+
+	RECNOINFO _recno_info;
+	u_int32_t _pagesize;
+	u_int32_t _flags;
+};
+
+struct __dbc_new {
+	DB *db;
+	db_recno_t pos;
+	DBT_v1 pos_key;
+	int (*c_close)(DBC *);
+	int (*c_get)(DBC *, DBT *, DBT *, u_int32_t);
+	int (*c_put)(DBC *, DBT *, DBT *, u_int32_t);
+};
+
+#endif /* USE_DB1 */

Index: src/external/bsd/nvi/usr.bin/nvi/Makefile
diff -u src/external/bsd/nvi/usr.bin/nvi/Makefile:1.2 src/external/bsd/nvi/usr.bin/nvi/Makefile:1.3
--- src/external/bsd/nvi/usr.bin/nvi/Makefile:1.2	Fri Nov 29 11:37:35 2013
+++ src/external/bsd/nvi/usr.bin/nvi/Makefile	Fri Nov 29 17:56:19 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.2 2013/11/29 16:37:35 christos Exp $
+#	$NetBSD: Makefile,v 1.3 2013/11/29 22:56:19 christos Exp $
 
 .include <bsd.own.mk>
 
@@ -6,9 +6,10 @@ USE_WIDECHAR?=yes
 
 CWARNFLAGS.clang+=	-Wno-uninitialized -Wno-format-security
 
-CPPFLAGS+=-I${DIST}/include -I${.CURDIR} -I. -DGTAGS -DUSE_BUNDLED_DB
+CPPFLAGS+=-I${DIST}/include -I${.CURDIR} -I. -DGTAGS
 #DBG=-g
 #CPPFLAGS+=-DLOGDEBUG -DTRACE
+#CPPFLAGS+=-DDBDEBUG -DTRACE
 
 #CWARNFLAGS+=-Wno-parentheses -Wno-unused -Wno-missing-prototypes
 #.if defined(HAVE_GCC)
@@ -31,14 +32,14 @@ SRCS=	api.c cl_bsd.c cl_funcs.c cl_main.
 	ex_write.c ex_yank.c ex_z.c exf.c getc.c gs.c \
 	ip_funcs.c ip_read.c ip_screen.c ip_term.c \
 	ip_run.c ip_send.c ip_trans.c ipc_cmd.c ipc_method.c \
-	key.c log1.c trace.c \
+	key.c trace.c \
 	main.c mark.c msg.c nothread.c options.c options_f.c put.c recover.c \
 	screen.c search.c seq.c util.c v_at.c v_ch.c v_cmd.c v_delete.c \
 	v_event.c v_ex.c v_increment.c v_init.c v_itxt.c v_left.c v_mark.c \
 	v_match.c v_paragraph.c v_put.c v_redraw.c v_replace.c v_right.c \
 	v_screen.c v_scroll.c v_search.c v_section.c v_sentence.c v_status.c \
 	v_txt.c v_ulcase.c v_undo.c v_util.c v_word.c v_xchar.c v_yank.c \
-	v_z.c v_zexit.c vi.c vi_db1.c vs_line.c vs_msg.c vs_refresh.c \
+	v_z.c v_zexit.c vi.c vs_line.c vs_msg.c vs_refresh.c \
 	vs_relative.c vs_smap.c vs_split.c
 
 # For wide char support
@@ -47,6 +48,14 @@ SRCS+=	regcomp.c regerror.c regexec.c re
 CPPFLAGS+=-I${DIST}/regex -D__REGEX_PRIVATE -DUSE_WIDECHAR
 .endif
 
+# For db3 db1 emulation
+#SRCS+=db1.c log.c vi_db.c
+#CPPFLAGS+=-DUSE_DB1
+
+# For built-in db1 emulation
+SRCS+=vi_db1.c log1.c
+CPPFLAGS+=-DUSE_BUNDLED_DB
+
 LINKS=	${BINDIR}/vi ${BINDIR}/ex ${BINDIR}/vi ${BINDIR}/view
 MLINKS=	vi.1 ex.1 vi.1 view.1
 
Index: src/external/bsd/nvi/usr.bin/nvi/config.h
diff -u src/external/bsd/nvi/usr.bin/nvi/config.h:1.2 src/external/bsd/nvi/usr.bin/nvi/config.h:1.3
--- src/external/bsd/nvi/usr.bin/nvi/config.h:1.2	Mon Nov 25 18:04:39 2013
+++ src/external/bsd/nvi/usr.bin/nvi/config.h	Fri Nov 29 17:56:19 2013
@@ -231,9 +231,6 @@
 /* Define to 1 if your <sys/time.h> declares `struct tm'. */
 /* #undef TM_IN_SYS_TIME */
 
-/* Define when using bundled db. */
-#define USE_BUNDLED_DB 1
-
 /* Define when using db4 logging. */
 /* #undef USE_DB4_LOGGING */
 

Index: src/external/bsd/nvi/usr.bin/nvi/port.h
diff -u src/external/bsd/nvi/usr.bin/nvi/port.h:1.1 src/external/bsd/nvi/usr.bin/nvi/port.h:1.2
--- src/external/bsd/nvi/usr.bin/nvi/port.h:1.1	Fri Nov 22 11:00:45 2013
+++ src/external/bsd/nvi/usr.bin/nvi/port.h	Fri Nov 29 17:56:19 2013
@@ -1,4 +1,4 @@
-/* $Id: port.h,v 1.1 2013/11/22 16:00:45 christos Exp $ (Berkeley) $Date: 2013/11/22 16:00:45 $ */
+/* $Id: port.h,v 1.2 2013/11/29 22:56:19 christos Exp $ (Berkeley) $Date: 2013/11/29 22:56:19 $ */
 
 /*
  * Declare the basic types, if they aren't already declared.  Named and
@@ -121,6 +121,7 @@
 #define	MIN(_a,_b)	((_a)<(_b)?(_a):(_b))
 #endif
 
+#ifndef USE_DB1
 /*
  * XXX
  * "DB" isn't always portable, and we want the private information.
@@ -128,6 +129,7 @@
 #define DB      L__DB
 #undef	pgno_t			/* IRIX has its own version. */
 #define	pgno_t	L__db_pgno_t
+#endif
 
 /*
  * XXX

Added files:

Index: src/external/bsd/nvi/dist/common/db1.c
diff -u /dev/null src/external/bsd/nvi/dist/common/db1.c:1.1
--- /dev/null	Fri Nov 29 17:56:19 2013
+++ src/external/bsd/nvi/dist/common/db1.c	Fri Nov 29 17:56:19 2013
@@ -0,0 +1,360 @@
+/*
+ * DB1->3 compatibility layer
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+
+#include "../common/vi_db.h"
+#include "../common/dbinternal.h"
+
+/*
+ * DB_ENV emulation
+ */
+
+static int db1_dbenv_close(DB_ENV *, u_int32_t);
+static int db1_dbenv_open(DB_ENV *, char *, u_int32_t, int);
+static int db1_dbenv_remove(DB_ENV *, char *, u_int32_t);
+
+int
+db_env_create(DB_ENV **dbenvp, u_int32_t flags) {
+	DB_ENV *dbenv;
+
+	assert(flags == 0);
+
+	dbenv = malloc(sizeof *dbenv);
+	if (dbenv == NULL)
+		return -1;
+
+	dbenv->close = db1_dbenv_close;
+	dbenv->open = db1_dbenv_open;
+	dbenv->remove = db1_dbenv_remove;
+
+	dbenv->base_path = NULL;
+	dbenv->mode = 0;
+
+	*dbenvp = dbenv;
+	return 0;
+}
+
+static int
+db1_dbenv_close(DB_ENV *dbenv, u_int32_t flags) {
+	assert(flags == 0);
+
+	if (dbenv->base_path != NULL)
+		free(dbenv->base_path);
+
+	free(dbenv);
+	return 0;
+}
+
+static int
+db1_dbenv_open(DB_ENV *dbenv, char *base_path, u_int32_t flags, int mode) {
+
+	/* We ignore flags on purpose */
+
+	dbenv->base_path = strdup(base_path);
+	if (dbenv->base_path == NULL)
+		return ENOSPC;
+
+	dbenv->mode = mode != 0? mode : 0660;
+	return 0;
+}
+
+static int
+db1_dbenv_remove(DB_ENV *dbenv_fake, char *base_path, u_int32_t flags) {
+	/* dbenv_fake is not a useful environment */
+	/* XXX check if we have to remove files here */
+
+	return 0;
+}
+
+/*
+ * DB emulation
+ */
+static int db1_db_close(DB *, u_int32_t);
+static int db1_db_open(DB *, const char *, const char *, DBTYPE, u_int32_t, int);
+static int db1_db_sync(DB *, u_int32_t);
+static int db1_db_get(DB *, DB_TXN *, DBT *, DBT *, u_int32_t);
+static int db1_db_put(DB *, DB_TXN *, DBT *, DBT *, u_int32_t);
+static int db1_db_del(DB *, DB_TXN *, DBT *, u_int32_t);
+static int db1_db_set_flags(DB *, u_int32_t);
+static int db1_db_set_pagesize(DB *, u_int32_t);
+static int db1_db_set_re_delim(DB *, int);
+static int db1_db_set_re_source(DB *, const char *);
+static int db1_db_cursor(DB *, DB_TXN *, DBC **, u_int32_t);
+
+int
+db_create(DB **dbp, DB_ENV *dbenv, u_int32_t flags) {
+	assert(flags == 0);
+
+	*dbp = malloc(sizeof **dbp);
+	if (*dbp == NULL)
+		return -1;
+
+	(*dbp)->type = DB_UNKNOWN;
+	(*dbp)->actual_db = NULL;
+	(*dbp)->_pagesize = 0;
+	(*dbp)->_flags = 0;
+	memset(&(*dbp)->_recno_info, 0, sizeof (RECNOINFO));
+
+	(*dbp)->close = db1_db_close;
+	(*dbp)->open = db1_db_open;
+	(*dbp)->sync = db1_db_sync;
+	(*dbp)->get = db1_db_get;
+	(*dbp)->put = db1_db_put;
+	(*dbp)->del = db1_db_del;
+	(*dbp)->set_flags = db1_db_set_flags;
+	(*dbp)->set_pagesize = db1_db_set_pagesize;
+	(*dbp)->set_re_delim = db1_db_set_re_delim;
+	(*dbp)->set_re_source = db1_db_set_re_source;
+	(*dbp)->cursor = db1_db_cursor;
+
+	return 0;
+}
+
+const char *
+db_strerror(int error) {
+	return error > 0? strerror(error) : "record not found";
+}
+
+static int
+db1_db_close(DB *db, u_int32_t flags) {
+	if (flags & DB_NOSYNC) {
+		/* XXX warn user? */
+	}
+	db->actual_db->close(db->actual_db);
+
+	db->type = DB_UNKNOWN;
+	db->actual_db = NULL;
+	db->_pagesize = 0;
+	db->_flags = 0;
+	memset(&db->_recno_info, 0, sizeof (RECNOINFO));
+
+	return 0;
+}
+
+static int
+db1_db_open(DB *db, const char *file, const char *database, DBTYPE type,
+						u_int32_t flags, int mode) {
+	int oldflags = 0;
+
+	assert(database == NULL && !(flags & ~(DB_CREATE | DB_TRUNCATE)));
+
+	db->type = type;
+
+	if (flags & DB_CREATE)
+		oldflags |= O_CREAT;
+	if (flags & DB_TRUNCATE)
+		oldflags |= O_TRUNC;
+
+	if (type == DB_RECNO) {
+		const char *tmp = file;
+
+		/* The interface is reversed in DB3 */
+		file = db->_recno_info.bfname;
+		db->_recno_info.bfname = __UNCONST(tmp);
+
+		/* ... and so, we should avoid to truncate the main file! */
+		oldflags &= ~O_TRUNC;
+
+		db->_recno_info.flags =
+			db->_flags & DB_SNAPSHOT? R_SNAPSHOT : 0;
+		db->_recno_info.psize = db->_pagesize;
+	}
+
+	db->actual_db = dbopen(file, oldflags, mode, type,
+				type == DB_RECNO? &db->_recno_info : NULL);
+
+	return db->actual_db == NULL? errno : 0;
+}
+
+static int
+db1_db_sync(DB *db, u_int32_t flags) {
+	assert(flags == 0);
+
+	return db->actual_db->sync(db->actual_db, db->type == DB_UNKNOWN?
+					R_RECNOSYNC : 0) == 0? 0 : errno;
+}
+
+static int
+db1_db_get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) {
+	int err;
+	DBT_v1 data1;
+
+	assert(flags == 0 && txnid == NULL);
+
+	err = db->actual_db->get(db->actual_db, (DBT_v1 *) key, &data1, flags);
+	if (err == 1)
+		return DB_NOTFOUND;
+	else if (err == -1)
+		return errno;
+
+	if (data->flags & DB_DBT_USERMEM) {
+		data->size = data1.size;
+		if (data1.size > data->ulen)
+			return DB_BUFFER_SMALL;
+
+		memcpy(data->data, data1.data, data1.size);
+	}
+
+	return 0;
+}
+
+static int
+db1_db_put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) {
+	int err;
+	DB_old *db_v1 = db->actual_db;
+	DBT data1;
+	DBT key1;
+	recno_t recno = 1;
+
+	assert((flags & ~DB_APPEND) == 0 && txnid == NULL);
+
+	key1 = *key;
+
+	if (flags & DB_APPEND) {
+		if (db_v1->seq(db_v1, (DBT_v1 *)(void *)key,
+		    (DBT_v1 *)(void *)&data1, R_LAST) == 1) {
+			key1.data = &recno;
+			key1.size = sizeof recno;
+		}
+	}
+	err = db_v1->put(db_v1, (DBT_v1 *)(void *)&key1, (DBT_v1 *)(void *)data,
+	    0);
+
+	return err == -1? errno : err;
+}
+
+static int
+db1_db_del(DB *db, DB_TXN *txnid, DBT *key, u_int32_t flags) {
+	int err;
+	DB_old *db_v1 = db->actual_db;
+
+	assert(txnid == NULL && flags == 0);
+
+	err = db_v1->del(db_v1, (DBT_v1 *) key, 0);
+	return err == -1? errno : err;
+}
+
+static int
+db1_db_set_flags(DB *db, u_int32_t flags) {
+	assert((flags & ~(DB_RENUMBER | DB_SNAPSHOT)) == 0);
+
+	/* Can't prevent renumbering from happening with DB1 */
+	assert((flags | db->_flags) & DB_RENUMBER);
+
+
+	db->_flags |= flags;
+
+	return 0;
+}
+
+static int
+db1_db_set_pagesize(DB *db, u_int32_t pagesize) {
+	db->_pagesize = pagesize;
+
+	return 0;
+}
+
+static int
+db1_db_set_re_delim(DB *db, int re_delim) {
+	db->_recno_info.bval = re_delim;
+
+	return 0;
+}
+
+static int
+db1_db_set_re_source(DB *db, const char *re_source) {
+	db->_recno_info.bfname = __UNCONST(re_source);
+
+	return 0;
+}
+
+/* DBC emulation. Very basic, only one cursor at a time, enough for vi */
+
+static int db1_dbc_close(DBC *);
+static int db1_dbc_get(DBC *, DBT *, DBT *, u_int32_t);
+static int db1_dbc_put(DBC *, DBT *, DBT *, u_int32_t);
+
+static int
+db1_db_cursor(DB *db, DB_TXN *txn, DBC **cursorp, u_int32_t flags) {
+	DBC *cursor;
+
+	assert(txn == NULL && flags == 0);
+
+	cursor = malloc(sizeof *cursor);
+	if (cursor == NULL)
+		return -1;
+
+	cursor->db = db;
+	cursor->pos_key.data = &cursor->pos;
+	cursor->pos_key.size = sizeof cursor->pos;
+	cursor->c_close = db1_dbc_close;
+	cursor->c_get = db1_dbc_get;
+	cursor->c_put = db1_dbc_put;
+
+	*cursorp = cursor;
+
+	return 0;
+}
+
+static int
+db1_dbc_close(DBC *cursor) {
+	free(cursor);
+	return 0;
+}
+
+static int
+db1_dbc_get(DBC *cursor, DBT *key, DBT *data, u_int32_t flags) {
+	DB *db = cursor->db;
+	DB_old *db_v1 = db->actual_db;
+	int ret = 0;
+
+
+	switch(flags) {
+	case DB_SET:
+		ret = db_v1->seq(db_v1, (DBT_v1 *) key, (DBT_v1 *) data,
+			R_CURSOR);
+		cursor->pos = * (db_recno_t *) key->data;
+		break;
+	case DB_FIRST:
+		ret = db_v1->seq(db_v1, (DBT_v1 *) key, (DBT_v1 *) data,
+			R_FIRST);
+		if (ret == 1)
+			ret = DB_NOTFOUND;
+		cursor->pos = * (db_recno_t *) key->data;
+		break;
+	case DB_LAST:
+		ret = db_v1->seq(db_v1, (DBT_v1 *) key, (DBT_v1 *) data,
+			R_LAST);
+		if (ret == 1)
+			ret = DB_NOTFOUND;
+		cursor->pos = * (db_recno_t *) key->data;
+		break;
+	default:
+		abort();
+	}
+
+	return ret;
+}
+
+static int
+db1_dbc_put(DBC *cursor, DBT *key, DBT *data, u_int32_t flags) {
+	DB *db = cursor->db;
+	DB_old *db_v1 = db->actual_db;
+	int ret = 0;
+
+	assert((flags & ~(DB_BEFORE | DB_AFTER)) == 0);
+
+	ret = db_v1->put(db_v1, &cursor->pos_key, (DBT_v1 *) data,
+		flags == DB_BEFORE? R_IBEFORE : R_IAFTER);
+
+	return ret == -1? errno : ret;
+}

Reply via email to