-/* $Cambridge: exim/src/src/expand.c,v 1.35 2005/06/22 15:44:38 ph10 Exp $ */
+/* $Cambridge: exim/src/src/expand.c,v 1.41 2005/08/23 08:46:33 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
{ "message_body", vtype_msgbody, &message_body },
{ "message_body_end", vtype_msgbody_end, &message_body_end },
{ "message_body_size", vtype_int, &message_body_size },
+ { "message_exim_id", vtype_stringptr, &message_id },
{ "message_headers", vtype_msgheaders, NULL },
{ "message_id", vtype_stringptr, &message_id },
{ "message_linecount", vtype_int, &message_linecount },
s = find_header(US"reply-to:", exists_only, newsize, FALSE,
headers_charset);
if (s == NULL || *s == 0)
+ {
+ *newsize = 0; /* For the *s==0 case */
s = find_header(US"from:", exists_only, newsize, FALSE, headers_charset);
+ }
return (s == NULL)? US"" : s;
/* A recipients list is available only during system message filtering,
int x = eval_term(&s, decimal, error);
if (*error == NULL)
{
- while (*s == '*' || *s == '/')
+ while (*s == '*' || *s == '/' || *s == '%')
{
int op = *s++;
int y = eval_term(&s, decimal, error);
if (*error != NULL) break;
- if (op == '*') x *= y; else x /= y;
+ if (op == '*') x *= y;
+ else if (op == '/') x /= y;
+ else x %= y;
}
}
*sptr = s;
/* Check that a key was provided for those lookup types that need it,
and was not supplied for those that use the query style. */
- if (!mac_islookup(stype, lookup_querystyle))
+ if (!mac_islookup(stype, lookup_querystyle|lookup_absfilequery))
{
if (key == NULL)
{
}
/* Get the next string in brackets and expand it. It is the file name for
- single-key+file lookups, and the whole query otherwise. */
+ single-key+file lookups, and the whole query otherwise. In the case of
+ queries that also require a file name (e.g. sqlite), the file name comes
+ first. */
if (*s != '{') goto EXPAND_FAILED_CURLY;
filename = expand_string_internal(s+1, TRUE, &s, skipping);
while (isspace(*s)) s++;
/* If this isn't a single-key+file lookup, re-arrange the variables
- to be appropriate for the search_ functions. */
+ to be appropriate for the search_ functions. For query-style lookups,
+ there is just a "key", and no file name. For the special query-style +
+ file types, the query (i.e. "key") starts with a file name. */
if (key == NULL)
{
+ while (isspace(*filename)) filename++;
key = filename;
- filename = NULL;
+
+ if (mac_islookup(stype, lookup_querystyle))
+ {
+ filename = NULL;
+ }
+ else
+ {
+ if (*filename != '/')
+ {
+ expand_string_message = string_sprintf(
+ "absolute file name expected for \"%s\" lookup", name);
+ goto EXPAND_FAILED;
+ }
+ while (*key != 0 && !isspace(*key)) key++;
+ if (*key != 0) *key++ = 0;
+ }
}
/* If skipping, don't do the next bit - just lookup_value == NULL, as if
}
yield = cat_file(f, yield, &size, &ptr, sub_arg[1]);
- fclose(f);
+ (void)fclose(f);
continue;
}
alarm(timeout);
yield = cat_file(f, yield, &size, &ptr, sub_arg[3]);
alarm(0);
- fclose(f);
+ (void)fclose(f);
/* After a timeout, we restore the pointer in the result, that is,
make sure we add nothing from the socket. */
/* Nothing is written to the standard input. */
- close(fd_in);
+ (void)close(fd_in);
/* Wait for the process to finish, applying the timeout, and inspect its
return code for serious disasters. Simple non-zero returns are passed on.
f = fdopen(fd_out, "rb");
lookup_value = NULL;
lookup_value = cat_file(f, lookup_value, &lsize, &lptr, NULL);
- fclose(f);
+ (void)fclose(f);
}
/* Process the yes/no strings; $value may be useful in both cases */
mode_t mode;
struct stat st;
+ if ((expand_forbid & RDO_EXISTS) != 0)
+ {
+ expand_string_message = US"Use of the stat() expansion is not permitted";
+ goto EXPAND_FAILED;
+ }
+
if (stat(CS sub, &st) < 0)
{
expand_string_message = string_sprintf("stat(%s) failed: %s",