cdb_fetch() and cdb_next_item() now return a struct cdbdata instead of a pointer...
authorArt Cancro <ajc@citadel.org>
Mon, 21 Aug 2023 20:45:38 +0000 (11:45 -0900)
committerArt Cancro <ajc@citadel.org>
Mon, 21 Aug 2023 20:45:38 +0000 (11:45 -0900)
16 files changed:
citadel/server/backends/berkeley_db/berkeley_db.c
citadel/server/config.c
citadel/server/control.c
citadel/server/database.c
citadel/server/database.h
citadel/server/euidindex.c
citadel/server/internet_addressing.c
citadel/server/modules/ctdlproto/serv_rooms.c
citadel/server/modules/ctdlproto/serv_user.c
citadel/server/modules/expire/serv_expire.c
citadel/server/modules/fulltext/serv_fulltext.c
citadel/server/modules/imap/imap_acl.c
citadel/server/msgbase.c
citadel/server/room_ops.c
citadel/server/user_ops.c
citadel/server/usetable.c

index 60063099e47cd3453a053b1fab5935ec563f0e03..7656e4f8be0bfb30a71e0c14bf7a7063cc5afa24 100644 (file)
@@ -522,13 +522,15 @@ static DBC *bdb_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 bdb_free() routine.
-struct cdbdata *bdb_fetch(int cdb, const void *key, int keylen) {
+struct cdbdata bdb_fetch(int cdb, const void *key, int keylen) {
+
+       struct cdbdata returned_data;
+       memset(&returned_data, 0, sizeof(struct cdbdata));
 
        if (keylen == 0) {              // key length zero is impossible
-               return(NULL);
+               return(returned_data);
        }
 
-       struct cdbdata *tempcdb;
        DBT dkey;
        int ret;
 
@@ -556,22 +558,13 @@ struct cdbdata *bdb_fetch(int cdb, const void *key, int keylen) {
                bdb_abort();
        }
 
-       if (ret != 0) {
-               return NULL;
+       if (ret == 0) {
+               bdb_decompress_if_necessary(&TSD->dbdata[cdb]);
+               returned_data.len = TSD->dbdata[cdb].size;
+               returned_data.ptr = TSD->dbdata[cdb].data;
        }
 
-       bdb_decompress_if_necessary(&TSD->dbdata[cdb]);
-
-       tempcdb = (struct cdbdata *) malloc(sizeof(struct cdbdata));
-       if (tempcdb == NULL) {
-               syslog(LOG_ERR, "bdb: bdb_fetch() cannot allocate memory for tempcdb: %m");
-               bdb_abort();
-       }
-       else {
-               tempcdb->len = TSD->dbdata[cdb].size;
-               tempcdb->ptr = TSD->dbdata[cdb].data;
-               return (tempcdb);
-       }
+       return(returned_data);
 }
 
 
@@ -612,10 +605,12 @@ void bdb_rewind(int cdb) {
 
 // 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 *bdb_next_item(int cdb) {
-       struct cdbdata *cdbret;
+struct cdbdata bdb_next_item(int cdb) {
+       struct cdbdata cdbret;
        int ret = 0;
 
+       memset(&cdbret, 0, sizeof(struct cdbdata));
+
        // reuse memory from the previous call.
        TSD->dbkey[cdb].flags = DB_DBT_MALLOC;
        TSD->dbdata[cdb].flags = DB_DBT_MALLOC;
@@ -628,14 +623,13 @@ struct cdbdata *bdb_next_item(int cdb) {
                        bdb_abort();
                }
                bdb_close_cursor(cdb);
-               return NULL;    // presumably, we are at the end
+               return(cdbret);         // presumably, we are at the end
        }
 
        bdb_decompress_if_necessary(&TSD->dbdata[cdb]);
 
-       cdbret = (struct cdbdata *) malloc(sizeof(struct cdbdata));
-       cdbret->len = TSD->dbdata[cdb].size;
-       cdbret->ptr = TSD->dbdata[cdb].data;
+       cdbret.len = TSD->dbdata[cdb].size;
+       cdbret.ptr = TSD->dbdata[cdb].data;
 
        return (cdbret);
 }
index 670e6e224b30a73a72fa82eac83b9d9fcd40dcf7..fc3d49ce75da654b7a91c2554db6600e6ef64d72 100644 (file)
@@ -362,7 +362,7 @@ void CtdlDelConfig(char *key) {
 // Fetch a system config value.  Caller does *not* own the returned value and may not alter it.
 char *CtdlGetConfigStr(char *key) {
        char *value = NULL;
-       struct cdbdata *cdb;
+       struct cdbdata cdb;
        int key_len = strlen(key);
 
        if (IsEmptyStr(key)) return(NULL);
@@ -374,13 +374,12 @@ char *CtdlGetConfigStr(char *key) {
 
        // Then look in the database.
        cdb = cdb_fetch(CDB_CONFIG, key, key_len);
-       if (cdb == NULL) {      // nope, not there either.
+       if (cdb.len <= 0) {     // nope, not there either.
                return(NULL);
        }
 
        // Got it.  Save it in memory for the next fetch.
-       value = strdup(cdb->ptr + key_len + 1);         // The key was stored there too; skip past it
-       cdb_free(cdb);
+       value = strdup(cdb.ptr + key_len + 1);          // The key was stored there too; skip past it
        Put(ctdlconfig, key, key_len, value, NULL);
        return value;
 }
index 5daef726ea18a3193cb50c330976bd07783cb3d9..3427240e1f98412f9f14484e724181448e91cb0e 100644 (file)
@@ -639,21 +639,20 @@ void cmd_conf(char *argbuf) {
 
        // CONF LISTVAL - list configuration variables in the database and their values
        else if (!strcasecmp(cmd, "LISTVAL")) {
-               struct cdbdata *cdbcfg;
+               struct cdbdata cdbcfg;
                int keylen = 0;
                char *key = NULL;
                char *value = NULL;
        
                cprintf("%d all configuration variables\n", LISTING_FOLLOWS);
                cdb_rewind(CDB_CONFIG);
-               while (cdbcfg = cdb_next_item(CDB_CONFIG), cdbcfg != NULL) {
-                       if (cdbcfg->len < 1020) {
-                               keylen = strlen(cdbcfg->ptr);
-                               key = cdbcfg->ptr;
-                               value = cdbcfg->ptr + keylen + 1;
+               while (cdbcfg = cdb_next_item(CDB_CONFIG), cdbcfg.len>0) {
+                       if (cdbcfg.len < 1020) {
+                               keylen = strlen(cdbcfg.ptr);
+                               key = cdbcfg.ptr;
+                               value = cdbcfg.ptr + keylen + 1;
                                cprintf("%s|%s\n", key, value);
                        }
-                       cdb_free(cdbcfg);
                }
                cprintf("000\n");
        }
index b3701b4b6a78a7754264bd49178ad4c86ee0bdff..7f6a612aab3bfaafa42dc30916f20b77899ba9be 100644 (file)
 // The initialization function of the selected backend will map them.
 void                   (*cdb_open_databases)(void)                             = NULL;
 void                   (*cdb_close_databases)(void)                            = NULL;
+struct cdbdata                 (*cdb_fetch)(int, const void *, int)                    = 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;
+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;
@@ -37,7 +38,6 @@ 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;
 
 // This function is responsible for choosing and initializing a back end.
 void cdb_init_backends(void) {
index 9b38d844b5cba265f4224566cbe30e5d53fc2047..d5d1ee802946796eeb0ac627719187382911b65a 100644 (file)
@@ -14,14 +14,14 @@ 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 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            (*check_handles)(void *);
-extern struct cdbdata *        (*cdb_fetch)(int, const void *, int);
+extern struct cdbdata  (*cdb_fetch)(int, const void *, int);
 extern void            (*cdb_checkpoint)(void);
 extern void            (*cdb_compact)(void);
 extern void            (*cdb_rewind)(int);
index b992d6f82c8e16648e937eb311ee22c4c3952fe9..2ebd2048430aa13af79819adf85ba43c37a6114d 100644 (file)
@@ -1,6 +1,6 @@
 // Index messages by EUID per room.
 //
-// Copyright (c) 1987-2022 by the citadel.org team
+// Copyright (c) 1987-2023 by the citadel.org team
 //
 // This program is open source software.  Use, duplication, or disclosure
 // is subject to the terms of the GNU General Public License, version 3.
@@ -52,7 +52,7 @@ long locate_message_by_euid(char *euid, struct ctdlroom *qrbuf) {
 long CtdlLocateMessageByEuid(char *euid, struct ctdlroom *qrbuf) {
        char *key;
        int key_len;
-       struct cdbdata *cdb_euid;
+       struct cdbdata cdb_euid;
        long msgnum = (-1L);
 
        syslog(LOG_DEBUG, "euidindex: searching for EUID <%s> in <%s>", euid, qrbuf->QRname);
@@ -65,13 +65,12 @@ long CtdlLocateMessageByEuid(char *euid, struct ctdlroom *qrbuf) {
        cdb_euid = cdb_fetch(CDB_EUIDINDEX, key, key_len);
        free(key);
 
-       if (cdb_euid == NULL) {
+       if (cdb_euid.len == 0) {
                msgnum = (-1L);
        }
        else {
                // The first (sizeof long) of the record is what we're looking for.  Throw away the rest.
-               memcpy(&msgnum, cdb_euid->ptr, sizeof(long));
-               cdb_free(cdb_euid);
+               memcpy(&msgnum, cdb_euid.ptr, sizeof(long));
        }
        syslog(LOG_DEBUG, "euidindex: returning msgnum = %ld", msgnum);
        return(msgnum);
index 4b78eba24282422857bfad0a03411d9058c30272..2a4b0a56777d2a8fc170ea977a5b7ebdff5d0713 100644 (file)
@@ -1235,7 +1235,7 @@ int CtdlDirectoryDelUser(char *internet_addr, char *citadel_addr) {
  * On failure: returns nonzero
  */
 int CtdlDirectoryLookup(char *target, char *internet_addr, size_t targbuflen) {
-       struct cdbdata *cdbrec;
+       struct cdbdata cdbrec;
        char key[SIZ];
 
        /* Dump it in there unchanged, just for kicks */
@@ -1251,11 +1251,10 @@ int CtdlDirectoryLookup(char *target, char *internet_addr, size_t targbuflen) {
 
        directory_key(key, internet_addr);
        cdbrec = cdb_fetch(CDB_DIRECTORY, key, strlen(key) );
-       if (cdbrec != NULL) {
+       if (cdbrec.len == 0) {
                if (target != NULL) {
-                       safestrncpy(target, cdbrec->ptr, targbuflen);
+                       safestrncpy(target, cdbrec.ptr, targbuflen);
                }
-               cdb_free(cdbrec);
                return(0);
        }
 
index 1ca2fc04fd99d16897bea1a83cbdde0b2cd612dc..d81a4e1e2e292f83d98f7bc7f58f9491d005347c 100644 (file)
@@ -322,15 +322,14 @@ void cmd_goto(char *gargs) {
 
 void cmd_whok(char *cmdbuf) {
        struct ctdluser temp;
-       struct cdbdata *cdbus;
+       struct cdbdata cdbus;
        int ra;
 
        cprintf("%d Who knows room:\n", LISTING_FOLLOWS);
        cdb_rewind(CDB_USERS);
-       while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
+       while (cdbus = cdb_next_item(CDB_USERS), cdbus.len>0) {
                memset(&temp, 0, sizeof temp);
-               memcpy(&temp, cdbus->ptr, sizeof temp);
-               cdb_free(cdbus);
+               memcpy(&temp, cdbus.ptr, sizeof temp);
 
                CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
                if ((!IsEmptyStr(temp.fullname)) && 
index f5f4ef525faaad5118cc7cc430dd75845f6f3396..f3c5c33a730ddd9388fd9592a7e0a259212324e3 100644 (file)
@@ -381,7 +381,7 @@ void cmd_forg(char *argbuf) {
 
 // Get Next Unregistered User
 void cmd_gnur(char *argbuf) {
-       struct cdbdata *cdbus;
+       struct cdbdata cdbus;
        struct ctdluser usbuf;
 
        if (CtdlAccessCheck(ac_aide)) {
@@ -395,10 +395,9 @@ void cmd_gnur(char *argbuf) {
 
        // There are unvalidated users.  Traverse the user database, and return the first user we find that needs validation.
        cdb_rewind(CDB_USERS);
-       while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
+       while (cdbus = cdb_next_item(CDB_USERS), cdbus.len>0) {
                memset(&usbuf, 0, sizeof(struct ctdluser));
-               memcpy(&usbuf, cdbus->ptr, ((cdbus->len > sizeof(struct ctdluser)) ?  sizeof(struct ctdluser) : cdbus->len));
-               cdb_free(cdbus);
+               memcpy(&usbuf, cdbus.ptr, ((cdbus.len > sizeof(struct ctdluser)) ?  sizeof(struct ctdluser) : cdbus.len));
                if ((usbuf.flags & US_NEEDVALID) && (usbuf.axlevel > AxDeleted)) {
                        cprintf("%d %s\n", MORE_DATA, usbuf.fullname);
                        cdb_close_cursor(CDB_USERS);
index af53a1ed3189246876df27789f8c1972093f3128..bda629bf35887a6db7bd460017d2001303bceb03 100644 (file)
@@ -486,7 +486,7 @@ int PurgeUsers(void) {
 // record is useless and should be removed.)
 //
 int PurgeVisits(void) {
-       struct cdbdata *cdbvisit;
+       struct cdbdata cdbvisit;
        struct visit vbuf;
        struct VPurgeList *VisitPurgeList = NULL;
        struct VPurgeList *vptr;
@@ -505,12 +505,11 @@ int PurgeVisits(void) {
 
        // Now traverse through the visits, purging irrelevant records...
        cdb_rewind(CDB_VISIT);
-       while(cdbvisit = cdb_next_item(CDB_VISIT), cdbvisit != NULL) {
+       while(cdbvisit = cdb_next_item(CDB_VISIT), cdbvisit.len>0) {
                memset(&vbuf, 0, sizeof(struct visit));
-               memcpy(&vbuf, cdbvisit->ptr,
-                       ( (cdbvisit->len > sizeof(struct visit)) ?
-                         sizeof(struct visit) : cdbvisit->len) );
-               cdb_free(cdbvisit);
+               memcpy(&vbuf, cdbvisit.ptr,
+                       ( (cdbvisit.len > sizeof(struct visit)) ?
+                         sizeof(struct visit) : cdbvisit.len) );
 
                RoomIsValid = 0;
                UserIsValid = 0;
@@ -577,7 +576,7 @@ int PurgeVisits(void) {
 int PurgeUseTable(StrBuf *ErrMsg) {
        int purged = 0;
        int total = 0;
-       struct cdbdata *cdbut;
+       struct cdbdata cdbut;
        struct UseTable ut;
        Array *purge_list = array_new(sizeof(int));
 
@@ -585,15 +584,14 @@ int PurgeUseTable(StrBuf *ErrMsg) {
 
        syslog(LOG_DEBUG, "Purge use table: phase 1");
        cdb_rewind(CDB_USETABLE);
-       while(cdbut = cdb_next_item(CDB_USETABLE), cdbut != NULL) {
+       while(cdbut = cdb_next_item(CDB_USETABLE), cdbut.len>0) {
                ++total;
-               if (cdbut->len > sizeof(struct UseTable))
-                       memcpy(&ut, cdbut->ptr, sizeof(struct UseTable));
+               if (cdbut.len > sizeof(struct UseTable))
+                       memcpy(&ut, cdbut.ptr, sizeof(struct UseTable));
                else {
                        memset(&ut, 0, sizeof(struct UseTable));
-                       memcpy(&ut, cdbut->ptr, cdbut->len);
+                       memcpy(&ut, cdbut.ptr, cdbut.len);
                }
-               cdb_free(cdbut);
 
                if ( (time(NULL) - ut.timestamp) > USETABLE_RETAIN ) {
                        array_append(purge_list, &ut.hash);
@@ -618,7 +616,7 @@ int PurgeUseTable(StrBuf *ErrMsg) {
 // Purge the EUID Index of old records.
 int PurgeEuidIndexTable(void) {
        int purged = 0;
-       struct cdbdata *cdbei;
+       struct cdbdata cdbei;
        struct EPurgeList *el = NULL;
        struct EPurgeList *eptr; 
        long msgnum;
@@ -627,9 +625,9 @@ int PurgeEuidIndexTable(void) {
        // Phase 1: traverse through the table, discovering old records...
        syslog(LOG_DEBUG, "Purge EUID index: phase 1");
        cdb_rewind(CDB_EUIDINDEX);
-       while(cdbei = cdb_next_item(CDB_EUIDINDEX), cdbei != NULL) {
+       while(cdbei = cdb_next_item(CDB_EUIDINDEX), cdbei.len>0) {
 
-               memcpy(&msgnum, cdbei->ptr, sizeof(long));
+               memcpy(&msgnum, cdbei.ptr, sizeof(long));
 
                msg = CtdlFetchMessage(msgnum, 0);
                if (msg != NULL) {
@@ -639,15 +637,14 @@ int PurgeEuidIndexTable(void) {
                        eptr = (struct EPurgeList *) malloc(sizeof(struct EPurgeList));
                        if (eptr != NULL) {
                                eptr->next = el;
-                               eptr->ep_keylen = cdbei->len - sizeof(long);
-                               eptr->ep_key = malloc(cdbei->len);
-                               memcpy(eptr->ep_key, &cdbei->ptr[sizeof(long)], eptr->ep_keylen);
+                               eptr->ep_keylen = cdbei.len - sizeof(long);
+                               eptr->ep_key = malloc(cdbei.len);
+                               memcpy(eptr->ep_key, &cdbei.ptr[sizeof(long)], eptr->ep_keylen);
                                el = eptr;
                        }
                        ++purged;
                }
 
-              cdb_free(cdbei);
 
        }
 
index e1558f445cbf4b5d6cb8535f5751c474824c2391..b7a497801e1974831df795dafc01ee17954b04df 100644 (file)
@@ -81,7 +81,7 @@ void ft_index_message(long msgnum, int op) {
        int num_tokens = 0;
        int *tokens = NULL;
        int i, j;
-       struct cdbdata *cdb_bucket;
+       struct cdbdata cdb_bucket;
        StrBuf *msgtext;
        char *txt;
        int tok;
@@ -128,11 +128,10 @@ void ft_index_message(long msgnum, int op) {
                                // fetch the bucket, Liza
                                if (ftc_msgs[tok] == NULL) {
                                        cdb_bucket = cdb_fetch(CDB_FULLTEXT, &tok, sizeof(int));
-                                       if (cdb_bucket != NULL) {
-                                               ftc_num_msgs[tok] = cdb_bucket->len / sizeof(long);
-                                               ftc_msgs[tok] = malloc(cdb_bucket->len);
-                                               memcpy(ftc_msgs[tok], cdb_bucket->ptr, cdb_bucket->len);
-                                               cdb_free(cdb_bucket);
+                                       if (cdb_bucket.len > 0) {
+                                               ftc_num_msgs[tok] = cdb_bucket.len / sizeof(long);
+                                               ftc_msgs[tok] = malloc(cdb_bucket.len);
+                                               memcpy(ftc_msgs[tok], cdb_bucket.ptr, cdb_bucket.len);
                                        }
                                        else {
                                                ftc_num_msgs[tok] = 0;
@@ -293,7 +292,7 @@ void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string) {
        int num_tokens = 0;
        int *tokens = NULL;
        int i, j;
-       struct cdbdata *cdb_bucket;
+       struct cdbdata cdb_bucket;
        int num_all_msgs = 0;
        long *all_msgs = NULL;
        int num_ret_msgs = 0;
@@ -311,11 +310,10 @@ void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string) {
                        // fetch the bucket, Liza
                        if (ftc_msgs[tok] == NULL) {
                                cdb_bucket = cdb_fetch(CDB_FULLTEXT, &tok, sizeof(int));
-                               if (cdb_bucket != NULL) {
-                                       ftc_num_msgs[tok] = cdb_bucket->len / sizeof(long);
-                                       ftc_msgs[tok] = (long *) malloc(cdb_bucket->len);
-                                       memcpy(ftc_msgs[tok], cdb_bucket->ptr, cdb_bucket->len);
-                                       cdb_free(cdb_bucket);
+                               if (cdb_bucket.len > 0) {
+                                       ftc_num_msgs[tok] = cdb_bucket.len / sizeof(long);
+                                       ftc_msgs[tok] = (long *) malloc(cdb_bucket.len);
+                                       memcpy(ftc_msgs[tok], cdb_bucket.ptr, cdb_bucket.len);
                                }
                                else {
                                        ftc_num_msgs[tok] = 0;
index 1cb6337f8cdfd0818c77cfd43e7d48ebe6c8a601..bcaacbce82303e24f6dd6c5c263d65c4089538c7 100644 (file)
@@ -107,7 +107,7 @@ void imap_getacl(int num_parms, ConstStr *Params) {
        int msgs, new;
        int ret;
        struct ctdluser temp;
-       struct cdbdata *cdbus;
+       struct cdbdata cdbus;
        int ra;
        StrBuf *rights;
 
@@ -136,10 +136,9 @@ void imap_getacl(int num_parms, ConstStr *Params) {
        // Traverse the userlist
        rights = NewStrBuf();
        cdb_rewind(CDB_USERS);
-       while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
+       while (cdbus = cdb_next_item(CDB_USERS), cdbus.len > 0) {
                memset(&temp, 0, sizeof temp);
-               memcpy(&temp, cdbus->ptr, sizeof temp);
-               cdb_free(cdbus);
+               memcpy(&temp, cdbus.ptr, sizeof temp);
 
                CtdlRoomAccess(&CC->room, &temp, &ra, NULL);
                if (!IsEmptyStr(temp.fullname)) {
index 5e054ac86b5077f219621f95485897fad9d660db..a1d003abf0bd6b3439ed3736f5448248956017be 100644 (file)
@@ -1104,25 +1104,23 @@ struct CtdlMessage *CtdlDeserializeMessage(long msgnum, int with_body, const cha
 //       using the CM_Free(); function.
 //
 struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) {
-       struct cdbdata *dmsgtext;
+       struct cdbdata dmsgtext;
        struct CtdlMessage *ret = NULL;
 
        syslog(LOG_DEBUG, "msgbase: CtdlFetchMessage(%ld, %d)", msgnum, with_body);
        dmsgtext = cdb_fetch(CDB_MSGMAIN, &msgnum, sizeof(long));
-       if (dmsgtext == NULL) {
+       if (dmsgtext.len == 0) {
                syslog(LOG_ERR, "msgbase: message #%ld was not found", msgnum);
                return NULL;
        }
 
-       if (dmsgtext->ptr[dmsgtext->len - 1] != '\0') {
+       if (dmsgtext.ptr[dmsgtext.len - 1] != '\0') {
+               // FIXME LMDB cannot write to immutable memory
                syslog(LOG_ERR, "msgbase: CtdlFetchMessage(%ld, %d) Forcefully terminating message!!", msgnum, with_body);
-               dmsgtext->ptr[dmsgtext->len - 1] = '\0';
+               dmsgtext.ptr[dmsgtext.len - 1] = '\0';
        }
 
-       ret = CtdlDeserializeMessage(msgnum, with_body, dmsgtext->ptr, dmsgtext->len);
-
-       cdb_free(dmsgtext);
-
+       ret = CtdlDeserializeMessage(msgnum, with_body, dmsgtext.ptr, dmsgtext.len);
        if (ret == NULL) {
                return NULL;
        }
@@ -1134,9 +1132,8 @@ struct CtdlMessage *CtdlFetchMessage(long msgnum, int with_body) {
        //
        if ( (CM_IsEmpty(ret, eMesageText)) && (with_body) ) {
                dmsgtext = cdb_fetch(CDB_BIGMSGS, &msgnum, sizeof(long));
-               if (dmsgtext != NULL) {
-                       CM_SetAsField(ret, eMesageText, &dmsgtext->ptr, dmsgtext->len - 1);
-                       cdb_free(dmsgtext);
+               if (dmsgtext.len > 0) {
+                       CM_SetAsField(ret, eMesageText, &dmsgtext.ptr, dmsgtext.len - 1);
                }
        }
        if (CM_IsEmpty(ret, eMesageText)) {
@@ -3298,7 +3295,7 @@ int CtdlDeleteMessages(const char *room_name,     // which room
  * GetMetaData()  -  Get the supplementary record for a message
  */
 void GetMetaData(struct MetaData *smibuf, long msgnum) {
-       struct cdbdata *cdbsmi;
+       struct cdbdata cdbsmi;
        long TheIndex;
 
        memset(smibuf, 0, sizeof(struct MetaData));
@@ -3309,14 +3306,10 @@ void GetMetaData(struct MetaData *smibuf, long msgnum) {
        TheIndex = (0L - msgnum);
 
        cdbsmi = cdb_fetch(CDB_MSGMAIN, &TheIndex, sizeof(long));
-       if (cdbsmi == NULL) {
+       if (cdbsmi.len == 0) {
                return;                 /* record not found; leave it alone */
        }
-       memcpy(smibuf, cdbsmi->ptr,
-              ((cdbsmi->len > sizeof(struct MetaData)) ?
-               sizeof(struct MetaData) : cdbsmi->len)
-       );
-       cdb_free(cdbsmi);
+       memcpy(smibuf, cdbsmi.ptr, ((cdbsmi.len > sizeof(struct MetaData)) ? sizeof(struct MetaData) : cdbsmi.len));
        return;
 }
 
index 45aa1079ff3f267a621d066a4e4e61b9e8c9925f..b45913c485bfe653b4645949f20205fb516e4a6c 100644 (file)
@@ -302,7 +302,7 @@ void room_sanity_check(struct ctdlroom *qrbuf) {
 
 // CtdlGetRoom()  -  retrieve room data from disk
 int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
-       struct cdbdata *cdbqr;
+       struct cdbdata cdbqr;
        char lowercase_name[ROOMNAMELEN];
        char personal_lowercase_name[ROOMNAMELEN];
        long len;
@@ -322,13 +322,12 @@ int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
        cdbqr = cdb_fetch(CDB_ROOMS, lowercase_name, strlen(lowercase_name));
 
        // If that didn't work, try the user's personal namespace
-       if (cdbqr == NULL) {
+       if (cdbqr.len == 0) {
                snprintf(personal_lowercase_name, sizeof personal_lowercase_name, "%010ld.%s", CC->user.usernum, lowercase_name);
                cdbqr = cdb_fetch(CDB_ROOMS, personal_lowercase_name, strlen(personal_lowercase_name));
        }
-       if (cdbqr != NULL) {
-               memcpy(qrbuf, cdbqr->ptr, ((cdbqr->len > sizeof(struct ctdlroom)) ?  sizeof(struct ctdlroom) : cdbqr->len));
-               cdb_free(cdbqr);
+       if (cdbqr.len > 0) {
+               memcpy(qrbuf, cdbqr.ptr, ((cdbqr.len > sizeof(struct ctdlroom)) ?  sizeof(struct ctdlroom) : cdbqr.len));
                room_sanity_check(qrbuf);
                return (0);
        }
@@ -432,13 +431,12 @@ int CtdlGetAvailableFloor(void) {
 
 // CtdlGetFloor()  -  retrieve floor data from disk
 void CtdlGetFloor(struct floor *flbuf, int floor_num) {
-       struct cdbdata *cdbfl;
+       struct cdbdata cdbfl;
 
        memset(flbuf, 0, sizeof(struct floor));
        cdbfl = cdb_fetch(CDB_FLOORTAB, &floor_num, sizeof(int));
-       if (cdbfl != NULL) {
-               memcpy(flbuf, cdbfl->ptr, ((cdbfl->len > sizeof(struct floor)) ?  sizeof(struct floor) : cdbfl->len));
-               cdb_free(cdbfl);
+       if (cdbfl.len > 0) {
+               memcpy(flbuf, cdbfl.ptr, ((cdbfl.len > sizeof(struct floor)) ?  sizeof(struct floor) : cdbfl.len));
        }
        else {
                if (floor_num == 0) {
@@ -525,14 +523,13 @@ void lputfloor(struct floor *flbuf, int floor_num) {
 // Iterate through the room table, performing a callback for each room.
 void CtdlForEachRoom(ForEachRoomCallBack callback_func, void *in_data) {
        struct ctdlroom qrbuf;
-       struct cdbdata *cdbqr;
+       struct cdbdata cdbqr;
 
        cdb_rewind(CDB_ROOMS);
 
-       while (cdbqr = cdb_next_item(CDB_ROOMS), cdbqr != NULL) {
+       while (cdbqr = cdb_next_item(CDB_ROOMS), cdbqr.len>0) {
                memset(&qrbuf, 0, sizeof(struct ctdlroom));
-               memcpy(&qrbuf, cdbqr->ptr, ((cdbqr->len > sizeof(struct ctdlroom)) ?  sizeof(struct ctdlroom) : cdbqr->len) );
-               cdb_free(cdbqr);
+               memcpy(&qrbuf, cdbqr.ptr, ((cdbqr.len > sizeof(struct ctdlroom)) ?  sizeof(struct ctdlroom) : cdbqr.len) );
                room_sanity_check(&qrbuf);
                if (qrbuf.QRflags & QR_INUSE) {
                        callback_func(&qrbuf, in_data);
@@ -543,14 +540,12 @@ void CtdlForEachRoom(ForEachRoomCallBack callback_func, void *in_data) {
 
 // delete_msglist()  -  delete room message pointers
 void delete_msglist(struct ctdlroom *whichroom) {
-        struct cdbdata *cdbml;
+        struct cdbdata cdbml;
 
        // Make sure the msglist we're deleting actually exists, otherwise
        // libdb will complain when we try to delete an invalid record
         cdbml = cdb_fetch(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
-        if (cdbml != NULL) {
-               cdb_free(cdbml);
-
+        if (cdbml.len > 0) {
                // Go ahead and delete it
                cdb_delete(CDB_MSGLISTS, &whichroom->QRnumber, sizeof(long));
        }
@@ -607,25 +602,24 @@ int CtdlIsNonEditable(struct ctdlroom *qrbuf) {
 // If no messages in room, returns 0 and msgs is set to NULL.
 int CtdlFetchMsgList(long roomnum, long **msgs) {
        int num_msgs = 0;
-        struct cdbdata *cdbfr;
+        struct cdbdata cdbfr;
 
         cdbfr = cdb_fetch(CDB_MSGLISTS, &roomnum, sizeof(long));
-       if (cdbfr == NULL) {
+       if (cdbfr.len == 0) {
                syslog(LOG_ERR, "room_ops: no msglist for room %ld", roomnum);
                *msgs = malloc(sizeof(long));   // dummy buffer
                *msgs[0] = 0;
                return (0);
        }
 
-               num_msgs = cdbfr->len / sizeof(long);
+               num_msgs = cdbfr.len / sizeof(long);
        if (num_msgs > 0) {
-               *msgs = malloc(cdbfr->len);
-               memcpy(*msgs, cdbfr->ptr, cdbfr->len);
+               *msgs = malloc(cdbfr.len);
+               memcpy(*msgs, cdbfr.ptr, cdbfr.len);
        }
        else {
                *msgs = NULL;
        }
-               cdb_free(cdbfr);
        return(num_msgs);
 }
 
index d6303ebcf165972b0a5c93ae234e7750ca9bff9b..76325e984cc3f8f56997cfddd5d42913a8f92462 100644 (file)
@@ -43,7 +43,7 @@ int CtdlUserCmp(char *s1, char *s2) {
 //                     returns 0 on success
 int CtdlGetUser(struct ctdluser *usbuf, char *name) {
        char usernamekey[USERNAME_SIZE];
-       struct cdbdata *cdbus;
+       struct cdbdata cdbus;
 
        if (usbuf != NULL) {
                memset(usbuf, 0, sizeof(struct ctdluser));
@@ -55,13 +55,12 @@ int CtdlGetUser(struct ctdluser *usbuf, char *name) {
        }
        cdbus = cdb_fetch(CDB_USERS, usernamekey, strlen(usernamekey));
 
-       if (cdbus == NULL) {    // user not found
+       if (cdbus.len == 0) {   // user not found
                return(1);
        }
        if (usbuf != NULL) {
-               memcpy(usbuf, cdbus->ptr, ((cdbus->len > sizeof(struct ctdluser)) ?  sizeof(struct ctdluser) : cdbus->len));
+               memcpy(usbuf, cdbus.ptr, ((cdbus.len > sizeof(struct ctdluser)) ?  sizeof(struct ctdluser) : cdbus.len));
        }
-       cdb_free(cdbus);
        return(0);
 }
 
@@ -179,7 +178,7 @@ void reindex_user_928(char *username, void *out_data) {
 
        char oldkey[USERNAME_SIZE];
        char newkey[USERNAME_SIZE];
-       struct cdbdata *cdbus;
+       struct cdbdata cdbus;
        struct ctdluser usbuf;
 
        makeuserkey_pre928(oldkey, username);
@@ -189,12 +188,11 @@ void reindex_user_928(char *username, void *out_data) {
 
        // Fetch the user record using the old index format
        cdbus = cdb_fetch(CDB_USERS, oldkey, strlen(oldkey));
-       if (cdbus == NULL) {
+       if (cdbus.len == 0) {
                syslog(LOG_INFO, "user_ops: <%s> not found, were they already reindexed?", username);
                return;
        }
-       memcpy(&usbuf, cdbus->ptr, ((cdbus->len > sizeof(struct ctdluser)) ? sizeof(struct ctdluser) : cdbus->len));
-       cdb_free(cdbus);
+       memcpy(&usbuf, cdbus.ptr, ((cdbus.len > sizeof(struct ctdluser)) ? sizeof(struct ctdluser) : cdbus.len));
 
        // delete the old record
        cdb_delete(CDB_USERS, oldkey, strlen(oldkey));
@@ -236,7 +234,7 @@ void CtdlSetRelationship(struct visit *newvisit, struct ctdluser *rel_user, stru
 
 // Locate a relationship between a user and a room
 void CtdlGetRelationship(struct visit *vbuf, struct ctdluser *rel_user, struct ctdlroom *rel_room) {
-       struct cdbdata *cdbvisit;
+       struct cdbdata cdbvisit;
 
        // Clear out the buffer
        memset(vbuf, 0, sizeof(struct visit));
@@ -247,9 +245,8 @@ void CtdlGetRelationship(struct visit *vbuf, struct ctdluser *rel_user, struct c
        vbuf->v_usernum = rel_user->usernum;
 
        cdbvisit = cdb_fetch(CDB_VISIT, vbuf, (sizeof(long)*3));
-       if (cdbvisit != NULL) {
-               memcpy(vbuf, cdbvisit->ptr, ((cdbvisit->len > sizeof(struct visit)) ?  sizeof(struct visit) : cdbvisit->len));
-               cdb_free(cdbvisit);
+       if (cdbvisit.len > 0) {
+               memcpy(vbuf, cdbvisit.ptr, ((cdbvisit.len > sizeof(struct visit)) ?  sizeof(struct visit) : cdbvisit.len));
        }
        else {
                // If this is the first time the user has seen this room, set the view to be the default for the room.
@@ -357,18 +354,17 @@ int is_room_aide(void) {
 // CtdlGetUserByNumber() - get user by number, returns 0 if user was found
 // Note: fetching a user this way requires one additional database operation.
 int CtdlGetUserByNumber(struct ctdluser *usbuf, long number) {
-       struct cdbdata *cdbun;
+       struct cdbdata cdbun;
        int r;
 
        cdbun = cdb_fetch(CDB_USERSBYNUMBER, &number, sizeof(long));
-       if (cdbun == NULL) {
+       if (cdbun.len == 0) {
                syslog(LOG_INFO, "user_ops: %ld not found", number);
                return(-1);
        }
 
-       syslog(LOG_INFO, "user_ops: %ld maps to %s", number, cdbun->ptr);
-       r = CtdlGetUser(usbuf, cdbun->ptr);
-       cdb_free(cdbun);
+       syslog(LOG_INFO, "user_ops: %ld maps to %s", number, cdbun.ptr);
+       r = CtdlGetUser(usbuf, cdbun.ptr);
        return(r);
 }
 
@@ -395,7 +391,7 @@ void rebuild_usersbynumber(void) {
 //                     Returns 0 if user was found
 int getuserbyuid(struct ctdluser *usbuf, uid_t number) {
 
-       struct cdbdata *cdbus;
+       struct cdbdata cdbus;
        struct ctdluser *usptr;
        int return_value = (-1);
 
@@ -403,8 +399,8 @@ int getuserbyuid(struct ctdluser *usbuf, uid_t number) {
        // No, we don't use CtdlForEachUser() because that requires multiple reads for each record
        // TODO: make an index
        cdb_rewind(CDB_USERS);
-       while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
-               usptr = (struct ctdluser *) cdbus->ptr;
+       while (cdbus = cdb_next_item(CDB_USERS), cdbus.len>0) {
+               usptr = (struct ctdluser *) cdbus.ptr;
 
                if (usptr->uid == number) {
                        syslog(LOG_DEBUG, "user_ops: found uid=%d username=%s", usptr->uid, usptr->fullname);
@@ -1035,7 +1031,7 @@ int CtdlForgetThisRoom(void) {
 // Traverse the user file and perform a callback for each user record.
 // (New improved version that runs in two phases so that callbacks can perform writes without having a r/o cursor open)
 void ForEachUser(void (*CallBack) (char *, void *out_data), void *in_data) {
-       struct cdbdata *cdbus;
+       struct cdbdata cdbus;
        struct ctdluser *usptr;
 
        Array *all_users = array_new(USERNAME_SIZE);
@@ -1048,8 +1044,8 @@ void ForEachUser(void (*CallBack) (char *, void *out_data), void *in_data) {
        cdb_rewind(CDB_USERS);
 
        // Phase 1 : build an array of all our user account names
-       while (cdbus = cdb_next_item(CDB_USERS), cdbus != NULL) {
-               usptr = (struct ctdluser *) cdbus->ptr;
+       while (cdbus = cdb_next_item(CDB_USERS), cdbus.len > 0) {
+               usptr = (struct ctdluser *) cdbus.ptr;
                if (strlen(usptr->fullname) > 0) {
                        array_append(all_users, usptr->fullname);
                }
index 816f76e098c4b5ca798b4dca40047f0038b3979d..6364a8fa0bf6b7b3917d79cf8bb59ff997c0a93a 100644 (file)
 int CheckIfAlreadySeen(StrBuf *guid) {
        int found = 0;
        struct UseTable ut;
-       struct cdbdata *cdbut;
+       struct cdbdata cdbut;
        int hash = HashLittle(ChrPtr(guid), StrLength(guid));
 
        syslog(LOG_DEBUG, "usetable: CheckIfAlreadySeen(0x%8x)", hash);
        cdbut = cdb_fetch(CDB_USETABLE, &hash, sizeof(hash));
-       if (cdbut != NULL) {
+       if (cdbut.len > 0) {
                found = 1;
-               cdb_free(cdbut);
        }
 
        // (Re)write the record, to update the timestamp.