From: Art Cancro Date: Wed, 23 Aug 2023 14:17:28 +0000 (-0900) Subject: cdb_next_item() now returns both key and value X-Git-Tag: v989~53 X-Git-Url: https://code.citadel.org/?a=commitdiff_plain;h=bf150835d1d9864155d9864e65c328d1f2d3b15b;p=citadel.git cdb_next_item() now returns both key and value --- diff --git a/citadel/server/backends/berkeley_db/berkeley_db.c b/citadel/server/backends/berkeley_db/berkeley_db.c index 2c118ce2b..a55c6113a 100644 --- a/citadel/server/backends/berkeley_db/berkeley_db.c +++ b/citadel/server/backends/berkeley_db/berkeley_db.c @@ -599,11 +599,11 @@ 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 cdbkeyval bdb_next_item(int cdb) { + struct cdbkeyval kv; int ret = 0; - memset(&cdbret, 0, sizeof(struct cdbdata)); + memset(&kv, 0, sizeof(struct cdbkeyval)); // reuse memory from the previous call. TSD->dbkey[cdb].flags = DB_DBT_MALLOC; @@ -617,15 +617,16 @@ struct cdbdata bdb_next_item(int cdb) { bdb_abort(); } bdb_close_cursor(cdb); - return(cdbret); // presumably, we are at the end + return(kv); // presumably, we are at the end } bdb_decompress_if_necessary(&TSD->dbdata[cdb]); - cdbret.len = TSD->dbdata[cdb].size; - cdbret.ptr = TSD->dbdata[cdb].data; - - return (cdbret); + kv.key.len = TSD->dbkey[cdb].size; + kv.key.ptr = TSD->dbkey[cdb].data; + kv.val.len = TSD->dbdata[cdb].size; + kv.val.ptr = TSD->dbdata[cdb].data; + return (kv); } diff --git a/citadel/server/control.c b/citadel/server/control.c index ff3cccaa0..b6e4d88be 100644 --- a/citadel/server/control.c +++ b/citadel/server/control.c @@ -639,18 +639,18 @@ 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 cdbkeyval 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.ptr!=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.val.ptr!=NULL) { + if (cdbcfg.val.len < 1020) { + keylen = strlen(cdbcfg.val.ptr); + key = cdbcfg.val.ptr; + value = cdbcfg.val.ptr + keylen + 1; cprintf("%s|%s\n", key, value); } } diff --git a/citadel/server/database.c b/citadel/server/database.c index 9f31ad074..2e7717d03 100644 --- a/citadel/server/database.c +++ b/citadel/server/database.c @@ -27,7 +27,7 @@ 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; -struct cdbdata (*cdb_next_item)(int) = NULL; +struct cdbkeyval (*cdb_next_item)(int) = NULL; void (*cdb_close_cursor)(int) = NULL; void (*cdb_begin_transaction)(void) = NULL; void (*cdb_end_transaction)(void) = NULL; diff --git a/citadel/server/database.h b/citadel/server/database.h index bcf3da5ba..ed72f55d1 100644 --- a/citadel/server/database.h +++ b/citadel/server/database.h @@ -13,7 +13,7 @@ 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 struct cdbdata (*cdb_next_item)(int); +extern struct cdbkeyval (*cdb_next_item)(int); extern void (*cdb_close_cursor)(int); extern void (*cdb_begin_transaction)(void); extern void (*cdb_end_transaction)(void); diff --git a/citadel/server/modules/ctdlproto/serv_rooms.c b/citadel/server/modules/ctdlproto/serv_rooms.c index c57395a78..29f57c888 100644 --- a/citadel/server/modules/ctdlproto/serv_rooms.c +++ b/citadel/server/modules/ctdlproto/serv_rooms.c @@ -322,21 +322,18 @@ void cmd_goto(char *gargs) { void cmd_whok(char *cmdbuf) { struct ctdluser temp; - struct cdbdata cdbus; + struct cdbkeyval cdbus; int ra; cprintf("%d Who knows room:\n", LISTING_FOLLOWS); cdb_rewind(CDB_USERS); - while (cdbus = cdb_next_item(CDB_USERS), cdbus.ptr!=NULL) { + while (cdbus = cdb_next_item(CDB_USERS), cdbus.val.ptr!=NULL) { memset(&temp, 0, sizeof temp); - memcpy(&temp, cdbus.ptr, sizeof temp); - + memcpy(&temp, cdbus.val.ptr, sizeof temp); CtdlRoomAccess(&CC->room, &temp, &ra, NULL); - if ((!IsEmptyStr(temp.fullname)) && - (CC->room.QRflags & QR_INUSE) && - (ra & UA_KNOWN) - ) + if ((!IsEmptyStr(temp.fullname)) && (CC->room.QRflags & QR_INUSE) && (ra & UA_KNOWN)) { cprintf("%s\n", temp.fullname); + } } cprintf("000\n"); } diff --git a/citadel/server/modules/ctdlproto/serv_user.c b/citadel/server/modules/ctdlproto/serv_user.c index 3b356ed4c..65e2bd47f 100644 --- a/citadel/server/modules/ctdlproto/serv_user.c +++ b/citadel/server/modules/ctdlproto/serv_user.c @@ -381,7 +381,7 @@ void cmd_forg(char *argbuf) { // Get Next Unregistered User void cmd_gnur(char *argbuf) { - struct cdbdata cdbus; + struct cdbkeyval cdbus; struct ctdluser usbuf; if (CtdlAccessCheck(ac_aide)) { @@ -395,9 +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.ptr!=NULL) { + while (cdbus = cdb_next_item(CDB_USERS), cdbus.val.ptr!=NULL) { memset(&usbuf, 0, sizeof(struct ctdluser)); - memcpy(&usbuf, cdbus.ptr, ((cdbus.len > sizeof(struct ctdluser)) ? sizeof(struct ctdluser) : cdbus.len)); + memcpy(&usbuf, cdbus.val.ptr, ((cdbus.val.len > sizeof(struct ctdluser)) ? sizeof(struct ctdluser) : cdbus.val.len)); if ((usbuf.flags & US_NEEDVALID) && (usbuf.axlevel > AxDeleted)) { cprintf("%d %s\n", MORE_DATA, usbuf.fullname); cdb_close_cursor(CDB_USERS); diff --git a/citadel/server/modules/expire/serv_expire.c b/citadel/server/modules/expire/serv_expire.c index 20ac197dd..876edc9fa 100644 --- a/citadel/server/modules/expire/serv_expire.c +++ b/citadel/server/modules/expire/serv_expire.c @@ -486,7 +486,7 @@ int PurgeUsers(void) { // record is useless and should be removed.) // int PurgeVisits(void) { - struct cdbdata cdbvisit; + struct cdbkeyval cdbvisit; struct visit vbuf; struct VPurgeList *VisitPurgeList = NULL; struct VPurgeList *vptr; @@ -505,32 +505,29 @@ int PurgeVisits(void) { // Now traverse through the visits, purging irrelevant records... cdb_rewind(CDB_VISIT); - while(cdbvisit = cdb_next_item(CDB_VISIT), cdbvisit.ptr!=NULL) { + while(cdbvisit = cdb_next_item(CDB_VISIT), cdbvisit.val.ptr!=NULL) { memset(&vbuf, 0, sizeof(struct visit)); - memcpy(&vbuf, cdbvisit.ptr, - ( (cdbvisit.len > sizeof(struct visit)) ? - sizeof(struct visit) : cdbvisit.len) ); - + memcpy(&vbuf, cdbvisit.val.ptr, ((cdbvisit.val.len > sizeof(struct visit)) ? sizeof(struct visit) : cdbvisit.val.len)); RoomIsValid = 0; UserIsValid = 0; // Check to see if the room exists for (vrptr=ValidRoomList; vrptr!=NULL; vrptr=vrptr->next) { - if ( (vrptr->vr_roomnum==vbuf.v_roomnum) - && (vrptr->vr_roomgen==vbuf.v_roomgen)) + if ( (vrptr->vr_roomnum==vbuf.v_roomnum) && (vrptr->vr_roomgen==vbuf.v_roomgen)) { RoomIsValid = 1; + } } // Check to see if the user exists for (vuptr=ValidUserList; vuptr!=NULL; vuptr=vuptr->next) { - if (vuptr->vu_usernum == vbuf.v_usernum) + if (vuptr->vu_usernum == vbuf.v_usernum) { UserIsValid = 1; + } } // Put the record on the purge list if it's dead if ((RoomIsValid==0) || (UserIsValid==0)) { - vptr = (struct VPurgeList *) - malloc(sizeof(struct VPurgeList)); + vptr = (struct VPurgeList *) malloc(sizeof(struct VPurgeList)); vptr->next = VisitPurgeList; vptr->vp_roomnum = vbuf.v_roomnum; vptr->vp_roomgen = vbuf.v_roomgen; @@ -576,7 +573,7 @@ int PurgeVisits(void) { int PurgeUseTable(StrBuf *ErrMsg) { int purged = 0; int total = 0; - struct cdbdata cdbut; + struct cdbkeyval cdbut; struct UseTable ut; Array *purge_list = array_new(sizeof(int)); @@ -584,13 +581,13 @@ int PurgeUseTable(StrBuf *ErrMsg) { syslog(LOG_DEBUG, "Purge use table: phase 1"); cdb_rewind(CDB_USETABLE); - while(cdbut = cdb_next_item(CDB_USETABLE), cdbut.ptr!=NULL) { + while(cdbut = cdb_next_item(CDB_USETABLE), cdbut.val.ptr!=NULL) { ++total; - if (cdbut.len > sizeof(struct UseTable)) - memcpy(&ut, cdbut.ptr, sizeof(struct UseTable)); + if (cdbut.val.len > sizeof(struct UseTable)) + memcpy(&ut, cdbut.val.ptr, sizeof(struct UseTable)); else { memset(&ut, 0, sizeof(struct UseTable)); - memcpy(&ut, cdbut.ptr, cdbut.len); + memcpy(&ut, cdbut.val.ptr, cdbut.val.len); } if ( (time(NULL) - ut.timestamp) > USETABLE_RETAIN ) { @@ -616,7 +613,7 @@ int PurgeUseTable(StrBuf *ErrMsg) { // Purge the EUID Index of old records. int PurgeEuidIndexTable(void) { int purged = 0; - struct cdbdata cdbei; + struct cdbkeyval cdbei; struct EPurgeList *el = NULL; struct EPurgeList *eptr; long msgnum; @@ -625,9 +622,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.ptr!=NULL) { + while(cdbei = cdb_next_item(CDB_EUIDINDEX), cdbei.val.ptr!=NULL) { - memcpy(&msgnum, cdbei.ptr, sizeof(long)); + memcpy(&msgnum, cdbei.val.ptr, sizeof(long)); msg = CtdlFetchMessage(msgnum, 0); if (msg != NULL) { @@ -637,9 +634,9 @@ 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.val.len - sizeof(long); + eptr->ep_key = malloc(cdbei.val.len); + memcpy(eptr->ep_key, &cdbei.val.ptr[sizeof(long)], eptr->ep_keylen); el = eptr; } ++purged; diff --git a/citadel/server/modules/imap/imap_acl.c b/citadel/server/modules/imap/imap_acl.c index da1ff39bd..fbc5460af 100644 --- a/citadel/server/modules/imap/imap_acl.c +++ b/citadel/server/modules/imap/imap_acl.c @@ -107,7 +107,7 @@ void imap_getacl(int num_parms, ConstStr *Params) { int msgs, new; int ret; struct ctdluser temp; - struct cdbdata cdbus; + struct cdbkeyval cdbus; int ra; StrBuf *rights; @@ -136,9 +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.ptr!=NULL) { + while (cdbus = cdb_next_item(CDB_USERS), cdbus.val.ptr!=NULL) { memset(&temp, 0, sizeof temp); - memcpy(&temp, cdbus.ptr, sizeof temp); + memcpy(&temp, cdbus.val.ptr, sizeof temp); CtdlRoomAccess(&CC->room, &temp, &ra, NULL); if (!IsEmptyStr(temp.fullname)) { diff --git a/citadel/server/room_ops.c b/citadel/server/room_ops.c index 7c48922f3..804eb3bb6 100644 --- a/citadel/server/room_ops.c +++ b/citadel/server/room_ops.c @@ -523,13 +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 cdbkeyval cdbqr; cdb_rewind(CDB_ROOMS); - while (cdbqr = cdb_next_item(CDB_ROOMS), cdbqr.ptr!=NULL) { + while (cdbqr = cdb_next_item(CDB_ROOMS), cdbqr.val.ptr!=NULL) { memset(&qrbuf, 0, sizeof(struct ctdlroom)); - memcpy(&qrbuf, cdbqr.ptr, ((cdbqr.len > sizeof(struct ctdlroom)) ? sizeof(struct ctdlroom) : cdbqr.len) ); + memcpy(&qrbuf, cdbqr.val.ptr, ((cdbqr.val.len > sizeof(struct ctdlroom)) ? sizeof(struct ctdlroom) : cdbqr.val.len) ); room_sanity_check(&qrbuf); if (qrbuf.QRflags & QR_INUSE) { callback_func(&qrbuf, in_data); diff --git a/citadel/server/server.h b/citadel/server/server.h index c628df2a1..f58a9c3f1 100644 --- a/citadel/server/server.h +++ b/citadel/server/server.h @@ -73,6 +73,13 @@ struct cdbdata { }; +// Row being fetched from the database, both key and value are returned +struct cdbkeyval { + struct cdbdata key; // size and pointer to key + struct cdbdata val; // size and pointer to value +}; + + // Defines the relationship of a user to a particular room // NOTE: if you add fields to this, you have to also write export/import code in server/modules/migrate/serv_migrate.c // NOTE: if you add fields to this, you have to also write conversion code in utils/ctdl3264/* diff --git a/citadel/server/user_ops.c b/citadel/server/user_ops.c index d05d0ef3d..7c85b0118 100644 --- a/citadel/server/user_ops.c +++ b/citadel/server/user_ops.c @@ -391,16 +391,15 @@ void rebuild_usersbynumber(void) { // Returns 0 if user was found int getuserbyuid(struct ctdluser *usbuf, uid_t number) { - struct cdbdata cdbus; + struct cdbkeyval cdbus; struct ctdluser *usptr; int return_value = (-1); - // Yes, we do this the long way. + // Yes, we do this the long way. Someday we might want to try an index. // 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.ptr!=NULL) { - usptr = (struct ctdluser *) cdbus.ptr; + while (cdbus = cdb_next_item(CDB_USERS), cdbus.val.ptr!=NULL) { + usptr = (struct ctdluser *) cdbus.val.ptr; if (usptr->uid == number) { syslog(LOG_DEBUG, "user_ops: found uid=%d username=%s", usptr->uid, usptr->fullname); @@ -1031,7 +1030,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 cdbkeyval cdbus; struct ctdluser *usptr; Array *all_users = array_new(USERNAME_SIZE); @@ -1044,8 +1043,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.ptr!=NULL) { - usptr = (struct ctdluser *) cdbus.ptr; + while (cdbus = cdb_next_item(CDB_USERS), cdbus.val.ptr!=NULL) { + usptr = (struct ctdluser *) cdbus.val.ptr; if (strlen(usptr->fullname) > 0) { array_append(all_users, usptr->fullname); }