summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/src/expand.c9
-rw-r--r--src/src/functions.h4
-rw-r--r--src/src/lookupapi.h3
-rw-r--r--src/src/lookups/cdb.c3
-rw-r--r--src/src/lookups/dbmdb.c13
-rw-r--r--src/src/lookups/dnsdb.c3
-rw-r--r--src/src/lookups/dsearch.c3
-rw-r--r--src/src/lookups/ibase.c5
-rw-r--r--src/src/lookups/json.c3
-rw-r--r--src/src/lookups/ldap.c9
-rw-r--r--src/src/lookups/lmdb.c2
-rw-r--r--src/src/lookups/lsearch.c12
-rw-r--r--src/src/lookups/mysql.c3
-rw-r--r--src/src/lookups/nis.c6
-rw-r--r--src/src/lookups/nisplus.c3
-rw-r--r--src/src/lookups/oracle.c6
-rw-r--r--src/src/lookups/passwd.c3
-rw-r--r--src/src/lookups/pgsql.c3
-rw-r--r--src/src/lookups/redis.c2
-rw-r--r--src/src/lookups/spf.c3
-rw-r--r--src/src/lookups/sqlite.c3
-rw-r--r--src/src/lookups/testdb.c3
-rw-r--r--src/src/lookups/whoson.c2
-rw-r--r--src/src/match.c6
-rw-r--r--src/src/search.c52
-rw-r--r--src/src/verify.c24
26 files changed, 116 insertions, 72 deletions
diff --git a/src/src/expand.c b/src/src/expand.c
index 2366eb882..de53fe411 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -4779,7 +4779,7 @@ while (*s != 0)
int expand_setup = 0;
int nameptr = 0;
uschar *key, *filename;
- const uschar *affix;
+ const uschar * affix, * opts;
uschar *save_lookup_value = lookup_value;
int save_expand_nmax =
save_expand_strings(save_expand_nstring, save_expand_nlength);
@@ -4830,9 +4830,8 @@ while (*s != 0)
/* Now check for the individual search type and any partial or default
options. Only those types that are actually in the binary are valid. */
- stype = search_findtype_partial(name, &partial, &affix, &affixlen,
- &starflags);
- if (stype < 0)
+ if ((stype = search_findtype_partial(name, &partial, &affix, &affixlen,
+ &starflags, &opts)) < 0)
{
expand_string_message = search_error_message;
goto EXPAND_FAILED;
@@ -4925,7 +4924,7 @@ while (*s != 0)
goto EXPAND_FAILED;
}
lookup_value = search_find(handle, filename, key, partial, affix,
- affixlen, starflags, &expand_setup);
+ affixlen, starflags, &expand_setup, opts);
if (f.search_find_defer)
{
expand_string_message =
diff --git a/src/src/functions.h b/src/src/functions.h
index 90e6e6791..f3877563d 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -439,10 +439,10 @@ extern void route_show_supported(FILE *);
extern void route_tidyup(void);
extern uschar *search_find(void *, const uschar *, uschar *, int,
- const uschar *, int, int, int *);
+ const uschar *, int, int, int *, const uschar *);
extern int search_findtype(const uschar *, int);
extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
- int *);
+ int *, const uschar **);
extern void *search_open(const uschar *, int, int, uid_t *, gid_t *);
extern void search_tidyup(void);
extern void set_process_info(const char *, ...) PRINTF_FUNCTION(1,2);
diff --git a/src/src/lookupapi.h b/src/src/lookupapi.h
index 07e7af91b..a3380527c 100644
--- a/src/src/lookupapi.h
+++ b/src/src/lookupapi.h
@@ -34,7 +34,8 @@ typedef struct lookup_info {
int, /* length of key or query */
uschar **, /* for returning answer */
uschar **, /* for error message */
- uint *); /* cache TTL, seconds */
+ uint *, /* cache TTL, seconds */
+ const uschar *); /* options */
void (*close)( /* close function */
void *); /* handle */
void (*tidy)(void); /* tidy function */
diff --git a/src/src/lookups/cdb.c b/src/src/lookups/cdb.c
index c9a5de1d8..44c7c4c4c 100644
--- a/src/src/lookups/cdb.c
+++ b/src/src/lookups/cdb.c
@@ -264,7 +264,8 @@ return lf_check_file(cdbp->fileno, filename, S_IFREG, modemask,
static int
cdb_find(void * handle, const uschar * filename, const uschar * keystring,
- int key_len, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int key_len, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
struct cdb_state * cdbp = handle;
uint32 item_key_len,
diff --git a/src/src/lookups/dbmdb.c b/src/src/lookups/dbmdb.c
index f3bd6d2da..4ff81afe6 100644
--- a/src/src/lookups/dbmdb.c
+++ b/src/src/lookups/dbmdb.c
@@ -91,7 +91,8 @@ the keylength in order to include the terminating zero. */
static int
dbmdb_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
EXIM_DB *d = (EXIM_DB *)handle;
EXIM_DATUM key, data;
@@ -124,10 +125,11 @@ return FAIL;
static int
dbmnz_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
- do_cache);
+ do_cache, opts);
}
@@ -144,7 +146,8 @@ return dbmdb_find(handle, filename, keystring, length-1, result, errmsg,
static int
dbmjz_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
uschar *key_item, *key_buffer, *key_p;
const uschar *key_elems = keystring;
@@ -205,7 +208,7 @@ DEBUG(D_lookup) debug_printf_indent("NUL-joined key length: %d\n", key_item_len)
because we've calculated the real length, we need to subtract one more here */
return dbmdb_find(handle, filename, key_buffer, key_item_len - 1,
- result, errmsg, do_cache);
+ result, errmsg, do_cache, opts);
}
diff --git a/src/src/lookups/dnsdb.c b/src/src/lookups/dnsdb.c
index cc711c5c3..a842d0d0c 100644
--- a/src/src/lookups/dnsdb.c
+++ b/src/src/lookups/dnsdb.c
@@ -131,7 +131,8 @@ separator, as always, is colon. */
static int
dnsdb_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
int rc;
int sep = 0;
diff --git a/src/src/lookups/dsearch.c b/src/src/lookups/dsearch.c
index 07931ae4a..d1cbdf73a 100644
--- a/src/src/lookups/dsearch.c
+++ b/src/src/lookups/dsearch.c
@@ -70,7 +70,8 @@ for us. */
static int
dsearch_find(void * handle, const uschar * dirname, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
struct stat statbuf;
int save_errno;
diff --git a/src/src/lookups/ibase.c b/src/src/lookups/ibase.c
index 2ccb7b4f1..84feb9fb7 100644
--- a/src/src/lookups/ibase.c
+++ b/src/src/lookups/ibase.c
@@ -451,7 +451,7 @@ deferred with a retryable error. */
static int
ibase_find(void * handle, const uschar * filename, uschar * query, int length,
- uschar ** result, uschar ** errmsg, uint *do_cache)
+ uschar ** result, uschar ** errmsg, uint * do_cache, const uschar * opts)
{
int sep = 0;
uschar *server;
@@ -463,8 +463,7 @@ do_cache = do_cache;
DEBUG(D_lookup) debug_printf_indent("Interbase query: %s\n", query);
-while ((server = string_nextinlist(&list, &sep, buffer,
- sizeof(buffer))))
+while ((server = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
{
BOOL defer_break = FALSE;
int rc = perform_ibase_search(query, server, result, errmsg, &defer_break);
diff --git a/src/src/lookups/json.c b/src/src/lookups/json.c
index f476db3d9..487b9b52d 100644
--- a/src/src/lookups/json.c
+++ b/src/src/lookups/json.c
@@ -80,7 +80,8 @@ return lf_check_file(fileno((FILE *)handle), filename, S_IFREG, modemask,
static int
json_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
FILE * f = handle;
json_t * j, * j0;
diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c
index b9a52d251..aa4f3f80a 100644
--- a/src/src/lookups/ldap.c
+++ b/src/src/lookups/ldap.c
@@ -1284,7 +1284,8 @@ The handle and filename arguments are not used. */
static int
eldap_find(void * handle, const uschar * filename, const uschar * ldap_url,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
/* Keep picky compilers happy */
do_cache = do_cache;
@@ -1293,7 +1294,8 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_SINGLE, result, errmsg));
static int
eldapm_find(void * handle, const uschar * filename, const uschar * ldap_url,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
/* Keep picky compilers happy */
do_cache = do_cache;
@@ -1302,7 +1304,8 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_MULTIPLE, result, errmsg));
static int
eldapdn_find(void * handle, const uschar * filename, const uschar * ldap_url,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
/* Keep picky compilers happy */
do_cache = do_cache;
diff --git a/src/src/lookups/lmdb.c b/src/src/lookups/lmdb.c
index 712261a41..61e53fae2 100644
--- a/src/src/lookups/lmdb.c
+++ b/src/src/lookups/lmdb.c
@@ -76,7 +76,7 @@ bad:
static int
lmdb_find(void * handle, const uschar * filename,
const uschar * keystring, int length, uschar ** result, uschar ** errmsg,
- uint * do_cache)
+ uint * do_cache, const uschar * opts)
{
int ret;
MDB_val dbkey, data;
diff --git a/src/src/lookups/lsearch.c b/src/src/lookups/lsearch.c
index 92a76e7c3..6586b5ca8 100644
--- a/src/src/lookups/lsearch.c
+++ b/src/src/lookups/lsearch.c
@@ -320,7 +320,8 @@ return FAIL;
static int
lsearch_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
do_cache = do_cache; /* Keep picky compilers happy */
return internal_lsearch_find(handle, filename, keystring, length, result,
@@ -337,7 +338,8 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
static int
wildlsearch_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
do_cache = do_cache; /* Keep picky compilers happy */
return internal_lsearch_find(handle, filename, keystring, length, result,
@@ -354,7 +356,8 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
static int
nwildlsearch_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
do_cache = do_cache; /* Keep picky compilers happy */
return internal_lsearch_find(handle, filename, keystring, length, result,
@@ -372,7 +375,8 @@ return internal_lsearch_find(handle, filename, keystring, length, result,
static int
iplsearch_find(void * handle, uschar const * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
do_cache = do_cache; /* Keep picky compilers happy */
diff --git a/src/src/lookups/mysql.c b/src/src/lookups/mysql.c
index 745c6505c..7651353a2 100644
--- a/src/src/lookups/mysql.c
+++ b/src/src/lookups/mysql.c
@@ -390,7 +390,8 @@ shared with other SQL lookups. */
static int
mysql_find(void * handle, const uschar * filename, const uschar * query,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
return lf_sqlperform(US"MySQL", US"mysql_servers", mysql_servers, query,
result, errmsg, do_cache, perform_mysql_search);
diff --git a/src/src/lookups/nis.c b/src/src/lookups/nis.c
index 10ecf74c9..6b7e7a067 100644
--- a/src/src/lookups/nis.c
+++ b/src/src/lookups/nis.c
@@ -42,7 +42,8 @@ code. */
static int
nis_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
int rc;
uschar *nis_data;
@@ -68,7 +69,8 @@ return (rc == YPERR_KEY || rc == YPERR_MAP)? FAIL : DEFER;
static int
nis0_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
int rc;
uschar *nis_data;
diff --git a/src/src/lookups/nisplus.c b/src/src/lookups/nisplus.c
index 370f6a655..cd72a6b44 100644
--- a/src/src/lookups/nisplus.c
+++ b/src/src/lookups/nisplus.c
@@ -43,7 +43,8 @@ equals sign. */
static int
nisplus_find(void * handle, const uschar * filename, const uschar * query,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
int error_error = FAIL;
const uschar * field_name = NULL;
diff --git a/src/src/lookups/oracle.c b/src/src/lookups/oracle.c
index e22ff8945..be9e162fd 100644
--- a/src/src/lookups/oracle.c
+++ b/src/src/lookups/oracle.c
@@ -504,7 +504,7 @@ deferred with a retryable error. */
static int
oracle_find(void * handle, const uschar * filename, uschar * query, int length,
- uschar ** result, uschar ** errmsg, uint * do_cache)
+ uschar ** result, uschar ** errmsg, uint * do_cache, const uschar * opts)
{
int sep = 0;
uschar *server;
@@ -515,14 +515,14 @@ do_cache = do_cache; /* Placate picky compilers */
DEBUG(D_lookup) debug_printf_indent("ORACLE query: %s\n", query);
-while ((server = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL)
+while ((server = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
{
BOOL defer_break;
int rc = perform_oracle_search(query, server, result, errmsg, &defer_break);
if (rc != DEFER || defer_break) return rc;
}
-if (oracle_servers == NULL)
+if (!oracle_servers)
*errmsg = "no ORACLE servers defined (oracle_servers option)";
return DEFER;
diff --git a/src/src/lookups/passwd.c b/src/src/lookups/passwd.c
index 58222f605..92c2ddac2 100644
--- a/src/src/lookups/passwd.c
+++ b/src/src/lookups/passwd.c
@@ -34,7 +34,8 @@ return (void *)(-1); /* Just return something non-null */
static int
passwd_find(void * handle, const uschar * filename, const uschar * keystring,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
struct passwd *pw;
diff --git a/src/src/lookups/pgsql.c b/src/src/lookups/pgsql.c
index cf287b179..90dda601a 100644
--- a/src/src/lookups/pgsql.c
+++ b/src/src/lookups/pgsql.c
@@ -382,7 +382,8 @@ shared with other SQL lookups. */
static int
pgsql_find(void * handle, const uschar * filename, const uschar * query,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
return lf_sqlperform(US"PostgreSQL", US"pgsql_servers", pgsql_servers, query,
result, errmsg, do_cache, perform_pgsql_search);
diff --git a/src/src/lookups/redis.c b/src/src/lookups/redis.c
index b5c2eda23..84a2dc6c7 100644
--- a/src/src/lookups/redis.c
+++ b/src/src/lookups/redis.c
@@ -377,7 +377,7 @@ static int
redis_find(void * handle __attribute__((unused)),
const uschar * filename __attribute__((unused)),
const uschar * command, int length, uschar ** result, uschar ** errmsg,
- uint * do_cache)
+ uint * do_cache, const uschar * opts)
{
return lf_sqlperform(US"Redis", US"redis_servers", redis_servers, command,
result, errmsg, do_cache, perform_redis_search);
diff --git a/src/src/lookups/spf.c b/src/src/lookups/spf.c
index 243c271a4..5c753d988 100644
--- a/src/src/lookups/spf.c
+++ b/src/src/lookups/spf.c
@@ -65,7 +65,8 @@ if (spf_server) SPF_server_free(spf_server);
static int
spf_find(void * handle, const uschar * filename, const uschar * keystring,
- int key_len, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int key_len, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
SPF_server_t *spf_server = handle;
SPF_request_t *spf_request;
diff --git a/src/src/lookups/sqlite.c b/src/src/lookups/sqlite.c
index 51d28c2ca..a7cca5419 100644
--- a/src/src/lookups/sqlite.c
+++ b/src/src/lookups/sqlite.c
@@ -73,7 +73,8 @@ return 0;
static int
sqlite_find(void * handle, const uschar * filename, const uschar * query,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
int ret;
gstring * res = NULL;
diff --git a/src/src/lookups/testdb.c b/src/src/lookups/testdb.c
index a4f0af729..c2d39382b 100644
--- a/src/src/lookups/testdb.c
+++ b/src/src/lookups/testdb.c
@@ -38,7 +38,8 @@ return (void *)(1); /* Just return something non-null */
static int
testdb_find(void * handle, const uschar * filename, const uschar * query,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
handle = handle; /* Keep picky compilers happy */
filename = filename;
diff --git a/src/src/lookups/whoson.c b/src/src/lookups/whoson.c
index 20d013351..8ece13444 100644
--- a/src/src/lookups/whoson.c
+++ b/src/src/lookups/whoson.c
@@ -36,7 +36,7 @@ return (void *)(1); /* Just return something non-null */
static int
whoson_find(void * handle, const uschar * filename, uschar * query, int length,
- uschar ** result, uschar ** errmsg, uint * do_cache)
+ uschar ** result, uschar ** errmsg, uint * do_cache, const uschar * opts)
{
uschar buffer[80];
handle = handle; /* Keep picky compilers happy */
diff --git a/src/src/match.c b/src/src/match.c
index 4cd9259bb..2ad28a95c 100644
--- a/src/src/match.c
+++ b/src/src/match.c
@@ -97,7 +97,7 @@ check_string(void *arg, const uschar *pattern, const uschar **valueptr, uschar *
const check_string_block *cb = arg;
int search_type, partial, affixlen, starflags;
int expand_setup = cb->expand_setup;
-const uschar *affix;
+const uschar * affix, * opts;
uschar *s;
uschar *filename = NULL;
uschar *keyquery, *result, *semicolon;
@@ -263,7 +263,7 @@ the part of the string preceding the semicolon. */
*semicolon = 0;
search_type = search_findtype_partial(pattern, &partial, &affix, &affixlen,
- &starflags);
+ &starflags, &opts);
*semicolon = ';';
if (search_type < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
search_error_message);
@@ -299,7 +299,7 @@ no search_close() because of the caching arrangements. */
if (!(handle = search_open(filename, search_type, 0, NULL, NULL)))
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", search_error_message);
result = search_find(handle, filename, keyquery, partial, affix, affixlen,
- starflags, &expand_setup);
+ starflags, &expand_setup, opts);
if (!result) return f.search_find_defer? DEFER : FAIL;
if (valueptr) *valueptr = result;
diff --git a/src/src/search.c b/src/src/search.c
index d67bdc59e..51bbc6aed 100644
--- a/src/src/search.c
+++ b/src/src/search.c
@@ -115,6 +115,7 @@ Arguments:
otherwise it's a literal string
afflen the length of the affix
starflags where to put the SEARCH_STAR and SEARCH_STARAT flags
+ opts where to put the options
Returns: +ve => valid lookup name; value is offset in lookup_list
-ve => invalid name; message in search_error_message.
@@ -122,11 +123,12 @@ Returns: +ve => valid lookup name; value is offset in lookup_list
int
search_findtype_partial(const uschar *name, int *ptypeptr, const uschar **ptypeaff,
- int *afflen, int *starflags)
+ int *afflen, int *starflags, const uschar ** opts)
{
int len, stype;
int pv = -1;
const uschar *ss = name;
+const uschar * t;
*starflags = 0;
*ptypeaff = NULL;
@@ -167,8 +169,10 @@ if (Ustrncmp(name, "partial", 7) == 0)
}
}
-/* Now we are left with a lookup name, possibly followed by * or *@. */
+/* 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)
{
@@ -180,6 +184,18 @@ else if (len >= 1 && ss[len-1] == '*')
*starflags |= SEARCH_STAR;
len--;
}
+#endif
+
+len = Ustrlen(ss);
+if ((t = Ustrchr(ss, '*')))
+ {
+ len = t - ss;
+ *starflags |= (t[1] == '@' ? SEARCH_STARAT : SEARCH_STAR);
+ }
+else
+ t = ss;
+
+* USS opts = (t = Ustrchr(t, ',')) ? string_copy(t+1) : 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
@@ -454,6 +470,7 @@ Arguments:
NULL for query-style searches
keystring the keystring for single-key+file lookups, or
the querystring for query-style lookups
+ opts type-specific options
Returns: a pointer to a dynamic string containing the answer,
or NULL if the query failed or was deferred; in the
@@ -462,7 +479,8 @@ Returns: a pointer to a dynamic string containing the answer,
*/
static uschar *
-internal_search_find(void * handle, const uschar * filename, uschar * keystring)
+internal_search_find(void * handle, const uschar * filename, uschar * keystring,
+ const uschar * opts)
{
tree_node * t = (tree_node *)handle;
search_cache * c = (search_cache *)(t->data.ptr);
@@ -478,8 +496,9 @@ search_error_message = US"";
f.search_find_defer = FALSE;
DEBUG(D_lookup) debug_printf_indent("internal_search_find: file=\"%s\"\n "
- "type=%s key=\"%s\"\n", filename,
- lookup_list[search_type]->name, keystring);
+ "type=%s key=\"%s\" opts=%s%s%s\n", filename,
+ lookup_list[search_type]->name, keystring,
+ opts ? "\"" : "", opts, opts ? "\"" : "");
/* Insurance. If the keystring is empty, just fail. */
@@ -520,7 +539,7 @@ else
distinguish if necessary. */
if (lookup_list[search_type]->find(c->handle, filename, keystring, keylength,
- &data, &search_error_message, &do_cache) == DEFER)
+ &data, &search_error_message, &do_cache, opts) == DEFER)
f.search_find_defer = TRUE;
/* A record that has been found is now in data, which is either NULL
@@ -598,6 +617,7 @@ Arguments:
starflags SEARCH_STAR and SEARCH_STARAT flags
expand_setup pointer to offset for setting up expansion strings;
don't do any if < 0
+ opts type-specific options
Returns: a pointer to a dynamic string containing the answer,
or NULL if the query failed or was deferred; in the
@@ -607,7 +627,7 @@ Returns: a pointer to a dynamic string containing the answer,
uschar *
search_find(void * handle, const uschar * filename, uschar * keystring,
int partial, const uschar * affix, int affixlen, int starflags,
- int * expand_setup)
+ int * expand_setup, const uschar * opts)
{
tree_node *t = (tree_node *)handle;
BOOL set_null_wild = FALSE;
@@ -617,9 +637,11 @@ DEBUG(D_lookup)
{
if (partial < 0) affixlen = 99; /* So that "NULL" prints */
debug_printf_indent("search_find: file=\"%s\"\n key=\"%s\" "
- "partial=%d affix=%.*s starflags=%x\n",
- (filename == NULL)? US"NULL" : filename,
- keystring, partial, affixlen, affix, starflags);
+ "partial=%d affix=%.*s starflags=%x opts=%s%s%s\n",
+ filename ? filename : US"NULL",
+ keystring, partial, affixlen, affix, starflags,
+ opts ? "\"" : "", opts, opts ? "\"" : "");
+
}
/* Arrange to put this database at the top of the LRU chain if it is a type
@@ -669,7 +691,7 @@ DEBUG(D_lookup)
/* First of all, try to match the key string verbatim. If matched a complete
entry but could have been partial, flag to set up variables. */
-yield = internal_search_find(handle, filename, keystring);
+yield = internal_search_find(handle, filename, keystring, opts);
if (f.search_find_defer) return NULL;
if (yield) { if (partial >= 0) set_null_wild = TRUE; }
@@ -694,7 +716,7 @@ else if (partial >= 0)
Ustrncpy(keystring2, affix, affixlen);
Ustrcpy(keystring2 + affixlen, keystring);
DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring2);
- yield = internal_search_find(handle, filename, keystring2);
+ yield = internal_search_find(handle, filename, keystring2, opts);
if (f.search_find_defer) return NULL;
}
@@ -732,7 +754,7 @@ else if (partial >= 0)
}
DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring3);
- yield = internal_search_find(handle, filename, keystring3);
+ yield = internal_search_find(handle, filename, keystring3, opts);
if (f.search_find_defer) return NULL;
if (yield)
{
@@ -773,7 +795,7 @@ if (!yield && starflags & SEARCH_STARAT)
*atat = '*';
DEBUG(D_lookup) debug_printf_indent("trying default match %s\n", atat);
- yield = internal_search_find(handle, filename, atat);
+ yield = internal_search_find(handle, filename, atat, opts);
*atat = savechar;
if (f.search_find_defer) return NULL;
@@ -796,7 +818,7 @@ and the second is empty. */
if (!yield && starflags & (SEARCH_STAR|SEARCH_STARAT))
{
DEBUG(D_lookup) debug_printf_indent("trying to match *\n");
- yield = internal_search_find(handle, filename, US"*");
+ yield = internal_search_find(handle, filename, US"*", opts);
if (yield && expand_setup && *expand_setup >= 0)
{
*expand_setup += 1;
diff --git a/src/src/verify.c b/src/src/verify.c
index 7b9d006f6..dc2e57614 100644
--- a/src/src/verify.c
+++ b/src/src/verify.c
@@ -2890,7 +2890,7 @@ BOOL iplookup = FALSE;
BOOL isquery = FALSE;
BOOL isiponly = cb->host_name != NULL && cb->host_name[0] == 0;
const uschar *t;
-uschar *semicolon;
+uschar * semicolon, * endname, * opts;
uschar **aliases;
/* Optimize for the special case when the pattern is "*". */
@@ -2949,15 +2949,14 @@ if (*t == 0 || (*t == '/' && t != ss))
/* See if there is a semicolon in the pattern */
-semicolon = Ustrchr(ss, ';');
+if ((semicolon = Ustrchr(ss, ';')))
+ endname = (opts = Ustrchr(ss, ',')) ? opts : semicolon;
/* If we are doing an IP address only match, then all lookups must be IP
address lookups, even if there is no "net-". */
if (isiponly)
- {
iplookup = semicolon != NULL;
- }
/* Otherwise, if the item is of the form net[n]-lookup;<file|query> then it is
a lookup on a masked IP network, in textual form. We obey this code even if we
@@ -2967,12 +2966,12 @@ key is implicit. For query-style lookups the key is specified in the query.
From release 4.30, the use of net- for query style is no longer needed, but we
retain it for backward compatibility. */
-if (Ustrncmp(ss, "net", 3) == 0 && semicolon != NULL)
+if (Ustrncmp(ss, "net", 3) == 0 && semicolon)
{
mlen = 0;
for (t = ss + 3; isdigit(*t); t++) mlen = mlen * 10 + *t - '0';
if (mlen == 0 && t == ss+3) mlen = -1; /* No mask supplied */
- iplookup = (*t++ == '-');
+ iplookup = *t++ == '-';
}
else
t = ss;
@@ -2990,7 +2989,7 @@ if (iplookup)
/* Find the search type */
- search_type = search_findtype(t, semicolon - t);
+ search_type = search_findtype(t, endname - t);
if (search_type < 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
search_error_message);
@@ -3033,7 +3032,7 @@ if (iplookup)
if (!(handle = search_open(filename, search_type, 0, NULL, NULL)))
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", search_error_message);
- result = search_find(handle, filename, key, -1, NULL, 0, 0, NULL);
+ result = search_find(handle, filename, key, -1, NULL, 0, 0, NULL, opts);
if (valueptr) *valueptr = result;
return result ? OK : f.search_find_defer ? DEFER: FAIL;
}
@@ -3091,7 +3090,7 @@ using the general string matching function. When this function is called for
outgoing hosts, the name is always given explicitly. If it is NULL, it means we
must use sender_host_name and its aliases, looking them up if necessary. */
-if (cb->host_name != NULL) /* Explicit host name given */
+if (cb->host_name) /* Explicit host name given */
return match_check_string(cb->host_name, ss, -1, TRUE, TRUE, TRUE,
valueptr);
@@ -3101,13 +3100,14 @@ query does not contain $sender_host_name. From release 4.23, a reference to
$sender_host_name causes it to be looked up, so we don't need to do the lookup
on spec. */
-if ((semicolon = Ustrchr(ss, ';')) != NULL)
+if ((semicolon = Ustrchr(ss, ';')))
{
- const uschar *affix;
+ const uschar * affix, * opts;
int partial, affixlen, starflags, id;
*semicolon = 0;
- id = search_findtype_partial(ss, &partial, &affix, &affixlen, &starflags);
+ id = search_findtype_partial(ss, &partial, &affix, &affixlen, &starflags,
+ &opts);
*semicolon=';';
if (id < 0) /* Unknown lookup type */