diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2020-04-03 14:36:17 +0100 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2020-04-03 14:36:17 +0100 |
commit | a5dc727afcc92deab722a84ae5cf3d00ae74c5f6 (patch) | |
tree | be4e69e817832064408af368787424c6a334e884 /src | |
parent | 67a57a5afd313490a8763d60ec4df857b9cf239b (diff) |
dsearch: full-path return option
Diffstat (limited to 'src')
-rw-r--r-- | src/src/lookups/dsearch.c | 15 | ||||
-rw-r--r-- | src/src/search.c | 29 | ||||
-rw-r--r-- | src/src/structs.h | 10 |
3 files changed, 33 insertions, 21 deletions
diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c index d1cbdf73a..0509a761b 100644 --- a/src/src/lookups/dsearch.c +++ b/src/src/lookups/dsearch.c @@ -64,6 +64,8 @@ return FALSE; * Find entry point * *************************************************/ +#define RET_FULL BIT(0) + /* See local README for interface description. We use lstat() instead of scanning the directory, as it is hopefully faster to let the OS do the scanning for us. */ @@ -76,6 +78,7 @@ dsearch_find(void * handle, const uschar * dirname, const uschar * keystring, struct stat statbuf; int save_errno; uschar * filename; +unsigned flags = 0; handle = handle; /* Keep picky compilers happy */ length = length; @@ -88,12 +91,22 @@ if (Ustrchr(keystring, '/') != 0) return DEFER; } +if (opts) + { + int sep = ','; + uschar * ele; + + while ((ele = string_nextinlist(&opts, &sep, NULL, 0))) + if (Ustrcmp(ele, "ret=full") == 0) + flags |= RET_FULL; + } + filename = string_sprintf("%s/%s", dirname, keystring); if (Ulstat(filename, &statbuf) >= 0) { /* Since the filename exists in the filesystem, we can return a non-tainted result. */ - *result = string_copy_taint(keystring, FALSE); + *result = string_copy_taint(flags & RET_FULL ? filename : keystring, FALSE); return OK; } diff --git a/src/src/search.c b/src/src/search.c index 51bbc6aed..2a60fc78a 100644 --- a/src/src/search.c +++ b/src/src/search.c @@ -172,20 +172,6 @@ if (Ustrncmp(name, "partial", 7) == 0) /* Now we are left with a lookup name, possibly followed by * or *@, and then by options starting with a "," */ -#ifdef old -len = Ustrlen(ss); -if (len >= 2 && Ustrncmp(ss + len - 2, "*@", 2) == 0) - { - *starflags |= SEARCH_STARAT; - len -= 2; - } -else if (len >= 1 && ss[len-1] == '*') - { - *starflags |= SEARCH_STAR; - len--; - } -#endif - len = Ustrlen(ss); if ((t = Ustrchr(ss, '*'))) { @@ -195,7 +181,14 @@ if ((t = Ustrchr(ss, '*'))) else t = ss; -* USS opts = (t = Ustrchr(t, ',')) ? string_copy(t+1) : NULL; +if ((t = Ustrchr(t, ','))) + { + int l = t - ss; + if (l < len) len = l; + *opts = string_copy(t+1); + } +else + * opts = NULL; /* Check for the individual search type. Only those that are actually in the binary are valid. For query-style types, "partial" and default types are @@ -513,6 +506,7 @@ file. No need to check c->item_cache for NULL, tree_search will do so. */ if ( (t = tree_search(c->item_cache, keystring)) && (!(e = t->data.ptr)->expiry || e->expiry > time(NULL)) + && (!opts && !e->opts || opts && e->opts && Ustrcmp(opts, e->opts) == 0) ) { /* Data was in the cache already; set the pointer from the tree node */ data = e->data.ptr; @@ -527,7 +521,8 @@ else DEBUG(D_lookup) { - if (t) debug_printf_indent("cached data found but past valid time; "); + if (t) + debug_printf_indent("cached data found but either wrong opts or dated; "); debug_printf_indent("%s lookup required for %s%s%s\n", filename ? US"file" : US"database", keystring, @@ -555,12 +550,14 @@ else if (t) /* Previous, out-of-date cache entry. Update with the */ { /* new result and forget the old one */ e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache; + e->opts = opts; e->data.ptr = data; } else { e = store_get(sizeof(expiring_data) + sizeof(tree_node) + len, is_tainted(keystring)); e->expiry = do_cache == UINT_MAX ? 0 : time(NULL)+do_cache; + e->opts = opts; e->data.ptr = data; t = (tree_node *)(e+1); memcpy(t->name, keystring, len); diff --git a/src/src/structs.h b/src/src/structs.h index 7d700fb72..ce6e8e857 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -727,14 +727,16 @@ typedef struct tree_node { /* Structure for holding time-limited data such as DNS returns. We use this rather than extending tree_node to avoid wasting space for most tree use (variables...) at the cost of complexity -for the lookups cache */ +for the lookups cache. +We also store any options used for the lookup. */ typedef struct expiring_data { - time_t expiry; /* if nonzero, data invalid after this time */ + time_t expiry; /* if nonzero, data invalid after this time */ + const uschar * opts; /* options, or NULL */ union { - void *ptr; /* pointer to data */ - int val; /* or integer data */ + void * ptr; /* pointer to data */ + int val; /* or integer data */ } data; } expiring_data; |