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