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;
+}