* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
/* See the file NOTICE for conditions of use and distribution. */
/* Miscellaneous string-handling functions. Some are not required for
va_start(ap, format);
if (!string_vformat(buffer, sizeof(buffer), format, ap))
log_write(0, LOG_MAIN|LOG_PANIC_DIE,
- "string_sprintf expansion was longer than " SIZE_T_FMT " (%s)",
- sizeof(buffer), format);
+ "string_sprintf expansion was longer than " SIZE_T_FMT
+ "; format string was (%s)\nexpansion started '%.32s'",
+ sizeof(buffer), format, buffer);
va_end(ap);
return string_copy(buffer);
}
#ifndef COMPILE_UTILITY
/************************************************
-* Add element to seperated list *
+* Add element to separated list *
************************************************/
/* This function is used to build a list, returning
an allocated null-terminated growable string. The
static const uschar *
Ustrnchr(const uschar * s, int c, unsigned * len)
{
-while (*len)
+unsigned siz = *len;
+while (siz)
{
if (!*s) return NULL;
- if (*s == c) return s;
+ if (*s == c)
+ {
+ *len = siz;
+ return s;
+ }
s++;
- *len--;
+ siz--;
}
return NULL;
}
string_get_localpart(address_item *addr, uschar *yield, int *sizeptr,
int *ptrptr)
{
-if (testflag(addr, af_include_affixes) && addr->prefix != NULL)
- yield = string_cat(yield, sizeptr, ptrptr, addr->prefix,
- Ustrlen(addr->prefix));
-yield = string_cat(yield, sizeptr, ptrptr, addr->local_part,
- Ustrlen(addr->local_part));
-if (testflag(addr, af_include_affixes) && addr->suffix != NULL)
- yield = string_cat(yield, sizeptr, ptrptr, addr->suffix,
- Ustrlen(addr->suffix));
+uschar * s;
+
+s = addr->prefix;
+if (testflag(addr, af_include_affixes) && s)
+ {
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s));
+ }
+
+s = addr->local_part;
+#ifdef SUPPORT_I18N
+if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s));
+
+s = addr->suffix;
+if (testflag(addr, af_include_affixes) && s)
+ {
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s));
+ }
+
return yield;
}
{
if (addr->local_part != NULL)
{
+ const uschar * s;
yield = string_get_localpart(addr, yield, &size, &ptr);
yield = string_cat(yield, &size, &ptr, US"@", 1);
- yield = string_cat(yield, &size, &ptr, addr->domain,
- Ustrlen(addr->domain) );
+ s = addr->domain;
+#ifdef SUPPORT_I18N
+ if (testflag(addr, af_utf8_downcvt))
+ s = string_localpart_utf8_to_alabel(s, NULL);
+#endif
+ yield = string_cat(yield, &size, &ptr, s, Ustrlen(s) );
}
else
{
#endif /* COMPILE_UTILITY */
+#ifndef COMPILE_UTILITY
+/* qsort(3), currently used to sort the environment variables
+for -bP environment output, needs a function to compare two pointers to string
+pointers. Here it is. */
+
+int
+string_compare_by_pointer(const void *a, const void *b)
+{
+return Ustrcmp(CUSS *(const char**) a, CUSS *(const char**) b);
+}
+#endif /* COMPILE_UTILITY */