X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fstring.c;h=71c7f6f8e86188692f5da6a45620fa62607238cb;hb=e0eb00cd78f2dbf91aba5dffa579177b1e1815a1;hp=d501453c79eeab054196410d04ad0fe785bc5efd;hpb=1ba28e2b955b005ce4825fec792df17f75a8de1e;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/string.c b/src/src/string.c index d501453c7..71c7f6f8e 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/string.c,v 1.15 2009/11/16 19:50:37 nm4 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2009 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Miscellaneous string-handling functions. Some are not required for @@ -36,7 +34,7 @@ Returns: 0 if the string is not a textual representation of an IP address */ int -string_is_ip_address(uschar *s, int *maskptr) +string_is_ip_address(const uschar *s, int *maskptr) { int i; int yield = 4; @@ -46,7 +44,7 @@ offset. */ if (maskptr != NULL) { - uschar *ss = s + Ustrlen(s); + const uschar *ss = s + Ustrlen(s); *maskptr = 0; if (s != ss && isdigit(*(--ss))) { @@ -167,7 +165,7 @@ Returns: pointer to the buffer uschar * string_format_size(int size, uschar *buffer) { -if (size == 0) Ustrcpy(CS buffer, " "); +if (size == 0) Ustrcpy(buffer, " "); else if (size < 1024) sprintf(CS buffer, "%5d", size); else if (size < 10*1024) sprintf(CS buffer, "%4.1fK", (double)size / 1024.0); @@ -212,7 +210,6 @@ return yield; -#ifndef COMPILE_UTILITY /************************************************* * Interpret escape sequence * *************************************************/ @@ -229,6 +226,9 @@ Returns: the value of the character escape int string_interpret_escape(uschar **pp) { +#ifdef COMPILE_UTILITY +const uschar *hex_digits= CUS"0123456789abcdef"; +#endif int ch; uschar *p = *pp; ch = *(++p); @@ -244,9 +244,12 @@ if (isdigit(ch) && ch != '8' && ch != '9') } else switch(ch) { + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; case 'n': ch = '\n'; break; case 'r': ch = '\r'; break; case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; case 'x': ch = 0; if (isxdigit(p[1])) @@ -261,7 +264,6 @@ else switch(ch) *pp = p; return ch; } -#endif /* COMPILE_UTILITY */ @@ -302,7 +304,7 @@ if (nonprintcount == 0) return s; /* Get a new block of store guaranteed big enough to hold the expanded string. */ -ss = store_get(length + nonprintcount * 4 + 1); +ss = store_get(length + nonprintcount * 3 + 1); /* Copy everying, escaping non printers. */ @@ -333,6 +335,73 @@ return ss; } #endif /* COMPILE_UTILITY */ +/************************************************* +* Undo printing escapes in string * +*************************************************/ + +/* This function is the reverse of string_printing2. It searches for +backslash characters and if any are found, it makes a new copy of the +string with escape sequences parsed. Otherwise it returns the original +string. + +Arguments: + s the input string + +Returns: string with printing escapes parsed back +*/ + +uschar * +string_unprinting(uschar *s) +{ +uschar *p, *q, *r, *ss; +int len, off; + +p = Ustrchr(s, '\\'); +if (!p) return s; + +len = Ustrlen(s) + 1; +ss = store_get(len); + +q = ss; +off = p - s; +if (off) + { + memcpy(q, s, off); + q += off; + } + +while (*p) + { + if (*p == '\\') + { + *q++ = string_interpret_escape(&p); + p++; + } + else + { + r = Ustrchr(p, '\\'); + if (!r) + { + off = Ustrlen(p); + memcpy(q, p, off); + p += off; + q += off; + break; + } + else + { + off = r - p; + memcpy(q, p, off); + q += off; + p = r; + } + } + } +*q = '\0'; + +return ss; +} + @@ -347,7 +416,7 @@ Returns: copy of string in new store */ uschar * -string_copy(uschar *s) +string_copy(const uschar *s) { int len = Ustrlen(s) + 1; uschar *ss = store_get(len); @@ -388,7 +457,7 @@ Returns: copy of string in new store, with letters lowercased */ uschar * -string_copylc(uschar *s) +string_copylc(const uschar *s) { uschar *ss = store_get(Ustrlen(s) + 1); uschar *p = ss; @@ -414,7 +483,7 @@ Returns: copy of string in new store */ uschar * -string_copyn(uschar *s, int n) +string_copyn(const uschar *s, int n) { uschar *ss = store_get(n + 1); Ustrncpy(ss, s, n); @@ -648,7 +717,8 @@ uschar buffer[STRING_SPRINTF_BUFFER_SIZE]; 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 %d", sizeof(buffer)); + "string_sprintf expansion was longer than " SIZE_T_FMT " (%s)", + sizeof(buffer), format); va_end(ap); return string_copy(buffer); } @@ -897,6 +967,50 @@ return buffer; #endif /* COMPILE_UTILITY */ +#ifndef COMPILE_UTILITY +/************************************************ +* Add element to seperated list * +************************************************/ +/* This function is used to build a list, returning +an allocated null-terminated growable string. The +given element has any embedded seperator characters +doubled. + +Arguments: + list points to the start of the list that is being built, or NULL + if this is a new list that has no contents yet + sep list seperator charactoer + ele new lement to be appended to the list + +Returns: pointer to the start of the list, changed if copied for expansion. +*/ + +uschar * +string_append_listele(uschar * list, uschar sep, const uschar * ele) +{ +uschar * new = NULL; +int sz = 0, off = 0; +uschar * sp; + +if (list) + { + new = string_cat(new, &sz, &off, list, Ustrlen(list)); + new = string_cat(new, &sz, &off, &sep, 1); + } + +while((sp = Ustrchr(ele, sep))) + { + new = string_cat(new, &sz, &off, ele, sp-ele+1); + new = string_cat(new, &sz, &off, &sep, 1); + ele = sp+1; + } +new = string_cat(new, &sz, &off, ele, Ustrlen(ele)); +new[off] = '\0'; +return new; +} +#endif /* COMPILE_UTILITY */ + + #ifndef COMPILE_UTILITY /************************************************* @@ -1066,7 +1180,8 @@ return yield; BOOL string_vformat(uschar *buffer, int buflen, const char *format, va_list ap) { -enum { L_NORMAL, L_SHORT, L_LONG, L_LONGLONG, L_LONGDOUBLE }; +/* We assume numbered ascending order, C does not guarantee that */ +enum { L_NORMAL=1, L_SHORT=2, L_LONG=3, L_LONGLONG=4, L_LONGDOUBLE=5, L_SIZE=6 }; BOOL yield = TRUE; int width, precision; @@ -1136,7 +1251,7 @@ while (*fp != 0) } } - /* Skip over 'h', 'L', 'l', and 'll', remembering the item length */ + /* Skip over 'h', 'L', 'l', 'll' and 'z', remembering the item length */ if (*fp == 'h') { fp++; length = L_SHORT; } @@ -1155,6 +1270,8 @@ while (*fp != 0) length = L_LONG; } } + else if (*fp == 'z') + { fp++; length = L_SIZE; } /* Handle each specific format type. */ @@ -1184,6 +1301,7 @@ while (*fp != 0) case L_NORMAL: sprintf(CS p, newformat, va_arg(ap, int)); break; case L_LONG: sprintf(CS p, newformat, va_arg(ap, long int)); break; case L_LONGLONG: sprintf(CS p, newformat, va_arg(ap, LONGLONG_T)); break; + case L_SIZE: sprintf(CS p, newformat, va_arg(ap, size_t)); break; } while (*p) p++; break;