1 /* stringhelp.c -  standard string helper functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007,
3  *               2008, 2009, 2010  Free Software Foundation, Inc.
4  * Copyright (C) 2014 Werner Koch
5  * Copyright (C) 2015, 2021  g10 Code GmbH
6  *
7  * This file is part of GnuPG.
8  *
9  * GnuPG is free software; you can redistribute and/or modify this
10  * part of GnuPG under the terms of either
11  *
12  *   - the GNU Lesser General Public License as published by the Free
13  *     Software Foundation; either version 3 of the License, or (at
14  *     your option) any later version.
15  *
16  * or
17  *
18  *   - the GNU General Public License as published by the Free
19  *     Software Foundation; either version 2 of the License, or (at
20  *     your option) any later version.
21  *
22  * or both in parallel, as here.
23  *
24  * GnuPG is distributed in the hope that it will be useful, but
25  * WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27  * General Public License for more details.
28  *
29  * You should have received a copies of the GNU General Public License
30  * and the GNU Lesser General Public License along with this program;
31  * if not, see <https://www.gnu.org/licenses/>.
32  * SPDX-License-Identifier: (LGPL-3.0-or-later OR GPL-2.0-or-later)
33  */
34 
35 #include <config.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdarg.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #ifdef HAVE_PWD_H
42 # include <pwd.h>
43 #endif
44 #include <unistd.h>
45 #include <sys/types.h>
46 #ifdef HAVE_W32_SYSTEM
47 # ifdef HAVE_WINSOCK2_H
48 #  include <winsock2.h>
49 # endif
50 # include <windows.h>
51 #endif
52 #include <limits.h>
53 
54 #include "util.h"
55 #include "common-defs.h"
56 #include "utf8conv.h"
57 #include "sysutils.h"
58 #include "stringhelp.h"
59 
60 #define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a'))
61 
62 
63 /* Sometimes we want to avoid mixing slashes and backslashes on W32
64    and prefer backslashes.  There is usual no problem with mixing
65    them, however a very few W32 API calls can't grok plain slashes.
66    Printing filenames with mixed slashes also looks a bit strange.
67    This function has no effext on POSIX. */
68 static inline char *
change_slashes(char * name)69 change_slashes (char *name)
70 {
71 #ifdef HAVE_DOSISH_SYSTEM
72   char *p;
73 
74   if (strchr (name, '\\'))
75     {
76       for (p=name; *p; p++)
77         if (*p == '/')
78           *p = '\\';
79     }
80 #endif /*HAVE_DOSISH_SYSTEM*/
81   return name;
82 }
83 
84 
85 /*
86  * Check whether STRING starts with KEYWORD.  The keyword is
87  * delimited by end of string, a space or a tab.  Returns NULL if not
88  * found or a pointer into STRING to the next non-space character
89  * after the KEYWORD (which may be end of string).
90  */
91 char *
has_leading_keyword(const char * string,const char * keyword)92 has_leading_keyword (const char *string, const char *keyword)
93 {
94   size_t n = strlen (keyword);
95 
96   if (!strncmp (string, keyword, n)
97       && (!string[n] || string[n] == ' ' || string[n] == '\t'))
98     {
99       string += n;
100       while (*string == ' ' || *string == '\t')
101         string++;
102       return (char*)string;
103     }
104   return NULL;
105 }
106 
107 
108 /*
109  * Look for the substring SUB in buffer and return a pointer to that
110  * substring in BUFFER or NULL if not found.
111  * Comparison is case-insensitive.
112  */
113 const char *
memistr(const void * buffer,size_t buflen,const char * sub)114 memistr (const void *buffer, size_t buflen, const char *sub)
115 {
116   const unsigned char *buf = buffer;
117   const unsigned char *t = (const unsigned char *)buffer;
118   const unsigned char *s = (const unsigned char *)sub;
119   size_t n = buflen;
120 
121   for ( ; n ; t++, n-- )
122     {
123       if ( toupper (*t) == toupper (*s) )
124         {
125           for ( buf=t++, buflen = n--, s++;
126                 n && toupper (*t) == toupper (*s); t++, s++, n-- )
127             ;
128           if (!*s)
129             return (const char*)buf;
130           t = buf;
131           s = (const unsigned char *)sub ;
132           n = buflen;
133 	}
134     }
135   return NULL;
136 }
137 
138 const char *
ascii_memistr(const void * buffer,size_t buflen,const char * sub)139 ascii_memistr ( const void *buffer, size_t buflen, const char *sub )
140 {
141   const unsigned char *buf = buffer;
142   const unsigned char *t = (const unsigned char *)buf;
143   const unsigned char *s = (const unsigned char *)sub;
144   size_t n = buflen;
145 
146   for ( ; n ; t++, n-- )
147     {
148       if (ascii_toupper (*t) == ascii_toupper (*s) )
149         {
150           for ( buf=t++, buflen = n--, s++;
151                 n && ascii_toupper (*t) == ascii_toupper (*s); t++, s++, n-- )
152             ;
153           if (!*s)
154             return (const char*)buf;
155           t = (const unsigned char *)buf;
156           s = (const unsigned char *)sub ;
157           n = buflen;
158 	}
159     }
160   return NULL;
161 }
162 
163 
164 /* This function is similar to strncpy().  However it won't copy more
165  * than N - 1 characters and makes sure that a '\0' is appended. With
166  * N given as 0, nothing will happen.  With DEST given as NULL, memory
167  * will be allocated using xmalloc (i.e. if it runs out of core the
168  * function terminates).  Returns DEST or a pointer to the allocated
169  * memory.
170  */
171 char *
mem2str(char * dest,const void * src,size_t n)172 mem2str (char *dest, const void *src, size_t n)
173 {
174   char *d;
175   const char *s;
176 
177   if (n)
178     {
179       if (!dest)
180         dest = xmalloc (n);
181       d = dest;
182       s = src ;
183       for (n--; n && *s; n--)
184         *d++ = *s++;
185       *d = '\0' ;
186     }
187 
188   return dest;
189 }
190 
191 
192 /****************
193  * remove leading and trailing white spaces
194  */
195 char *
trim_spaces(char * str)196 trim_spaces( char *str )
197 {
198     char *string, *p, *mark;
199 
200     string = str;
201     /* find first non space character */
202     for( p=string; *p && isspace( *(byte*)p ) ; p++ )
203 	;
204     /* move characters */
205     for( (mark = NULL); (*string = *p); string++, p++ )
206 	if( isspace( *(byte*)p ) ) {
207 	    if( !mark )
208 		mark = string ;
209 	}
210 	else
211 	    mark = NULL ;
212     if( mark )
213 	*mark = '\0' ;  /* remove trailing spaces */
214 
215     return str ;
216 }
217 
218 
219 /* Same as trim_spaces but only consider, space, tab, cr and lf as space.  */
220 char *
ascii_trim_spaces(char * str)221 ascii_trim_spaces (char *str)
222 {
223   char *string, *p, *mark;
224 
225   string = str;
226 
227   /* Find first non-ascii space character.  */
228   for (p=string; *p && ascii_isspace (*p); p++)
229     ;
230   /* Move characters.  */
231   for (mark=NULL; (*string = *p); string++, p++ )
232     {
233       if (ascii_isspace (*p))
234         {
235           if (!mark)
236             mark = string;
237         }
238       else
239         mark = NULL ;
240     }
241   if (mark)
242     *mark = '\0' ;  /* Remove trailing spaces. */
243 
244   return str ;
245 }
246 
247 
248 /****************
249  * remove trailing white spaces
250  */
251 char *
trim_trailing_spaces(char * string)252 trim_trailing_spaces( char *string )
253 {
254     char *p, *mark;
255 
256     for( mark = NULL, p = string; *p; p++ ) {
257 	if( isspace( *(byte*)p ) ) {
258 	    if( !mark )
259 		mark = p;
260 	}
261 	else
262 	    mark = NULL;
263     }
264     if( mark )
265 	*mark = '\0' ;
266 
267     return string ;
268 }
269 
270 
271 unsigned
trim_trailing_chars(byte * line,unsigned len,const char * trimchars)272 trim_trailing_chars( byte *line, unsigned len, const char *trimchars )
273 {
274     byte *p, *mark;
275     unsigned n;
276 
277     for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
278 	if( strchr(trimchars, *p ) ) {
279 	    if( !mark )
280 		mark = p;
281 	}
282 	else
283 	    mark = NULL;
284     }
285 
286     if( mark ) {
287 	*mark = 0;
288 	return mark - line;
289     }
290     return len;
291 }
292 
293 /****************
294  * remove trailing white spaces and return the length of the buffer
295  */
296 unsigned
trim_trailing_ws(byte * line,unsigned len)297 trim_trailing_ws( byte *line, unsigned len )
298 {
299     return trim_trailing_chars( line, len, " \t\r\n" );
300 }
301 
302 size_t
length_sans_trailing_chars(const unsigned char * line,size_t len,const char * trimchars)303 length_sans_trailing_chars (const unsigned char *line, size_t len,
304                             const char *trimchars )
305 {
306   const unsigned char *p, *mark;
307   size_t n;
308 
309   for( mark=NULL, p=line, n=0; n < len; n++, p++ )
310     {
311       if (strchr (trimchars, *p ))
312         {
313           if( !mark )
314             mark = p;
315         }
316       else
317         mark = NULL;
318     }
319 
320   if (mark)
321     return mark - line;
322   return len;
323 }
324 
325 /*
326  *  Return the length of line ignoring trailing white-space.
327  */
328 size_t
length_sans_trailing_ws(const unsigned char * line,size_t len)329 length_sans_trailing_ws (const unsigned char *line, size_t len)
330 {
331   return length_sans_trailing_chars (line, len, " \t\r\n");
332 }
333 
334 
335 
336 /*
337  * Extract from a given path the filename component.  This function
338  * terminates the process on memory shortage.
339  */
340 char *
make_basename(const char * filepath,const char * inputpath)341 make_basename(const char *filepath, const char *inputpath)
342 {
343 #ifdef __riscos__
344     return riscos_make_basename(filepath, inputpath);
345 #else
346     char *p;
347 
348     (void)inputpath; /* Only required for riscos.  */
349 
350     if ( !(p=strrchr(filepath, '/')) )
351 #ifdef HAVE_DOSISH_SYSTEM
352 	if ( !(p=strrchr(filepath, '\\')) )
353 #endif
354 #ifdef HAVE_DRIVE_LETTERS
355 	    if ( !(p=strrchr(filepath, ':')) )
356 #endif
357 	      {
358 		return xstrdup(filepath);
359 	      }
360 
361     return xstrdup(p+1);
362 #endif
363 }
364 
365 
366 
367 /*
368  * Extract from a given filename the path prepended to it.  If there
369  * isn't a path prepended to the filename, a dot is returned ('.').
370  * This function terminates the process on memory shortage.
371  */
372 char *
make_dirname(const char * filepath)373 make_dirname(const char *filepath)
374 {
375     char *dirname;
376     int  dirname_length;
377     char *p;
378 
379     if ( !(p=strrchr(filepath, '/')) )
380 #ifdef HAVE_DOSISH_SYSTEM
381 	if ( !(p=strrchr(filepath, '\\')) )
382 #endif
383 #ifdef HAVE_DRIVE_LETTERS
384 	    if ( !(p=strrchr(filepath, ':')) )
385 #endif
386 	      {
387 		return xstrdup(".");
388 	      }
389 
390     dirname_length = p-filepath;
391     dirname = xmalloc(dirname_length+1);
392     strncpy(dirname, filepath, dirname_length);
393     dirname[dirname_length] = 0;
394 
395     return dirname;
396 }
397 
398 
399 
400 static char *
get_pwdir(int xmode,const char * name)401 get_pwdir (int xmode, const char *name)
402 {
403   char *result = NULL;
404 #ifdef HAVE_PWD_H
405   struct passwd *pwd = NULL;
406 
407   if (name)
408     {
409 #ifdef HAVE_GETPWNAM
410       /* Fixme: We should use getpwnam_r if available.  */
411       pwd = getpwnam (name);
412 #endif
413     }
414   else
415     {
416 #ifdef HAVE_GETPWUID
417       /* Fixme: We should use getpwuid_r if available.  */
418       pwd = getpwuid (getuid());
419 #endif
420     }
421   if (pwd)
422     {
423       if (xmode)
424         result = xstrdup (pwd->pw_dir);
425       else
426         result = xtrystrdup (pwd->pw_dir);
427     }
428 #else /*!HAVE_PWD_H*/
429   /* No support at all.  */
430   (void)xmode;
431   (void)name;
432 #endif /*HAVE_PWD_H*/
433   return result;
434 }
435 
436 
437 /* xmode 0 := Return NULL on error
438          1 := Terminate on error
439          2 := Make sure that name is absolute; return NULL on error
440          3 := Make sure that name is absolute; terminate on error
441  */
442 static char *
do_make_filename(int xmode,const char * first_part,va_list arg_ptr)443 do_make_filename (int xmode, const char *first_part, va_list arg_ptr)
444 {
445   const char *argv[32];
446   int argc;
447   size_t n;
448   int skip = 1;
449   char *home_buffer = NULL;
450   char *name, *home, *p;
451   int want_abs;
452 
453   want_abs = !!(xmode & 2);
454   xmode &= 1;
455 
456   n = strlen (first_part) + 1;
457   argc = 0;
458   while ( (argv[argc] = va_arg (arg_ptr, const char *)) )
459     {
460       n += strlen (argv[argc]) + 1;
461       if (argc >= DIM (argv)-1)
462         {
463           if (xmode)
464             BUG ();
465           gpg_err_set_errno (EINVAL);
466           return NULL;
467         }
468       argc++;
469     }
470   n++;
471 
472   home = NULL;
473   if (*first_part == '~')
474     {
475       if (first_part[1] == '/' || !first_part[1])
476         {
477           /* This is the "~/" or "~" case.  */
478           home = getenv("HOME");
479           if (!home)
480             home = home_buffer = get_pwdir (xmode, NULL);
481           if (home && *home)
482             n += strlen (home);
483         }
484       else
485         {
486           /* This is the "~username/" or "~username" case.  */
487           char *user;
488 
489           if (xmode)
490             user = xstrdup (first_part+1);
491           else
492             {
493               user = xtrystrdup (first_part+1);
494               if (!user)
495                 return NULL;
496             }
497           p = strchr (user, '/');
498           if (p)
499             *p = 0;
500           skip = 1 + strlen (user);
501 
502           home = home_buffer = get_pwdir (xmode, user);
503           xfree (user);
504           if (home)
505             n += strlen (home);
506           else
507             skip = 1;
508         }
509     }
510 
511   if (xmode)
512     name = xmalloc (n);
513   else
514     {
515       name = xtrymalloc (n);
516       if (!name)
517         {
518           xfree (home_buffer);
519           return NULL;
520         }
521     }
522 
523   if (home)
524     p = stpcpy (stpcpy (name, home), first_part + skip);
525   else
526     p = stpcpy (name, first_part);
527 
528   xfree (home_buffer);
529   for (argc=0; argv[argc]; argc++)
530     {
531       /* Avoid a leading double slash if the first part was "/".  */
532       if (!argc && name[0] == '/' && !name[1])
533         p = stpcpy (p, argv[argc]);
534       else
535         p = stpcpy (stpcpy (p, "/"), argv[argc]);
536     }
537 
538   if (want_abs)
539     {
540 #ifdef HAVE_DRIVE_LETTERS
541       p = strchr (name, ':');
542       if (p)
543         p++;
544       else
545         p = name;
546 #else
547       p = name;
548 #endif
549       if (*p != '/'
550 #ifdef HAVE_DRIVE_LETTERS
551           && *p != '\\'
552 #endif
553           )
554         {
555           home = gnupg_getcwd ();
556           if (!home)
557             {
558               if (xmode)
559                 {
560                   fprintf (stderr, "\nfatal: getcwd failed: %s\n",
561                            strerror (errno));
562                   exit(2);
563                 }
564               xfree (name);
565               return NULL;
566             }
567           n = strlen (home) + 1 + strlen (name) + 1;
568           if (xmode)
569             home_buffer = xmalloc (n);
570           else
571             {
572               home_buffer = xtrymalloc (n);
573               if (!home_buffer)
574                 {
575                   xfree (home);
576                   xfree (name);
577                   return NULL;
578                 }
579             }
580           if (p == name)
581             p = home_buffer;
582           else /* Windows case.  */
583             {
584               memcpy (home_buffer, p, p - name + 1);
585               p = home_buffer + (p - name + 1);
586             }
587 
588           /* Avoid a leading double slash if the cwd is "/".  */
589           if (home[0] == '/' && !home[1])
590             strcpy (stpcpy (p, "/"), name);
591           else
592             strcpy (stpcpy (stpcpy (p, home), "/"), name);
593 
594           xfree (home);
595           xfree (name);
596           name = home_buffer;
597           /* Let's do a simple compression to catch the most common
598              case of using "." for gpg's --homedir option.  */
599           n = strlen (name);
600           if (n > 2 && name[n-2] == '/' && name[n-1] == '.')
601             name[n-2] = 0;
602         }
603     }
604   return change_slashes (name);
605 }
606 
607 /* Construct a filename from the NULL terminated list of parts.  Tilde
608    expansion is done for the first argument.  This function terminates
609    the process on memory shortage. */
610 char *
make_filename(const char * first_part,...)611 make_filename (const char *first_part, ... )
612 {
613   va_list arg_ptr;
614   char *result;
615 
616   va_start (arg_ptr, first_part);
617   result = do_make_filename (1, first_part, arg_ptr);
618   va_end (arg_ptr);
619   return result;
620 }
621 
622 /* Construct a filename from the NULL terminated list of parts.  Tilde
623    expansion is done for the first argument.  This function may return
624    NULL on error. */
625 char *
make_filename_try(const char * first_part,...)626 make_filename_try (const char *first_part, ... )
627 {
628   va_list arg_ptr;
629   char *result;
630 
631   va_start (arg_ptr, first_part);
632   result = do_make_filename (0, first_part, arg_ptr);
633   va_end (arg_ptr);
634   return result;
635 }
636 
637 /* Construct an absolute filename from the NULL terminated list of
638    parts.  Tilde expansion is done for the first argument.  This
639    function terminates the process on memory shortage. */
640 char *
make_absfilename(const char * first_part,...)641 make_absfilename (const char *first_part, ... )
642 {
643   va_list arg_ptr;
644   char *result;
645 
646   va_start (arg_ptr, first_part);
647   result = do_make_filename (3, first_part, arg_ptr);
648   va_end (arg_ptr);
649   return result;
650 }
651 
652 /* Construct an absolute filename from the NULL terminated list of
653    parts.  Tilde expansion is done for the first argument.  This
654    function may return NULL on error. */
655 char *
make_absfilename_try(const char * first_part,...)656 make_absfilename_try (const char *first_part, ... )
657 {
658   va_list arg_ptr;
659   char *result;
660 
661   va_start (arg_ptr, first_part);
662   result = do_make_filename (2, first_part, arg_ptr);
663   va_end (arg_ptr);
664   return result;
665 }
666 
667 
668 
669 /* Compare whether the filenames are identical.  This is a
670    special version of strcmp() taking the semantics of filenames in
671    account.  Note that this function works only on the supplied names
672    without considering any context like the current directory.  See
673    also same_file_p(). */
674 int
compare_filenames(const char * a,const char * b)675 compare_filenames (const char *a, const char *b)
676 {
677 #ifdef HAVE_DOSISH_SYSTEM
678   for ( ; *a && *b; a++, b++ )
679     {
680       if (*a != *b
681           && (toupper (*(const unsigned char*)a)
682               != toupper (*(const unsigned char*)b) )
683           && !((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/')))
684         break;
685     }
686   if ((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/'))
687     return 0;
688   else
689     return (toupper (*(const unsigned char*)a)
690             - toupper (*(const unsigned char*)b));
691 #else
692     return strcmp(a,b);
693 #endif
694 }
695 
696 
697 /* Convert a base-10 number in STRING into a 64 bit unsigned int
698  * value.  Leading white spaces are skipped but no error checking is
699  * done.  Thus it is similar to atoi(). */
700 uint64_t
string_to_u64(const char * string)701 string_to_u64 (const char *string)
702 {
703   uint64_t val = 0;
704 
705   while (spacep (string))
706     string++;
707   for (; digitp (string); string++)
708     {
709       val *= 10;
710       val += *string - '0';
711     }
712   return val;
713 }
714 
715 
716 /* Convert 2 hex characters at S to a byte value.  Return this value
717    or -1 if there is an error. */
718 int
hextobyte(const char * s)719 hextobyte (const char *s)
720 {
721   int c;
722 
723   if ( *s >= '0' && *s <= '9' )
724     c = 16 * (*s - '0');
725   else if ( *s >= 'A' && *s <= 'F' )
726     c = 16 * (10 + *s - 'A');
727   else if ( *s >= 'a' && *s <= 'f' )
728     c = 16 * (10 + *s - 'a');
729   else
730     return -1;
731   s++;
732   if ( *s >= '0' && *s <= '9' )
733     c += *s - '0';
734   else if ( *s >= 'A' && *s <= 'F' )
735     c += 10 + *s - 'A';
736   else if ( *s >= 'a' && *s <= 'f' )
737     c += 10 + *s - 'a';
738   else
739     return -1;
740   return c;
741 }
742 
743 /* Given a string containing an UTF-8 encoded text, return the number
744    of characters in this string.  It differs from strlen in that it
745    only counts complete UTF-8 characters.  SIZE is the maximum length
746    of the string in bytes.  If SIZE is -1, then a NUL character is
747    taken to be the end of the string.  Note, that this function does
748    not take combined characters into account.  */
749 size_t
utf8_charcount(const char * s,int len)750 utf8_charcount (const char *s, int len)
751 {
752   size_t n;
753 
754   if (len == 0)
755     return 0;
756 
757   for (n=0; *s; s++)
758     {
759       if ( (*s&0xc0) != 0x80 ) /* Exclude continuation bytes: 10xxxxxx */
760         n++;
761 
762       if (len != -1)
763         {
764           len --;
765           if (len == 0)
766             break;
767         }
768     }
769 
770   return n;
771 }
772 
773 
774 /****************************************************
775  **********  W32 specific functions  ****************
776  ****************************************************/
777 
778 #ifdef HAVE_W32_SYSTEM
779 const char *
w32_strerror(int ec)780 w32_strerror (int ec)
781 {
782   static char strerr[256];
783 
784   if (ec == -1)
785     ec = (int)GetLastError ();
786 #ifdef HAVE_W32CE_SYSTEM
787   /* There is only a wchar_t FormatMessage.  It does not make much
788      sense to play the conversion game; we print only the code.  */
789   snprintf (strerr, sizeof strerr, "ec=%d", (int)GetLastError ());
790 #else
791   FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
792                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
793                  strerr, DIM (strerr)-1, NULL);
794   {
795     /* Strip the CR,LF - we want just the string.  */
796     size_t n = strlen (strerr);
797     if (n > 2 && strerr[n-2] == '\r' && strerr[n-1] == '\n' )
798       strerr[n-2] = 0;
799   }
800 #endif
801   return strerr;
802 }
803 #endif /*HAVE_W32_SYSTEM*/
804 
805 
806 /****************************************************
807  ******** Locale insensitive ctype functions ********
808  ****************************************************/
809 /* FIXME: replace them by a table lookup and macros */
810 int
ascii_isupper(int c)811 ascii_isupper (int c)
812 {
813     return c >= 'A' && c <= 'Z';
814 }
815 
816 int
ascii_islower(int c)817 ascii_islower (int c)
818 {
819     return c >= 'a' && c <= 'z';
820 }
821 
822 int
ascii_toupper(int c)823 ascii_toupper (int c)
824 {
825     if (c >= 'a' && c <= 'z')
826         c &= ~0x20;
827     return c;
828 }
829 
830 int
ascii_tolower(int c)831 ascii_tolower (int c)
832 {
833     if (c >= 'A' && c <= 'Z')
834         c |= 0x20;
835     return c;
836 }
837 
838 /* Lowercase all ASCII characters in S.  */
839 char *
ascii_strlwr(char * s)840 ascii_strlwr (char *s)
841 {
842   char *p = s;
843 
844   for (p=s; *p; p++ )
845     if (isascii (*p) && *p >= 'A' && *p <= 'Z')
846       *p |= 0x20;
847 
848   return s;
849 }
850 
851 /* Upcase all ASCII characters in S.  */
852 char *
ascii_strupr(char * s)853 ascii_strupr (char *s)
854 {
855   char *p = s;
856 
857   for (p=s; *p; p++ )
858     if (isascii (*p) && *p >= 'a' && *p <= 'z')
859       *p &= ~0x20;
860 
861   return s;
862 }
863 
864 int
ascii_strcasecmp(const char * a,const char * b)865 ascii_strcasecmp( const char *a, const char *b )
866 {
867     if (a == b)
868         return 0;
869 
870     for (; *a && *b; a++, b++) {
871 	if (*a != *b && ascii_toupper(*a) != ascii_toupper(*b))
872 	    break;
873     }
874     return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
875 }
876 
877 int
ascii_strncasecmp(const char * a,const char * b,size_t n)878 ascii_strncasecmp (const char *a, const char *b, size_t n)
879 {
880   const unsigned char *p1 = (const unsigned char *)a;
881   const unsigned char *p2 = (const unsigned char *)b;
882   unsigned char c1, c2;
883 
884   if (p1 == p2 || !n )
885     return 0;
886 
887   do
888     {
889       c1 = ascii_tolower (*p1);
890       c2 = ascii_tolower (*p2);
891 
892       if ( !--n || c1 == '\0')
893 	break;
894 
895       ++p1;
896       ++p2;
897     }
898   while (c1 == c2);
899 
900   return c1 - c2;
901 }
902 
903 
904 int
ascii_memcasecmp(const void * a_arg,const void * b_arg,size_t n)905 ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n )
906 {
907   const char *a = a_arg;
908   const char *b = b_arg;
909 
910   if (a == b)
911     return 0;
912   for ( ; n; n--, a++, b++ )
913     {
914       if( *a != *b  && ascii_toupper (*a) != ascii_toupper (*b) )
915         return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b));
916     }
917   return 0;
918 }
919 
920 int
ascii_strcmp(const char * a,const char * b)921 ascii_strcmp( const char *a, const char *b )
922 {
923     if (a == b)
924         return 0;
925 
926     for (; *a && *b; a++, b++) {
927 	if (*a != *b )
928 	    break;
929     }
930     return *a == *b? 0 : (*(signed char *)a - *(signed char *)b);
931 }
932 
933 
934 void *
ascii_memcasemem(const void * haystack,size_t nhaystack,const void * needle,size_t nneedle)935 ascii_memcasemem (const void *haystack, size_t nhaystack,
936                   const void *needle, size_t nneedle)
937 {
938 
939   if (!nneedle)
940     return (void*)haystack; /* finding an empty needle is really easy */
941   if (nneedle <= nhaystack)
942     {
943       const char *a = haystack;
944       const char *b = a + nhaystack - nneedle;
945 
946       for (; a <= b; a++)
947         {
948           if ( !ascii_memcasecmp (a, needle, nneedle) )
949             return (void *)a;
950         }
951     }
952   return NULL;
953 }
954 
955 /*********************************************
956  ********** missing string functions *********
957  *********************************************/
958 
959 #ifndef HAVE_STPCPY
960 char *
stpcpy(char * a,const char * b)961 stpcpy(char *a,const char *b)
962 {
963     while( *b )
964 	*a++ = *b++;
965     *a = 0;
966 
967     return (char*)a;
968 }
969 #endif
970 
971 #ifndef HAVE_STRPBRK
972 /* Find the first occurrence in S of any character in ACCEPT.
973    Code taken from glibc-2.6/string/strpbrk.c (LGPLv2.1+) and modified. */
974 char *
strpbrk(const char * s,const char * accept)975 strpbrk (const char *s, const char *accept)
976 {
977   while (*s != '\0')
978     {
979       const char *a = accept;
980       while (*a != '\0')
981 	if (*a++ == *s)
982 	  return (char *) s;
983       ++s;
984     }
985 
986   return NULL;
987 }
988 #endif /*!HAVE_STRPBRK*/
989 
990 
991 #ifndef HAVE_STRSEP
992 /* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
993 char *
strsep(char ** stringp,const char * delim)994 strsep (char **stringp, const char *delim)
995 {
996   char *begin, *end;
997 
998   begin = *stringp;
999   if (begin == NULL)
1000     return NULL;
1001 
1002   /* A frequent case is when the delimiter string contains only one
1003      character.  Here we don't need to call the expensive 'strpbrk'
1004      function and instead work using 'strchr'.  */
1005   if (delim[0] == '\0' || delim[1] == '\0')
1006     {
1007       char ch = delim[0];
1008 
1009       if (ch == '\0')
1010         end = NULL;
1011       else
1012         {
1013           if (*begin == ch)
1014             end = begin;
1015           else if (*begin == '\0')
1016             end = NULL;
1017           else
1018             end = strchr (begin + 1, ch);
1019         }
1020     }
1021   else
1022     /* Find the end of the token.  */
1023     end = strpbrk (begin, delim);
1024 
1025   if (end)
1026     {
1027       /* Terminate the token and set *STRINGP past NUL character.  */
1028       *end++ = '\0';
1029       *stringp = end;
1030     }
1031   else
1032     /* No more delimiters; this is the last token.  */
1033     *stringp = NULL;
1034 
1035   return begin;
1036 }
1037 #endif /*HAVE_STRSEP*/
1038 
1039 
1040 #ifndef HAVE_STRLWR
1041 char *
strlwr(char * s)1042 strlwr(char *s)
1043 {
1044     char *p;
1045     for(p=s; *p; p++ )
1046 	*p = tolower(*p);
1047     return s;
1048 }
1049 #endif
1050 
1051 
1052 #ifndef HAVE_STRCASECMP
1053 int
strcasecmp(const char * a,const char * b)1054 strcasecmp( const char *a, const char *b )
1055 {
1056     for( ; *a && *b; a++, b++ ) {
1057 	if( *a != *b && toupper(*a) != toupper(*b) )
1058 	    break;
1059     }
1060     return *(const byte*)a - *(const byte*)b;
1061 }
1062 #endif
1063 
1064 
1065 /****************
1066  * mingw32/cpd has a memicmp()
1067  */
1068 #ifndef HAVE_MEMICMP
1069 int
memicmp(const char * a,const char * b,size_t n)1070 memicmp( const char *a, const char *b, size_t n )
1071 {
1072     for( ; n; n--, a++, b++ )
1073 	if( *a != *b  && toupper(*(const byte*)a) != toupper(*(const byte*)b) )
1074 	    return *(const byte *)a - *(const byte*)b;
1075     return 0;
1076 }
1077 #endif
1078 
1079 
1080 #ifndef HAVE_MEMRCHR
1081 void *
memrchr(const void * buffer,int c,size_t n)1082 memrchr (const void *buffer, int c, size_t n)
1083 {
1084   const unsigned char *p = buffer;
1085 
1086   for (p += n; n ; n--)
1087     if (*--p == c)
1088       return (void *)p;
1089   return NULL;
1090 }
1091 #endif /*HAVE_MEMRCHR*/
1092 
1093 
1094 /* Percent-escape the string STR by replacing colons with '%3a'.  If
1095    EXTRA is not NULL all characters in EXTRA are also escaped.  */
1096 static char *
do_percent_escape(const char * str,const char * extra,int die)1097 do_percent_escape (const char *str, const char *extra, int die)
1098 {
1099   int i, j;
1100   char *ptr;
1101 
1102   if (!str)
1103     return NULL;
1104 
1105   for (i=j=0; str[i]; i++)
1106     if (str[i] == ':' || str[i] == '%' || str[i] == '\n'
1107         || (extra && strchr (extra, str[i])))
1108       j++;
1109   if (die)
1110     ptr = xmalloc (i + 2 * j + 1);
1111   else
1112     {
1113       ptr = xtrymalloc (i + 2 * j + 1);
1114       if (!ptr)
1115         return NULL;
1116     }
1117   i = 0;
1118   while (*str)
1119     {
1120       if (*str == ':')
1121 	{
1122 	  ptr[i++] = '%';
1123 	  ptr[i++] = '3';
1124 	  ptr[i++] = 'a';
1125 	}
1126       else if (*str == '%')
1127 	{
1128 	  ptr[i++] = '%';
1129 	  ptr[i++] = '2';
1130 	  ptr[i++] = '5';
1131 	}
1132       else if (*str == '\n')
1133 	{
1134 	  /* The newline is problematic in a line-based format.  */
1135 	  ptr[i++] = '%';
1136 	  ptr[i++] = '0';
1137 	  ptr[i++] = 'a';
1138 	}
1139       else if (extra && strchr (extra, *str))
1140         {
1141 	  ptr[i++] = '%';
1142           ptr[i++] = tohex_lower ((*str>>4)&15);
1143           ptr[i++] = tohex_lower (*str&15);
1144         }
1145       else
1146 	ptr[i++] = *str;
1147       str++;
1148     }
1149   ptr[i] = '\0';
1150 
1151   return ptr;
1152 }
1153 
1154 /* Percent-escape the string STR by replacing colons with '%3a'.  If
1155    EXTRA is not NULL all characters in EXTRA are also escaped.  This
1156    function terminates the process on memory shortage.  */
1157 char *
percent_escape(const char * str,const char * extra)1158 percent_escape (const char *str, const char *extra)
1159 {
1160   return do_percent_escape (str, extra, 1);
1161 }
1162 
1163 /* Same as percent_escape but return NULL instead of exiting on memory
1164    error. */
1165 char *
try_percent_escape(const char * str,const char * extra)1166 try_percent_escape (const char *str, const char *extra)
1167 {
1168   return do_percent_escape (str, extra, 0);
1169 }
1170 
1171 
1172 
1173 static char *
do_strconcat(const char * s1,va_list arg_ptr)1174 do_strconcat (const char *s1, va_list arg_ptr)
1175 {
1176   const char *argv[48];
1177   size_t argc;
1178   size_t needed;
1179   char *buffer, *p;
1180 
1181   argc = 0;
1182   argv[argc++] = s1;
1183   needed = strlen (s1);
1184   while (((argv[argc] = va_arg (arg_ptr, const char *))))
1185     {
1186       needed += strlen (argv[argc]);
1187       if (argc >= DIM (argv)-1)
1188         {
1189           gpg_err_set_errno (EINVAL);
1190           return NULL;
1191         }
1192       argc++;
1193     }
1194   needed++;
1195   buffer = xtrymalloc (needed);
1196   if (buffer)
1197     {
1198       for (p = buffer, argc=0; argv[argc]; argc++)
1199         p = stpcpy (p, argv[argc]);
1200     }
1201   return buffer;
1202 }
1203 
1204 
1205 /* Concatenate the string S1 with all the following strings up to a
1206    NULL.  Returns a malloced buffer with the new string or NULL on a
1207    malloc error or if too many arguments are given.  */
1208 char *
strconcat(const char * s1,...)1209 strconcat (const char *s1, ...)
1210 {
1211   va_list arg_ptr;
1212   char *result;
1213 
1214   if (!s1)
1215     result = xtrystrdup ("");
1216   else
1217     {
1218       va_start (arg_ptr, s1);
1219       result = do_strconcat (s1, arg_ptr);
1220       va_end (arg_ptr);
1221     }
1222   return result;
1223 }
1224 
1225 /* Same as strconcat but terminate the process with an error message
1226    if something goes wrong.  */
1227 char *
xstrconcat(const char * s1,...)1228 xstrconcat (const char *s1, ...)
1229 {
1230   va_list arg_ptr;
1231   char *result;
1232 
1233   if (!s1)
1234     result = xstrdup ("");
1235   else
1236     {
1237       va_start (arg_ptr, s1);
1238       result = do_strconcat (s1, arg_ptr);
1239       va_end (arg_ptr);
1240     }
1241   if (!result)
1242     {
1243       if (errno == EINVAL)
1244         fputs ("\nfatal: too many args for xstrconcat\n", stderr);
1245       else
1246         fputs ("\nfatal: out of memory\n", stderr);
1247       exit (2);
1248     }
1249   return result;
1250 }
1251 
1252 /* Split a string into fields at DELIM.  REPLACEMENT is the character
1253    to replace the delimiter with (normally: '\0' so that each field is
1254    NUL terminated).  The caller is responsible for freeing the result.
1255    Note: this function modifies STRING!  If you need the original
1256    value, then you should pass a copy to this function.
1257 
1258    If malloc fails, this function returns NULL.  */
1259 char **
strsplit(char * string,char delim,char replacement,int * count)1260 strsplit (char *string, char delim, char replacement, int *count)
1261 {
1262   int fields = 1;
1263   char *t;
1264   char **result;
1265 
1266   /* First, count the number of fields.  */
1267   for (t = strchr (string, delim); t; t = strchr (t + 1, delim))
1268     fields ++;
1269 
1270   result = xtrycalloc ((fields + 1), sizeof (*result));
1271   if (! result)
1272     return NULL;
1273 
1274   result[0] = string;
1275   fields = 1;
1276   for (t = strchr (string, delim); t; t = strchr (t + 1, delim))
1277     {
1278       result[fields ++] = t + 1;
1279       *t = replacement;
1280     }
1281 
1282   if (count)
1283     *count = fields;
1284 
1285   return result;
1286 }
1287 
1288 
1289 /* Tokenize STRING using the set of delimiters in DELIM.  Leading
1290  * spaces and tabs are removed from all tokens.  The caller must xfree
1291  * the result.
1292  *
1293  * Returns: A malloced and NULL delimited array with the tokens.  On
1294  *          memory error NULL is returned and ERRNO is set.
1295  */
1296 static char **
do_strtokenize(const char * string,const char * delim,int trim)1297 do_strtokenize (const char *string, const char *delim, int trim)
1298 {
1299   const char *s;
1300   size_t fields;
1301   size_t bytes, n;
1302   char *buffer;
1303   char *p, *px, *pend;
1304   char **result;
1305 
1306   /* Count the number of fields.  */
1307   for (fields = 1, s = strpbrk (string, delim); s; s = strpbrk (s + 1, delim))
1308     fields++;
1309   fields++; /* Add one for the terminating NULL.  */
1310 
1311   /* Allocate an array for all fields, a terminating NULL, and space
1312      for a copy of the string.  */
1313   bytes = fields * sizeof *result;
1314   if (bytes / sizeof *result != fields)
1315     {
1316       gpg_err_set_errno (ENOMEM);
1317       return NULL;
1318     }
1319   n = strlen (string) + 1;
1320   bytes += n;
1321   if (bytes < n)
1322     {
1323       gpg_err_set_errno (ENOMEM);
1324       return NULL;
1325     }
1326   result = xtrymalloc (bytes);
1327   if (!result)
1328     return NULL;
1329   buffer = (char*)(result + fields);
1330 
1331   /* Copy and parse the string.  */
1332   strcpy (buffer, string);
1333   for (n = 0, p = buffer; (pend = strpbrk (p, delim)); p = pend + 1)
1334     {
1335       *pend = 0;
1336       if (trim)
1337         {
1338           while (spacep (p))
1339             p++;
1340           for (px = pend - 1; px >= p && spacep (px); px--)
1341             *px = 0;
1342         }
1343       result[n++] = p;
1344     }
1345   if (trim)
1346     {
1347       while (spacep (p))
1348         p++;
1349       for (px = p + strlen (p) - 1; px >= p && spacep (px); px--)
1350         *px = 0;
1351     }
1352   result[n++] = p;
1353   result[n] = NULL;
1354 
1355   log_assert ((char*)(result + n + 1) == buffer);
1356 
1357   return result;
1358 }
1359 
1360 /* Tokenize STRING using the set of delimiters in DELIM.  Leading
1361  * spaces and tabs are removed from all tokens.  The caller must xfree
1362  * the result.
1363  *
1364  * Returns: A malloced and NULL delimited array with the tokens.  On
1365  *          memory error NULL is returned and ERRNO is set.
1366  */
1367 char **
strtokenize(const char * string,const char * delim)1368 strtokenize (const char *string, const char *delim)
1369 {
1370   return do_strtokenize (string, delim, 1);
1371 }
1372 
1373 /* Same as strtokenize but does not trim leading and trailing spaces
1374  * from the fields.  */
1375 char **
strtokenize_nt(const char * string,const char * delim)1376 strtokenize_nt (const char *string, const char *delim)
1377 {
1378   return do_strtokenize (string, delim, 0);
1379 }
1380 
1381 
1382 /* Split a string into space delimited fields and remove leading and
1383  * trailing spaces from each field.  A pointer to each field is stored
1384  * in ARRAY.  Stop splitting at ARRAYSIZE fields.  The function
1385  * modifies STRING.  The number of parsed fields is returned.
1386  * Example:
1387  *
1388  *   char *fields[2];
1389  *   if (split_fields (string, fields, DIM (fields)) < 2)
1390  *     return  // Not enough args.
1391  *   foo (fields[0]);
1392  *   foo (fields[1]);
1393  */
1394 int
split_fields(char * string,const char ** array,int arraysize)1395 split_fields (char *string, const char **array, int arraysize)
1396 {
1397   int n = 0;
1398   const char *p;
1399   char *pend;
1400 
1401   for (p = string; *p == ' '; p++)
1402     ;
1403   do
1404     {
1405       if (n == arraysize)
1406         break;
1407       array[n++] = p;
1408       pend = strchr (p, ' ');
1409       if (!pend)
1410         break;
1411       *pend++ = 0;
1412       for (p = pend; *p == ' '; p++)
1413         ;
1414     }
1415   while (*p);
1416 
1417   return n;
1418 }
1419 
1420 
1421 /* Split a string into colon delimited fields A pointer to each field
1422  * is stored in ARRAY.  Stop splitting at ARRAYSIZE fields.  The
1423  * function modifies STRING.  The number of parsed fields is returned.
1424  * Note that leading and trailing spaces are not removed from the fields.
1425  * Example:
1426  *
1427  *   char *fields[2];
1428  *   if (split_fields (string, fields, DIM (fields)) < 2)
1429  *     return  // Not enough args.
1430  *   foo (fields[0]);
1431  *   foo (fields[1]);
1432  */
1433 int
split_fields_colon(char * string,const char ** array,int arraysize)1434 split_fields_colon (char *string, const char **array, int arraysize)
1435 {
1436   int n = 0;
1437   const char *p;
1438   char *pend;
1439 
1440   p = string;
1441   do
1442     {
1443       if (n == arraysize)
1444         break;
1445       array[n++] = p;
1446       pend = strchr (p, ':');
1447       if (!pend)
1448         break;
1449       *pend++ = 0;
1450       p = pend;
1451     }
1452   while (*p);
1453 
1454   return n;
1455 }
1456 
1457 
1458 
1459 /* Version number parsing.  */
1460 
1461 /* This function parses the first portion of the version number S and
1462    stores it in *NUMBER.  On success, this function returns a pointer
1463    into S starting with the first character, which is not part of the
1464    initial number portion; on failure, NULL is returned.  */
1465 static const char*
parse_version_number(const char * s,int * number)1466 parse_version_number (const char *s, int *number)
1467 {
1468   int val = 0;
1469 
1470   if (*s == '0' && digitp (s+1))
1471     return NULL;  /* Leading zeros are not allowed.  */
1472   for (; digitp (s); s++)
1473     {
1474       val *= 10;
1475       val += *s - '0';
1476     }
1477   *number = val;
1478   return val < 0 ? NULL : s;
1479 }
1480 
1481 
1482 /* This function breaks up the complete string-representation of the
1483    version number S, which is of the following structure: <major
1484    number>.<minor number>[.<micro number>]<patch level>.  The major,
1485    minor, and micro number components will be stored in *MAJOR, *MINOR
1486    and *MICRO.  If MICRO is not given 0 is used instead.
1487 
1488    On success, the last component, the patch level, will be returned;
1489    in failure, NULL will be returned.  */
1490 static const char *
parse_version_string(const char * s,int * major,int * minor,int * micro)1491 parse_version_string (const char *s, int *major, int *minor, int *micro)
1492 {
1493   s = parse_version_number (s, major);
1494   if (!s || *s != '.')
1495     return NULL;
1496   s++;
1497   s = parse_version_number (s, minor);
1498   if (!s)
1499     return NULL;
1500   if (*s == '.')
1501     {
1502       s++;
1503       s = parse_version_number (s, micro);
1504       if (!s)
1505         return NULL;
1506     }
1507   else
1508     *micro = 0;
1509   return s;  /* Patchlevel.  */
1510 }
1511 
1512 
1513 /* Compare the version string MY_VERSION to the version string
1514  * REQ_VERSION.  Returns -1, 0, or 1 if MY_VERSION is found,
1515  * respectively, to be less than, to match, or be greater than
1516  * REQ_VERSION.  This function works for three and two part version
1517  * strings; for a two part version string the micro part is assumed to
1518  * be 0.  Patch levels are compared as strings.  If a version number
1519  * is invalid INT_MIN is returned.  If REQ_VERSION is given as NULL
1520  * the function returns 0 if MY_VERSION is parsable version string. */
1521 int
compare_version_strings(const char * my_version,const char * req_version)1522 compare_version_strings (const char *my_version, const char *req_version)
1523 {
1524   int my_major, my_minor, my_micro;
1525   int rq_major, rq_minor, rq_micro;
1526   const char *my_patch, *rq_patch;
1527   int result;
1528 
1529   if (!my_version)
1530     return INT_MIN;
1531 
1532   my_patch = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
1533   if (!my_patch)
1534     return INT_MIN;
1535   if (!req_version)
1536     return 0; /* MY_VERSION can be parsed.  */
1537   rq_patch = parse_version_string (req_version, &rq_major, &rq_minor,&rq_micro);
1538   if (!rq_patch)
1539     return INT_MIN;
1540 
1541   if (my_major == rq_major)
1542     {
1543       if (my_minor == rq_minor)
1544         {
1545           if (my_micro == rq_micro)
1546             result = strcmp (my_patch, rq_patch);
1547           else
1548             result = my_micro - rq_micro;
1549         }
1550       else
1551         result = my_minor - rq_minor;
1552     }
1553   else
1554     result = my_major - rq_major;
1555 
1556   return !result? 0 : result < 0 ? -1 : 1;
1557 }
1558 
1559 
1560 
1561 /* Format a string so that it fits within about TARGET_COLS columns.
1562  * TEXT_IN is copied to a new buffer, which is returned.  Normally,
1563  * target_cols will be 72 and max_cols is 80.  On error NULL is
1564  * returned and ERRNO is set. */
1565 char *
format_text(const char * text_in,int target_cols,int max_cols)1566 format_text (const char *text_in, int target_cols, int max_cols)
1567 {
1568   /* const int do_debug = 0; */
1569 
1570   /* The character under consideration.  */
1571   char *p;
1572   /* The start of the current line.  */
1573   char *line;
1574   /* The last space that we saw.  */
1575   char *last_space = NULL;
1576   int last_space_cols = 0;
1577   int copied_last_space = 0;
1578   char *text;
1579 
1580   text = xtrystrdup (text_in);
1581   if (!text)
1582     return NULL;
1583 
1584   p = line = text;
1585   while (1)
1586     {
1587       /* The number of columns including any trailing space.  */
1588       int cols;
1589 
1590       p = p + strcspn (p, "\n ");
1591       if (! p)
1592         /* P now points to the NUL character.  */
1593         p = &text[strlen (text)];
1594 
1595       if (*p == '\n')
1596         /* Pass through any newlines.  */
1597         {
1598           p ++;
1599           line = p;
1600           last_space = NULL;
1601           last_space_cols = 0;
1602           copied_last_space = 1;
1603           continue;
1604         }
1605 
1606       /* Have a space or a NUL.  Note: we don't count the trailing
1607          space.  */
1608       cols = utf8_charcount (line, (uintptr_t) p - (uintptr_t) line);
1609       if (cols < target_cols)
1610         {
1611           if (! *p)
1612             /* Nothing left to break.  */
1613             break;
1614 
1615           last_space = p;
1616           last_space_cols = cols;
1617           p ++;
1618           /* Skip any immediately following spaces.  If we break:
1619              "... foo bar ..." between "foo" and "bar" then we want:
1620              "... foo\nbar ...", which means that the left space has
1621              to be the first space after foo, not the last space
1622              before bar.  */
1623           while (*p == ' ')
1624             p ++;
1625         }
1626       else
1627         {
1628           int cols_with_left_space;
1629           int cols_with_right_space;
1630           int left_penalty;
1631           int right_penalty;
1632 
1633           cols_with_left_space = last_space_cols;
1634           cols_with_right_space = cols;
1635 
1636           /* if (do_debug) */
1637           /*   log_debug ("Breaking: '%.*s'\n", */
1638           /*              (int) ((uintptr_t) p - (uintptr_t) line), line); */
1639 
1640           /* The number of columns away from TARGET_COLS.  We prefer
1641              to underflow than to overflow.  */
1642           left_penalty = target_cols - cols_with_left_space;
1643           right_penalty = 2 * (cols_with_right_space - target_cols);
1644 
1645           if (cols_with_right_space > max_cols)
1646             /* Add a large penalty for each column that exceeds
1647                max_cols.  */
1648             right_penalty += 4 * (cols_with_right_space - max_cols);
1649 
1650           /* if (do_debug) */
1651           /*   log_debug ("Left space => %d cols (penalty: %d); " */
1652           /*              "right space => %d cols (penalty: %d)\n", */
1653           /*              cols_with_left_space, left_penalty, */
1654           /*              cols_with_right_space, right_penalty); */
1655           if (last_space_cols && left_penalty <= right_penalty)
1656             {
1657               /* Prefer the left space.  */
1658               /* if (do_debug) */
1659               /*   log_debug ("Breaking at left space.\n"); */
1660               p = last_space;
1661             }
1662           else
1663             {
1664               /* if (do_debug) */
1665               /*   log_debug ("Breaking at right space.\n"); */
1666             }
1667 
1668           if (! *p)
1669             break;
1670 
1671           *p = '\n';
1672           p ++;
1673           if (*p == ' ')
1674             {
1675               int spaces;
1676               for (spaces = 1; p[spaces] == ' '; spaces ++)
1677                 ;
1678               memmove (p, &p[spaces], strlen (&p[spaces]) + 1);
1679             }
1680           line = p;
1681           last_space = NULL;
1682           last_space_cols = 0;
1683           copied_last_space = 0;
1684         }
1685     }
1686 
1687   /* Chop off any trailing space.  */
1688   trim_trailing_chars (text, strlen (text), " ");
1689   /* If we inserted the trailing newline, then remove it.  */
1690   if (! copied_last_space && *text && text[strlen (text) - 1] == '\n')
1691     text[strlen (text) - 1] = '\0';
1692 
1693   return text;
1694 }
1695 
1696 
1697 /* Substitute environment variables in STRING and return a new string.
1698  * On error the function returns NULL.  */
1699 char *
substitute_envvars(const char * string)1700 substitute_envvars (const char *string)
1701 {
1702   char *line, *p, *pend;
1703   const char *value;
1704   size_t valuelen, n;
1705   char *result = NULL;
1706 
1707   result = line = xtrystrdup (string);
1708   if (!result)
1709     return NULL; /* Ooops */
1710 
1711   while (*line)
1712     {
1713       p = strchr (line, '$');
1714       if (!p)
1715         goto leave; /* No or no more variables.  */
1716 
1717       if (p[1] == '$') /* Escaped dollar sign. */
1718         {
1719           memmove (p, p+1, strlen (p+1)+1);
1720           line = p + 1;
1721           continue;
1722         }
1723 
1724       if (p[1] == '{')
1725         {
1726           int count = 0;
1727 
1728           for (pend=p+2; *pend; pend++)
1729             {
1730               if (*pend == '{')
1731                 count++;
1732               else if (*pend == '}')
1733                 {
1734                   if (--count < 0)
1735                     break;
1736                 }
1737             }
1738           if (!*pend)
1739             goto leave; /* Unclosed - don't substitute.  */
1740         }
1741       else
1742         {
1743           for (pend = p+1; *pend && (alnump (pend) || *pend == '_'); pend++)
1744             ;
1745         }
1746 
1747       if (p[1] == '{' && *pend == '}')
1748         {
1749           int save = *pend;
1750           *pend = 0;
1751           value = getenv (p+2);
1752           *pend++ = save;
1753         }
1754       else
1755         {
1756           int save = *pend;
1757           *pend = 0;
1758           value = getenv (p+1);
1759           *pend = save;
1760         }
1761 
1762       if (!value)
1763         value = "";
1764       valuelen = strlen (value);
1765       if (valuelen <= pend - p)
1766         {
1767           memcpy (p, value, valuelen);
1768           p += valuelen;
1769           n = pend - p;
1770           if (n)
1771             memmove (p, p+n, strlen (p+n)+1);
1772           line = p;
1773         }
1774       else
1775         {
1776           char *src = result;
1777           char *dst;
1778 
1779           dst = xtrymalloc (strlen (src) + valuelen + 1);
1780           if (!dst)
1781             {
1782               xfree (result);
1783               return NULL;
1784             }
1785           n = p - src;
1786           memcpy (dst, src, n);
1787           memcpy (dst + n, value, valuelen);
1788           n += valuelen;
1789           strcpy (dst + n, pend);
1790           line = dst + n;
1791           xfree (result);
1792           result = dst;
1793         }
1794     }
1795 
1796  leave:
1797   return result;
1798 }
1799