}
DEBUG(D_expand)
- debug_printf("expanding: acl: %s arg: %s%s\n",
+ debug_printf_indent("expanding: acl: %s arg: %s%s\n",
sub[0],
acl_narg>0 ? acl_arg[0] : US"<none>",
acl_narg>1 ? " +more" : "");
{
num[i] = 0;
DEBUG(D_expand)
- debug_printf("empty string cast to zero for numerical comparison\n");
+ debug_printf_indent("empty string cast to zero for numerical comparison\n");
}
else
{
uschar *save_iterate_item = iterate_item;
int (*compare)(const uschar *, const uschar *);
- DEBUG(D_expand) debug_printf("condition: %s\n", name);
+ DEBUG(D_expand) debug_printf_indent("condition: %s\n", name);
tempcond = FALSE;
compare = cond_type == ECOND_INLISTI
int sep = 0;
uschar *save_iterate_item = iterate_item;
- DEBUG(D_expand) debug_printf("condition: %s\n", name);
+ DEBUG(D_expand) debug_printf_indent("condition: %s\n", name);
while (isspace(*s)) s++;
if (*s++ != '{') goto COND_FAILED_CURLY_START; /* }-for-text-editors */
list = sub[0];
while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
{
- DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, iterate_item);
+ DEBUG(D_expand) debug_printf_indent("%s: $item = \"%s\"\n", name, iterate_item);
if (!eval_condition(sub[1], resetok, &tempcond))
{
expand_string_message = string_sprintf("%s inside \"%s\" condition",
iterate_item = save_iterate_item;
return NULL;
}
- DEBUG(D_expand) debug_printf("%s: condition evaluated to %s\n", name,
+ DEBUG(D_expand) debug_printf_indent("%s: condition evaluated to %s\n", name,
tempcond? "true":"false");
if (yield != NULL) *yield = (tempcond == testfor);
}
}
DEBUG(D_expand)
- debug_printf("considering %s: %s\n", ourname, len ? t : US"<empty>");
+ debug_printf_indent("considering %s: %s\n", ourname, len ? t : US"<empty>");
/* logic for the lax case from expand_check_condition(), which also does
expands, and the logic is both short and stable enough that there should
be no maintenance burden from replicating it. */
"value \"%s\"", t);
return NULL;
}
- DEBUG(D_expand) debug_printf("%s: condition evaluated to %s\n", ourname,
+ DEBUG(D_expand) debug_printf_indent("%s: condition evaluated to %s\n", ourname,
boolvalue? "true":"false");
if (yield != NULL) *yield = (boolvalue == testfor);
return s;
while (isspace(*s)) s++;
if (*s == '}')
{
- if (!skipping)
- if (type[0] == 'i')
- {
- if (yes) *yieldptr = string_catn(*yieldptr, sizeptr, ptrptr, US"true", 4);
- }
- else
- {
- if (yes && lookup_value)
- *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, lookup_value);
- lookup_value = save_lookup;
- }
+ if (type[0] == 'i')
+ {
+ if (yes && !skipping)
+ *yieldptr = string_catn(*yieldptr, sizeptr, ptrptr, US"true", 4);
+ }
+ else
+ {
+ if (yes && lookup_value && !skipping)
+ *yieldptr = string_cat(*yieldptr, sizeptr, ptrptr, lookup_value);
+ lookup_value = save_lookup;
+ }
s++;
goto RETURN;
}
hash_source = string_cat(hash_source, &size, &offset, address);
hash_source[offset] = '\0';
-DEBUG(D_expand) debug_printf("prvs: hash source is '%s'\n", hash_source);
+DEBUG(D_expand) debug_printf_indent("prvs: hash source is '%s'\n", hash_source);
memset(innerkey, 0x36, 64);
memset(outerkey, 0x5c, 64);
int save_expand_nlength[EXPAND_MAXN+1];
BOOL resetok = TRUE;
+expand_level++;
DEBUG(D_expand)
- debug_printf("%s: %s\n", skipping ? " scanning" : "considering", string);
+ debug_printf_indent(UTF8_DOWN_RIGHT "%s: %s\n",
+ skipping
+ ? UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ "scanning"
+ : "considering",
+ string);
expand_string_forcedfail = FALSE;
expand_string_message = US"";
case OK:
case FAIL:
DEBUG(D_expand)
- debug_printf("acl expansion yield: %s\n", user_msg);
+ debug_printf_indent("acl expansion yield: %s\n", user_msg);
if (user_msg)
yield = string_cat(yield, &size, &ptr, user_msg);
continue;
if (next_s == NULL) goto EXPAND_FAILED; /* message already set */
DEBUG(D_expand)
- debug_printf(" condition: %.*s\n result: %s\n",
- (int)(next_s - s), s,
- cond ? "true" : "false");
+ {
+ debug_printf_indent(UTF8_VERT_RIGHT UTF8_HORIZ UTF8_HORIZ
+ "condition: %.*s\n",
+ (int)(next_s - s), s);
+ debug_printf_indent(UTF8_VERT_RIGHT UTF8_HORIZ UTF8_HORIZ
+ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
+ "result: %s\n",
+ cond ? "true" : "false");
+ }
s = next_s;
uschar *hash = string_copyn(expand_nstring[3],expand_nlength[3]);
uschar *domain = string_copyn(expand_nstring[5],expand_nlength[5]);
- DEBUG(D_expand) debug_printf("prvscheck localpart: %s\n", local_part);
- DEBUG(D_expand) debug_printf("prvscheck key number: %s\n", key_num);
- DEBUG(D_expand) debug_printf("prvscheck daystamp: %s\n", daystamp);
- DEBUG(D_expand) debug_printf("prvscheck hash: %s\n", hash);
- DEBUG(D_expand) debug_printf("prvscheck domain: %s\n", domain);
+ DEBUG(D_expand) debug_printf_indent("prvscheck localpart: %s\n", local_part);
+ DEBUG(D_expand) debug_printf_indent("prvscheck key number: %s\n", key_num);
+ DEBUG(D_expand) debug_printf_indent("prvscheck daystamp: %s\n", daystamp);
+ DEBUG(D_expand) debug_printf_indent("prvscheck hash: %s\n", hash);
+ DEBUG(D_expand) debug_printf_indent("prvscheck domain: %s\n", domain);
/* Set up expansion variables */
prvscheck_address = string_cat (NULL, &mysize, &myptr, local_part);
goto EXPAND_FAILED;
}
- DEBUG(D_expand) debug_printf("prvscheck: received hash is %s\n", hash);
- DEBUG(D_expand) debug_printf("prvscheck: own hash is %s\n", p);
+ DEBUG(D_expand) debug_printf_indent("prvscheck: received hash is %s\n", hash);
+ DEBUG(D_expand) debug_printf_indent("prvscheck: own hash is %s\n", p);
if (Ustrcmp(p,hash) == 0)
{
if (iexpire >= inow)
{
prvscheck_result = US"1";
- DEBUG(D_expand) debug_printf("prvscheck: success, $pvrs_result set to 1\n");
+ DEBUG(D_expand) debug_printf_indent("prvscheck: success, $pvrs_result set to 1\n");
}
else
{
prvscheck_result = NULL;
- DEBUG(D_expand) debug_printf("prvscheck: signature expired, $pvrs_result unset\n");
+ DEBUG(D_expand) debug_printf_indent("prvscheck: signature expired, $pvrs_result unset\n");
}
}
else
{
prvscheck_result = NULL;
- DEBUG(D_expand) debug_printf("prvscheck: hash failure, $pvrs_result unset\n");
+ DEBUG(D_expand) debug_printf_indent("prvscheck: hash failure, $pvrs_result unset\n");
}
/* Now expand the final argument. We leave this till now so that
struct sockaddr_un sockun; /* don't call this "sun" ! */
uschar *arg;
uschar *sub_arg[4];
+ BOOL do_shutdown = TRUE;
- if ((expand_forbid & RDO_READSOCK) != 0)
+ if (expand_forbid & RDO_READSOCK)
{
expand_string_message = US"socket insertions are not permitted";
goto EXPAND_FAILED;
case 3: goto EXPAND_FAILED;
}
- /* Sort out timeout, if given */
+ /* Sort out timeout, if given. The second arg is a list with the first element
+ being a time value. Any more are options of form "name=value". Currently the
+ only option recognised is "shutdown". */
- if (sub_arg[2] != NULL)
+ if (sub_arg[2])
{
- timeout = readconf_readtime(sub_arg[2], 0, FALSE);
- if (timeout < 0)
+ const uschar * list = sub_arg[2];
+ uschar * item;
+ int sep = 0;
+
+ item = string_nextinlist(&list, &sep, NULL, 0);
+ if ((timeout = readconf_readtime(item, 0, FALSE)) < 0)
{
- expand_string_message = string_sprintf("bad time value %s",
- sub_arg[2]);
+ expand_string_message = string_sprintf("bad time value %s", item);
goto EXPAND_FAILED;
}
+
+ while ((item = string_nextinlist(&list, &sep, NULL, 0)))
+ if (Ustrncmp(item, US"shutdown=", 9) == 0)
+ if (Ustrcmp(item + 9, US"no") == 0)
+ do_shutdown = FALSE;
}
else sub_arg[3] = NULL; /* No eol if no timeout */
port = ntohs(service_info->s_port);
}
- if ((fd = ip_connectedsocket(SOCK_STREAM, server_name, port, port,
- timeout, NULL, &expand_string_message)) < 0)
+ fd = ip_connectedsocket(SOCK_STREAM, server_name, port, port,
+ timeout, NULL, &expand_string_message);
+ callout_address = NULL;
+ if (fd < 0)
goto SOCK_FAIL;
}
}
}
- DEBUG(D_expand) debug_printf("connected to socket %s\n", sub_arg[0]);
+ DEBUG(D_expand) debug_printf_indent("connected to socket %s\n", sub_arg[0]);
/* Allow sequencing of test actions */
if (running_in_test_harness) millisleep(100);
if (sub_arg[1][0] != 0)
{
int len = Ustrlen(sub_arg[1]);
- DEBUG(D_expand) debug_printf("writing \"%s\" to socket\n",
+ DEBUG(D_expand) debug_printf_indent("writing \"%s\" to socket\n",
sub_arg[1]);
if (write(fd, sub_arg[1], len) != len)
{
recognise that it is their turn to do some work. Just in case some
system doesn't have this function, make it conditional. */
- #ifdef SHUT_WR
- shutdown(fd, SHUT_WR);
- #endif
+#ifdef SHUT_WR
+ if (do_shutdown) shutdown(fd, SHUT_WR);
+#endif
if (running_in_test_harness) millisleep(100);
while (isspace(*s)) s++;
}
- readsock_done:
+ READSOCK_DONE:
if (*s++ != '}')
{
expand_string_message = US"missing '}' closing readsocket";
socket, or timeout on reading. If another substring follows, expand and
use it. Otherwise, those conditions give expand errors. */
- SOCK_FAIL:
+ SOCK_FAIL:
if (*s != '{') goto EXPAND_FAILED;
DEBUG(D_any) debug_printf("%s\n", expand_string_message);
if (!(arg = expand_string_internal(s+1, TRUE, &s, FALSE, TRUE, &resetok)))
goto EXPAND_FAILED_CURLY;
}
while (isspace(*s)) s++;
- goto readsock_done;
+ goto READSOCK_DONE;
}
/* Handle "run" to execute a program. */
processing for real, we perform the iteration. */
if (skipping) continue;
- while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)) != NULL)
+ while ((iterate_item = string_nextinlist(&list, &sep, NULL, 0)))
{
*outsep = (uschar)sep; /* Separator as a string */
- DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, iterate_item);
+ DEBUG(D_expand) debug_printf_indent("%s: $item = '%s' $value = '%s'\n",
+ name, iterate_item, lookup_value);
if (item_type == EITEM_FILTER)
{
expand_string_message, name);
goto EXPAND_FAILED;
}
- DEBUG(D_expand) debug_printf("%s: condition is %s\n", name,
+ DEBUG(D_expand) debug_printf_indent("%s: condition is %s\n", name,
condresult? "true":"false");
if (condresult)
temp = iterate_item; /* TRUE => include this item */
uschar * newkeylist = NULL;
uschar * srcfield;
- DEBUG(D_expand) debug_printf("%s: $item = \"%s\"\n", name, srcitem);
+ DEBUG(D_expand) debug_printf_indent("%s: $item = \"%s\"\n", name, srcitem);
/* extract field for comparisons */
iterate_item = srcitem;
/* build and run condition string */
expr = string_sprintf("%s{%s}{%s}", cmp, srcfield, dstfield);
- DEBUG(D_expand) debug_printf("%s: cond = \"%s\"\n", name, expr);
+ DEBUG(D_expand) debug_printf_indent("%s: cond = \"%s\"\n", name, expr);
if (!eval_condition(expr, &resetok, &before))
{
expand_string_message = string_sprintf("comparison in sort: %s",
dstlist = newlist;
dstkeylist = newkeylist;
- DEBUG(D_expand) debug_printf("%s: dstlist = \"%s\"\n", name, dstlist);
- DEBUG(D_expand) debug_printf("%s: dstkeylist = \"%s\"\n", name, dstkeylist);
+ DEBUG(D_expand) debug_printf_indent("%s: dstlist = \"%s\"\n", name, dstlist);
+ DEBUG(D_expand) debug_printf_indent("%s: dstkeylist = \"%s\"\n", name, dstkeylist);
}
if (dstlist)
case EOP_LOCAL_PART:
case EOP_DOMAIN:
{
- uschar *error;
+ uschar * error;
int start, end, domain;
- uschar *t = parse_extract_address(sub, &error, &start, &end, &domain,
+ uschar * t = parse_extract_address(sub, &error, &start, &end, &domain,
FALSE);
- if (t != NULL)
- {
+ if (t)
if (c != EOP_DOMAIN)
{
if (c == EOP_LOCAL_PART && domain != 0) end = start + domain - 1;
domain += start;
yield = string_catn(yield, &size, &ptr, sub+domain, end-domain);
}
- }
continue;
}
goto EXPAND_FAILED;
}
yield = string_cat(yield, &size, &ptr, s);
- DEBUG(D_expand) debug_printf("yield: '%s'\n", yield);
+ DEBUG(D_expand) debug_printf_indent("yield: '%s'\n", yield);
continue;
}
DEBUG(D_expand)
{
- debug_printf(" expanding: %.*s\n result: %s\n", (int)(s - string), string,
+ debug_printf_indent(UTF8_VERT_RIGHT UTF8_HORIZ UTF8_HORIZ
+ "expanding: %.*s\n",
+ (int)(s - string), string);
+ debug_printf_indent("%s"
+ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
+ "result: %s\n",
+ skipping ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT,
yield);
- if (skipping) debug_printf(" skipping: result is not used\n");
+ if (skipping)
+ debug_printf_indent(UTF8_UP_RIGHT UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
+ "skipping: result is not used\n");
}
+expand_level--;
return yield;
/* This is the failure exit: easiest to program with a goto. We still need
if (left != NULL) *left = s;
DEBUG(D_expand)
{
- debug_printf("failed to expand: %s\n", string);
- debug_printf(" error message: %s\n", expand_string_message);
- if (expand_string_forcedfail) debug_printf("failure was forced\n");
+ debug_printf_indent(UTF8_VERT_RIGHT "failed to expand: %s\n",
+ string);
+ debug_printf_indent("%s" UTF8_HORIZ UTF8_HORIZ UTF8_HORIZ
+ "error message: %s\n",
+ expand_string_forcedfail ? UTF8_VERT_RIGHT : UTF8_UP_RIGHT,
+ expand_string_message);
+ if (expand_string_forcedfail)
+ debug_printf_indent(UTF8_UP_RIGHT "failure was forced\n");
}
if (resetok_p) *resetok_p = resetok;
+expand_level--;
return NULL;
}
if (*s == '\0')
{
DEBUG(D_expand)
- debug_printf("treating blank string as number 0\n");
+ debug_printf_indent("treating blank string as number 0\n");
return 0;
}
}
uschar * region_start;
uschar * region_end;
const uschar *var_name;
+ const uschar *var_data;
} err_ctx;
static void
{
err_ctx * e = ctx;
if (var_data >= e->region_start && var_data < e->region_end)
+ {
e->var_name = CUS var_name;
+ e->var_data = CUS var_data;
+ }
}
void
assert_variable_notin(US v->name, *(USS v->value), &e);
if (e.var_name)
- log_write(0, LOG_MAIN|LOG_PANIC_DIE, "live variable '%s' destroyed by reset_store"
- " at %s:%d\n", e.var_name, e.filename, e.linenumber);
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+ "live variable '%s' destroyed by reset_store at %s:%d\n- value '%.64s'",
+ e.var_name, e.filename, e.linenumber, e.var_data);
}