{ "local_part", vtype_stringptr, &deliver_localpart },
{ "local_part_data", vtype_stringptr, &deliver_localpart_data },
{ "local_part_prefix", vtype_stringptr, &deliver_localpart_prefix },
+ { "local_part_prefix_v", vtype_stringptr, &deliver_localpart_prefix_v },
{ "local_part_suffix", vtype_stringptr, &deliver_localpart_suffix },
+ { "local_part_suffix_v", vtype_stringptr, &deliver_localpart_suffix_v },
{ "local_part_verified", vtype_stringptr, &deliver_localpart_verified },
#ifdef HAVE_LOCAL_SCAN
{ "local_scan_data", vtype_stringptr, &local_scan_data },
#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
sa_un.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */
len = offsetof(struct sockaddr_un, sun_path) + 1
- + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s", NOTIFIER_SOCKET_NAME);
+ + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s",
+ expand_string(notifier_socket));
#else
len = offsetof(struct sockaddr_un, sun_path)
- + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s/%s",
- spool_directory, NOTIFIER_SOCKET_NAME);
+ + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s",
+ expand_string(notifier_socket));
#endif
if (connect(fd, (const struct sockaddr *)&sa_un, len) < 0)
uschar * item;
int sep = 0;
- item = string_nextinlist(&list, &sep, NULL, 0);
- if ((timeout = readconf_readtime(item, 0, FALSE)) < 0)
+ if ( !(item = string_nextinlist(&list, &sep, NULL, 0))
+ || !*item
+ || (timeout = readconf_readtime(item, 0, FALSE)) < 0)
{
expand_string_message = string_sprintf("bad time value %s", item);
goto EXPAND_FAILED;
/* Create the child process, making it a group leader. */
- if ((pid = child_open(USS argv, NULL, 0077, &fd_in, &fd_out, TRUE)) < 0)
+ if ((pid = child_open(USS argv, NULL, 0077, &fd_in, &fd_out, TRUE,
+ US"expand-run")) < 0)
{
expand_string_message =
string_sprintf("couldn't create child process: %s", strerror(errno));
case EOP_QUOTE_LOCAL_PART:
if (!arg)
{
- BOOL needs_quote = (*sub == 0); /* TRUE for empty string */
+ BOOL needs_quote = (!*sub); /* TRUE for empty string */
uschar *t = sub - 1;
if (c == EOP_QUOTE)
case EOP_FROM_UTF8:
{
- while (*sub != 0)
+ uschar * buff = store_get(4, is_tainted(sub));
+ while (*sub)
{
int c;
- uschar buff[4];
GETUTF8INC(c, sub);
if (c > 255) c = '_';
buff[0] = c;
continue;
}
- /* replace illegal UTF-8 sequences by replacement character */
+ /* replace illegal UTF-8 sequences by replacement character */
#define UTF8_REPLACEMENT_CHAR US"?"
int complete;
uschar seq_buff[4]; /* accumulate utf-8 here */
- while (*sub != 0)
+ /* Manually track tainting, as we deal in individual chars below */
+
+ if (is_tainted(sub))
+ if (yield->s && yield->ptr)
+ gstring_rebuffer(yield);
+ else
+ yield->s = store_get(yield->size = Ustrlen(sub), TRUE);
+
+ /* Check the UTF-8, byte-by-byte */
+
+ while (*sub)
{
complete = 0;
uschar c = *sub++;
}
else /* no bytes left: new sequence */
{
- if((c & 0x80) == 0) /* 1-byte sequence, US-ASCII, keep it */
+ if(!(c & 0x80)) /* 1-byte sequence, US-ASCII, keep it */
{
yield = string_catn(yield, &c, 1);
continue;
* Eg, ${length_1:フィル} is one byte, not one character, so we expect
* ${utf8clean:${length_1:フィル}} to yield '?' */
if (bytes_left != 0)
- {
yield = string_catn(yield, UTF8_REPLACEMENT_CHAR, 1);
- }
+
continue;
}