X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsrc%2Fexpand.c;h=04bb9291610f4d910cb32447bd90893648ad1217;hb=4c0a7a9cb02f9904c2e890f77ff8ce3a6beb25f4;hp=d35bf99018dee942bcefc1df263d72d100b750bf;hpb=cf0812d57c63b531e2e73187508c7ae99156043c;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/expand.c b/src/src/expand.c index d35bf9901..04bb92916 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -642,7 +642,7 @@ static var_entry var_table[] = { { "received_ip_address", vtype_stringptr, &interface_address }, { "received_port", vtype_int, &interface_port }, { "received_protocol", vtype_stringptr, &received_protocol }, - { "received_time", vtype_int, &received_time }, + { "received_time", vtype_int, &received_time.tv_sec }, { "recipient_data", vtype_stringptr, &recipient_data }, { "recipient_verify_failure",vtype_stringptr,&recipient_verify_failure }, { "recipients", vtype_string_func, &fn_recipients }, @@ -680,6 +680,7 @@ static var_entry var_table[] = { { "smtp_active_hostname", vtype_stringptr, &smtp_active_hostname }, { "smtp_command", vtype_stringptr, &smtp_cmd_buffer }, { "smtp_command_argument", vtype_stringptr, &smtp_cmd_argument }, + { "smtp_command_history", vtype_string_func, &smtp_cmd_hist }, { "smtp_count_at_connection_start", vtype_int, &smtp_accept_count }, { "smtp_notquit_reason", vtype_stringptr, &smtp_notquit_reason }, { "sn0", vtype_filter_int, &filter_sn[0] }, @@ -1483,9 +1484,7 @@ while (*s != 0) /* If value2 is unset, just compute one number */ if (value2 < 0) - { s = string_sprintf("%d", total % value1); - } /* Otherwise do a div/mod hash */ @@ -1554,11 +1553,9 @@ for (i = 0; i < 2; i++) int size = 0; header_line *h; - for (h = header_list; size < header_insert_maxlen && h != NULL; h = h->next) - { - if (h->type != htype_old && h->text != NULL) /* NULL => Received: placeholder */ - { - if (name == NULL || (len <= h->slen && strncmpic(name, h->text, len) == 0)) + for (h = header_list; size < header_insert_maxlen && h; h = h->next) + if (h->type != htype_old && h->text) /* NULL => Received: placeholder */ + if (!name || (len <= h->slen && strncmpic(name, h->text, len) == 0)) { int ilen; uschar *t; @@ -1580,7 +1577,7 @@ for (i = 0; i < 2; i++) that contains an address list, except when asked for raw headers. Only need to do this once. */ - if (!want_raw && name != NULL && comma == 0 && + if (!want_raw && name && comma == 0 && Ustrchr("BCFRST", h->type) != NULL) comma = 1; @@ -1613,8 +1610,6 @@ for (i = 0; i < 2; i++) } } } - } - } /* At end of first pass, return NULL if no header found. Then truncate size if necessary, and get the buffer to hold the data, returning the buffer size. @@ -1632,9 +1627,7 @@ for (i = 0; i < 2; i++) /* That's all we do for raw header expansion. */ if (want_raw) - { *ptr = 0; - } /* Otherwise, remove a final newline and a redundant added comma. Then we do RFC 2047 decoding, translating the charset if requested. The rfc2047_decode2() @@ -1838,7 +1831,7 @@ switch (vp->type) case vtype_msgbody: /* Pointer to msgbody string */ case vtype_msgbody_end: /* Ditto, the end of the msg */ ss = (uschar **)(val); - if (*ss == NULL && deliver_datafile >= 0) /* Read body when needed */ + if (!*ss && deliver_datafile >= 0) /* Read body when needed */ { uschar *body; off_t start_offset = SPOOL_DATA_START_OFFSET; @@ -1871,7 +1864,7 @@ switch (vp->type) { if (body[--len] == '\n' || body[len] == 0) body[len] = ' '; } } } - return (*ss == NULL)? US"" : *ss; + return *ss ? *ss : US""; case vtype_todbsdin: /* BSD inbox time of day */ return tod_stamp(tod_bsdin); @@ -2099,7 +2092,7 @@ while (i < nsub) } 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"", acl_narg>1 ? " +more" : ""); @@ -2384,8 +2377,10 @@ switch(cond_type) case 3: return NULL; } - *resetok = FALSE; /* eval_acl() might allocate; do not reclaim */ - if (yield != NULL) switch(eval_acl(sub, nelem(sub), &user_msg)) + if (yield != NULL) + { + *resetok = FALSE; /* eval_acl() might allocate; do not reclaim */ + switch(eval_acl(sub, nelem(sub), &user_msg)) { case OK: cond = TRUE; @@ -2406,6 +2401,7 @@ switch(cond_type) expand_string_message = string_sprintf("error from acl \"%s\"", sub[0]); return NULL; } + } return s; } @@ -2523,7 +2519,7 @@ switch(cond_type) { 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 { @@ -2832,7 +2828,7 @@ switch(cond_type) 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 @@ -2920,7 +2916,7 @@ switch(cond_type) 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 */ @@ -2959,7 +2955,7 @@ switch(cond_type) 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", @@ -2967,7 +2963,7 @@ switch(cond_type) 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); @@ -3024,7 +3020,7 @@ switch(cond_type) } } DEBUG(D_expand) - debug_printf("considering %s: %s\n", ourname, len ? t : US""); + debug_printf_indent("considering %s: %s\n", ourname, len ? t : US""); /* 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. */ @@ -3051,7 +3047,7 @@ switch(cond_type) "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; @@ -3194,17 +3190,17 @@ items. */ 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; } @@ -3447,7 +3443,7 @@ hash_source = string_catn(hash_source, &size, &offset, daystamp, 3); 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); @@ -3870,8 +3866,13 @@ uschar *save_expand_nstring[EXPAND_MAXN+1]; 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""; @@ -4086,7 +4087,7 @@ while (*s != 0) 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; @@ -4117,9 +4118,15 @@ while (*s != 0) 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; @@ -4576,11 +4583,11 @@ while (*s != 0) 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); @@ -4608,8 +4615,8 @@ while (*s != 0) 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) { @@ -4627,18 +4634,18 @@ while (*s != 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 @@ -4724,8 +4731,9 @@ while (*s != 0) 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; @@ -4741,17 +4749,27 @@ while (*s != 0) 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 */ @@ -4801,8 +4819,10 @@ while (*s != 0) 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; } @@ -4839,7 +4859,7 @@ while (*s != 0) } } - 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); @@ -4849,7 +4869,7 @@ while (*s != 0) 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) { @@ -4863,9 +4883,9 @@ while (*s != 0) 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); @@ -4905,7 +4925,7 @@ while (*s != 0) while (isspace(*s)) s++; } - readsock_done: + READSOCK_DONE: if (*s++ != '}') { expand_string_message = US"missing '}' closing readsocket"; @@ -4917,7 +4937,7 @@ while (*s != 0) 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))) @@ -4929,7 +4949,7 @@ while (*s != 0) goto EXPAND_FAILED_CURLY; } while (isspace(*s)) s++; - goto readsock_done; + goto READSOCK_DONE; } /* Handle "run" to execute a program. */ @@ -5797,11 +5817,12 @@ while (*s != 0) 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) { @@ -5814,7 +5835,7 @@ while (*s != 0) 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 */ @@ -5966,10 +5987,12 @@ while (*s != 0) { uschar * dstitem; uschar * newlist = NULL; + int size = 0, len = 0; uschar * newkeylist = NULL; + int ksize = 0, klen = 0; 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; @@ -5998,7 +6021,7 @@ while (*s != 0) /* 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", @@ -6011,40 +6034,40 @@ while (*s != 0) /* New-item sorts before this dst-item. Append new-item, then dst-item, then remainder of dst list. */ - newlist = string_append_listele(newlist, sep, srcitem); - newkeylist = string_append_listele(newkeylist, sep, srcfield); + newlist = string_append_listele(newlist, &size, &len, sep, srcitem); + newkeylist = string_append_listele(newkeylist, &ksize, &klen, sep, srcfield); srcitem = NULL; - newlist = string_append_listele(newlist, sep, dstitem); - newkeylist = string_append_listele(newkeylist, sep, dstfield); + newlist = string_append_listele(newlist, &size, &len, sep, dstitem); + newkeylist = string_append_listele(newkeylist, &ksize, &klen, sep, dstfield); while ((dstitem = string_nextinlist(&dstlist, &sep, NULL, 0))) { if (!(dstfield = string_nextinlist(&dstkeylist, &sep, NULL, 0))) goto sort_mismatch; - newlist = string_append_listele(newlist, sep, dstitem); - newkeylist = string_append_listele(newkeylist, sep, dstfield); + newlist = string_append_listele(newlist, &size, &len, sep, dstitem); + newkeylist = string_append_listele(newkeylist, &ksize, &klen, sep, dstfield); } break; } - newlist = string_append_listele(newlist, sep, dstitem); - newkeylist = string_append_listele(newkeylist, sep, dstfield); + newlist = string_append_listele(newlist, &size, &len, sep, dstitem); + newkeylist = string_append_listele(newkeylist, &ksize, &klen, sep, dstfield); } /* If we ran out of dstlist without consuming srcitem, append it */ if (srcitem) { - newlist = string_append_listele(newlist, sep, srcitem); - newkeylist = string_append_listele(newkeylist, sep, srcfield); + newlist = string_append_listele(newlist, &size, &len, sep, srcitem); + newkeylist = string_append_listele(newkeylist, &ksize, &klen, sep, srcfield); } 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) @@ -6441,7 +6464,7 @@ while (*s != 0) blob b; char st[3]; - if (!exim_sha_init(&h, HASH_SHA256)) + if (!exim_sha_init(&h, HASH_SHA2_256)) { expand_string_message = US"unrecognised sha256 variant"; goto EXPAND_FAILED; @@ -6635,19 +6658,19 @@ while (*s != 0) char * cp; char tok[3]; tok[0] = sep; tok[1] = ':'; tok[2] = 0; - while ((cp= strpbrk((const char *)item, tok))) + while ((cp= strpbrk(CCS item, tok))) { - yield = string_catn(yield, &size, &ptr, item, cp-(char *)item); + yield = string_catn(yield, &size, &ptr, item, cp-CS item); if (*cp++ == ':') /* colon in a non-colon-sep list item, needs doubling */ { yield = string_catn(yield, &size, &ptr, US"::", 2); - item = (uschar *)cp; + item = US cp; } else /* sep in item; should already be doubled; emit once */ { - yield = string_catn(yield, &size, &ptr, (uschar *)tok, 1); + yield = string_catn(yield, &size, &ptr, US tok, 1); if (*cp == sep) cp++; - item = (uschar *)cp; + item = US cp; } } } @@ -6741,12 +6764,11 @@ while (*s != 0) 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; @@ -6757,7 +6779,6 @@ while (*s != 0) domain += start; yield = string_catn(yield, &size, &ptr, sub+domain, end-domain); } - } continue; } @@ -7093,7 +7114,7 @@ while (*s != 0) 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; } @@ -7487,10 +7508,19 @@ else if (resetok_p) *resetok_p = FALSE; 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 @@ -7512,11 +7542,17 @@ EXPAND_FAILED: 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; } @@ -7643,7 +7679,7 @@ if (isspace(*s)) 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; } } @@ -7786,6 +7822,7 @@ typedef struct { uschar * region_start; uschar * region_end; const uschar *var_name; + const uschar *var_data; } err_ctx; static void @@ -7793,7 +7830,10 @@ assert_variable_notin(uschar * var_name, uschar * var_data, void * ctx) { 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 @@ -7821,8 +7861,9 @@ for (v = var_table; v < var_table + var_table_size; v++) 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); }