static uschar * checkexpand(uschar *s, address_item *addr, uschar *name, int type) { uschar *t; uschar *ss = expand_string(s); if (ss == NULL) { addr->transport_return = FAIL; addr->message = string_sprintf("Expansion of \"%s\" failed in %s transport: " "%s", s, name, expand_string_message); return NULL; } if (type != cke_text) for (t = ss; *t != 0; t++) { int c = *t; if (mac_isprint(c)) continue; if (type == cke_hdr && c == '\n' && (t[1] == ' ' || t[1] == '\t')) continue; s = string_printing(s); addr->transport_return = FAIL; addr->message = string_sprintf("Expansion of \"%s\" in %s transport " "contains non-printing character %d", s, name, c); return NULL; } return ss; }
const uschar * string_printing2(const uschar *s, BOOL allow_tab) { int nonprintcount = 0; int length = 0; const uschar *t = s; uschar *ss, *tt; while (*t != 0) { int c = *t++; if (!mac_isprint(c) || (!allow_tab && c == '\t')) nonprintcount++; length++; } if (nonprintcount == 0) return s; /* Get a new block of store guaranteed big enough to hold the expanded string. */ ss = store_get(length + nonprintcount * 3 + 1); /* Copy everying, escaping non printers. */ t = s; tt = ss; while (*t != 0) { int c = *t; if (mac_isprint(c) && (allow_tab || c != '\t')) *tt++ = *t++; else { *tt++ = '\\'; switch (*t) { case '\n': *tt++ = 'n'; break; case '\r': *tt++ = 'r'; break; case '\b': *tt++ = 'b'; break; case '\v': *tt++ = 'v'; break; case '\f': *tt++ = 'f'; break; case '\t': *tt++ = 't'; break; default: sprintf(CS tt, "%03o", *t); tt += 3; break; } t++; } } *tt = 0; return ss; }