Mostly finished the abstractions, now just need to silence some compiler warnings...
authorArt Cancro <ajc@citadel.org>
Tue, 8 Aug 2023 21:55:10 +0000 (17:55 -0400)
committerArt Cancro <ajc@citadel.org>
Tue, 8 Aug 2023 21:55:10 +0000 (17:55 -0400)
citadel/server/database.h
citadel/server/database_bdb.c

index f1da45f7627891113c2886f1dcfc2a57f69b66fa..ae7df39631046820783d2bf69c97279ee94ab795 100644 (file)
 
 void                   cdb_init_backends(void);
 
-void                   cdb_open_databases(void);
-void                   cdb_close_databases(void);
-int                    cdb_store(int, const void *, int, void *, int);
-int                    cdb_delete(int, void *, int);
-void                   cdb_free(struct cdbdata *);
-struct cdbdata *       cdb_next_item(int);
-void                   cdb_close_cursor(int);
-void                   cdb_begin_transaction(void);
-void                   cdb_end_transaction(void);
-void                   cdb_check_handles(void);
-void                   cdb_trunc(int);
-void                   cdb_chmod_data(void);
-void                   check_handles(void *);
-
+extern void            (*cdb_open_databases)(void);
+extern void            (*cdb_close_databases)(void);
+extern int             (*cdb_store)(int, const void *, int, void *, int);
+extern int             (*cdb_delete)(int, void *, int);
+extern void            (*cdb_free)(struct cdbdata *);
+extern struct cdbdata *        (*cdb_next_item)(int);
+extern void            (*cdb_close_cursor)(int);
+extern void            (*cdb_begin_transaction)(void);
+extern void            (*cdb_end_transaction)(void);
+extern void            (*cdb_check_handles)(void);
+extern void            (*cdb_trunc)(int);
+extern void            (*cdb_chmod_data)(void);
+extern void            (*check_handles)(void *);
 extern struct cdbdata *        (*cdb_fetch)(int, const void *, int);
 extern void            (*cdb_checkpoint)(void);
 extern void            (*cdb_compact)(void);
index 6f55c476f0d94a82c3619e775a3f21930ce123ca..95b90d7e890ffe84c00ee1de17bbfc634cf7f9a9 100644 (file)
 #include "citserver.h"
 #include "config.h"
 
-void                   (*cdb_compact)(void)                            = NULL;
-void                   (*cdb_checkpoint)(void)                         = NULL;
-void                   (*cdb_rewind)(int)                              = NULL;
-struct cdbdata *       (*cdb_fetch)(int, const void *, int)            = NULL;
+void                   (*cdb_open_databases)(void)                             = NULL;
+void                   (*cdb_close_databases)(void)                            = NULL;
+int                    (*cdb_store)(int, const void *, int, void *, int)       = NULL;
+int                    (*cdb_delete)(int, void *, int)                         = NULL;
+void                   (*cdb_free)(struct cdbdata *)                           = NULL;
+struct cdbdata *       (*cdb_next_item)(int)                                   = NULL;
+void                   (*cdb_close_cursor)(int)                                = NULL;
+void                   (*cdb_begin_transaction)(void)                          = NULL;
+void                   (*cdb_end_transaction)(void)                            = NULL;
+void                   (*cdb_check_handles)(void)                              = NULL;
+void                   (*cdb_trunc)(int)                                       = NULL;
+void                   (*cdb_chmod_data)(void)                                 = NULL;
+void                   (*check_handles)(void *)                                = NULL;
+void                   (*cdb_compact)(void)                                    = NULL;
+void                   (*cdb_checkpoint)(void)                                 = NULL;
+void                   (*cdb_rewind)(int)                                      = NULL;
+struct cdbdata *       (*cdb_fetch)(int, const void *, int)                    = NULL;
 
 static DB *dbp[MAXCDB];                // One DB handle for each Citadel database
 static DB_ENV *dbenv;          // The DB environment (global)
 
 
