Move common code to get a piece of data from cdb into
its own function.

Signed-off-by: Michael Tokarev <m...@tls.msk.ru>
---
On top of the previous patch.

 src/util/dict_cdb.c | 89 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 74 insertions(+), 15 deletions(-)

diff --git a/src/util/dict_cdb.c b/src/util/dict_cdb.c
index 9b4648b7..fb3e77d5 100644
--- a/src/util/dict_cdb.c
+++ b/src/util/dict_cdb.c
@@ -85,6 +85,10 @@ typedef struct {
     DICT    dict;                      /* generic members */
     struct cdb cdb;                    /* cdb structure */
     VSTRING *val_buf;                  /* value result */
+#ifdef TINYCDB_VERSION
+    VSTRING *key_buf;                  /* key result */
+    unsigned seq_cptr;                 /* current sequence pointer */
+#endif
 } DICT_CDBQ;                           /* query interface */
 
 typedef struct {
@@ -94,12 +98,29 @@ typedef struct {
     char   *tmp_path;                  /* temporary pathname (.tmp) */
 } DICT_CDBM;                           /* rebuild interface */
 
+/* dict_cdbq_getdata - get data out of the cdb using given buffer */
+
+static const char *dict_cdbq_get_data(DICT_CDBQ *dict_cdbq,
+               VSTRING **bufp, unsigned len, unsigned pos)
+{
+    VSTRING *buf = *bufp;
+    if (!buf)
+       buf = *bufp = vstring_alloc(len < 20 ? 20 : len);
+    VSTRING_RESET(buf);
+    VSTRING_SPACE(buf, len);
+
+    if (cdb_read(&dict_cdbq->cdb, vstring_str(buf), len, pos) < 0)
+        msg_fatal("error reading %s: %m", dict_cdbq->dict.name);
+    vstring_set_payload_size(buf, len);
+    VSTRING_TERMINATE(buf);
+    return vstring_str(buf);
+}
+
 /* dict_cdbq_lookup - find database entry, query mode */
 
 static const char *dict_cdbq_lookup(DICT *dict, const char *name)
 {
     DICT_CDBQ *dict_cdbq = (DICT_CDBQ *) dict;
-    unsigned vlen;
     int     status = 0;
     const char *result = 0;
 
@@ -140,20 +161,8 @@ static const char *dict_cdbq_lookup(DICT *dict, const char 
*name)
        msg_fatal("error reading %s: %m", dict->name);
 
     if (status) {
-       vlen = cdb_datalen(&dict_cdbq->cdb);
-       if (!dict_cdbq->val_buf)
-           dict_cdbq->val_buf = vstring_alloc(vlen < 20 ? 20 : vlen);
-       else {
-           VSTRING_RESET(dict_cdbq->val_buf);
-           VSTRING_SPACE(dict_cdbq->val_buf, vlen);
-       }
-       if (cdb_read(&dict_cdbq->cdb, vstring_str(dict_cdbq->val_buf),
-                    vlen, cdb_datapos(&dict_cdbq->cdb)) < 0)
-           msg_fatal("error reading %s: %m", dict->name);
-       vstring_set_payload_size(dict_cdbq->val_buf, vlen);
-       VSTRING_TERMINATE(dict_cdbq->val_buf);
-
-       result = vstring_str(dict_cdbq->val_buf);
+       result = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->val_buf,
+               cdb_datalen(&dict_cdbq->cdb), cdb_datapos(&dict_cdbq->cdb));
     }
 
     /* No locking so not release the lock.  */
@@ -161,6 +170,49 @@ static const char *dict_cdbq_lookup(DICT *dict, const char 
*name)
     return (result);
 }
 
+#ifdef TINYCDB_VERSION
+
+/* dict_cdbq_sequence - traverse the dictionary */
+
+static int dict_cdbq_sequence(DICT *dict, int function,
+                                const char **key, const char **value)
+{
+    const char *myname = "dict_cdbq_sequence";
+    DICT_CDBQ *dict_cdbq = (DICT_CDBQ *)dict;
+    int status;
+
+    switch (function) {
+    case DICT_SEQ_FUN_FIRST:
+       cdb_seqinit(&dict_cdbq->seq_cptr, &dict_cdbq->cdb);
+       break;
+    case DICT_SEQ_FUN_NEXT:
+       if (!dict_cdbq->seq_cptr)
+           msg_panic("%s: %s: no cursor", myname, dict_cdbq->dict.name);
+       break;
+    default:
+       msg_panic("%s: invalid function %d", myname, function);
+    }
+
+    status = cdb_seqnext(&dict_cdbq->seq_cptr, &dict_cdbq->cdb);
+
+    if (status < 0)
+       msg_fatal("error seeking %s: %m", dict_cdbq->dict.name);
+
+    if (!status) {
+       dict_cdbq->seq_cpos = 0;
+       return -1; /* not found */
+    }
+
+    *key = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->key_buf,
+               cdb_keylen(&dict_cdbq->cdb), cdb_keypos(&dict_cdbq->cdb));
+    *value = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->val_buf,
+               cdb_datalen(&dict_cdbq->cdb), cdb_datapos(&dict_cdbq->cdb));
+
+    return 0;
+}
+
+#endif /* TINYCDB_VERSION */
+
 /* dict_cdbq_close - close data base, query mode */
 
 static void dict_cdbq_close(DICT *dict)
@@ -173,6 +225,10 @@ static void dict_cdbq_close(DICT *dict)
        vstring_free(dict->fold_buf);
     if (dict_cdbq->val_buf)
        vstring_free(dict_cdbq->val_buf);
+#ifdef TINYCDB_VERSION
+    if (dict_cdbq->key_buf)
+       vstring_free(dict_cdbq->key_buf);
+#endif
     dict_free(dict);
 }
 
@@ -205,8 +261,11 @@ static DICT *dict_cdbq_open(const char *path, int 
dict_flags)
                                         cdb_path, sizeof(*dict_cdbq));
     dict_cdbq->val_buf = 0;
 #if defined(TINYCDB_VERSION)
+    dict_cdbq->key_buf = 0;
+    dict_cdbq->seq_cptr = 0;
     if (cdb_init(&(dict_cdbq->cdb), fd) != 0)
        msg_fatal("dict_cdbq_open: unable to init %s: %m", cdb_path);
+    dict_cdbq->dict.sequence = dict_cdbq_sequence;
 #else
     cdb_init(&(dict_cdbq->cdb), fd);
 #endif
-- 
2.39.5

_______________________________________________
Postfix-devel mailing list -- postfix-devel@postfix.org
To unsubscribe send an email to postfix-devel-le...@postfix.org

Reply via email to