Move common code to get a piece of data from cdb into
its own function.
Signed-off-by: Michael Tokarev <[email protected]>
---
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 -- [email protected]
To unsubscribe send an email to [email protected]