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