-void cdb_abort(void) {
+void bdb_abort(void) {
        syslog(LOG_DEBUG, "bdb: citserver is stopping in order to prevent data loss. uid=%d gid=%d euid=%d egid=%d",
                getuid(), getgid(), geteuid(), getegid()
        );
@@ -49,7 +62,7 @@ void cdb_abort(void) {
 
 
 // Verbose logging callback
-void cdb_verbose_log(const DB_ENV *dbenv, const char *msg, const char *foo) {
+void bdb_verbose_log(const DB_ENV *dbenv, const char *msg, const char *foo) {
        if (!IsEmptyStr(msg)) {
                syslog(LOG_DEBUG, "bdb: %s %s", msg, foo);
        }
@@ -57,7 +70,7 @@ void cdb_verbose_log(const DB_ENV *dbenv, const char *msg, const char *foo) {
 
 
 // Verbose logging callback
-void cdb_verbose_err(const DB_ENV *dbenv, const char *errpfx, const char *msg) {
+void bdb_verbose_err(const DB_ENV *dbenv, const char *errpfx, const char *msg) {
        syslog(LOG_ERR, "bdb: %s", msg);
 }
 
@@ -70,7 +83,7 @@ static void txabort(DB_TXN *tid) {
 
        if (ret) {
                syslog(LOG_ERR, "bdb: txn_abort: %s", db_strerror(ret));
-               cdb_abort();
+               bdb_abort();
        }
 }
 
@@ -83,7 +96,7 @@ static void txcommit(DB_TXN *tid) {
 
        if (ret) {
                syslog(LOG_ERR, "bdb: txn_commit: %s", db_strerror(ret));
-               cdb_abort();
+               bdb_abort();
        }
 }
 
@@ -96,7 +109,7 @@ static void txbegin(DB_TXN **tid) {
 
        if (ret) {
                syslog(LOG_ERR, "bdb: txn_begin: %s", db_strerror(ret));
-               cdb_abort();
+               bdb_abort();
        }
 }
 
@@ -104,7 +117,7 @@ static void txbegin(DB_TXN **tid) {
 // panic callback
 static void dbpanic(DB_ENV *env, int errval) {
        syslog(LOG_ERR, "bdb: PANIC: %s", db_strerror(errval));
-       cdb_abort();
+       bdb_abort();
 }
 
 
@@ -113,7 +126,7 @@ static void cclose(DBC *cursor) {
 
        if ((ret = cursor->c_close(cursor))) {
                syslog(LOG_ERR, "bdb: c_close: %s", db_strerror(ret));
-               cdb_abort();
+               bdb_abort();
        }
 }
 
@@ -124,17 +137,17 @@ static void bailIfCursor(DBC **cursors, const char *msg) {
        for (i = 0; i < MAXCDB; i++)
                if (cursors[i] != NULL) {
                        syslog(LOG_ERR, "bdb: cursor still in progress on cdb %02x: %s", i, msg);
-                       cdb_abort();
+                       bdb_abort();
                }
 }
 
 
-void cdb_check_handles(void) {
+void bdb_check_handles(void) {
        bailIfCursor(TSD->cursors, "in check_handles");
 
        if (TSD->tid != NULL) {
                syslog(LOG_ERR, "bdb: transaction still in progress!");
-               cdb_abort();
+               bdb_abort();
        }
 }
 
@@ -147,8 +160,8 @@ void bdb_checkpoint(void) {
        ret = dbenv->txn_checkpoint(dbenv, MAX_CHECKPOINT_KBYTES, MAX_CHECKPOINT_MINUTES, 0);
 
        if (ret != 0) {
-               syslog(LOG_ERR, "bdb: cdb_checkpoint() txn_checkpoint: %s", db_strerror(ret));
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_checkpoint() txn_checkpoint: %s", db_strerror(ret));
+               bdb_abort();
        }
 
        // After a successful checkpoint, we can cull the unused logs
@@ -165,14 +178,14 @@ void bdb_checkpoint(void) {
 // does not exist should be created.  Note that we don't need a
 // critical section here, because there aren't any active threads
 // manipulating the database yet.
-void cdb_open_databases(void) {
+void bdb_open_databases(void) {
        int ret;
        int i;
        char dbfilename[32];
        u_int32_t flags = 0;
        int dbversion_major, dbversion_minor, dbversion_patch;
 
-       syslog(LOG_DEBUG, "bdb: cdb_open_databases() starting");
+       syslog(LOG_DEBUG, "bdb: bdb_open_databases() starting");
        syslog(LOG_DEBUG, "bdb:    Linked zlib: %s", zlibVersion());
        syslog(LOG_DEBUG, "bdb: Compiled libdb: %s", DB_VERSION_STRING);
        syslog(LOG_DEBUG, "bdb:   Linked libdb: %s", db_version(&dbversion_major, &dbversion_minor, &dbversion_patch));
@@ -209,8 +222,8 @@ void cdb_open_databases(void) {
        }
        dbenv->set_errpfx(dbenv, "citserver");
        dbenv->set_paniccall(dbenv, dbpanic);
-       dbenv->set_errcall(dbenv, cdb_verbose_err);
-       dbenv->set_msgcall(dbenv, cdb_verbose_log);
+       dbenv->set_errcall(dbenv, bdb_verbose_err);
+       dbenv->set_msgcall(dbenv, bdb_verbose_log);
        dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK, 1);
        dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, 1);
 
@@ -277,7 +290,7 @@ void cdb_open_databases(void) {
 
 
 // Make sure we own all the files, because in a few milliseconds we're going to drop root privs.
-void cdb_chmod_data(void) {
+void bdb_chmod_data(void) {
        DIR *dp;
        struct dirent *d;
        char filename[PATH_MAX];
@@ -297,7 +310,7 @@ void cdb_chmod_data(void) {
 
 
 // Close all of the db database files we've opened.  This can be done in a loop, since it's just a bunch of closes.
-void cdb_close_databases(void) {
+void bdb_close_databases(void) {
        int i;
        int ret;
 
@@ -336,7 +349,7 @@ void cdb_close_databases(void) {
 
 
 // Decompress a database item if it was compressed on disk
-void cdb_decompress_if_necessary(struct cdbdata *cdb) {
+void bdb_decompress_if_necessary(struct cdbdata *cdb) {
        static int magic = COMPRESS_MAGIC;
 
        if ((cdb == NULL) || (cdb->ptr == NULL) || (cdb->len < sizeof(magic)) || (memcmp(cdb->ptr, &magic, sizeof(magic)))) {
@@ -368,7 +381,7 @@ void cdb_decompress_if_necessary(struct cdbdata *cdb) {
        if (uncompress((Bytef *) uncompressed_data,
                       (uLongf *) &destLen, (const Bytef *) compressed_data, (uLong) sourceLen) != Z_OK) {
                syslog(LOG_ERR, "bdb: uncompress() error");
-               cdb_abort();
+               bdb_abort();
        }
 
        free(cdb->ptr);
@@ -379,7 +392,7 @@ void cdb_decompress_if_necessary(struct cdbdata *cdb) {
 
 // Store a piece of data.  Returns 0 if the operation was successful.  If a
 // key already exists it should be overwritten.
-int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen) {
+int bdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen) {
 
        DBT dkey, ddata;
        DB_TXN *tid = NULL;
@@ -408,7 +421,7 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
                compressed_data = malloc(buffer_len);
                if (compress2((Bytef *) (compressed_data + sizeof(struct CtdlCompressHeader)), &destLen, (Bytef *) cdata, (uLongf) cdatalen, 1) != Z_OK) {
                        syslog(LOG_ERR, "bdb: compress2() error");
-                       cdb_abort();
+                       bdb_abort();
                }
                zheader.compressed_len = (size_t) destLen;
                memcpy(compressed_data, &zheader, sizeof(struct CtdlCompressHeader));
@@ -424,8 +437,8 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
                                    0           // flags
                );
                if (ret) {
-                       syslog(LOG_ERR, "bdb: cdb_store(%d): %s", cdb, db_strerror(ret));
-                       cdb_abort();
+                       syslog(LOG_ERR, "bdb: bdb_store(%d): %s", cdb, db_strerror(ret));
+                       bdb_abort();
                }
                if (compressing) {
                        free(compressed_data);
@@ -448,8 +461,8 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
                                goto retry;
                        }
                        else {
-                               syslog(LOG_ERR, "bdb: cdb_store(%d): %s", cdb, db_strerror(ret));
-                               cdb_abort();
+                               syslog(LOG_ERR, "bdb: bdb_store(%d): %s", cdb, db_strerror(ret));
+                               bdb_abort();
                        }
                }
                else {
@@ -465,7 +478,7 @@ int cdb_store(int cdb, const void *ckey, int ckeylen, void *cdata, int cdatalen)
 
 
 // Delete a piece of data.  Returns 0 if the operation was successful.
-int cdb_delete(int cdb, void *key, int keylen) {
+int bdb_delete(int cdb, void *key, int keylen) {
        DBT dkey;
        DB_TXN *tid;
        int ret;
@@ -477,9 +490,9 @@ int cdb_delete(int cdb, void *key, int keylen) {
        if (TSD->tid != NULL) {
                ret = dbp[cdb]->del(dbp[cdb], TSD->tid, &dkey, 0);
                if (ret) {
-                       syslog(LOG_ERR, "bdb: cdb_delete(%d): %s", cdb, db_strerror(ret));
+                       syslog(LOG_ERR, "bdb: bdb_delete(%d): %s", cdb, db_strerror(ret));
                        if (ret != DB_NOTFOUND) {
-                               cdb_abort();
+                               bdb_abort();
                        }
                }
        }
@@ -495,8 +508,8 @@ int cdb_delete(int cdb, void *key, int keylen) {
                                goto retry;
                        }
                        else {
-                               syslog(LOG_ERR, "bdb: cdb_delete(%d): %s", cdb, db_strerror(ret));
-                               cdb_abort();
+                               syslog(LOG_ERR, "bdb: bdb_delete(%d): %s", cdb, db_strerror(ret));
+                               bdb_abort();
                        }
                }
                else {
@@ -520,7 +533,7 @@ static DBC *localcursor(int cdb) {
 
        if (ret) {
                syslog(LOG_ERR, "bdb: localcursor: %s", db_strerror(ret));
-               cdb_abort();
+               bdb_abort();
        }
 
        return curs;
@@ -529,7 +542,7 @@ static DBC *localcursor(int cdb) {
 
 // Fetch a piece of data.  If not found, returns NULL.  Otherwise, it returns
 // a struct cdbdata which it is the caller's responsibility to free later on
-// using the cdb_free() routine.
+// using the bdb_free() routine.
 struct cdbdata *bdb_fetch(int cdb, const void *key, int keylen) {
 
        if (keylen == 0) {              // key length zero is impossible
@@ -562,8 +575,8 @@ struct cdbdata *bdb_fetch(int cdb, const void *key, int keylen) {
        }
 
        if ((ret != 0) && (ret != DB_NOTFOUND)) {
-               syslog(LOG_ERR, "bdb: cdb_fetch(%d): %s", cdb, db_strerror(ret));
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_fetch(%d): %s", cdb, db_strerror(ret));
+               bdb_abort();
        }
 
        if (ret != 0) {
@@ -572,13 +585,13 @@ struct cdbdata *bdb_fetch(int cdb, const void *key, int keylen) {
 
        tempcdb = (struct cdbdata *) malloc(sizeof(struct cdbdata));
        if (tempcdb == NULL) {
-               syslog(LOG_ERR, "bdb: cdb_fetch() cannot allocate memory for tempcdb: %m");
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_fetch() cannot allocate memory for tempcdb: %m");
+               bdb_abort();
        }
        else {
                tempcdb->len = dret.size;
                tempcdb->ptr = dret.data;
-               cdb_decompress_if_necessary(tempcdb);
+               bdb_decompress_if_necessary(tempcdb);
                return (tempcdb);
        }
 }
@@ -588,9 +601,9 @@ struct cdbdata *bdb_fetch(int cdb, const void *key, int keylen) {
 //
 // Note that we only free the 'ptr' portion if it is not NULL.  This allows
 // other code to assume ownership of that memory simply by storing the
-// pointer elsewhere and then setting 'ptr' to NULL.  cdb_free() will then
+// pointer elsewhere and then setting 'ptr' to NULL.  bdb_free() will then
 // avoid freeing it.
-void cdb_free(struct cdbdata *cdb) {
+void bdb_free(struct cdbdata *cdb) {
        if (cdb->ptr) {
                free(cdb->ptr);
        }
@@ -598,7 +611,7 @@ void cdb_free(struct cdbdata *cdb) {
 }
 
 
-void cdb_close_cursor(int cdb) {
+void bdb_close_cursor(int cdb) {
        if (TSD->cursors[cdb] != NULL) {
                cclose(TSD->cursors[cdb]);
        }
@@ -614,23 +627,23 @@ void bdb_rewind(int cdb) {
        int ret = 0;
 
        if (TSD->cursors[cdb] != NULL) {
-               syslog(LOG_ERR, "bdb: cdb_rewind: must close cursor on database %d before reopening", cdb);
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_rewind: must close cursor on database %d before reopening", cdb);
+               bdb_abort();
                // cclose(TSD->cursors[cdb]);
        }
 
        // Now initialize the cursor
        ret = dbp[cdb]->cursor(dbp[cdb], TSD->tid, &TSD->cursors[cdb], 0);
        if (ret) {
-               syslog(LOG_ERR, "bdb: cdb_rewind: db_cursor: %s", db_strerror(ret));
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_rewind: db_cursor: %s", db_strerror(ret));
+               bdb_abort();
        }
 }
 
 
 // Fetch the next item in a sequential search.  Returns a pointer to a 
 // cdbdata structure, or NULL if we've hit the end.
-struct cdbdata *cdb_next_item(int cdb) {
+struct cdbdata *bdb_next_item(int cdb) {
        DBT key, data;
        struct cdbdata *cdbret;
        int ret = 0;
@@ -644,49 +657,49 @@ struct cdbdata *cdb_next_item(int cdb) {
 
        if (ret) {
                if (ret != DB_NOTFOUND) {
-                       syslog(LOG_ERR, "bdb: cdb_next_item(%d): %s", cdb, db_strerror(ret));
-                       cdb_abort();
+                       syslog(LOG_ERR, "bdb: bdb_next_item(%d): %s", cdb, db_strerror(ret));
+                       bdb_abort();
                }
-               cdb_close_cursor(cdb);
+               bdb_close_cursor(cdb);
                return NULL;    // presumably, end of file
        }
 
        cdbret = (struct cdbdata *) malloc(sizeof(struct cdbdata));
        cdbret->len = data.size;
        cdbret->ptr = data.data;
-       cdb_decompress_if_necessary(cdbret);
+       bdb_decompress_if_necessary(cdbret);
 
        return (cdbret);
 }
 
 
 // Transaction-based stuff.  I'm writing this as I bake cookies...
-void cdb_begin_transaction(void) {
+void bdb_begin_transaction(void) {
        bailIfCursor(TSD->cursors, "can't begin transaction during r/o cursor");
 
        if (TSD->tid != NULL) {
-               syslog(LOG_ERR, "bdb: cdb_begin_transaction: ERROR: nested transaction");
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_begin_transaction: ERROR: nested transaction");
+               bdb_abort();
        }
 
        txbegin(&TSD->tid);
 }
 
 
-void cdb_end_transaction(void) {
+void bdb_end_transaction(void) {
        int i;
 
        for (i = 0; i < MAXCDB; i++) {
                if (TSD->cursors[i] != NULL) {
-                       syslog(LOG_WARNING, "bdb: cdb_end_transaction: WARNING: cursor %d still open at transaction end", i);
+                       syslog(LOG_WARNING, "bdb: bdb_end_transaction: WARNING: cursor %d still open at transaction end", i);
                        cclose(TSD->cursors[i]);
                        TSD->cursors[i] = NULL;
                }
        }
 
        if (TSD->tid == NULL) {
-               syslog(LOG_ERR, "bdb: cdb_end_transaction: ERROR: txcommit(NULL) !!");
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_end_transaction: ERROR: txcommit(NULL) !!");
+               bdb_abort();
        }
        else {
                txcommit(TSD->tid);
@@ -697,13 +710,13 @@ void cdb_end_transaction(void) {
 
 
 // Truncate (delete every record)
-void cdb_trunc(int cdb) {
+void bdb_trunc(int cdb) {
        int ret;
        u_int32_t count;
 
        if (TSD->tid != NULL) {
-               syslog(LOG_ERR, "bdb: cdb_trunc must not be called in a transaction.");
-               cdb_abort();
+               syslog(LOG_ERR, "bdb: bdb_trunc must not be called in a transaction.");
+               bdb_abort();
        }
        else {
                bailIfCursor(TSD->cursors, "attempt to write during r/o cursor");
@@ -718,7 +731,7 @@ void cdb_trunc(int cdb) {
                                goto retry;
                        }
                        else {
-                               syslog(LOG_ERR, "bdb: cdb_truncate(%d): %s", cdb, db_strerror(ret));
+                               syslog(LOG_ERR, "bdb: bdb_truncate(%d): %s", cdb, db_strerror(ret));
                                if (ret == ENOMEM) {
                                        syslog(LOG_ERR, "bdb: You may need to tune your database; please read http://www.citadel.org for more information.");
                                }
@@ -734,7 +747,7 @@ void bdb_compact(void) {
        int ret;
        int i;
 
-       syslog(LOG_DEBUG, "bdb: cdb_compact() started");
+       syslog(LOG_DEBUG, "bdb: bdb_compact() started");
        for (i = 0; i < MAXCDB; i++) {
                syslog(LOG_DEBUG, "bdb: compacting database %d", i);
                ret = dbp[i]->compact(dbp[i], NULL, NULL, NULL, NULL, DB_FREE_SPACE, NULL);
@@ -742,7 +755,7 @@ void bdb_compact(void) {
                        syslog(LOG_ERR, "bdb: compact: %s", db_strerror(ret));
                }
        }
-       syslog(LOG_DEBUG, "bdb: cdb_compact() finished");
+       syslog(LOG_DEBUG, "bdb: bdb_compact() finished");
 }
 
 
@@ -751,5 +764,18 @@ void cdb_init_backends(void) {
        cdb_checkpoint = bdb_checkpoint;
        cdb_rewind = bdb_rewind;
        cdb_fetch = bdb_fetch;
+       cdb_open_databases = bdb_open_databases;
+       cdb_close_databases = bdb_close_databases;
+       cdb_store = bdb_store;
+       cdb_delete = bdb_delete;
+       cdb_free = bdb_free;
+       cdb_next_item = bdb_next_item;
+       cdb_close_cursor = bdb_close_cursor;
+       cdb_begin_transaction = bdb_begin_transaction;
+       cdb_end_transaction = bdb_end_transaction;
+       cdb_check_handles = bdb_check_handles;
+       cdb_trunc = bdb_trunc;
+       cdb_chmod_data = bdb_chmod_data;
+
        syslog(LOG_INFO, "db: initialized Berkeley DB backend");
 }