1 /*
2  * Copyright 2004-2021 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #ifndef _GNU_SOURCE
13 #  define _GNU_SOURCE
14 #endif
15 
16 #include <regex.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <ctype.h>
21 #include <float.h>  // DBL_MIN
22 #include <limits.h>
23 #include <math.h>   // fabs()
24 #include <bzlib.h>
25 #include <sys/types.h>
26 
27 /*!
28  * \internal
29  * \brief Scan a long long integer from a string
30  *
31  * \param[in]  text           String to scan
32  * \param[out] result         If not NULL, where to store scanned value
33  * \param[in]  default_value  Value to use if text is NULL or invalid
34  * \param[out] end_text       If not NULL, where to store pointer to first
35  *                            non-integer character
36  *
37  * \return Standard Pacemaker return code (\c pcmk_rc_ok on success,
38  *         \c EINVAL on failed string conversion due to invalid input,
39  *         or \c EOVERFLOW on arithmetic overflow)
40  * \note Sets \c errno on error
41  */
42 static int
scan_ll(const char * text,long long * result,long long default_value,char ** end_text)43 scan_ll(const char *text, long long *result, long long default_value,
44         char **end_text)
45 {
46     long long local_result = default_value;
47     char *local_end_text = NULL;
48     int rc = pcmk_rc_ok;
49 
50     errno = 0;
51     if (text != NULL) {
52         local_result = strtoll(text, &local_end_text, 10);
53         if (errno == ERANGE) {
54             rc = EOVERFLOW;
55             crm_warn("Integer parsed from '%s' was clipped to %lld",
56                      text, local_result);
57 
58         } else if (errno != 0) {
59             rc = errno;
60             local_result = default_value;
61             crm_warn("Could not parse integer from '%s' (using %lld instead): "
62                      "%s", text, default_value, pcmk_rc_str(rc));
63 
64         } else if (local_end_text == text) {
65             rc = EINVAL;
66             local_result = default_value;
67             crm_warn("Could not parse integer from '%s' (using %lld instead): "
68                     "No digits found", text, default_value);
69         }
70 
71         if ((end_text == NULL) && !pcmk__str_empty(local_end_text)) {
72             crm_warn("Characters left over after parsing '%s': '%s'",
73                      text, local_end_text);
74         }
75         errno = rc;
76     }
77     if (end_text != NULL) {
78         *end_text = local_end_text;
79     }
80     if (result != NULL) {
81         *result = local_result;
82     }
83     return rc;
84 }
85 
86 /*!
87  * \internal
88  * \brief Scan a long long integer value from a string
89  *
90  * \param[in]  text           The string to scan (may be NULL)
91  * \param[out] result         Where to store result (or NULL to ignore)
92  * \param[in]  default_value  Value to use if text is NULL or invalid
93  *
94  * \return Standard Pacemaker return code
95  */
96 int
pcmk__scan_ll(const char * text,long long * result,long long default_value)97 pcmk__scan_ll(const char *text, long long *result, long long default_value)
98 {
99     long long local_result = default_value;
100     int rc = pcmk_rc_ok;
101 
102     if (text != NULL) {
103         rc = scan_ll(text, &local_result, default_value, NULL);
104         if (rc != pcmk_rc_ok) {
105             local_result = default_value;
106         }
107     }
108     if (result != NULL) {
109         *result = local_result;
110     }
111     return rc;
112 }
113 
114 /*!
115  * \internal
116  * \brief Scan an integer value from a string, constrained to a minimum
117  *
118  * \param[in]  text           The string to scan (may be NULL)
119  * \param[out] result         Where to store result (or NULL to ignore)
120  * \param[in]  minimum        Value to use as default and minimum
121  *
122  * \return Standard Pacemaker return code
123  * \note If the value is larger than the maximum integer, EOVERFLOW will be
124  *       returned and \p result will be set to the maximum integer.
125  */
126 int
pcmk__scan_min_int(const char * text,int * result,int minimum)127 pcmk__scan_min_int(const char *text, int *result, int minimum)
128 {
129     int rc;
130     long long result_ll;
131 
132     rc = pcmk__scan_ll(text, &result_ll, (long long) minimum);
133 
134     if (result_ll < (long long) minimum) {
135         crm_warn("Clipped '%s' to minimum acceptable value %d", text, minimum);
136         result_ll = (long long) minimum;
137 
138     } else if (result_ll > INT_MAX) {
139         crm_warn("Clipped '%s' to maximum integer %d", text, INT_MAX);
140         result_ll = (long long) INT_MAX;
141         rc = EOVERFLOW;
142     }
143 
144     if (result != NULL) {
145         *result = (int) result_ll;
146     }
147     return rc;
148 }
149 
150 /*!
151  * \internal
152  * \brief Scan a TCP port number from a string
153  *
154  * \param[in]  text  The string to scan
155  * \param[out] port  Where to store result (or NULL to ignore)
156  *
157  * \return Standard Pacemaker return code
158  * \note \p port will be -1 if \p text is NULL or invalid
159  */
160 int
pcmk__scan_port(const char * text,int * port)161 pcmk__scan_port(const char *text, int *port)
162 {
163     long long port_ll;
164     int rc = pcmk__scan_ll(text, &port_ll, -1LL);
165 
166     if ((text != NULL) && (rc == pcmk_rc_ok) // wasn't default or invalid
167         && ((port_ll < 0LL) || (port_ll > 65535LL))) {
168         crm_warn("Ignoring port specification '%s' "
169                  "not in valid range (0-65535)", text);
170         rc = (port_ll < 0LL)? pcmk_rc_before_range : pcmk_rc_after_range;
171         port_ll = -1LL;
172     }
173     if (port != NULL) {
174         *port = (int) port_ll;
175     }
176     return rc;
177 }
178 
179 /*!
180  * \internal
181  * \brief Scan a double-precision floating-point value from a string
182  *
183  * \param[in]      text         The string to parse
184  * \param[out]     result       Parsed value on success, or
185  *                              \c PCMK__PARSE_DBL_DEFAULT on error
186  * \param[in]      default_text Default string to parse if \p text is
187  *                              \c NULL
188  * \param[out]     end_text     If not \c NULL, where to store a pointer
189  *                              to the position immediately after the
190  *                              value
191  *
192  * \return Standard Pacemaker return code (\c pcmk_rc_ok on success,
193  *         \c EINVAL on failed string conversion due to invalid input,
194  *         \c EOVERFLOW on arithmetic overflow, \c pcmk_rc_underflow
195  *         on arithmetic underflow, or \c errno from \c strtod() on
196  *         other parse errors)
197  */
198 int
pcmk__scan_double(const char * text,double * result,const char * default_text,char ** end_text)199 pcmk__scan_double(const char *text, double *result, const char *default_text,
200                   char **end_text)
201 {
202     int rc = pcmk_rc_ok;
203     char *local_end_text = NULL;
204 
205     CRM_ASSERT(result != NULL);
206     *result = PCMK__PARSE_DBL_DEFAULT;
207 
208     text = (text != NULL) ? text : default_text;
209 
210     if (text == NULL) {
211         rc = EINVAL;
212         crm_debug("No text and no default conversion value supplied");
213 
214     } else {
215         errno = 0;
216         *result = strtod(text, &local_end_text);
217 
218         if (errno == ERANGE) {
219             /*
220              * Overflow: strtod() returns +/- HUGE_VAL and sets errno to
221              *           ERANGE
222              *
223              * Underflow: strtod() returns "a value whose magnitude is
224              *            no greater than the smallest normalized
225              *            positive" double. Whether ERANGE is set is
226              *            implementation-defined.
227              */
228             const char *over_under;
229 
230             if (fabs(*result) > DBL_MIN) {
231                 rc = EOVERFLOW;
232                 over_under = "over";
233             } else {
234                 rc = pcmk_rc_underflow;
235                 over_under = "under";
236             }
237 
238             crm_debug("Floating-point value parsed from '%s' would %sflow "
239                       "(using %g instead)", text, over_under, *result);
240 
241         } else if (errno != 0) {
242             rc = errno;
243             // strtod() set *result = 0 on parse failure
244             *result = PCMK__PARSE_DBL_DEFAULT;
245 
246             crm_debug("Could not parse floating-point value from '%s' (using "
247                       "%.1f instead): %s", text, PCMK__PARSE_DBL_DEFAULT,
248                       pcmk_rc_str(rc));
249 
250         } else if (local_end_text == text) {
251             // errno == 0, but nothing was parsed
252             rc = EINVAL;
253             *result = PCMK__PARSE_DBL_DEFAULT;
254 
255             crm_debug("Could not parse floating-point value from '%s' (using "
256                       "%.1f instead): No digits found", text,
257                       PCMK__PARSE_DBL_DEFAULT);
258 
259         } else if (fabs(*result) <= DBL_MIN) {
260             /*
261              * errno == 0 and text was parsed, but value might have
262              * underflowed.
263              *
264              * ERANGE might not be set for underflow. Check magnitude
265              * of *result, but also make sure the input number is not
266              * actually zero (0 <= DBL_MIN is not underflow).
267              *
268              * This check must come last. A parse failure in strtod()
269              * also sets *result == 0, so a parse failure would match
270              * this test condition prematurely.
271              */
272             for (const char *p = text; p != local_end_text; p++) {
273                 if (strchr("0.eE", *p) == NULL) {
274                     rc = pcmk_rc_underflow;
275                     crm_debug("Floating-point value parsed from '%s' would "
276                               "underflow (using %g instead)", text, *result);
277                     break;
278                 }
279             }
280 
281         } else {
282             crm_trace("Floating-point value parsed successfully from "
283                       "'%s': %g", text, *result);
284         }
285 
286         if ((end_text == NULL) && !pcmk__str_empty(local_end_text)) {
287             crm_debug("Characters left over after parsing '%s': '%s'",
288                       text, local_end_text);
289         }
290     }
291 
292     if (end_text != NULL) {
293         *end_text = local_end_text;
294     }
295 
296     return rc;
297 }
298 
299 /*!
300  * \internal
301  * \brief Parse a guint from a string stored in a hash table
302  *
303  * \param[in]  table        Hash table to search
304  * \param[in]  key          Hash table key to use to retrieve string
305  * \param[in]  default_val  What to use if key has no entry in table
306  * \param[out] result       If not NULL, where to store parsed integer
307  *
308  * \return Standard Pacemaker return code
309  */
310 int
pcmk__guint_from_hash(GHashTable * table,const char * key,guint default_val,guint * result)311 pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val,
312                       guint *result)
313 {
314     const char *value;
315     long long value_ll;
316     int rc = pcmk_rc_ok;
317 
318     CRM_CHECK((table != NULL) && (key != NULL), return EINVAL);
319 
320     if (result != NULL) {
321         *result = default_val;
322     }
323 
324     value = g_hash_table_lookup(table, key);
325     if (value == NULL) {
326         return pcmk_rc_ok;
327     }
328 
329     rc = pcmk__scan_ll(value, &value_ll, 0LL);
330     if (rc != pcmk_rc_ok) {
331         return rc;
332     }
333 
334     if ((value_ll < 0) || (value_ll > G_MAXUINT)) {
335         crm_warn("Could not parse non-negative integer from %s", value);
336         return ERANGE;
337     }
338 
339     if (result != NULL) {
340         *result = (guint) value_ll;
341     }
342     return pcmk_rc_ok;
343 }
344 
345 #ifndef NUMCHARS
346 #  define	NUMCHARS	"0123456789."
347 #endif
348 
349 #ifndef WHITESPACE
350 #  define	WHITESPACE	" \t\n\r\f"
351 #endif
352 
353 /*!
354  * \brief Parse a time+units string and return milliseconds equivalent
355  *
356  * \param[in] input  String with a number and units (optionally with whitespace
357  *                   before and/or after the number)
358  *
359  * \return Milliseconds corresponding to string expression, or
360  *         PCMK__PARSE_INT_DEFAULT on error
361  */
362 long long
crm_get_msec(const char * input)363 crm_get_msec(const char *input)
364 {
365     const char *num_start = NULL;
366     const char *units;
367     long long multiplier = 1000;
368     long long divisor = 1;
369     long long msec = PCMK__PARSE_INT_DEFAULT;
370     size_t num_len = 0;
371     char *end_text = NULL;
372 
373     if (input == NULL) {
374         return PCMK__PARSE_INT_DEFAULT;
375     }
376 
377     num_start = input + strspn(input, WHITESPACE);
378     num_len = strspn(num_start, NUMCHARS);
379     if (num_len < 1) {
380         return PCMK__PARSE_INT_DEFAULT;
381     }
382     units = num_start + num_len;
383     units += strspn(units, WHITESPACE);
384 
385     if (!strncasecmp(units, "ms", 2) || !strncasecmp(units, "msec", 4)) {
386         multiplier = 1;
387         divisor = 1;
388     } else if (!strncasecmp(units, "us", 2) || !strncasecmp(units, "usec", 4)) {
389         multiplier = 1;
390         divisor = 1000;
391     } else if (!strncasecmp(units, "s", 1) || !strncasecmp(units, "sec", 3)) {
392         multiplier = 1000;
393         divisor = 1;
394     } else if (!strncasecmp(units, "m", 1) || !strncasecmp(units, "min", 3)) {
395         multiplier = 60 * 1000;
396         divisor = 1;
397     } else if (!strncasecmp(units, "h", 1) || !strncasecmp(units, "hr", 2)) {
398         multiplier = 60 * 60 * 1000;
399         divisor = 1;
400     } else if ((*units != '\0') && (*units != '\n') && (*units != '\r')) {
401         return PCMK__PARSE_INT_DEFAULT;
402     }
403 
404     scan_ll(num_start, &msec, PCMK__PARSE_INT_DEFAULT, &end_text);
405     if (msec > (LLONG_MAX / multiplier)) {
406         // Arithmetics overflow while multiplier/divisor mutually exclusive
407         return LLONG_MAX;
408     }
409     msec *= multiplier;
410     msec /= divisor;
411     return msec;
412 }
413 
414 gboolean
crm_is_true(const char * s)415 crm_is_true(const char *s)
416 {
417     gboolean ret = FALSE;
418 
419     if (s != NULL) {
420         crm_str_to_boolean(s, &ret);
421     }
422     return ret;
423 }
424 
425 int
crm_str_to_boolean(const char * s,int * ret)426 crm_str_to_boolean(const char *s, int *ret)
427 {
428     if (s == NULL) {
429         return -1;
430 
431     } else if (strcasecmp(s, "true") == 0
432                || strcasecmp(s, "on") == 0
433                || strcasecmp(s, "yes") == 0 || strcasecmp(s, "y") == 0 || strcasecmp(s, "1") == 0) {
434         *ret = TRUE;
435         return 1;
436 
437     } else if (strcasecmp(s, "false") == 0
438                || strcasecmp(s, "off") == 0
439                || strcasecmp(s, "no") == 0 || strcasecmp(s, "n") == 0 || strcasecmp(s, "0") == 0) {
440         *ret = FALSE;
441         return 1;
442     }
443     return -1;
444 }
445 
446 /*!
447  * \internal
448  * \brief Replace any trailing newlines in a string with \0's
449  *
450  * \param[in] str  String to trim
451  *
452  * \return \p str
453  */
454 char *
pcmk__trim(char * str)455 pcmk__trim(char *str)
456 {
457     int len;
458 
459     if (str == NULL) {
460         return str;
461     }
462 
463     for (len = strlen(str) - 1; len >= 0 && str[len] == '\n'; len--) {
464         str[len] = '\0';
465     }
466 
467     return str;
468 }
469 
470 /*!
471  * \brief Check whether a string starts with a certain sequence
472  *
473  * \param[in] str    String to check
474  * \param[in] prefix Sequence to match against beginning of \p str
475  *
476  * \return \c true if \p str begins with match, \c false otherwise
477  * \note This is equivalent to !strncmp(s, prefix, strlen(prefix))
478  *       but is likely less efficient when prefix is a string literal
479  *       if the compiler optimizes away the strlen() at compile time,
480  *       and more efficient otherwise.
481  */
482 bool
pcmk__starts_with(const char * str,const char * prefix)483 pcmk__starts_with(const char *str, const char *prefix)
484 {
485     const char *s = str;
486     const char *p = prefix;
487 
488     if (!s || !p) {
489         return false;
490     }
491     while (*s && *p) {
492         if (*s++ != *p++) {
493             return false;
494         }
495     }
496     return (*p == 0);
497 }
498 
499 static inline bool
ends_with(const char * s,const char * match,bool as_extension)500 ends_with(const char *s, const char *match, bool as_extension)
501 {
502     if (pcmk__str_empty(match)) {
503         return true;
504     } else if (s == NULL) {
505         return false;
506     } else {
507         size_t slen, mlen;
508 
509         /* Besides as_extension, we could also check
510            !strchr(&match[1], match[0]) but that would be inefficient.
511          */
512         if (as_extension) {
513             s = strrchr(s, match[0]);
514             return (s == NULL)? false : !strcmp(s, match);
515         }
516 
517         mlen = strlen(match);
518         slen = strlen(s);
519         return ((slen >= mlen) && !strcmp(s + slen - mlen, match));
520     }
521 }
522 
523 /*!
524  * \internal
525  * \brief Check whether a string ends with a certain sequence
526  *
527  * \param[in] s      String to check
528  * \param[in] match  Sequence to match against end of \p s
529  *
530  * \return \c true if \p s ends case-sensitively with match, \c false otherwise
531  * \note pcmk__ends_with_ext() can be used if the first character of match
532  *       does not recur in match.
533  */
534 bool
pcmk__ends_with(const char * s,const char * match)535 pcmk__ends_with(const char *s, const char *match)
536 {
537     return ends_with(s, match, false);
538 }
539 
540 /*!
541  * \internal
542  * \brief Check whether a string ends with a certain "extension"
543  *
544  * \param[in] s      String to check
545  * \param[in] match  Extension to match against end of \p s, that is,
546  *                   its first character must not occur anywhere
547  *                   in the rest of that very sequence (example: file
548  *                   extension where the last dot is its delimiter,
549  *                   e.g., ".html"); incorrect results may be
550  *                   returned otherwise.
551  *
552  * \return \c true if \p s ends (verbatim, i.e., case sensitively)
553  *         with "extension" designated as \p match (including empty
554  *         string), \c false otherwise
555  *
556  * \note Main incentive to prefer this function over \c pcmk__ends_with()
557  *       where possible is the efficiency (at the cost of added
558  *       restriction on \p match as stated; the complexity class
559  *       remains the same, though: BigO(M+N) vs. BigO(M+2N)).
560  */
561 bool
pcmk__ends_with_ext(const char * s,const char * match)562 pcmk__ends_with_ext(const char *s, const char *match)
563 {
564     return ends_with(s, match, true);
565 }
566 
567 /*!
568  * \internal
569  * \brief Create a hash of a string suitable for use with GHashTable
570  *
571  * \param[in] v  String to hash
572  *
573  * \return A hash of \p v compatible with g_str_hash() before glib 2.28
574  * \note glib changed their hash implementation:
575  *
576  * https://gitlab.gnome.org/GNOME/glib/commit/354d655ba8a54b754cb5a3efb42767327775696c
577  *
578  * Note that the new g_str_hash is presumably a *better* hash (it's actually
579  * a correct implementation of DJB's hash), but we need to preserve existing
580  * behaviour, because the hash key ultimately determines the "sort" order
581  * when iterating through GHashTables, which affects allocation of scores to
582  * clone instances when iterating through rsc->allowed_nodes.  It (somehow)
583  * also appears to have some minor impact on the ordering of a few
584  * pseudo_event IDs in the transition graph.
585  */
586 static guint
pcmk__str_hash(gconstpointer v)587 pcmk__str_hash(gconstpointer v)
588 {
589     const signed char *p;
590     guint32 h = 0;
591 
592     for (p = v; *p != '\0'; p++)
593         h = (h << 5) - h + *p;
594 
595     return h;
596 }
597 
598 /*!
599  * \internal
600  * \brief Create a hash table with case-sensitive strings as keys
601  *
602  * \param[in] key_destroy_func    Function to free a key
603  * \param[in] value_destroy_func  Function to free a value
604  *
605  * \return Newly allocated hash table
606  * \note It is the caller's responsibility to free the result, using
607  *       g_hash_table_destroy().
608  */
609 GHashTable *
pcmk__strkey_table(GDestroyNotify key_destroy_func,GDestroyNotify value_destroy_func)610 pcmk__strkey_table(GDestroyNotify key_destroy_func,
611                    GDestroyNotify value_destroy_func)
612 {
613     return g_hash_table_new_full(pcmk__str_hash, g_str_equal,
614                                  key_destroy_func, value_destroy_func);
615 }
616 
617 /* used with hash tables where case does not matter */
618 static gboolean
pcmk__strcase_equal(gconstpointer a,gconstpointer b)619 pcmk__strcase_equal(gconstpointer a, gconstpointer b)
620 {
621     return pcmk__str_eq((const char *)a, (const char *)b, pcmk__str_casei);
622 }
623 
624 static guint
pcmk__strcase_hash(gconstpointer v)625 pcmk__strcase_hash(gconstpointer v)
626 {
627     const signed char *p;
628     guint32 h = 0;
629 
630     for (p = v; *p != '\0'; p++)
631         h = (h << 5) - h + g_ascii_tolower(*p);
632 
633     return h;
634 }
635 
636 /*!
637  * \internal
638  * \brief Create a hash table with case-insensitive strings as keys
639  *
640  * \param[in] key_destroy_func    Function to free a key
641  * \param[in] value_destroy_func  Function to free a value
642  *
643  * \return Newly allocated hash table
644  * \note It is the caller's responsibility to free the result, using
645  *       g_hash_table_destroy().
646  */
647 GHashTable *
pcmk__strikey_table(GDestroyNotify key_destroy_func,GDestroyNotify value_destroy_func)648 pcmk__strikey_table(GDestroyNotify key_destroy_func,
649                     GDestroyNotify value_destroy_func)
650 {
651     return g_hash_table_new_full(pcmk__strcase_hash, pcmk__strcase_equal,
652                                  key_destroy_func, value_destroy_func);
653 }
654 
655 static void
copy_str_table_entry(gpointer key,gpointer value,gpointer user_data)656 copy_str_table_entry(gpointer key, gpointer value, gpointer user_data)
657 {
658     if (key && value && user_data) {
659         g_hash_table_insert((GHashTable*)user_data, strdup(key), strdup(value));
660     }
661 }
662 
663 /*!
664  * \internal
665  * \brief Copy a hash table that uses dynamically allocated strings
666  *
667  * \param[in] old_table  Hash table to duplicate
668  *
669  * \return New hash table with copies of everything in \p old_table
670  * \note This assumes the hash table uses dynamically allocated strings -- that
671  *       is, both the key and value free functions are free().
672  */
673 GHashTable *
pcmk__str_table_dup(GHashTable * old_table)674 pcmk__str_table_dup(GHashTable *old_table)
675 {
676     GHashTable *new_table = NULL;
677 
678     if (old_table) {
679         new_table = pcmk__strkey_table(free, free);
680         g_hash_table_foreach(old_table, copy_str_table_entry, new_table);
681     }
682     return new_table;
683 }
684 
685 /*!
686  * \internal
687  * \brief Add a word to a string list of words
688  *
689  * \param[in,out] list       Pointer to current string list (may not be NULL)
690  * \param[in,out] len        If not NULL, must be set to length of \p list,
691  *                           and will be updated to new length of \p list
692  * \param[in]     word       String to add to \p list (\p list will be
693  *                           unchanged if this is NULL or the empty string)
694  * \param[in]     separator  String to separate words in \p list
695  *                           (a space will be used if this is NULL)
696  *
697  * \note This dynamically reallocates \p list as needed. \p word may contain
698  *       \p separator, though that would be a bad idea if the string needs to be
699  *       parsed later.
700  */
701 void
pcmk__add_separated_word(char ** list,size_t * len,const char * word,const char * separator)702 pcmk__add_separated_word(char **list, size_t *len, const char *word,
703                          const char *separator)
704 {
705     size_t orig_len, new_len;
706 
707     CRM_ASSERT(list != NULL);
708 
709     if (pcmk__str_empty(word)) {
710         return;
711     }
712 
713     // Use provided length, or calculate it if not available
714     orig_len = (len != NULL)? *len : ((*list == NULL)? 0 : strlen(*list));
715 
716     // Don't add a separator before the first word in the list
717     if (orig_len == 0) {
718         separator = "";
719 
720     // Default to space-separated
721     } else if (separator == NULL) {
722         separator = " ";
723     }
724 
725     new_len = orig_len + strlen(separator) + strlen(word);
726     if (len != NULL) {
727         *len = new_len;
728     }
729 
730     // +1 for null terminator
731     *list = pcmk__realloc(*list, new_len + 1);
732     sprintf(*list + orig_len, "%s%s", separator, word);
733 }
734 
735 /*!
736  * \internal
737  * \brief Compress data
738  *
739  * \param[in]  data        Data to compress
740  * \param[in]  length      Number of characters of data to compress
741  * \param[in]  max         Maximum size of compressed data (or 0 to estimate)
742  * \param[out] result      Where to store newly allocated compressed result
743  * \param[out] result_len  Where to store actual compressed length of result
744  *
745  * \return Standard Pacemaker return code
746  */
747 int
pcmk__compress(const char * data,unsigned int length,unsigned int max,char ** result,unsigned int * result_len)748 pcmk__compress(const char *data, unsigned int length, unsigned int max,
749                char **result, unsigned int *result_len)
750 {
751     int rc;
752     char *compressed = NULL;
753     char *uncompressed = strdup(data);
754 #ifdef CLOCK_MONOTONIC
755     struct timespec after_t;
756     struct timespec before_t;
757 #endif
758 
759     if (max == 0) {
760         max = (length * 1.01) + 601; // Size guaranteed to hold result
761     }
762 
763 #ifdef CLOCK_MONOTONIC
764     clock_gettime(CLOCK_MONOTONIC, &before_t);
765 #endif
766 
767     compressed = calloc((size_t) max, sizeof(char));
768     CRM_ASSERT(compressed);
769 
770     *result_len = max;
771     rc = BZ2_bzBuffToBuffCompress(compressed, result_len, uncompressed, length,
772                                   CRM_BZ2_BLOCKS, 0, CRM_BZ2_WORK);
773     free(uncompressed);
774     if (rc != BZ_OK) {
775         crm_err("Compression of %d bytes failed: %s " CRM_XS " bzerror=%d",
776                 length, bz2_strerror(rc), rc);
777         free(compressed);
778         return pcmk_rc_error;
779     }
780 
781 #ifdef CLOCK_MONOTONIC
782     clock_gettime(CLOCK_MONOTONIC, &after_t);
783 
784     crm_trace("Compressed %d bytes into %d (ratio %d:1) in %.0fms",
785              length, *result_len, length / (*result_len),
786              (after_t.tv_sec - before_t.tv_sec) * 1000 +
787              (after_t.tv_nsec - before_t.tv_nsec) / 1e6);
788 #else
789     crm_trace("Compressed %d bytes into %d (ratio %d:1)",
790              length, *result_len, length / (*result_len));
791 #endif
792 
793     *result = compressed;
794     return pcmk_rc_ok;
795 }
796 
797 char *
crm_strdup_printf(char const * format,...)798 crm_strdup_printf(char const *format, ...)
799 {
800     va_list ap;
801     int len = 0;
802     char *string = NULL;
803 
804     va_start(ap, format);
805     len = vasprintf (&string, format, ap);
806     CRM_ASSERT(len > 0);
807     va_end(ap);
808     return string;
809 }
810 
811 int
pcmk__parse_ll_range(const char * srcstring,long long * start,long long * end)812 pcmk__parse_ll_range(const char *srcstring, long long *start, long long *end)
813 {
814     char *remainder = NULL;
815 
816     CRM_ASSERT(start != NULL && end != NULL);
817 
818     *start = PCMK__PARSE_INT_DEFAULT;
819     *end = PCMK__PARSE_INT_DEFAULT;
820 
821     crm_trace("Attempting to decode: [%s]", srcstring);
822     if (pcmk__str_empty(srcstring) || !strcmp(srcstring, "-")) {
823         return pcmk_rc_unknown_format;
824     }
825 
826     /* String starts with a dash, so this is either a range with
827      * no beginning or garbage.
828      * */
829     if (*srcstring == '-') {
830         int rc = scan_ll(srcstring+1, end, PCMK__PARSE_INT_DEFAULT, &remainder);
831 
832         if (rc != pcmk_rc_ok || *remainder != '\0') {
833             return pcmk_rc_unknown_format;
834         } else {
835             return pcmk_rc_ok;
836         }
837     }
838 
839     if (scan_ll(srcstring, start, PCMK__PARSE_INT_DEFAULT,
840                 &remainder) != pcmk_rc_ok) {
841         return pcmk_rc_unknown_format;
842     }
843 
844     if (*remainder && *remainder == '-') {
845         if (*(remainder+1)) {
846             char *more_remainder = NULL;
847             int rc = scan_ll(remainder+1, end, PCMK__PARSE_INT_DEFAULT,
848                              &more_remainder);
849 
850             if (rc != pcmk_rc_ok || *more_remainder != '\0') {
851                 return pcmk_rc_unknown_format;
852             }
853         }
854     } else if (*remainder && *remainder != '-') {
855         *start = PCMK__PARSE_INT_DEFAULT;
856         return pcmk_rc_unknown_format;
857     } else {
858         /* The input string contained only one number.  Set start and end
859          * to the same value and return pcmk_rc_ok.  This gives the caller
860          * a way to tell this condition apart from a range with no end.
861          */
862         *end = *start;
863     }
864 
865     return pcmk_rc_ok;
866 }
867 
868 /*!
869  * \internal
870  * \brief Find a string in a list of strings
871  *
872  * Search \p lst for \p s, taking case into account.  As a special case,
873  * if "*" is the only element of \p lst, the search is successful.
874  *
875  * Behavior can be changed with various flags:
876  *
877  * - pcmk__str_casei - By default, comparisons are done taking case into
878  *                     account.  This flag makes comparisons case-insensitive.
879  * - pcmk__str_null_matches - If the input string is NULL, return TRUE.
880  *
881  * \note The special "*" matching rule takes precedence over flags.  In
882  *       particular, "*" will match a NULL input string even without
883  *       pcmk__str_null_matches being specified.
884  *
885  * \note No matter what input string or flags are provided, an empty
886  *       list will always return FALSE.
887  *
888  * \param[in]  lst   List to search
889  * \param[in]  s     String to search for
890  * \param[in]  flags A bitfield of pcmk__str_flags to modify operation
891  *
892  * \return \c TRUE if \p s is in \p lst, or \c FALSE otherwise
893  */
894 gboolean
pcmk__str_in_list(GList * lst,const gchar * s,uint32_t flags)895 pcmk__str_in_list(GList *lst, const gchar *s, uint32_t flags)
896 {
897     GCompareFunc fn;
898 
899     if (lst == NULL) {
900         return FALSE;
901     }
902 
903     if (strcmp(lst->data, "*") == 0 && lst->next == NULL) {
904         return TRUE;
905     }
906 
907     if (s == NULL) {
908         return pcmk_is_set(flags, pcmk__str_null_matches);
909     }
910 
911     if (pcmk_is_set(flags, pcmk__str_casei)) {
912         fn = (GCompareFunc) strcasecmp;
913     } else {
914         fn = (GCompareFunc) strcmp;
915     }
916 
917     return g_list_find_custom(lst, s, fn) != NULL;
918 }
919 
920 static bool
str_any_of(bool casei,const char * s,va_list args)921 str_any_of(bool casei, const char *s, va_list args)
922 {
923     bool rc = false;
924 
925     if (s != NULL) {
926         while (1) {
927             const char *ele = va_arg(args, const char *);
928 
929             if (ele == NULL) {
930                 break;
931             } else if (pcmk__str_eq(s, ele,
932                                     casei? pcmk__str_casei : pcmk__str_none)) {
933                 rc = true;
934                 break;
935             }
936         }
937     }
938     return rc;
939 }
940 
941 /*!
942  * \internal
943  * \brief Is a string a member of a list of strings?
944  *
945  * \param[in]  s    String to search for in \p ...
946  * \param[in]  ...  Strings to compare \p s against.  The final string
947  *                  must be NULL.
948  *
949  * \note The comparison is done case-insensitively.  The function name is
950  *       meant to be reminiscent of strcasecmp.
951  *
952  * \return \c true if \p s is in \p ..., or \c false otherwise
953  */
954 bool
pcmk__strcase_any_of(const char * s,...)955 pcmk__strcase_any_of(const char *s, ...)
956 {
957     va_list ap;
958     bool rc;
959 
960     va_start(ap, s);
961     rc = str_any_of(true, s, ap);
962     va_end(ap);
963     return rc;
964 }
965 
966 /*!
967  * \internal
968  * \brief Is a string a member of a list of strings?
969  *
970  * \param[in]  s    String to search for in \p ...
971  * \param[in]  ...  Strings to compare \p s against.  The final string
972  *                  must be NULL.
973  *
974  * \note The comparison is done taking case into account.
975  *
976  * \return \c true if \p s is in \p ..., or \c false otherwise
977  */
978 bool
pcmk__str_any_of(const char * s,...)979 pcmk__str_any_of(const char *s, ...)
980 {
981     va_list ap;
982     bool rc;
983 
984     va_start(ap, s);
985     rc = str_any_of(false, s, ap);
986     va_end(ap);
987     return rc;
988 }
989 
990 /*!
991  * \internal
992  * \brief Check whether a character is in any of a list of strings
993  *
994  * \param[in]   ch      Character (ASCII) to search for
995  * \param[in]   ...     Strings to search. Final argument must be
996  *                      \c NULL.
997  *
998  * \return  \c true if any of \p ... contain \p ch, \c false otherwise
999  * \note    \p ... must contain at least one argument (\c NULL).
1000  */
1001 bool
pcmk__char_in_any_str(int ch,...)1002 pcmk__char_in_any_str(int ch, ...)
1003 {
1004     bool rc = false;
1005     va_list ap;
1006 
1007     /*
1008      * Passing a char to va_start() can generate compiler warnings,
1009      * so ch is declared as an int.
1010      */
1011     va_start(ap, ch);
1012 
1013     while (1) {
1014         const char *ele = va_arg(ap, const char *);
1015 
1016         if (ele == NULL) {
1017             break;
1018         } else if (strchr(ele, ch) != NULL) {
1019             rc = true;
1020             break;
1021         }
1022     }
1023 
1024     va_end(ap);
1025     return rc;
1026 }
1027 
1028 /*!
1029  * \internal
1030  * \brief Sort strings, with numeric portions sorted numerically
1031  *
1032  * Sort two strings case-insensitively like strcasecmp(), but with any numeric
1033  * portions of the string sorted numerically. This is particularly useful for
1034  * node names (for example, "node10" will sort higher than "node9" but lower
1035  * than "remotenode9").
1036  *
1037  * \param[in] s1  First string to compare (must not be NULL)
1038  * \param[in] s2  Second string to compare (must not be NULL)
1039  *
1040  * \retval -1 \p s1 comes before \p s2
1041  * \retval  0 \p s1 and \p s2 are equal
1042  * \retval  1 \p s1 comes after \p s2
1043  */
1044 int
pcmk__numeric_strcasecmp(const char * s1,const char * s2)1045 pcmk__numeric_strcasecmp(const char *s1, const char *s2)
1046 {
1047     while (*s1 && *s2) {
1048         if (isdigit(*s1) && isdigit(*s2)) {
1049             // If node names contain a number, sort numerically
1050 
1051             char *end1 = NULL;
1052             char *end2 = NULL;
1053             long num1 = strtol(s1, &end1, 10);
1054             long num2 = strtol(s2, &end2, 10);
1055 
1056             // allow ordering e.g. 007 > 7
1057             size_t len1 = end1 - s1;
1058             size_t len2 = end2 - s2;
1059 
1060             if (num1 < num2) {
1061                 return -1;
1062             } else if (num1 > num2) {
1063                 return 1;
1064             } else if (len1 < len2) {
1065                 return -1;
1066             } else if (len1 > len2) {
1067                 return 1;
1068             }
1069             s1 = end1;
1070             s2 = end2;
1071         } else {
1072             // Compare non-digits case-insensitively
1073             int lower1 = tolower(*s1);
1074             int lower2 = tolower(*s2);
1075 
1076             if (lower1 < lower2) {
1077                 return -1;
1078             } else if (lower1 > lower2) {
1079                 return 1;
1080             }
1081             ++s1;
1082             ++s2;
1083         }
1084     }
1085     if (!*s1 && *s2) {
1086         return -1;
1087     } else if (*s1 && !*s2) {
1088         return 1;
1089     }
1090     return 0;
1091 }
1092 
1093 /*
1094  * \brief Sort strings.
1095  *
1096  * This is your one-stop function for string comparison.  By default, this
1097  * function works like g_strcmp0.  That is, like strcmp but a NULL string
1098  * sorts before a non-NULL string.
1099  *
1100  * Behavior can be changed with various flags:
1101  *
1102  * - pcmk__str_regex - The second string is a regular expression that the
1103  *                     first string will be matched against.
1104  * - pcmk__str_casei - By default, comparisons are done taking case into
1105  *                     account.  This flag makes comparisons case-insensitive.
1106  *                     This can be combined with pcmk__str_regex.
1107  * - pcmk__str_null_matches - If one string is NULL and the other is not,
1108  *                            still return 0.
1109  *
1110  * \param[in] s1    First string to compare
1111  * \param[in] s2    Second string to compare, or a regular expression to
1112  *                  match if pcmk__str_regex is set
1113  * \param[in] flags A bitfield of pcmk__str_flags to modify operation
1114  *
1115  * \retval -1 \p s1 is NULL or comes before \p s2
1116  * \retval  0 \p s1 and \p s2 are equal, or \p s1 is found in \p s2 if
1117  *            pcmk__str_regex is set
1118  * \retval  1 \p s2 is NULL or \p s1 comes after \p s2, or if \p s2
1119  *            is an invalid regular expression, or \p s1 was not found
1120  *            in \p s2 if pcmk__str_regex is set.
1121  */
1122 int
pcmk__strcmp(const char * s1,const char * s2,uint32_t flags)1123 pcmk__strcmp(const char *s1, const char *s2, uint32_t flags)
1124 {
1125     /* If this flag is set, the second string is a regex. */
1126     if (pcmk_is_set(flags, pcmk__str_regex)) {
1127         regex_t *r_patt = calloc(1, sizeof(regex_t));
1128         int reg_flags = REG_EXTENDED | REG_NOSUB;
1129         int regcomp_rc = 0;
1130         int rc = 0;
1131 
1132         if (s1 == NULL || s2 == NULL) {
1133             free(r_patt);
1134             return 1;
1135         }
1136 
1137         if (pcmk_is_set(flags, pcmk__str_casei)) {
1138             reg_flags |= REG_ICASE;
1139         }
1140         regcomp_rc = regcomp(r_patt, s2, reg_flags);
1141         if (regcomp_rc != 0) {
1142             rc = 1;
1143             crm_err("Bad regex '%s' for update: %s", s2, strerror(regcomp_rc));
1144         } else {
1145             rc = regexec(r_patt, s1, 0, NULL, 0);
1146 
1147             if (rc != 0) {
1148                 rc = 1;
1149             }
1150         }
1151 
1152         regfree(r_patt);
1153         free(r_patt);
1154         return rc;
1155     }
1156 
1157     /* If the strings are the same pointer, return 0 immediately. */
1158     if (s1 == s2) {
1159         return 0;
1160     }
1161 
1162     /* If this flag is set, return 0 if either (or both) of the input strings
1163      * are NULL.  If neither one is NULL, we need to continue and compare
1164      * them normally.
1165      */
1166     if (pcmk_is_set(flags, pcmk__str_null_matches)) {
1167         if (s1 == NULL || s2 == NULL) {
1168             return 0;
1169         }
1170     }
1171 
1172     /* Handle the cases where one is NULL and the str_null_matches flag is not set.
1173      * A NULL string always sorts to the beginning.
1174      */
1175     if (s1 == NULL) {
1176         return -1;
1177     } else if (s2 == NULL) {
1178         return 1;
1179     }
1180 
1181     if (pcmk_is_set(flags, pcmk__str_casei)) {
1182         return strcasecmp(s1, s2);
1183     } else {
1184         return strcmp(s1, s2);
1185     }
1186 }
1187 
1188 // Deprecated functions kept only for backward API compatibility
1189 
1190 #include <crm/common/util_compat.h>
1191 
1192 gboolean
safe_str_neq(const char * a,const char * b)1193 safe_str_neq(const char *a, const char *b)
1194 {
1195     if (a == b) {
1196         return FALSE;
1197 
1198     } else if (a == NULL || b == NULL) {
1199         return TRUE;
1200 
1201     } else if (strcasecmp(a, b) == 0) {
1202         return FALSE;
1203     }
1204     return TRUE;
1205 }
1206 
1207 gboolean
crm_str_eq(const char * a,const char * b,gboolean use_case)1208 crm_str_eq(const char *a, const char *b, gboolean use_case)
1209 {
1210     if (use_case) {
1211         return g_strcmp0(a, b) == 0;
1212 
1213         /* TODO - Figure out which calls, if any, really need to be case independent */
1214     } else if (a == b) {
1215         return TRUE;
1216 
1217     } else if (a == NULL || b == NULL) {
1218         /* shouldn't be comparing NULLs */
1219         return FALSE;
1220 
1221     } else if (strcasecmp(a, b) == 0) {
1222         return TRUE;
1223     }
1224     return FALSE;
1225 }
1226 
1227 char *
crm_itoa_stack(int an_int,char * buffer,size_t len)1228 crm_itoa_stack(int an_int, char *buffer, size_t len)
1229 {
1230     if (buffer != NULL) {
1231         snprintf(buffer, len, "%d", an_int);
1232     }
1233     return buffer;
1234 }
1235 
1236 guint
g_str_hash_traditional(gconstpointer v)1237 g_str_hash_traditional(gconstpointer v)
1238 {
1239     return pcmk__str_hash(v);
1240 }
1241 
1242 gboolean
crm_strcase_equal(gconstpointer a,gconstpointer b)1243 crm_strcase_equal(gconstpointer a, gconstpointer b)
1244 {
1245     return pcmk__strcase_equal(a, b);
1246 }
1247 
1248 guint
crm_strcase_hash(gconstpointer v)1249 crm_strcase_hash(gconstpointer v)
1250 {
1251     return pcmk__strcase_hash(v);
1252 }
1253 
1254 GHashTable *
crm_str_table_dup(GHashTable * old_table)1255 crm_str_table_dup(GHashTable *old_table)
1256 {
1257     return pcmk__str_table_dup(old_table);
1258 }
1259 
1260 long long
crm_parse_ll(const char * text,const char * default_text)1261 crm_parse_ll(const char *text, const char *default_text)
1262 {
1263     long long result;
1264 
1265     if (text == NULL) {
1266         text = default_text;
1267         if (text == NULL) {
1268             crm_err("No default conversion value supplied");
1269             errno = EINVAL;
1270             return PCMK__PARSE_INT_DEFAULT;
1271         }
1272     }
1273     scan_ll(text, &result, PCMK__PARSE_INT_DEFAULT, NULL);
1274     return result;
1275 }
1276 
1277 int
crm_parse_int(const char * text,const char * default_text)1278 crm_parse_int(const char *text, const char *default_text)
1279 {
1280     long long result = crm_parse_ll(text, default_text);
1281 
1282     if (result < INT_MIN) {
1283         // If errno is ERANGE, crm_parse_ll() has already logged a message
1284         if (errno != ERANGE) {
1285             crm_err("Conversion of %s was clipped: %lld", text, result);
1286             errno = ERANGE;
1287         }
1288         return INT_MIN;
1289 
1290     } else if (result > INT_MAX) {
1291         // If errno is ERANGE, crm_parse_ll() has already logged a message
1292         if (errno != ERANGE) {
1293             crm_err("Conversion of %s was clipped: %lld", text, result);
1294             errno = ERANGE;
1295         }
1296         return INT_MAX;
1297     }
1298 
1299     return (int) result;
1300 }
1301 
1302 char *
crm_strip_trailing_newline(char * str)1303 crm_strip_trailing_newline(char *str)
1304 {
1305     return pcmk__trim(str);
1306 }
1307 
1308 int
pcmk_numeric_strcasecmp(const char * s1,const char * s2)1309 pcmk_numeric_strcasecmp(const char *s1, const char *s2)
1310 {
1311     return pcmk__numeric_strcasecmp(s1, s2);
1312 }
1313 
1314 // End deprecated API
1315