add an abstraction layer separating out db-4 specific code
authorSven Verdoolaege <skimo@kotnet.org>
Tue, 29 Dec 2009 16:15:14 +0000 (29 17:15 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Wed, 30 Dec 2009 07:44:10 +0000 (30 08:44 +0100)
The extra abstraction layer is needed to more easily add a db-1 implementation
later.

common/db.c
common/db.h
common/exf.c
common/msg.c

index 83f8578..9e375a2 100644 (file)
@@ -16,6 +16,7 @@ static const char sccsid[] = "$Id: db.c,v 10.48 2002/06/08 19:32:52 skimo Exp $
 #include <sys/types.h>
 #include <sys/queue.h>
 #include <sys/time.h>
+#include <sys/stat.h>
 
 #include <bitstring.h>
 #include <errno.h>
@@ -680,3 +681,143 @@ line_insdel(SCR *sp, lnop_t op, db_recno_t lno)
 
        return rval;
 }
+
+#ifdef USE_DB4_LOGGING
+#define VI_DB_INIT_LOG DB_INIT_LOG
+#else
+#define VI_DB_INIT_LOG 0
+#endif
+
+/*
+ * PUBLIC: int db_setup __P((SCR *, EXF *));
+ */
+int
+db_setup(SCR *sp, EXF *ep)
+{
+       char path[MAXPATHLEN];
+       int fd;
+       DB_ENV  *env;
+
+       (void)snprintf(path, sizeof(path), "%s/vi.XXXXXX", O_STR(sp, O_RECDIR));
+       if ((fd = mkstemp(path)) == -1) {
+               msgq(sp, M_SYSERR, "%s", path);
+               goto err;
+       }
+       (void)close(fd);
+       (void)unlink(path);
+       if (mkdir(path, S_IRWXU)) {
+               msgq(sp, M_SYSERR, "%s", path);
+               goto err;
+       }
+       if (db_env_create(&env, 0)) {
+               msgq(sp, M_ERR, "env_create");
+               goto err;
+       }
+#ifdef USE_DB4_LOGGING
+       if ((sp->db_error = vi_db_init_recover(env))) {
+               msgq(sp, M_DBERR, "init_recover");
+               goto err;
+       }
+       if ((sp->db_error = __vi_init_recover(env))) {
+               msgq(sp, M_DBERR, "init_recover");
+               goto err;
+       }
+#endif
+       if ((sp->db_error = db_env_open(env, path, 
+           DB_PRIVATE | DB_CREATE | DB_INIT_MPOOL | VI_DB_THREAD 
+           | VI_DB_INIT_LOG, 0)) != 0) {
+               msgq(sp, M_DBERR, "env->open");
+               goto err;
+       }
+
+       if ((ep->env_path = strdup(path)) == NULL) {
+               msgq(sp, M_SYSERR, NULL);
+               (void)rmdir(path);
+               goto err;
+       }
+       ep->env = env;
+       return 0;
+err:
+       return 1;
+}
+
+/*
+ * PUBLIC: int db_msg_open __P((SCR *, char *, DB **));
+ */
+int db_msg_open(SCR *sp, char *file, DB **dbp)
+{
+       return  (sp->db_error = db_create(dbp, 0, 0)) != 0 ||
+               (sp->db_error = (*dbp)->set_re_source(*dbp, file)) != 0 ||
+               (sp->db_error = db_open(*dbp, NULL, DB_RECNO, 0, 0)) != 0;
+}
+
+/*
+ * PUBLIC: int db_init __P((SCR *, EXF *, char *, char *, size_t, int *));
+ */
+int
+db_init(SCR *sp, EXF *ep, char *rcv_name, char *oname, size_t psize, int *open_err)
+{
+       if (db_setup(sp, ep))
+               return 1;
+
+       /* Open a db structure. */
+       if ((sp->db_error = db_create(&ep->db, 0, 0)) != 0) {
+               msgq(sp, M_DBERR, "db_create");
+               return 1;
+       }
+
+       ep->db->set_re_delim(ep->db, '\n');             /* Always set. */
+       ep->db->set_pagesize(ep->db, psize);
+       ep->db->set_flags(ep->db, DB_RENUMBER | DB_SNAPSHOT);
+       if (rcv_name == NULL)
+               ep->db->set_re_source(ep->db, oname);
+
+/* 
+ * Don't let db use mmap when using fcntl for locking
+ */
+#ifdef HAVE_LOCK_FCNTL
+#define NOMMAPIFFCNTL DB_NOMMAP
+#else
+#define NOMMAPIFFCNTL 0
+#endif
+
+#define _DB_OPEN_MODE  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
+
+       if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO,
+           ((rcv_name == 0) ? DB_TRUNCATE : 0) | VI_DB_THREAD | NOMMAPIFFCNTL,
+           _DB_OPEN_MODE)) != 0) {
+               msgq_str(sp,
+                   M_DBERR, rcv_name == NULL ? oname : rcv_name, "%s");
+               /*
+                * !!!
+                * Historically, vi permitted users to edit files that couldn't
+                * be read.  This isn't useful for single files from a command
+                * line, but it's quite useful for "vi *.c", since you can skip
+                * past files that you can't read.
+                */ 
+               ep->db = NULL; /* Don't close it; it wasn't opened */
+
+               *open_err = 1;
+               return 1;
+       }
+
+       /* re_source is loaded into the database.
+        * Close it and reopen it in the environment. 
+        */
+       if ((sp->db_error = ep->db->close(ep->db, 0))) {
+               msgq(sp, M_DBERR, "close");
+               return 1;
+       }
+       if ((sp->db_error = db_create(&ep->db, ep->env, 0)) != 0) {
+               msgq(sp, M_DBERR, "db_create 2");
+               return 1;
+       }
+       if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO,
+           VI_DB_THREAD | NOMMAPIFFCNTL, _DB_OPEN_MODE)) != 0) {
+               msgq_str(sp,
+                   M_DBERR, ep->rcv_path, "%s");
+               return 1;
+       }
+
+       return 0;
+}
index fd1dc64..87dcf2d 100644 (file)
@@ -16,6 +16,9 @@
     (env)->remove(env, path, NULL, flags)
 #endif
 
