Fix ${readsocket } eol-replacement. Bug 2630
[exim.git] / src / src / string.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* Copyright (c) The Exim Maintainers 2020 */
7 /* See the file NOTICE for conditions of use and distribution. */
8
9 /* Miscellaneous string-handling functions. Some are not required for
10 utilities and tests, and are cut out by the COMPILE_UTILITY macro. */
11
12
13 #include "exim.h"
14 #include <assert.h>
15
16
17 #ifndef COMPILE_UTILITY
18 /*************************************************
19 *            Test for IP address                 *
20 *************************************************/
21
22 /* This used just to be a regular expression, but with IPv6 things are a bit
23 more complicated. If the address contains a colon, it is assumed to be a v6
24 address (assuming HAVE_IPV6 is set). If a mask is permitted and one is present,
25 and maskptr is not NULL, its offset is placed there.
26
27 Arguments:
28   s         a string
29   maskptr   NULL if no mask is permitted to follow
30             otherwise, points to an int where the offset of '/' is placed
31             if there is no / followed by trailing digits, *maskptr is set 0
32
33 Returns:    0 if the string is not a textual representation of an IP address
34             4 if it is an IPv4 address
35             6 if it is an IPv6 address
36 */
37
38 int
39 string_is_ip_address(const uschar *s, int *maskptr)
40 {
41 int yield = 4;
42
43 /* If an optional mask is permitted, check for it. If found, pass back the
44 offset. */
45
46 if (maskptr)
47   {
48   const uschar *ss = s + Ustrlen(s);
49   *maskptr = 0;
50   if (s != ss && isdigit(*(--ss)))
51     {
52     while (ss > s && isdigit(ss[-1])) ss--;
53     if (ss > s && *(--ss) == '/') *maskptr = ss - s;
54     }
55   }
56
57 /* A colon anywhere in the string => IPv6 address */
58
59 if (Ustrchr(s, ':') != NULL)
60   {
61   BOOL had_double_colon = FALSE;
62   BOOL v4end = FALSE;
63
64   yield = 6;
65
66   /* An IPv6 address must start with hex digit or double colon. A single
67   colon is invalid. */
68
69   if (*s == ':' && *(++s) != ':') return 0;
70
71   /* Now read up to 8 components consisting of up to 4 hex digits each. There
72   may be one and only one appearance of double colon, which implies any number
73   of binary zero bits. The number of preceding components is held in count. */
74
75   for (int count = 0; count < 8; count++)
76     {
77     /* If the end of the string is reached before reading 8 components, the
78     address is valid provided a double colon has been read. This also applies
79     if we hit the / that introduces a mask or the % that introduces the
80     interface specifier (scope id) of a link-local address. */
81
82     if (*s == 0 || *s == '%' || *s == '/') return had_double_colon ? yield : 0;
83
84     /* If a component starts with an additional colon, we have hit a double
85     colon. This is permitted to appear once only, and counts as at least
86     one component. The final component may be of this form. */
87
88     if (*s == ':')
89       {
90       if (had_double_colon) return 0;
91       had_double_colon = TRUE;
92       s++;
93       continue;
94       }
95
96     /* If the remainder of the string contains a dot but no colons, we
97     can expect a trailing IPv4 address. This is valid if either there has
98     been no double-colon and this is the 7th component (with the IPv4 address
99     being the 7th & 8th components), OR if there has been a double-colon
100     and fewer than 6 components. */
101
102     if (Ustrchr(s, ':') == NULL && Ustrchr(s, '.') != NULL)
103       {
104       if ((!had_double_colon && count != 6) ||
105           (had_double_colon && count > 6)) return 0;
106       v4end = TRUE;
107       yield = 6;
108       break;
109       }
110
111     /* Check for at least one and not more than 4 hex digits for this
112     component. */
113
114     if (!isxdigit(*s++)) return 0;
115     if (isxdigit(*s) && isxdigit(*(++s)) && isxdigit(*(++s))) s++;
116
117     /* If the component is terminated by colon and there is more to
118     follow, skip over the colon. If there is no more to follow the address is
119     invalid. */
120
121     if (*s == ':' && *(++s) == 0) return 0;
122     }
123
124   /* If about to handle a trailing IPv4 address, drop through. Otherwise
125   all is well if we are at the end of the string or at the mask or at a percent
126   sign, which introduces the interface specifier (scope id) of a link local
127   address. */
128
129   if (!v4end)
130     return (*s == 0 || *s == '%' ||
131            (*s == '/' && maskptr != NULL && *maskptr != 0))? yield : 0;
132   }
133
134 /* Test for IPv4 address, which may be the tail-end of an IPv6 address. */
135
136 for (int i = 0; i < 4; i++)
137   {
138   long n;
139   uschar * end;
140
141   if (i != 0 && *s++ != '.') return 0;
142   n = strtol(CCS s, CSS &end, 10);
143   if (n > 255 || n < 0 || end <= s || end > s+3) return 0;
144   s = end;
145   }
146
147 return !*s || (*s == '/' && maskptr && *maskptr != 0) ? yield : 0;
148 }
149 #endif  /* COMPILE_UTILITY */
150
151
152 /*************************************************
153 *              Format message size               *
154 *************************************************/
155
156 /* Convert a message size in bytes to printing form, rounding
157 according to the magnitude of the number. A value of zero causes
158 a string of spaces to be returned.
159
160 Arguments:
161   size        the message size in bytes
162   buffer      where to put the answer
163
164 Returns:      pointer to the buffer
165               a string of exactly 5 characters is normally returned
166 */
167
168 uschar *
169 string_format_size(int size, uschar *buffer)
170 {
171 if (size == 0) Ustrcpy(buffer, US"     ");
172 else if (size < 1024) sprintf(CS buffer, "%5d", size);
173 else if (size < 10*1024)
174   sprintf(CS buffer, "%4.1fK", (double)size / 1024.0);
175 else if (size < 1024*1024)
176   sprintf(CS buffer, "%4dK", (size + 512)/1024);
177 else if (size < 10*1024*1024)
178   sprintf(CS buffer, "%4.1fM", (double)size / (1024.0 * 1024.0));
179 else
180   sprintf(CS buffer, "%4dM", (size + 512 * 1024)/(1024*1024));
181 return buffer;
182 }
183
184
185
186 #ifndef COMPILE_UTILITY
187 /*************************************************
188 *       Convert a number to base 62 format       *
189 *************************************************/
190
191 /* Convert a long integer into an ASCII base 62 string. For Cygwin the value of
192 BASE_62 is actually 36. Always return exactly 6 characters plus zero, in a
193 static area.
194
195 Argument: a long integer
196 Returns:  pointer to base 62 string
197 */
198
199 uschar *
200 string_base62(unsigned long int value)
201 {
202 static uschar yield[7];
203 uschar *p = yield + sizeof(yield) - 1;
204 *p = 0;
205 while (p > yield)
206   {
207   *(--p) = base62_chars[value % BASE_62];
208   value /= BASE_62;
209   }
210 return yield;
211 }
212 #endif  /* COMPILE_UTILITY */
213
214
215
216 /*************************************************
217 *          Interpret escape sequence             *
218 *************************************************/
219
220 /* This function is called from several places where escape sequences are to be
221 interpreted in strings.
222
223 Arguments:
224   pp       points a pointer to the initiating "\" in the string;
225            the pointer gets updated to point to the final character
226            If the backslash is the last character in the string, it
227            is not interpreted.
228 Returns:   the value of the character escape
229 */
230
231 int
232 string_interpret_escape(const uschar **pp)
233 {
234 #ifdef COMPILE_UTILITY
235 const uschar *hex_digits= CUS"0123456789abcdef";
236 #endif
237 int ch;
238 const uschar *p = *pp;
239 ch = *(++p);
240 if (ch == '\0') return **pp;
241 if (isdigit(ch) && ch != '8' && ch != '9')
242   {
243   ch -= '0';
244   if (isdigit(p[1]) && p[1] != '8' && p[1] != '9')
245     {
246     ch = ch * 8 + *(++p) - '0';
247     if (isdigit(p[1]) && p[1] != '8' && p[1] != '9')
248       ch = ch * 8 + *(++p) - '0';
249     }
250   }
251 else switch(ch)
252   {
253   case 'b':  ch = '\b'; break;
254   case 'f':  ch = '\f'; break;
255   case 'n':  ch = '\n'; break;
256   case 'r':  ch = '\r'; break;
257   case 't':  ch = '\t'; break;
258   case 'v':  ch = '\v'; break;
259   case 'x':
260   ch = 0;
261   if (isxdigit(p[1]))
262     {
263     ch = ch * 16 +
264       Ustrchr(hex_digits, tolower(*(++p))) - hex_digits;
265     if (isxdigit(p[1])) ch = ch * 16 +
266       Ustrchr(hex_digits, tolower(*(++p))) - hex_digits;
267     }
268   break;
269   }
270 *pp = p;
271 return ch;
272 }
273
274
275
276 #ifndef COMPILE_UTILITY
277 /*************************************************
278 *          Ensure string is printable            *
279 *************************************************/
280
281 /* This function is called for critical strings. It checks for any
282 non-printing characters, and if any are found, it makes a new copy
283 of the string with suitable escape sequences. It is most often called by the
284 macro string_printing(), which sets flags to 0.
285
286 Arguments:
287   s             the input string
288   flags         Bit 0: convert tabs.  Bit 1: convert spaces.
289
290 Returns:        string with non-printers encoded as printing sequences
291 */
292
293 const uschar *
294 string_printing2(const uschar *s, int flags)
295 {
296 int nonprintcount = 0;
297 int length = 0;
298 const uschar *t = s;
299 uschar *ss, *tt;
300
301 while (*t != 0)
302   {
303   int c = *t++;
304   if (  !mac_isprint(c)
305      || flags & SP_TAB && c == '\t'
306      || flags & SP_SPACE && c == ' '
307      ) nonprintcount++;
308   length++;
309   }
310
311 if (nonprintcount == 0) return s;
312
313 /* Get a new block of store guaranteed big enough to hold the
314 expanded string. */
315
316 tt = ss = store_get(length + nonprintcount * 3 + 1, is_tainted(s));
317
318 /* Copy everything, escaping non printers. */
319
320 for (t = s; *t; )
321   {
322   int c = *t;
323   if (  mac_isprint(c)
324      && (!(flags & SP_TAB) || c != '\t')
325      && (!(flags & SP_SPACE) || c != ' ')
326      )
327     *tt++ = *t++;
328   else
329     {
330     *tt++ = '\\';
331     switch (*t)
332       {
333       case '\n': *tt++ = 'n'; break;
334       case '\r': *tt++ = 'r'; break;
335       case '\b': *tt++ = 'b'; break;
336       case '\v': *tt++ = 'v'; break;
337       case '\f': *tt++ = 'f'; break;
338       case '\t': *tt++ = 't'; break;
339       default: sprintf(CS tt, "%03o", *t); tt += 3; break;
340       }
341     t++;
342     }
343   }
344 *tt = 0;
345 return ss;
346 }
347 #endif  /* COMPILE_UTILITY */
348
349 /*************************************************
350 *        Undo printing escapes in string         *
351 *************************************************/
352
353 /* This function is the reverse of string_printing2.  It searches for
354 backslash characters and if any are found, it makes a new copy of the
355 string with escape sequences parsed.  Otherwise it returns the original
356 string.
357
358 Arguments:
359   s             the input string
360
361 Returns:        string with printing escapes parsed back
362 */
363
364 uschar *
365 string_unprinting(uschar *s)
366 {
367 uschar *p, *q, *r, *ss;
368 int len, off;
369
370 p = Ustrchr(s, '\\');
371 if (!p) return s;
372
373 len = Ustrlen(s) + 1;
374 ss = store_get(len, is_tainted(s));
375
376 q = ss;
377 off = p - s;
378 if (off)
379   {
380   memcpy(q, s, off);
381   q += off;
382   }
383
384 while (*p)
385   {
386   if (*p == '\\')
387     {
388     *q++ = string_interpret_escape((const uschar **)&p);
389     p++;
390     }
391   else
392     {
393     r = Ustrchr(p, '\\');
394     if (!r)
395       {
396       off = Ustrlen(p);
397       memcpy(q, p, off);
398       p += off;
399       q += off;
400       break;
401       }
402     else
403       {
404       off = r - p;
405       memcpy(q, p, off);
406       q += off;
407       p = r;
408       }
409     }
410   }
411 *q = '\0';
412
413 return ss;
414 }
415
416
417
418
419 #if (defined(HAVE_LOCAL_SCAN) || defined(EXPAND_DLFUNC)) \
420         && !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
421 /*************************************************
422 *            Copy and save string                *
423 *************************************************/
424
425 /*
426 Argument: string to copy
427 Returns:  copy of string in new store with the same taint status
428 */
429
430 uschar *
431 string_copy_function(const uschar *s)
432 {
433 return string_copy_taint(s, is_tainted(s));
434 }
435
436 /* This function assumes that memcpy() is faster than strcpy().
437 As above, but explicitly specifying the result taint status
438 */
439
440 uschar *
441 string_copy_taint_function(const uschar * s, BOOL tainted)
442 {
443 int len = Ustrlen(s) + 1;
444 uschar *ss = store_get(len, tainted);
445 memcpy(ss, s, len);
446 return ss;
447 }
448
449
450
451 /*************************************************
452 *       Copy and save string, given length       *
453 *************************************************/
454
455 /* It is assumed the data contains no zeros. A zero is added
456 onto the end.
457
458 Arguments:
459   s         string to copy
460   n         number of characters
461
462 Returns:    copy of string in new store
463 */
464
465 uschar *
466 string_copyn_function(const uschar *s, int n)
467 {
468 uschar *ss = store_get(n + 1, is_tainted(s));
469 Ustrncpy(ss, s, n);
470 ss[n] = 0;
471 return ss;
472 }
473 #endif
474
475
476 /*************************************************
477 *     Copy and save string in malloc'd store     *
478 *************************************************/
479
480 /* This function assumes that memcpy() is faster than strcpy().
481
482 Argument: string to copy
483 Returns:  copy of string in new store
484 */
485
486 uschar *
487 string_copy_malloc(const uschar *s)
488 {
489 int len = Ustrlen(s) + 1;
490 uschar *ss = store_malloc(len);
491 memcpy(ss, s, len);
492 return ss;
493 }
494
495
496
497 /*************************************************
498 *    Copy string if long, inserting newlines     *
499 *************************************************/
500
501 /* If the given string is longer than 75 characters, it is copied, and within
502 the copy, certain space characters are converted into newlines.
503
504 Argument:  pointer to the string
505 Returns:   pointer to the possibly altered string
506 */
507
508 uschar *
509 string_split_message(uschar *msg)
510 {
511 uschar *s, *ss;
512
513 if (msg == NULL || Ustrlen(msg) <= 75) return msg;
514 s = ss = msg = string_copy(msg);
515
516 for (;;)
517   {
518   int i = 0;
519   while (i < 75 && *ss != 0 && *ss != '\n') ss++, i++;
520   if (*ss == 0) break;
521   if (*ss == '\n')
522     s = ++ss;
523   else
524     {
525     uschar *t = ss + 1;
526     uschar *tt = NULL;
527     while (--t > s + 35)
528       {
529       if (*t == ' ')
530         {
531         if (t[-1] == ':') { tt = t; break; }
532         if (tt == NULL) tt = t;
533         }
534       }
535
536     if (tt == NULL)          /* Can't split behind - try ahead */
537       {
538       t = ss + 1;
539       while (*t != 0)
540         {
541         if (*t == ' ' || *t == '\n')
542           { tt = t; break; }
543         t++;
544         }
545       }
546
547     if (tt == NULL) break;   /* Can't find anywhere to split */
548     *tt = '\n';
549     s = ss = tt+1;
550     }
551   }
552
553 return msg;
554 }
555
556
557
558 /*************************************************
559 *   Copy returned DNS domain name, de-escaping   *
560 *************************************************/
561
562 /* If a domain name contains top-bit characters, some resolvers return
563 the fully qualified name with those characters turned into escapes. The
564 convention is a backslash followed by _decimal_ digits. We convert these
565 back into the original binary values. This will be relevant when
566 allow_utf8_domains is set true and UTF-8 characters are used in domain
567 names. Backslash can also be used to escape other characters, though we
568 shouldn't come across them in domain names.
569
570 Argument:   the domain name string
571 Returns:    copy of string in new store, de-escaped
572 */
573
574 uschar *
575 string_copy_dnsdomain(uschar *s)
576 {
577 uschar *yield;
578 uschar *ss = yield = store_get(Ustrlen(s) + 1, is_tainted(s));
579
580 while (*s != 0)
581   {
582   if (*s != '\\')
583     *ss++ = *s++;
584   else if (isdigit(s[1]))
585     {
586     *ss++ = (s[1] - '0')*100 + (s[2] - '0')*10 + s[3] - '0';
587     s += 4;
588     }
589   else if (*(++s) != 0)
590     *ss++ = *s++;
591   }
592
593 *ss = 0;
594 return yield;
595 }
596
597
598 #ifndef COMPILE_UTILITY
599 /*************************************************
600 *     Copy space-terminated or quoted string     *
601 *************************************************/
602
603 /* This function copies from a string until its end, or until whitespace is
604 encountered, unless the string begins with a double quote, in which case the
605 terminating quote is sought, and escaping within the string is done. The length
606 of a de-quoted string can be no longer than the original, since escaping always
607 turns n characters into 1 character.
608
609 Argument:  pointer to the pointer to the first character, which gets updated
610 Returns:   the new string
611 */
612
613 uschar *
614 string_dequote(const uschar **sptr)
615 {
616 const uschar *s = *sptr;
617 uschar *t, *yield;
618
619 /* First find the end of the string */
620
621 if (*s != '\"')
622   while (*s != 0 && !isspace(*s)) s++;
623 else
624   {
625   s++;
626   while (*s && *s != '\"')
627     {
628     if (*s == '\\') (void)string_interpret_escape(&s);
629     s++;
630     }
631   if (*s) s++;
632   }
633
634 /* Get enough store to copy into */
635
636 t = yield = store_get(s - *sptr + 1, is_tainted(*sptr));
637 s = *sptr;
638
639 /* Do the copy */
640
641 if (*s != '\"')
642   while (*s != 0 && !isspace(*s)) *t++ = *s++;
643 else
644   {
645   s++;
646   while (*s != 0 && *s != '\"')
647     {
648     *t++ = *s == '\\' ? string_interpret_escape(&s) : *s;
649     s++;
650     }
651   if (*s) s++;
652   }
653
654 /* Update the pointer and return the terminated copy */
655
656 *sptr = s;
657 *t = 0;
658 return yield;
659 }
660 #endif  /* COMPILE_UTILITY */
661
662
663
664 /*************************************************
665 *          Format a string and save it           *
666 *************************************************/
667
668 /* The formatting is done by string_vformat, which checks the length of
669 everything.  Taint is taken from the worst of the arguments.
670
671 Arguments:
672   format    a printf() format - deliberately char * rather than uschar *
673               because it will most usually be a literal string
674   ...       arguments for format
675
676 Returns:    pointer to fresh piece of store containing sprintf'ed string
677 */
678
679 uschar *
680 string_sprintf_trc(const char *format, const uschar * func, unsigned line, ...)
681 {
682 #ifdef COMPILE_UTILITY
683 uschar buffer[STRING_SPRINTF_BUFFER_SIZE];
684 gstring gs = { .size = STRING_SPRINTF_BUFFER_SIZE, .ptr = 0, .s = buffer };
685 gstring * g = &gs;
686 unsigned flags = 0;
687 #else
688 gstring * g = NULL;
689 unsigned flags = SVFMT_REBUFFER|SVFMT_EXTEND;
690 #endif
691
692 va_list ap;
693 va_start(ap, line);
694 g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
695         flags, format, ap);
696 va_end(ap);
697
698 if (!g)
699   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
700     "string_sprintf expansion was longer than %d; format string was (%s)\n"
701     " called from %s %d\n",
702     STRING_SPRINTF_BUFFER_SIZE, format, func, line);
703
704 #ifdef COMPILE_UTILITY
705 return string_copyn(g->s, g->ptr);
706 #else
707 gstring_release_unused(g);
708 return string_from_gstring(g);
709 #endif
710 }
711
712
713
714 /*************************************************
715 *         Case-independent strncmp() function    *
716 *************************************************/
717
718 /*
719 Arguments:
720   s         first string
721   t         second string
722   n         number of characters to compare
723
724 Returns:    < 0, = 0, or > 0, according to the comparison
725 */
726
727 int
728 strncmpic(const uschar *s, const uschar *t, int n)
729 {
730 while (n--)
731   {
732   int c = tolower(*s++) - tolower(*t++);
733   if (c) return c;
734   }
735 return 0;
736 }
737
738
739 /*************************************************
740 *         Case-independent strcmp() function     *
741 *************************************************/
742
743 /*
744 Arguments:
745   s         first string
746   t         second string
747
748 Returns:    < 0, = 0, or > 0, according to the comparison
749 */
750
751 int
752 strcmpic(const uschar *s, const uschar *t)
753 {
754 while (*s != 0)
755   {
756   int c = tolower(*s++) - tolower(*t++);
757   if (c != 0) return c;
758   }
759 return *t;
760 }
761
762
763 /*************************************************
764 *         Case-independent strstr() function     *
765 *************************************************/
766
767 /* The third argument specifies whether whitespace is required
768 to follow the matched string.
769
770 Arguments:
771   s              string to search
772   t              substring to search for
773   space_follows  if TRUE, match only if whitespace follows
774
775 Returns:         pointer to substring in string, or NULL if not found
776 */
777
778 uschar *
779 strstric(uschar *s, uschar *t, BOOL space_follows)
780 {
781 uschar *p = t;
782 uschar *yield = NULL;
783 int cl = tolower(*p);
784 int cu = toupper(*p);
785
786 while (*s)
787   {
788   if (*s == cl || *s == cu)
789     {
790     if (yield == NULL) yield = s;
791     if (*(++p) == 0)
792       {
793       if (!space_follows || s[1] == ' ' || s[1] == '\n' ) return yield;
794       yield = NULL;
795       p = t;
796       }
797     cl = tolower(*p);
798     cu = toupper(*p);
799     s++;
800     }
801   else if (yield != NULL)
802     {
803     yield = NULL;
804     p = t;
805     cl = tolower(*p);
806     cu = toupper(*p);
807     }
808   else s++;
809   }
810 return NULL;
811 }
812
813
814
815 #ifdef COMPILE_UTILITY
816 /* Dummy version for this function; it should never be called */
817 static void
818 gstring_grow(gstring * g, int count)
819 {
820 assert(FALSE);
821 }
822 #endif
823
824
825
826 #ifndef COMPILE_UTILITY
827 /*************************************************
828 *       Get next string from separated list      *
829 *************************************************/
830
831 /* Leading and trailing space is removed from each item. The separator in the
832 list is controlled by the int pointed to by the separator argument as follows:
833
834   If the value is > 0 it is used as the separator. This is typically used for
835   sublists such as slash-separated options. The value is always a printing
836   character.
837
838     (If the value is actually > UCHAR_MAX there is only one item in the list.
839     This is used for some cases when called via functions that sometimes
840     plough through lists, and sometimes are given single items.)
841
842   If the value is <= 0, the string is inspected for a leading <x, where x is an
843   ispunct() or an iscntrl() character. If found, x is used as the separator. If
844   not found:
845
846       (a) if separator == 0, ':' is used
847       (b) if separator <0, -separator is used
848
849   In all cases the value of the separator that is used is written back to the
850   int so that it is used on subsequent calls as we progress through the list.
851
852 A literal ispunct() separator can be represented in an item by doubling, but
853 there is no way to include an iscntrl() separator as part of the data.
854
855 Arguments:
856   listptr    points to a pointer to the current start of the list; the
857              pointer gets updated to point after the end of the next item
858   separator  a pointer to the separator character in an int (see above)
859   buffer     where to put a copy of the next string in the list; or
860                NULL if the next string is returned in new memory
861   buflen     when buffer is not NULL, the size of buffer; otherwise ignored
862
863 Returns:     pointer to buffer, containing the next substring,
864              or NULL if no more substrings
865 */
866
867 uschar *
868 string_nextinlist_trc(const uschar **listptr, int *separator, uschar *buffer, int buflen,
869  const uschar * func, int line)
870 {
871 int sep = *separator;
872 const uschar *s = *listptr;
873 BOOL sep_is_special;
874
875 if (!s) return NULL;
876
877 /* This allows for a fixed specified separator to be an iscntrl() character,
878 but at the time of implementation, this is never the case. However, it's best
879 to be conservative. */
880
881 while (isspace(*s) && *s != sep) s++;
882
883 /* A change of separator is permitted, so look for a leading '<' followed by an
884 allowed character. */
885
886 if (sep <= 0)
887   {
888   if (*s == '<' && (ispunct(s[1]) || iscntrl(s[1])))
889     {
890     sep = s[1];
891     if (*++s) ++s;
892     while (isspace(*s) && *s != sep) s++;
893     }
894   else
895     sep = sep ? -sep : ':';
896   *separator = sep;
897   }
898
899 /* An empty string has no list elements */
900
901 if (!*s) return NULL;
902
903 /* Note whether whether or not the separator is an iscntrl() character. */
904
905 sep_is_special = iscntrl(sep);
906
907 /* Handle the case when a buffer is provided. */
908
909 if (buffer)
910   {
911   int p = 0;
912   if (is_tainted(s) && !is_tainted(buffer))
913     die_tainted(US"string_nextinlist", func, line);
914   for (; *s; s++)
915     {
916     if (*s == sep && (*(++s) != sep || sep_is_special)) break;
917     if (p < buflen - 1) buffer[p++] = *s;
918     }
919   while (p > 0 && isspace(buffer[p-1])) p--;
920   buffer[p] = '\0';
921   }
922
923 /* Handle the case when a buffer is not provided. */
924
925 else
926   {
927   gstring * g = NULL;
928
929   /* We know that *s != 0 at this point. However, it might be pointing to a
930   separator, which could indicate an empty string, or (if an ispunct()
931   character) could be doubled to indicate a separator character as data at the
932   start of a string. Avoid getting working memory for an empty item. */
933
934   if (*s == sep)
935     if (*++s != sep || sep_is_special)
936       {
937       *listptr = s;
938       return string_copy(US"");
939       }
940
941   /* Not an empty string; the first character is guaranteed to be a data
942   character. */
943
944   for (;;)
945     {
946     const uschar * ss;
947     for (ss = s + 1; *ss && *ss != sep; ) ss++;
948     g = string_catn(g, s, ss-s);
949     s = ss;
950     if (!*s || *++s != sep || sep_is_special) break;
951     }
952   /* while (g->ptr > 0 && isspace(g->s[g->ptr-1])) g->ptr--; */
953   while (  g->ptr > 0 && isspace(g->s[g->ptr-1])
954         && (g->ptr == 1 || g->s[g->ptr-2] != '\\') )
955     g->ptr--;
956   buffer = string_from_gstring(g);
957   gstring_release_unused(g);
958   }
959
960 /* Update the current pointer and return the new string */
961
962 *listptr = s;
963 return buffer;
964 }
965
966
967 static const uschar *
968 Ustrnchr(const uschar * s, int c, unsigned * len)
969 {
970 unsigned siz = *len;
971 while (siz)
972   {
973   if (!*s) return NULL;
974   if (*s == c)
975     {
976     *len = siz;
977     return s;
978     }
979   s++;
980   siz--;
981   }
982 return NULL;
983 }
984
985
986 /************************************************
987 *       Add element to separated list           *
988 ************************************************/
989 /* This function is used to build a list, returning an allocated null-terminated
990 growable string. The given element has any embedded separator characters
991 doubled.
992
993 Despite having the same growable-string interface as string_cat() the list is
994 always returned null-terminated.
995
996 Arguments:
997   list  expanding-string for the list that is being built, or NULL
998         if this is a new list that has no contents yet
999   sep   list separator character
1000   ele   new element to be appended to the list
1001
1002 Returns:  pointer to the start of the list, changed if copied for expansion.
1003 */
1004
1005 gstring *
1006 string_append_listele(gstring * list, uschar sep, const uschar * ele)
1007 {
1008 uschar * sp;
1009
1010 if (list && list->ptr)
1011   list = string_catn(list, &sep, 1);
1012
1013 while((sp = Ustrchr(ele, sep)))
1014   {
1015   list = string_catn(list, ele, sp-ele+1);
1016   list = string_catn(list, &sep, 1);
1017   ele = sp+1;
1018   }
1019 list = string_cat(list, ele);
1020 (void) string_from_gstring(list);
1021 return list;
1022 }
1023
1024
1025 gstring *
1026 string_append_listele_n(gstring * list, uschar sep, const uschar * ele,
1027  unsigned len)
1028 {
1029 const uschar * sp;
1030
1031 if (list && list->ptr)
1032   list = string_catn(list, &sep, 1);
1033
1034 while((sp = Ustrnchr(ele, sep, &len)))
1035   {
1036   list = string_catn(list, ele, sp-ele+1);
1037   list = string_catn(list, &sep, 1);
1038   ele = sp+1;
1039   len--;
1040   }
1041 list = string_catn(list, ele, len);
1042 (void) string_from_gstring(list);
1043 return list;
1044 }
1045
1046
1047
1048 /* A slightly-bogus listmaker utility; the separator is a string so
1049 can be multiple chars - there is no checking for the element content
1050 containing any of the separator. */
1051
1052 gstring *
1053 string_append2_listele_n(gstring * list, const uschar * sepstr,
1054  const uschar * ele, unsigned len)
1055 {
1056 if (list && list->ptr)
1057   list = string_cat(list, sepstr);
1058
1059 list = string_catn(list, ele, len);
1060 (void) string_from_gstring(list);
1061 return list;
1062 }
1063
1064
1065
1066 /************************************************/
1067 /* Add more space to a growable-string.  The caller should check
1068 first if growth is required.  The gstring struct is modified on
1069 return; specifically, the string-base-pointer may have been changed.
1070
1071 Arguments:
1072   g             the growable-string
1073   count         amount needed for g->ptr to increase by
1074 */
1075
1076 static void
1077 gstring_grow(gstring * g, int count)
1078 {
1079 int p = g->ptr;
1080 int oldsize = g->size;
1081 BOOL tainted = is_tainted(g->s);
1082
1083 /* Mostly, string_cat() is used to build small strings of a few hundred
1084 characters at most. There are times, however, when the strings are very much
1085 longer (for example, a lookup that returns a vast number of alias addresses).
1086 To try to keep things reasonable, we use increments whose size depends on the
1087 existing length of the string. */
1088
1089 unsigned inc = oldsize < 4096 ? 127 : 1023;
1090
1091 if (count <= 0) return;
1092 g->size = (p + count + inc + 1) & ~inc;         /* one for a NUL */
1093
1094 /* Try to extend an existing allocation. If the result of calling
1095 store_extend() is false, either there isn't room in the current memory block,
1096 or this string is not the top item on the dynamic store stack. We then have
1097 to get a new chunk of store and copy the old string. When building large
1098 strings, it is helpful to call store_release() on the old string, to release
1099 memory blocks that have become empty. (The block will be freed if the string
1100 is at its start.) However, we can do this only if we know that the old string
1101 was the last item on the dynamic memory stack. This is the case if it matches
1102 store_last_get. */
1103
1104 if (!store_extend(g->s, tainted, oldsize, g->size))
1105   g->s = store_newblock(g->s, tainted, g->size, p);
1106 }
1107
1108
1109
1110 /*************************************************
1111 *             Add chars to string                *
1112 *************************************************/
1113 /* This function is used when building up strings of unknown length. Room is
1114 always left for a terminating zero to be added to the string that is being
1115 built. This function does not require the string that is being added to be NUL
1116 terminated, because the number of characters to add is given explicitly. It is
1117 sometimes called to extract parts of other strings.
1118
1119 Arguments:
1120   string   points to the start of the string that is being built, or NULL
1121              if this is a new string that has no contents yet
1122   s        points to characters to add
1123   count    count of characters to add; must not exceed the length of s, if s
1124              is a C string.
1125
1126 Returns:   pointer to the start of the string, changed if copied for expansion.
1127            Note that a NUL is not added, though space is left for one. This is
1128            because string_cat() is often called multiple times to build up a
1129            string - there's no point adding the NUL till the end.
1130
1131 */
1132 /* coverity[+alloc] */
1133
1134 gstring *
1135 string_catn(gstring * g, const uschar *s, int count)
1136 {
1137 int p;
1138 BOOL srctaint = is_tainted(s);
1139
1140 if (!g)
1141   {
1142   unsigned inc = count < 4096 ? 127 : 1023;
1143   unsigned size = ((count + inc) &  ~inc) + 1;
1144   g = string_get_tainted(size, srctaint);
1145   }
1146 else if (srctaint && !is_tainted(g->s))
1147   gstring_rebuffer(g);
1148
1149 p = g->ptr;
1150 if (p + count >= g->size)
1151   gstring_grow(g, count);
1152
1153 /* Because we always specify the exact number of characters to copy, we can
1154 use memcpy(), which is likely to be more efficient than strncopy() because the
1155 latter has to check for zero bytes. */
1156
1157 memcpy(g->s + p, s, count);
1158 g->ptr = p + count;
1159 return g;
1160 }
1161
1162
1163 gstring *
1164 string_cat(gstring *string, const uschar *s)
1165 {
1166 return string_catn(string, s, Ustrlen(s));
1167 }
1168
1169
1170
1171 /*************************************************
1172 *        Append strings to another string        *
1173 *************************************************/
1174
1175 /* This function can be used to build a string from many other strings.
1176 It calls string_cat() to do the dirty work.
1177
1178 Arguments:
1179   string   expanding-string that is being built, or NULL
1180              if this is a new string that has no contents yet
1181   count    the number of strings to append
1182   ...      "count" uschar* arguments, which must be valid zero-terminated
1183              C strings
1184
1185 Returns:   pointer to the start of the string, changed if copied for expansion.
1186            The string is not zero-terminated - see string_cat() above.
1187 */
1188
1189 __inline__ gstring *
1190 string_append(gstring *string, int count, ...)
1191 {
1192 va_list ap;
1193
1194 va_start(ap, count);
1195 while (count-- > 0)
1196   {
1197   uschar *t = va_arg(ap, uschar *);
1198   string = string_cat(string, t);
1199   }
1200 va_end(ap);
1201
1202 return string;
1203 }
1204 #endif
1205
1206
1207
1208 /*************************************************
1209 *        Format a string with length checks      *
1210 *************************************************/
1211
1212 /* This function is used to format a string with checking of the length of the
1213 output for all conversions. It protects Exim from absent-mindedness when
1214 calling functions like debug_printf and string_sprintf, and elsewhere. There
1215 are two different entry points to what is actually the same function, depending
1216 on whether the variable length list of data arguments are given explicitly or
1217 as a va_list item.
1218
1219 The formats are the usual printf() ones, with some omissions (never used) and
1220 three additions for strings: %S forces lower case, %T forces upper case, and
1221 %#s or %#S prints nothing for a NULL string. Without the # "NULL" is printed
1222 (useful in debugging). There is also the addition of %D and %M, which insert
1223 the date in the form used for datestamped log files.
1224
1225 Arguments:
1226   buffer       a buffer in which to put the formatted string
1227   buflen       the length of the buffer
1228   format       the format string - deliberately char * and not uschar *
1229   ... or ap    variable list of supplementary arguments
1230
1231 Returns:       TRUE if the result fitted in the buffer
1232 */
1233
1234 BOOL
1235 string_format_trc(uschar * buffer, int buflen,
1236   const uschar * func, unsigned line, const char * format, ...)
1237 {
1238 gstring g = { .size = buflen, .ptr = 0, .s = buffer }, *gp;
1239 va_list ap;
1240 va_start(ap, format);
1241 gp = string_vformat_trc(&g, func, line, STRING_SPRINTF_BUFFER_SIZE,
1242         0, format, ap);
1243 va_end(ap);
1244 g.s[g.ptr] = '\0';
1245 return !!gp;
1246 }
1247
1248
1249
1250
1251 /* Build or append to a growing-string, sprintf-style.
1252
1253 Arguments:
1254         g       a growable-string
1255         func    called-from function name, for debug
1256         line    called-from file line number, for debug
1257         limit   maximum string size
1258         flags   see below
1259         format  printf-like format string
1260         ap      variable-args pointer
1261
1262 Flags:
1263         SVFMT_EXTEND            buffer can be created or exteded as needed
1264         SVFMT_REBUFFER          buffer can be recopied to tainted mem as needed
1265         SVFMT_TAINT_NOCHK       do not check inputs for taint
1266
1267 If the "extend" flag is true, the string passed in can be NULL,
1268 empty, or non-empty.  Growing is subject to an overall limit given
1269 by the limit argument.
1270
1271 If the "extend" flag is false, the string passed in may not be NULL,
1272 will not be grown, and is usable in the original place after return.
1273 The return value can be NULL to signify overflow.
1274
1275 Returns the possibly-new (if copy for growth or taint-handling was needed)
1276 string, not nul-terminated.
1277 */
1278
1279 gstring *
1280 string_vformat_trc(gstring * g, const uschar * func, unsigned line,
1281   unsigned size_limit, unsigned flags, const char *format, va_list ap)
1282 {
1283 enum ltypes { L_NORMAL=1, L_SHORT=2, L_LONG=3, L_LONGLONG=4, L_LONGDOUBLE=5, L_SIZE=6 };
1284
1285 int width, precision, off, lim, need;
1286 const char * fp = format;       /* Deliberately not unsigned */
1287 BOOL dest_tainted = FALSE;
1288
1289 string_datestamp_offset = -1;   /* Datestamp not inserted */
1290 string_datestamp_length = 0;    /* Datestamp not inserted */
1291 string_datestamp_type = 0;      /* Datestamp not inserted */
1292
1293 #ifdef COMPILE_UTILITY
1294 assert(!(flags & SVFMT_EXTEND));
1295 assert(g);
1296 #else
1297
1298 /* Ensure we have a string, to save on checking later */
1299 if (!g) g = string_get(16);
1300 else if (!(flags & SVFMT_TAINT_NOCHK)) dest_tainted = is_tainted(g->s);
1301
1302 if (!(flags & SVFMT_TAINT_NOCHK) && !dest_tainted && is_tainted(format))
1303   {
1304 #ifndef MACRO_PREDEF
1305   if (!(flags & SVFMT_REBUFFER))
1306     die_tainted(US"string_vformat", func, line);
1307 #endif
1308   gstring_rebuffer(g);
1309   dest_tainted = TRUE;
1310   }
1311 #endif  /*!COMPILE_UTILITY*/
1312
1313 lim = g->size - 1;      /* leave one for a nul */
1314 off = g->ptr;           /* remember initial offset in gstring */
1315
1316 /* Scan the format and handle the insertions */
1317
1318 while (*fp)
1319   {
1320   int length = L_NORMAL;
1321   int *nptr;
1322   int slen;
1323   const char *null = "NULL";            /* ) These variables */
1324   const char *item_start, *s;           /* ) are deliberately */
1325   char newformat[16];                   /* ) not unsigned */
1326   char * gp = CS g->s + g->ptr;         /* ) */
1327
1328   /* Non-% characters just get copied verbatim */
1329
1330   if (*fp != '%')
1331     {
1332     /* Avoid string_copyn() due to COMPILE_UTILITY */
1333     if ((need = g->ptr + 1) > lim)
1334       {
1335       if (!(flags & SVFMT_EXTEND) || need > size_limit) return NULL;
1336       gstring_grow(g, 1);
1337       lim = g->size - 1;
1338       }
1339     g->s[g->ptr++] = (uschar) *fp++;
1340     continue;
1341     }
1342
1343   /* Deal with % characters. Pick off the width and precision, for checking
1344   strings, skipping over the flag and modifier characters. */
1345
1346   item_start = fp;
1347   width = precision = -1;
1348
1349   if (strchr("-+ #0", *(++fp)) != NULL)
1350     {
1351     if (*fp == '#') null = "";
1352     fp++;
1353     }
1354
1355   if (isdigit((uschar)*fp))
1356     {
1357     width = *fp++ - '0';
1358     while (isdigit((uschar)*fp)) width = width * 10 + *fp++ - '0';
1359     }
1360   else if (*fp == '*')
1361     {
1362     width = va_arg(ap, int);
1363     fp++;
1364     }
1365
1366   if (*fp == '.')
1367     if (*(++fp) == '*')
1368       {
1369       precision = va_arg(ap, int);
1370       fp++;
1371       }
1372     else
1373       for (precision = 0; isdigit((uschar)*fp); fp++)
1374         precision = precision*10 + *fp - '0';
1375
1376   /* Skip over 'h', 'L', 'l', 'll' and 'z', remembering the item length */
1377
1378   if (*fp == 'h')
1379     { fp++; length = L_SHORT; }
1380   else if (*fp == 'L')
1381     { fp++; length = L_LONGDOUBLE; }
1382   else if (*fp == 'l')
1383     if (fp[1] == 'l')
1384       { fp += 2; length = L_LONGLONG; }
1385     else
1386       { fp++; length = L_LONG; }
1387   else if (*fp == 'z')
1388     { fp++; length = L_SIZE; }
1389
1390   /* Handle each specific format type. */
1391
1392   switch (*fp++)
1393     {
1394     case 'n':
1395       nptr = va_arg(ap, int *);
1396       *nptr = g->ptr - off;
1397       break;
1398
1399     case 'd':
1400     case 'o':
1401     case 'u':
1402     case 'x':
1403     case 'X':
1404       width = length > L_LONG ? 24 : 12;
1405       if ((need = g->ptr + width) > lim)
1406         {
1407         if (!(flags & SVFMT_EXTEND) || need >= size_limit) return NULL;
1408         gstring_grow(g, width);
1409         lim = g->size - 1;
1410         gp = CS g->s + g->ptr;
1411         }
1412       strncpy(newformat, item_start, fp - item_start);
1413       newformat[fp - item_start] = 0;
1414
1415       /* Short int is promoted to int when passing through ..., so we must use
1416       int for va_arg(). */
1417
1418       switch(length)
1419         {
1420         case L_SHORT:
1421         case L_NORMAL:
1422           g->ptr += sprintf(gp, newformat, va_arg(ap, int)); break;
1423         case L_LONG:
1424           g->ptr += sprintf(gp, newformat, va_arg(ap, long int)); break;
1425         case L_LONGLONG:
1426           g->ptr += sprintf(gp, newformat, va_arg(ap, LONGLONG_T)); break;
1427         case L_SIZE:
1428           g->ptr += sprintf(gp, newformat, va_arg(ap, size_t)); break;
1429         }
1430       break;
1431
1432     case 'p':
1433       {
1434       void * ptr;
1435       if ((need = g->ptr + 24) > lim)
1436         {
1437         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1438         gstring_grow(g, 24);
1439         lim = g->size - 1;
1440         gp = CS g->s + g->ptr;
1441         }
1442       /* sprintf() saying "(nil)" for a null pointer seems unreliable.
1443       Handle it explicitly. */
1444       if ((ptr = va_arg(ap, void *)))
1445         {
1446         strncpy(newformat, item_start, fp - item_start);
1447         newformat[fp - item_start] = 0;
1448         g->ptr += sprintf(gp, newformat, ptr);
1449         }
1450       else
1451         g->ptr += sprintf(gp, "(nil)");
1452       }
1453     break;
1454
1455     /* %f format is inherently insecure if the numbers that it may be
1456     handed are unknown (e.g. 1e300). However, in Exim, %f is used for
1457     printing load averages, and these are actually stored as integers
1458     (load average * 1000) so the size of the numbers is constrained.
1459     It is also used for formatting sending rates, where the simplicity
1460     of the format prevents overflow. */
1461
1462     case 'f':
1463     case 'e':
1464     case 'E':
1465     case 'g':
1466     case 'G':
1467       if (precision < 0) precision = 6;
1468       if ((need = g->ptr + precision + 8) > lim)
1469         {
1470         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1471         gstring_grow(g, precision+8);
1472         lim = g->size - 1;
1473         gp = CS g->s + g->ptr;
1474         }
1475       strncpy(newformat, item_start, fp - item_start);
1476       newformat[fp-item_start] = 0;
1477       if (length == L_LONGDOUBLE)
1478         g->ptr += sprintf(gp, newformat, va_arg(ap, long double));
1479       else
1480         g->ptr += sprintf(gp, newformat, va_arg(ap, double));
1481       break;
1482
1483     /* String types */
1484
1485     case '%':
1486       if ((need = g->ptr + 1) > lim)
1487         {
1488         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1489         gstring_grow(g, 1);
1490         lim = g->size - 1;
1491         }
1492       g->s[g->ptr++] = (uschar) '%';
1493       break;
1494
1495     case 'c':
1496       if ((need = g->ptr + 1) > lim)
1497         {
1498         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1499         gstring_grow(g, 1);
1500         lim = g->size - 1;
1501         }
1502       g->s[g->ptr++] = (uschar) va_arg(ap, int);
1503       break;
1504
1505     case 'D':                   /* Insert daily datestamp for log file names */
1506       s = CS tod_stamp(tod_log_datestamp_daily);
1507       string_datestamp_offset = g->ptr;         /* Passed back via global */
1508       string_datestamp_length = Ustrlen(s);     /* Passed back via global */
1509       string_datestamp_type = tod_log_datestamp_daily;
1510       slen = string_datestamp_length;
1511       goto INSERT_STRING;
1512
1513     case 'M':                   /* Insert monthly datestamp for log file names */
1514       s = CS tod_stamp(tod_log_datestamp_monthly);
1515       string_datestamp_offset = g->ptr;         /* Passed back via global */
1516       string_datestamp_length = Ustrlen(s);     /* Passed back via global */
1517       string_datestamp_type = tod_log_datestamp_monthly;
1518       slen = string_datestamp_length;
1519       goto INSERT_STRING;
1520
1521     case 's':
1522     case 'S':                   /* Forces *lower* case */
1523     case 'T':                   /* Forces *upper* case */
1524       s = va_arg(ap, char *);
1525
1526       if (!s) s = null;
1527       slen = Ustrlen(s);
1528
1529       if (!(flags & SVFMT_TAINT_NOCHK) && !dest_tainted && is_tainted(s))
1530         if (flags & SVFMT_REBUFFER)
1531           {
1532           gstring_rebuffer(g);
1533           gp = CS g->s + g->ptr;
1534           dest_tainted = TRUE;
1535           }
1536 #ifndef MACRO_PREDEF
1537         else
1538           die_tainted(US"string_vformat", func, line);
1539 #endif
1540
1541     INSERT_STRING:              /* Come to from %D or %M above */
1542
1543       {
1544       BOOL truncated = FALSE;
1545
1546       /* If the width is specified, check that there is a precision
1547       set; if not, set it to the width to prevent overruns of long
1548       strings. */
1549
1550       if (width >= 0)
1551         {
1552         if (precision < 0) precision = width;
1553         }
1554
1555       /* If a width is not specified and the precision is specified, set
1556       the width to the precision, or the string length if shorted. */
1557
1558       else if (precision >= 0)
1559         width = precision < slen ? precision : slen;
1560
1561       /* If neither are specified, set them both to the string length. */
1562
1563       else
1564         width = precision = slen;
1565
1566       if ((need = g->ptr + width) >= size_limit || !(flags & SVFMT_EXTEND))
1567         {
1568         if (g->ptr == lim) return NULL;
1569         if (need > lim)
1570           {
1571           truncated = TRUE;
1572           width = precision = lim - g->ptr - 1;
1573           if (width < 0) width = 0;
1574           if (precision < 0) precision = 0;
1575           }
1576         }
1577       else if (need > lim)
1578         {
1579         gstring_grow(g, width);
1580         lim = g->size - 1;
1581         gp = CS g->s + g->ptr;
1582         }
1583
1584       g->ptr += sprintf(gp, "%*.*s", width, precision, s);
1585       if (fp[-1] == 'S')
1586         while (*gp) { *gp = tolower(*gp); gp++; }
1587       else if (fp[-1] == 'T')
1588         while (*gp) { *gp = toupper(*gp); gp++; }
1589
1590       if (truncated) return NULL;
1591       break;
1592       }
1593
1594     /* Some things are never used in Exim; also catches junk. */
1595
1596     default:
1597       strncpy(newformat, item_start, fp - item_start);
1598       newformat[fp-item_start] = 0;
1599       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "string_format: unsupported type "
1600         "in \"%s\" in \"%s\"", newformat, format);
1601       break;
1602     }
1603   }
1604
1605 if (g->ptr > g->size)
1606   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1607     "string_format internal error: caller %s %d", func, line);
1608 return g;
1609 }
1610
1611
1612
1613 #ifndef COMPILE_UTILITY
1614 /*************************************************
1615 *       Generate an "open failed" message        *
1616 *************************************************/
1617
1618 /* This function creates a message after failure to open a file. It includes a
1619 string supplied as data, adds the strerror() text, and if the failure was
1620 "Permission denied", reads and includes the euid and egid.
1621
1622 Arguments:
1623   format        a text format string - deliberately not uschar *
1624   ...           arguments for the format string
1625
1626 Returns:        a message, in dynamic store
1627 */
1628
1629 uschar *
1630 string_open_failed_trc(const uschar * func, unsigned line,
1631   const char *format, ...)
1632 {
1633 va_list ap;
1634 gstring * g = string_get(1024);
1635
1636 g = string_catn(g, US"failed to open ", 15);
1637
1638 /* Use the checked formatting routine to ensure that the buffer
1639 does not overflow. It should not, since this is called only for internally
1640 specified messages. If it does, the message just gets truncated, and there
1641 doesn't seem much we can do about that. */
1642
1643 va_start(ap, format);
1644 (void) string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
1645         SVFMT_REBUFFER, format, ap);
1646 va_end(ap);
1647
1648 g = string_catn(g, US": ", 2);
1649 g = string_cat(g, US strerror(errno));
1650
1651 if (errno == EACCES)
1652   {
1653   int save_errno = errno;
1654   g = string_fmt_append(g, " (euid=%ld egid=%ld)",
1655     (long int)geteuid(), (long int)getegid());
1656   errno = save_errno;
1657   }
1658 gstring_release_unused(g);
1659 return string_from_gstring(g);
1660 }
1661
1662
1663
1664
1665
1666 /* qsort(3), currently used to sort the environment variables
1667 for -bP environment output, needs a function to compare two pointers to string
1668 pointers. Here it is. */
1669
1670 int
1671 string_compare_by_pointer(const void *a, const void *b)
1672 {
1673 return Ustrcmp(* CUSS a, * CUSS b);
1674 }
1675 #endif /* COMPILE_UTILITY */
1676
1677
1678
1679
1680 /*************************************************
1681 **************************************************
1682 *             Stand-alone test program           *
1683 **************************************************
1684 *************************************************/
1685
1686 #ifdef STAND_ALONE
1687 int main(void)
1688 {
1689 uschar buffer[256];
1690
1691 printf("Testing is_ip_address\n");
1692
1693 while (fgets(CS buffer, sizeof(buffer), stdin) != NULL)
1694   {
1695   int offset;
1696   buffer[Ustrlen(buffer) - 1] = 0;
1697   printf("%d\n", string_is_ip_address(buffer, NULL));
1698   printf("%d %d %s\n", string_is_ip_address(buffer, &offset), offset, buffer);
1699   }
1700
1701 printf("Testing string_nextinlist\n");
1702
1703 while (fgets(CS buffer, sizeof(buffer), stdin) != NULL)
1704   {
1705   uschar *list = buffer;
1706   uschar *lp1, *lp2;
1707   uschar item[256];
1708   int sep1 = 0;
1709   int sep2 = 0;
1710
1711   if (*list == '<')
1712     {
1713     sep1 = sep2 = list[1];
1714     list += 2;
1715     }
1716
1717   lp1 = lp2 = list;
1718   for (;;)
1719     {
1720     uschar *item1 = string_nextinlist(&lp1, &sep1, item, sizeof(item));
1721     uschar *item2 = string_nextinlist(&lp2, &sep2, NULL, 0);
1722
1723     if (item1 == NULL && item2 == NULL) break;
1724     if (item == NULL || item2 == NULL || Ustrcmp(item1, item2) != 0)
1725       {
1726       printf("***ERROR\nitem1=\"%s\"\nitem2=\"%s\"\n",
1727         (item1 == NULL)? "NULL" : CS item1,
1728         (item2 == NULL)? "NULL" : CS item2);
1729       break;
1730       }
1731     else printf("  \"%s\"\n", CS item1);
1732     }
1733   }
1734
1735 /* This is a horrible lash-up, but it serves its purpose. */
1736
1737 printf("Testing string_format\n");
1738
1739 while (fgets(CS buffer, sizeof(buffer), stdin) != NULL)
1740   {
1741   void *args[3];
1742   long long llargs[3];
1743   double dargs[3];
1744   int dflag = 0;
1745   int llflag = 0;
1746   int n = 0;
1747   int count;
1748   int countset = 0;
1749   uschar format[256];
1750   uschar outbuf[256];
1751   uschar *s;
1752   buffer[Ustrlen(buffer) - 1] = 0;
1753
1754   s = Ustrchr(buffer, ',');
1755   if (s == NULL) s = buffer + Ustrlen(buffer);
1756
1757   Ustrncpy(format, buffer, s - buffer);
1758   format[s-buffer] = 0;
1759
1760   if (*s == ',') s++;
1761
1762   while (*s != 0)
1763     {
1764     uschar *ss = s;
1765     s = Ustrchr(ss, ',');
1766     if (s == NULL) s = ss + Ustrlen(ss);
1767
1768     if (isdigit(*ss))
1769       {
1770       Ustrncpy(outbuf, ss, s-ss);
1771       if (Ustrchr(outbuf, '.') != NULL)
1772         {
1773         dflag = 1;
1774         dargs[n++] = Ustrtod(outbuf, NULL);
1775         }
1776       else if (Ustrstr(outbuf, "ll") != NULL)
1777         {
1778         llflag = 1;
1779         llargs[n++] = strtoull(CS outbuf, NULL, 10);
1780         }
1781       else
1782         {
1783         args[n++] = (void *)Uatoi(outbuf);
1784         }
1785       }
1786
1787     else if (Ustrcmp(ss, "*") == 0)
1788       {
1789       args[n++] = (void *)(&count);
1790       countset = 1;
1791       }
1792
1793     else
1794       {
1795       uschar *sss = malloc(s - ss + 1);
1796       Ustrncpy(sss, ss, s-ss);
1797       args[n++] = sss;
1798       }
1799
1800     if (*s == ',') s++;
1801     }
1802
1803   if (!dflag && !llflag)
1804     printf("%s\n", string_format(outbuf, sizeof(outbuf), CS format,
1805       args[0], args[1], args[2])? "True" : "False");
1806
1807   else if (dflag)
1808     printf("%s\n", string_format(outbuf, sizeof(outbuf), CS format,
1809       dargs[0], dargs[1], dargs[2])? "True" : "False");
1810
1811   else printf("%s\n", string_format(outbuf, sizeof(outbuf), CS format,
1812     llargs[0], llargs[1], llargs[2])? "True" : "False");
1813
1814   printf("%s\n", CS outbuf);
1815   if (countset) printf("count=%d\n", count);
1816   }
1817
1818 return 0;
1819 }
1820 #endif
1821
1822 /* End of string.c */