*************************************************/
/* Copyright (c) University of Cambridge 1995 - 2015 */
-/* Copyright (c) The Exim Maintainers 2020 */
+/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */
/* A set of functions to search databases in various formats. An open
*/
int
-search_findtype(const uschar *name, int len)
+search_findtype(const uschar * name, int len)
{
-int bot = 0;
-int top = lookup_list_count;
-while (top > bot)
+for (int bot = 0, top = lookup_list_count; top > bot; )
{
int mid = (top + bot)/2;
int c = Ustrncmp(name, lookup_list[mid]->name, len);
if (c > 0) bot = mid + 1; else top = mid;
}
-search_error_message = string_sprintf("unknown lookup type \"%.*s\"",len,name);
+search_error_message = string_sprintf("unknown lookup type \"%.*s\"", len, name);
return -1;
}
search the search-type string
query argument for the search; filename or query
fnamep pointer to return filename
+ opts options
Return: keyquery the search-type (for single-key) or query (for query-type)
*/
uschar *
-search_args(int search_type, uschar * search, uschar * query, uschar ** fnamep)
+search_args(int search_type, uschar * search, uschar * query, uschar ** fnamep,
+ const uschar * opts)
{
Uskip_whitespace(&query);
if (mac_islookup(search_type, lookup_absfilequery))
{ /* query-style but with file (sqlite) */
- uschar * s = query;
+ int sep = ',';
+
+ /* Check options first for new-style file spec */
+ if (opts) for (uschar * s; s = string_nextinlist(&opts, &sep, NULL, 0); )
+ if (Ustrncmp(s, "file=", 5) == 0)
+ {
+ *fnamep = s+5;
+ return query;
+ }
+
+ /* If no filename from options, use old-tyle space-sep prefix on query */
if (*query == '/')
{
+ uschar * s = query;
while (*query && !isspace(*query)) query++;
*fnamep = string_copyn(s, query - s);
Uskip_whitespace(&query);
uschar keybuffer[256];
int old_pool = store_pool;
-if (filename && is_tainted(filename))
- {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "Tainted filename for search: '%s'", filename);
+if (filename && is_tainted2(filename, LOG_MAIN|LOG_PANIC, "Tainted filename for search: '%s'", filename))
return NULL;
- }
/* Change to the search store pool and remember our reset point */
e->data.ptr = data;
}
- /* If caching was disabled, empty the cache tree. We just set the cache
- pointer to NULL here, because we cannot release the store at this stage. */
+/* If caching was disabled, empty the cache tree. We just set the cache
+pointer to NULL here, because we cannot release the store at this stage. */
else
{
/* Arrange to put this database at the top of the LRU chain if it is a type
that opens real files. */
-if ( open_top != (tree_node *)handle
+if ( open_top != (tree_node *)handle
&& lookup_list[t->name[0]-'0']->type == lookup_absfile)
{
search_cache *c = (search_cache *)(t->data.ptr);