+#define db_env_close(env,flags)                                                \
+    (env)->close(env, flags)
+
 #if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
 #define db_open(db,file,type,flags,mode)                               \
     (db)->open(db, NULL, file, NULL, type, flags, mode)
 #define db_open(db,file,type,flags,mode)                               \
     (db)->open(db, file, NULL, type, flags, mode)
 #endif
+#define db_get_low(db,key,data,flags)                                  \
+    (db)->get(db, NULL, key, data, flags)
+#define db_close(db)                                                   \
+    (db)->close(db, DB_NOSYNC)
 
 #ifdef USE_DYNAMIC_LOADING
 #define db_create      nvi_db_create
index 75c3d9f..d24db99 100644 (file)
@@ -42,7 +42,6 @@ static int    file_backup __P((SCR *, char *, char *));
 static void    file_cinit __P((SCR *));
 static void    file_comment __P((SCR *));
 static int     file_spath __P((SCR *, FREF *, struct stat *, int *));
-static int     db_setup __P((SCR *sp, EXF *ep));
 
 /*
  * file_add --
@@ -261,68 +260,9 @@ file_init(SCR *sp, FREF *frp, char *rcv_name, int flags)
                F_SET(ep, F_MODIFIED);
        }
 
-       if (db_setup(sp, ep))
-               goto err;
-
-       /* Open a db structure. */
-       if ((sp->db_error = db_create(&ep->db, 0, 0)) != 0) {
-               msgq(sp, M_DBERR, "db_create");
-               goto err;
-       }
-
-       ep->db->set_re_delim(ep->db, '\n');             /* Always set. */
-       ep->db->set_pagesize(ep->db, psize);
-       ep->db->set_flags(ep->db, DB_RENUMBER | DB_SNAPSHOT);
-       if (rcv_name == NULL)
-               ep->db->set_re_source(ep->db, oname);
-
-/* 
- * Don't let db use mmap when using fcntl for locking
- */
-#ifdef HAVE_LOCK_FCNTL
-#define NOMMAPIFFCNTL DB_NOMMAP
-#else
-#define NOMMAPIFFCNTL 0
-#endif
-
-#define _DB_OPEN_MODE  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH
-
-       if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO,
-           ((rcv_name == 0) ? DB_TRUNCATE : 0) | VI_DB_THREAD | NOMMAPIFFCNTL,
-           _DB_OPEN_MODE)) != 0) {
-               msgq_str(sp,
-                   M_DBERR, rcv_name == NULL ? oname : rcv_name, "%s");
-               /*
-                * !!!
-                * Historically, vi permitted users to edit files that couldn't
-                * be read.  This isn't useful for single files from a command
-                * line, but it's quite useful for "vi *.c", since you can skip
-                * past files that you can't read.
-                */ 
-               ep->db = NULL; /* Don't close it; it wasn't opened */
-
-               if (LF_ISSET(FS_OPENERR)) 
-                   goto err;
-
-               open_err = 1;
-               goto oerr;
-       }
-
-       /* re_source is loaded into the database.
-        * Close it and reopen it in the environment. 
-        */
-       if ((sp->db_error = ep->db->close(ep->db, 0))) {
-               msgq(sp, M_DBERR, "close");
-               goto err;
-       }
-       if ((sp->db_error = db_create(&ep->db, ep->env, 0)) != 0) {
-               msgq(sp, M_DBERR, "db_create 2");
-               goto err;
-       }
-       if ((sp->db_error = db_open(ep->db, ep->rcv_path, DB_RECNO,
-           VI_DB_THREAD | NOMMAPIFFCNTL, _DB_OPEN_MODE)) != 0) {
-               msgq_str(sp,
-                   M_DBERR, ep->rcv_path, "%s");
+       if (db_init(sp, ep, rcv_name, oname, psize, &open_err)) {
+               if (open_err && !LF_ISSET(FS_OPENERR))
+                       goto oerr;
                goto err;
        }
 
@@ -502,7 +442,7 @@ oerr:       if (F_ISSET(ep, F_RCV_ON))
                ep->rcv_path = NULL;
        }
        if (ep->db != NULL) {
-               (void)ep->db->close(ep->db, DB_NOSYNC);
+               (void)db_close(ep->db);
                ep->db = NULL;
        }
        free(ep);
@@ -751,7 +691,7 @@ file_end(SCR *sp, EXF *ep, int force)
         * Close the db structure.
         */
        if (ep->db->close != NULL) {
-               if ((sp->db_error = ep->db->close(ep->db, DB_NOSYNC)) != 0 && 
+               if ((sp->db_error = db_close(ep->db)) != 0 && 
                    !force) {
                        msgq_str(sp, M_DBERR, frp->name, "241|%s: close");
                        CIRCLEQ_INSERT_HEAD(&ep->scrq, sp, eq);
@@ -772,7 +712,7 @@ file_end(SCR *sp, EXF *ep, int force)
        if (ep->env) {
                DB_ENV *env;
 
-               ep->env->close(ep->env, 0);
+               db_env_close(ep->env, 0);
                ep->env = 0;
                if ((sp->db_error = db_env_create(&env, 0)))
                        msgq(sp, M_DBERR, "env_create");
@@ -1584,59 +1524,3 @@ file_lock(SCR *sp, char *name, int *fdp, int fd, int iswrite)
        return (LOCK_SUCCESS);
 #endif
 }
-
-#ifdef USE_DB4_LOGGING
-#define VI_DB_INIT_LOG DB_INIT_LOG
-#else
-#define VI_DB_INIT_LOG 0
-#endif
-
-static int
-db_setup(SCR *sp, EXF *ep)
-{
-       char path[MAXPATHLEN];
-       int fd;
-       DB_ENV  *env;
-
-       (void)snprintf(path, sizeof(path), "%s/vi.XXXXXX", O_STR(sp, O_RECDIR));
-       if ((fd = mkstemp(path)) == -1) {
-               msgq(sp, M_SYSERR, "%s", path);
-               goto err;
-       }
-       (void)close(fd);
-       (void)unlink(path);
-       if (mkdir(path, S_IRWXU)) {
-               msgq(sp, M_SYSERR, "%s", path);
-               goto err;
-       }
-       if (db_env_create(&env, 0)) {
-               msgq(sp, M_ERR, "env_create");
-               goto err;
-       }
-#ifdef USE_DB4_LOGGING
-       if ((sp->db_error = vi_db_init_recover(env))) {
-               msgq(sp, M_DBERR, "init_recover");
-               goto err;
-       }
-       if ((sp->db_error = __vi_init_recover(env))) {
-               msgq(sp, M_DBERR, "init_recover");
-               goto err;
-       }
-#endif
-       if ((sp->db_error = db_env_open(env, path, 
-           DB_PRIVATE | DB_CREATE | DB_INIT_MPOOL | VI_DB_THREAD 
-           | VI_DB_INIT_LOG, 0)) != 0) {
-               msgq(sp, M_DBERR, "env->open");
-               goto err;
-       }
-
-       if ((ep->env_path = strdup(path)) == NULL) {
-               msgq(sp, M_SYSERR, NULL);
-               (void)rmdir(path);
-               goto err;
-       }
-       ep->env = env;
-       return 0;
-err:
-       return 1;
-}
index a47d986..6bcd316 100644 (file)
@@ -724,9 +724,7 @@ msg_open(SCR *sp, char *file)
                p = buf;
        } else
                p = file;
-       if ((sp->db_error = db_create(&db, 0, 0)) != 0 ||
-           (sp->db_error = db->set_re_source(db, p)) != 0 ||
-           (sp->db_error = db_open(db, NULL, DB_RECNO, 0, 0)) != 0) {
+       if (db_msg_open(sp, p, &db)) {
                if (first) {
                        first = 0;
                        return (1);
@@ -745,10 +743,10 @@ msg_open(SCR *sp, char *file)
        key.size = sizeof(db_recno_t);
        memset(&data, 0, sizeof(data));
        msgno = 1;
-       if ((sp->db_error = db->get(db, NULL, &key, &data, 0)) != 0 ||
+       if ((sp->db_error = db_get_low(db, &key, &data, 0)) != 0 ||
            data.size != sizeof(VMC) - 1 ||
            memcmp(data.data, VMC, sizeof(VMC) - 1)) {
-               (void)db->close(db, DB_NOSYNC);
+               (void)db_close(db);
                if (first) {
                        first = 0;
                        return (1);
@@ -760,7 +758,7 @@ msg_open(SCR *sp, char *file)
        first = 0;
 
        if (sp->gp->msg != NULL)
-               (void)sp->gp->msg->close(sp->gp->msg, DB_NOSYNC);
+               (void)db_close(sp->gp->msg);
        sp->gp->msg = db;
        return (0);
 }
@@ -775,7 +773,7 @@ void
 msg_close(GS *gp)
 {
        if (gp->msg != NULL) {
-               (void)gp->msg->close(gp->msg, 0);
+               (void)db_close(gp->msg);
                gp->msg = NULL;
        }
 }
@@ -850,7 +848,7 @@ msg_cat(SCR *sp, const char *str, size_t *lenp)
                 */
                gp = sp == NULL ? NULL : sp->gp;
                if (gp != NULL && gp->msg != NULL &&
-                   gp->msg->get(gp->msg, NULL, &key, &data, 0) == 0 &&
+                   db_get_low(gp->msg, &key, &data, 0) == 0 &&
                    data.size != 0) {
                        if (lenp != NULL)
                                *lenp = data.size - 1;