1    	/*
2    	 * Copyright 2004-2026 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   	#include <regex.h>
13   	#include <stdarg.h>     // va_list, etc.
14   	#include <stdbool.h>
15   	#include <stdio.h>
16   	#include <string.h>
17   	#include <stdlib.h>
18   	#include <ctype.h>
19   	#include <float.h>  // DBL_MIN
20   	#include <limits.h>
21   	#include <bzlib.h>
22   	#include <sys/types.h>
23   	
24   	/*!
25   	 * \internal
26   	 * \brief Scan a long long integer from a string
27   	 *
28   	 * \param[in]  text           String to scan
29   	 * \param[out] result         If not NULL, where to store scanned value
30   	 * \param[in]  default_value  Value to use if text is NULL or invalid
31   	 * \param[out] end_text       If not NULL, where to store pointer to first
32   	 *                            non-integer character
33   	 *
34   	 * \return Standard Pacemaker return code (\c pcmk_rc_ok on success,
35   	 *         \c pcmk_rc_bad_input on failed string conversion due to invalid
36   	 *         input, or \c ERANGE if outside long long range)
37   	 * \note Sets \c errno on error
38   	 */
39   	static int
40   	scan_ll(const char *text, long long *result, long long default_value,
41   	        char **end_text)
42   	{
43   	    long long local_result = default_value;
44   	    char *local_end_text = NULL;
45   	    int rc = pcmk_rc_ok;
46   	
47   	    errno = 0;
48   	    if (text != NULL) {
49   	        local_result = strtoll(text, &local_end_text, 10);
50   	        if (errno == ERANGE) {
51   	            rc = errno;
52   	            pcmk__debug("Integer parsed from '%s' was clipped to %lld", text,
53   	                        local_result);
54   	
55   	        } else if (local_end_text == text) {
56   	            rc = pcmk_rc_bad_input;
57   	            local_result = default_value;
58   	            pcmk__debug("Could not parse integer from '%s' (using %lld "
59   	                        "instead): No digits found",
60   	                        text, default_value);
61   	
62   	        } else if (errno != 0) {
63   	            rc = errno;
64   	            local_result = default_value;
65   	            pcmk__debug("Could not parse integer from '%s' (using %lld "
66   	                        "instead): %s",
67   	                        text, default_value, pcmk_rc_str(rc));
68   	        }
69   	
70   	        if ((end_text == NULL) && !pcmk__str_empty(local_end_text)) {
71   	            pcmk__debug("Characters left over after parsing '%s': '%s'",
72   	                        text, local_end_text);
73   	        }
74   	        errno = rc;
75   	    }
76   	    if (end_text != NULL) {
77   	        *end_text = local_end_text;
78   	    }
79   	    if (result != NULL) {
80   	        *result = local_result;
81   	    }
82   	    return rc;
83   	}
84   	
85   	/*!
86   	 * \internal
87   	 * \brief Scan a long long integer value from a string
88   	 *
89   	 * \param[in]  text           The string to scan (may be NULL)
90   	 * \param[out] result         Where to store result (or NULL to ignore)
91   	 * \param[in]  default_value  Value to use if text is NULL or invalid
92   	 *
93   	 * \return Standard Pacemaker return code
94   	 */
95   	int
96   	pcmk__scan_ll(const char *text, long long *result, long long default_value)
97   	{
98   	    long long local_result = default_value;
99   	    int rc = scan_ll(text, &local_result, default_value, NULL);
100  	
101  	    if (result != NULL) {
102  	        *result = local_result;
103  	    }
104  	    return rc;
105  	}
106  	
107  	/*!
108  	 * \internal
109  	 * \brief Scan an integer value from a string, constrained to a minimum
110  	 *
111  	 * \param[in]  text           The string to scan (may be NULL)
112  	 * \param[out] result         Where to store result (or NULL to ignore)
113  	 * \param[in]  minimum        Value to use as default and minimum
114  	 *
115  	 * \return Standard Pacemaker return code
116  	 * \note If the value is larger than the maximum integer, EOVERFLOW will be
117  	 *       returned and \p result will be set to the maximum integer.
118  	 */
119  	int
120  	pcmk__scan_min_int(const char *text, int *result, int minimum)
121  	{
122  	    int rc;
123  	    long long result_ll;
124  	
125  	    rc = pcmk__scan_ll(text, &result_ll, (long long) minimum);
126  	
127  	    if (result_ll < (long long) minimum) {
128  	        pcmk__warn("Clipped '%s' to minimum acceptable value %d", text,
129  	                   minimum);
130  	        result_ll = (long long) minimum;
131  	
132  	    } else if (result_ll > INT_MAX) {
133  	        pcmk__warn("Clipped '%s' to maximum integer %d", text, INT_MAX);
134  	        result_ll = (long long) INT_MAX;
135  	        rc = EOVERFLOW;
136  	    }
137  	
138  	    if (result != NULL) {
139  	        *result = (int) result_ll;
140  	    }
141  	    return rc;
142  	}
143  	
144  	/*!
145  	 * \internal
146  	 * \brief Scan a TCP port number from a string
147  	 *
148  	 * \param[in]  text  The string to scan
149  	 * \param[out] port  Where to store result (or NULL to ignore)
150  	 *
151  	 * \return Standard Pacemaker return code
152  	 * \note \p port will be -1 if \p text is NULL or invalid
153  	 */
154  	int
155  	pcmk__scan_port(const char *text, int *port)
156  	{
157  	    long long port_ll;
158  	    int rc = pcmk__scan_ll(text, &port_ll, -1LL);
159  	
160  	    if (rc != pcmk_rc_ok) {
161  	        pcmk__warn("'%s' is not a valid port: %s", text, pcmk_rc_str(rc));
162  	
163  	    } else if ((text != NULL) // wasn't default or invalid
164  	        && ((port_ll < 0LL) || (port_ll > 65535LL))) {
165  	        pcmk__warn("Ignoring port specification '%s' not in valid range "
166  	                   "(0-65535)",
167  	                   text);
168  	        rc = (port_ll < 0LL)? pcmk_rc_before_range : pcmk_rc_after_range;
169  	        port_ll = -1LL;
170  	    }
171  	    if (port != NULL) {
172  	        *port = (int) port_ll;
173  	    }
174  	    return rc;
175  	}
176  	
177  	/*!
178  	 * \internal
179  	 * \brief Scan a double-precision floating-point value from a string
180  	 *
181  	 * \param[in]      text         The string to parse
182  	 * \param[out]     result       Parsed value on success, or
183  	 *                              \c PCMK__PARSE_DBL_DEFAULT on error
184  	 * \param[in]      default_text Default string to parse if \p text is
185  	 *                              \c NULL
186  	 * \param[out]     end_text     If not \c NULL, where to store a pointer
187  	 *                              to the position immediately after the
188  	 *                              value
189  	 *
190  	 * \return Standard Pacemaker return code (\c pcmk_rc_ok on success,
191  	 *         \c EINVAL on failed string conversion due to invalid input,
192  	 *         \c EOVERFLOW on arithmetic overflow, \c pcmk_rc_underflow
193  	 *         on arithmetic underflow, or \c errno from \c strtod() on
194  	 *         other parse errors)
195  	 */
196  	int
197  	pcmk__scan_double(const char *text, double *result, const char *default_text,
198  	                  char **end_text)
199  	{
200  	    int rc = pcmk_rc_ok;
201  	    char *local_end_text = NULL;
202  	
203  	    pcmk__assert(result != NULL);
204  	    *result = PCMK__PARSE_DBL_DEFAULT;
205  	
206  	    text = (text != NULL) ? text : default_text;
207  	
208  	    if (text == NULL) {
209  	        rc = EINVAL;
210  	        pcmk__debug("No text and no default conversion value supplied");
211  	
212  	    } else {
213  	        errno = 0;
214  	        *result = strtod(text, &local_end_text);
215  	
216  	        if (errno == ERANGE) {
217  	            /*
218  	             * Overflow: strtod() returns +/- HUGE_VAL and sets errno to
219  	             *           ERANGE
220  	             *
221  	             * Underflow: strtod() returns "a value whose magnitude is
222  	             *            no greater than the smallest normalized
223  	             *            positive" double. Whether ERANGE is set is
224  	             *            implementation-defined.
225  	             */
226  	            const char *over_under;
227  	
228  	            if (QB_ABS(*result) > DBL_MIN) {
229  	                rc = EOVERFLOW;
230  	                over_under = "over";
231  	            } else {
232  	                rc = pcmk_rc_underflow;
233  	                over_under = "under";
234  	            }
235  	
236  	            pcmk__debug("Floating-point value parsed from '%s' would %sflow "
237  	                        "(using %g instead)",
238  	                        text, over_under, *result);
239  	
240  	        } else if (errno != 0) {
241  	            rc = errno;
242  	            // strtod() set *result = 0 on parse failure
243  	            *result = PCMK__PARSE_DBL_DEFAULT;
244  	
245  	            pcmk__debug("Could not parse floating-point value from '%s' (using "
246  	                        "%.1f instead): %s",
247  	                        text, PCMK__PARSE_DBL_DEFAULT, pcmk_rc_str(rc));
248  	
249  	        } else if (local_end_text == text) {
250  	            // errno == 0, but nothing was parsed
251  	            rc = EINVAL;
252  	            *result = PCMK__PARSE_DBL_DEFAULT;
253  	
254  	            pcmk__debug("Could not parse floating-point value from '%s' (using "
255  	                        "%.1f instead): No digits found",
256  	                        text, PCMK__PARSE_DBL_DEFAULT);
257  	
258  	        } else if (QB_ABS(*result) <= DBL_MIN) {
259  	            /*
260  	             * errno == 0 and text was parsed, but value might have
261  	             * underflowed.
262  	             *
263  	             * ERANGE might not be set for underflow. Check magnitude
264  	             * of *result, but also make sure the input number is not
265  	             * actually zero (0 <= DBL_MIN is not underflow).
266  	             *
267  	             * This check must come last. A parse failure in strtod()
268  	             * also sets *result == 0, so a parse failure would match
269  	             * this test condition prematurely.
270  	             */
271  	            for (const char *p = text; p != local_end_text; p++) {
272  	                if (strchr("0.eE", *p) == NULL) {
273  	                    rc = pcmk_rc_underflow;
274  	                    pcmk__debug("Floating-point value parsed from '%s' would "
275  	                                "underflow (using %g instead)", text, *result);
276  	                    break;
277  	                }
278  	            }
279  	
280  	        } else {
281  	            pcmk__trace("Floating-point value parsed successfully from '%s': "
282  	                        "%g",
283  	                        text, *result);
284  	        }
285  	
286  	        if ((end_text == NULL) && !pcmk__str_empty(local_end_text)) {
287  	            pcmk__debug("Characters left over after parsing '%s': '%s'", text,
288  	                        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
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  	        pcmk__warn("Using default (%u) for %s because '%s' is not a valid "
332  	                   "integer: %s",
333  	                   default_val, key, value, pcmk_rc_str(rc));
334  	        return rc;
335  	    }
336  	
337  	    if ((value_ll < 0) || (value_ll > G_MAXUINT)) {
338  	        pcmk__warn("Using default (%u) for %s because '%s' is not in valid "
339  	                   "range",
340  	                   default_val, key, value);
341  	        return ERANGE;
342  	    }
343  	
344  	    if (result != NULL) {
345  	        *result = (guint) value_ll;
346  	    }
347  	    return pcmk_rc_ok;
348  	}
349  	
350  	/*!
351  	 * \brief Parse milliseconds from a Pacemaker interval specification
352  	 *
353  	 * \param[in]  input      Pacemaker time interval specification (a bare number
354  	 *                        of seconds; a number with a unit, optionally with
355  	 *                        whitespace before and/or after the number; or an ISO
356  	 *                        8601 duration) (can be \c NULL)
357  	 * \param[out] result_ms  Where to store milliseconds equivalent of \p input on
358  	 *                        success (limited to the range of an unsigned integer),
359  	 *                        or 0 if \p input is \c NULL or invalid
360  	 *
361  	 * \return Standard Pacemaker return code
362  	 */
363  	int
364  	pcmk_parse_interval_spec(const char *input, guint *result_ms)
365  	{
366  	    long long msec = PCMK__PARSE_INT_DEFAULT;
367  	    int rc = pcmk_rc_ok;
368  	
369  	    if (input == NULL) {
370  	        msec = 0;
371  	        goto done;
372  	    }
373  	
374  	    if (input[0] == 'P') {
375  	        crm_time_t *period_s = pcmk__time_parse_duration(input);
376  	
377  	        if (period_s != NULL) {
378  	            msec = crm_time_get_seconds(period_s);
379  	            msec = QB_MIN(msec, G_MAXUINT / 1000) * 1000;
380  	            crm_time_free(period_s);
381  	        }
382  	
383  	    } else {
384  	        rc = pcmk__parse_ms(input, &msec);
385  	    }
386  	
387  	    if (msec < 0) {
388  	        pcmk__warn("Using 0 instead of invalid interval specification '%s'",
389  	                   input);
390  	        msec = 0;
391  	
392  	        if (rc == pcmk_rc_ok) {
393  	            // Preserve any error from pcmk__parse_ms()
394  	            rc = EINVAL;
395  	        }
396  	    }
397  	
398  	done:
399  	    if (result_ms != NULL) {
400  	        *result_ms = (msec >= G_MAXUINT)? G_MAXUINT : (guint) msec;
401  	    }
402  	    return rc;
403  	}
404  	
405  	/*!
406  	 * \internal
407  	 * \brief Create a hash of a string suitable for use with GHashTable
408  	 *
409  	 * \param[in] v  String to hash
410  	 *
411  	 * \return A hash of \p v compatible with g_str_hash() before glib 2.28
412  	 * \note glib changed their hash implementation:
413  	 *
414  	 * https://gitlab.gnome.org/GNOME/glib/commit/354d655ba8a54b754cb5a3efb42767327775696c
415  	 *
416  	 * Note that the new g_str_hash is presumably a *better* hash (it's actually
417  	 * a correct implementation of DJB's hash), but we need to preserve existing
418  	 * behaviour, because the hash key ultimately determines the "sort" order
419  	 * when iterating through GHashTables, which affects allocation of scores to
420  	 * clone instances when iterating through allowed nodes. It (somehow) also
421  	 * appears to have some minor impact on the ordering of a few pseudo_event IDs
422  	 * in the transition graph.
423  	 */
424  	static guint
425  	pcmk__str_hash(gconstpointer v)
426  	{
427  	    const signed char *p;
428  	    guint32 h = 0;
429  	
430  	    for (p = v; *p != '\0'; p++)
431  	        h = (h << 5) - h + *p;
432  	
433  	    return h;
434  	}
435  	
436  	/*!
437  	 * \internal
438  	 * \brief Create a hash table with case-sensitive strings as keys
439  	 *
440  	 * \param[in] key_destroy_func    Function to free a key
441  	 * \param[in] value_destroy_func  Function to free a value
442  	 *
443  	 * \return Newly allocated hash table
444  	 * \note It is the caller's responsibility to free the result, using
445  	 *       g_hash_table_destroy().
446  	 */
447  	GHashTable *
448  	pcmk__strkey_table(GDestroyNotify key_destroy_func,
449  	                   GDestroyNotify value_destroy_func)
450  	{
451  	    return g_hash_table_new_full(pcmk__str_hash, g_str_equal,
452  	                                 key_destroy_func, value_destroy_func);
453  	}
454  	
455  	/*!
456  	 * \internal
457  	 * \brief Insert string copies into a hash table as key and value
458  	 *
459  	 * \param[in,out] table  Hash table to add to
460  	 * \param[in]     name   String to add a copy of as key
461  	 * \param[in]     value  String to add a copy of as value
462  	 *
463  	 * \note This asserts on invalid arguments or memory allocation failure.
464  	 */
465  	void
466  	pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
467  	{
468  	    pcmk__assert((table != NULL) && (name != NULL));
469  	
470  	    g_hash_table_insert(table, pcmk__str_copy(name), pcmk__str_copy(value));
471  	}
472  	
473  	/* used with hash tables where case does not matter */
474  	static gboolean
475  	pcmk__strcase_equal(gconstpointer a, gconstpointer b)
476  	{
477  	    return pcmk__str_eq((const char *)a, (const char *)b, pcmk__str_casei);
478  	}
479  	
480  	static guint
481  	pcmk__strcase_hash(gconstpointer v)
482  	{
483  	    const signed char *p;
484  	    guint32 h = 0;
485  	
486  	    for (p = v; *p != '\0'; p++)
487  	        h = (h << 5) - h + g_ascii_tolower(*p);
488  	
489  	    return h;
490  	}
491  	
492  	/*!
493  	 * \internal
494  	 * \brief Create a hash table with case-insensitive strings as keys
495  	 *
496  	 * \param[in] key_destroy_func    Function to free a key
497  	 * \param[in] value_destroy_func  Function to free a value
498  	 *
499  	 * \return Newly allocated hash table
500  	 * \note It is the caller's responsibility to free the result, using
501  	 *       g_hash_table_destroy().
502  	 */
503  	GHashTable *
504  	pcmk__strikey_table(GDestroyNotify key_destroy_func,
505  	                    GDestroyNotify value_destroy_func)
506  	{
507  	    return g_hash_table_new_full(pcmk__strcase_hash, pcmk__strcase_equal,
508  	                                 key_destroy_func, value_destroy_func);
509  	}
510  	
511  	static void
512  	copy_str_table_entry(gpointer key, gpointer value, gpointer user_data)
513  	{
514  	    if (key && value && user_data) {
515  	        pcmk__insert_dup((GHashTable *) user_data,
516  	                         (const char *) key, (const char *) value);
517  	    }
518  	}
519  	
520  	/*!
521  	 * \internal
522  	 * \brief Copy a hash table that uses dynamically allocated strings
523  	 *
524  	 * \param[in,out] old_table  Hash table to duplicate
525  	 *
526  	 * \return New hash table with copies of everything in \p old_table
527  	 * \note This assumes the hash table uses dynamically allocated strings -- that
528  	 *       is, both the key and value free functions are free().
529  	 */
530  	GHashTable *
531  	pcmk__str_table_dup(GHashTable *old_table)
532  	{
533  	    GHashTable *new_table = NULL;
534  	
535  	    if (old_table) {
536  	        new_table = pcmk__strkey_table(free, free);
537  	        g_hash_table_foreach(old_table, copy_str_table_entry, new_table);
538  	    }
539  	    return new_table;
540  	}
541  	
542  	/*!
543  	 * \internal
544  	 * \brief Add a word to a string list of words
545  	 *
546  	 * \param[in,out] list       Pointer to current string list (may not be \p NULL)
547  	 * \param[in]     init_size  \p list will be initialized to at least this size,
548  	 *                           if it needs initialization (if 0, use GLib's default
549  	 *                           initial string size)
550  	 * \param[in]     word       String to add to \p list (\p list will be
551  	 *                           unchanged if this is \p NULL or the empty string)
552  	 * \param[in]     separator  String to separate words in \p list
553  	 *
554  	 * \note \p word may contain \p separator, though that would be a bad idea if
555  	 *       the string needs to be parsed later.
556  	 */
557  	void
558  	pcmk__add_separated_word(GString **list, size_t init_size, const char *word,
559  	                         const char *separator)
560  	{
561  	    pcmk__assert((list != NULL) && (separator != NULL));
562  	
563  	    if (pcmk__str_empty(word)) {
564  	        return;
565  	    }
566  	
567  	    if (*list == NULL) {
568  	        if (init_size > 0) {
569  	            *list = g_string_sized_new(init_size);
570  	        } else {
571  	            *list = g_string_new(NULL);
572  	        }
573  	    }
574  	
575  	    if ((*list)->len > 0) {
576  	        // Don't add a separator before the first word in the list
577  	        g_string_append(*list, separator);
578  	    }
579  	    g_string_append(*list, word);
580  	}
581  	
582  	/*!
583  	 * \internal
584  	 * \brief Compress data
585  	 *
586  	 * \param[in]  data        Data to compress
587  	 * \param[in]  length      Number of characters of data to compress
588  	 * \param[in]  max         Maximum size of compressed data (or 0 to estimate)
589  	 * \param[out] result      Where to store newly allocated compressed result
590  	 * \param[out] result_len  Where to store actual compressed length of result
591  	 *
592  	 * \return Standard Pacemaker return code
593  	 */
594  	int
595  	pcmk__compress(const char *data, unsigned int length, unsigned int max,
596  	               char **result, unsigned int *result_len)
597  	{
598  	    int rc;
599  	    char *compressed = NULL;
600  	    char *uncompressed = strdup(data);
601  	#ifdef CLOCK_MONOTONIC
602  	    struct timespec after_t;
603  	    struct timespec before_t;
604  	#endif
605  	
606  	    if (max == 0) {
607  	        max = (length * 1.01) + 601; // Size guaranteed to hold result
608  	    }
609  	
610  	#ifdef CLOCK_MONOTONIC
611  	    clock_gettime(CLOCK_MONOTONIC, &before_t);
612  	#endif
613  	
614  	    compressed = pcmk__assert_alloc((size_t) max, sizeof(char));
615  	
616  	    *result_len = max;
617  	    rc = BZ2_bzBuffToBuffCompress(compressed, result_len, uncompressed, length,
618  	                                  PCMK__BZ2_BLOCKS, 0, PCMK__BZ2_WORK);
619  	    rc = pcmk__bzlib2rc(rc);
620  	
621  	    free(uncompressed);
622  	
623  	    if (rc != pcmk_rc_ok) {
624  	        pcmk__err("Compression of %d bytes failed: %s " QB_XS " rc=%d", length,
625  	                  pcmk_rc_str(rc), rc);
626  	        free(compressed);
627  	        return rc;
628  	    }
629  	
630  	#ifdef CLOCK_MONOTONIC
631  	    clock_gettime(CLOCK_MONOTONIC, &after_t);
632  	
633  	    pcmk__trace("Compressed %d bytes into %d (ratio %d:1) in %.0fms", length,
634  	                *result_len, (length / *result_len),
635  	                (((after_t.tv_sec - before_t.tv_sec) * 1000)
636  	                 + ((after_t.tv_nsec - before_t.tv_nsec) / 1e6)));
637  	#else
638  	    pcmk__trace("Compressed %d bytes into %d (ratio %d:1)", length, *result_len,
639  	                (length / *result_len));
640  	#endif
641  	
642  	    *result = compressed;
643  	    return pcmk_rc_ok;
644  	}
645  	
646  	/*!
647  	 * \internal
648  	 * \brief Parse a boolean value from a string
649  	 *
650  	 * Valid input strings (case-insensitive) are as follows:
651  	 * * \c PCMK_VALUE_TRUE, \c "on", \c "yes", \c "y", or \c "1" for \c true
652  	 * * \c PCMK_VALUE_FALSE, \c PCMK_VALUE_OFF, \c "no", \c "n", or \c "0" for
653  	 *   \c false
654  	 *
655  	 * \param[in]  input   Input string
656  	 * \param[out] result  Where to store result (can be \c NULL; unchanged on
657  	 *                     error)
658  	 *
659  	 * \retval Standard Pacemaker return code
660  	 */
661  	int
662  	pcmk__parse_bool(const char *input, bool *result)
663  	{
664  	    bool local_result = false;
665  	
666  	    CRM_CHECK(input != NULL, return EINVAL);
667  	
668  	    if (pcmk__strcase_any_of(input, PCMK_VALUE_TRUE, "on", "yes", "y", "1",
669  	                             NULL)) {
670  	        local_result = true;
671  	
672  	    } else if (pcmk__strcase_any_of(input, PCMK_VALUE_FALSE, PCMK_VALUE_OFF,
673  	                                    "no", "n", "0", NULL)) {
674  	        local_result = false;
675  	
676  	    } else {
677  	        return pcmk_rc_bad_input;
678  	    }
679  	
680  	    if (result != NULL) {
681  	        *result = local_result;
682  	    }
683  	    return pcmk_rc_ok;
684  	}
685  	
686  	/*!
687  	 * \internal
688  	 * \brief Parse a range specification string
689  	 *
690  	 * A valid range specification string can be in any of the following forms,
691  	 * where \c "X", \c "Y", and \c "Z" are nonnegative integers that fit into a
692  	 * <tt>long long</tt> variable:
693  	 * * "X-Y"
694  	 * * "X-"
695  	 * * "-Y"
696  	 * * "Z"
697  	 *
698  	 * In the list above, \c "X" is the start value and \c "Y" is the end value of
699  	 * the range. Either the start value or the end value, but not both, can be
700  	 * empty. \c "Z", a single integer with no \c '-' character, is both the start
701  	 * value and the end value of its range.
702  	 *
703  	 * If the start value or end value is empty, then the parsed result stored in
704  	 * \p *start or \p *end (respectively) is \c PCMK__PARSE_INT_DEFAULT after a
705  	 * successful parse.
706  	 *
707  	 * If the specification string consists of only a single number, then the same
708  	 * value is stored in both \p *start and \p *end on a successful parse.
709  	 *
710  	 * \param[in]  text   String to parse
711  	 * \param[out] start  Where to store start value (can be \c NULL)
712  	 * \param[out] end    Where to store end value (can be \c NULL)
713  	 *
714  	 * \return Standard Pacemaker return code
715  	 *
716  	 * \note The values stored in \p *start and \p *end are undefined if the return
717  	 *       value is not \c pcmk_rc_ok.
718  	 */
719  	int
720  	pcmk__parse_ll_range(const char *text, long long *start, long long *end)
721  	{
722  	    int rc = pcmk_rc_ok;
723  	    long long local_start = 0;
724  	    long long local_end = 0;
725  	    gchar **split = NULL;
726  	    guint length = 0;
727  	    const gchar *start_s = NULL;
728  	    const gchar *end_s = NULL;
729  	
730  	    // Do not free
731  	    char *remainder = NULL;
732  	
733  	    if (start == NULL) {
734  	        start = &local_start;
735  	    }
736  	    if (end == NULL) {
737  	        end = &local_end;
738  	    }
739  	    *start = PCMK__PARSE_INT_DEFAULT;
740  	    *end = PCMK__PARSE_INT_DEFAULT;
741  	
742  	    if (pcmk__str_empty(text)) {
743  	        rc = ENODATA;
744  	        goto done;
745  	    }
746  	
747  	    split = g_strsplit(text, "-", 2);
748  	    length = g_strv_length(split);
749  	    start_s = split[0];
750  	    if (length == 2) {
751  	        end_s = split[1];
752  	    }
753  	
754  	    if (pcmk__str_empty(start_s) && pcmk__str_empty(end_s)) {
755  	        rc = pcmk_rc_bad_input;
756  	        goto done;
757  	    }
758  	
759  	    if (!pcmk__str_empty(start_s)) {
760  	        rc = scan_ll(start_s, start, PCMK__PARSE_INT_DEFAULT, &remainder);
761  	        if (rc != pcmk_rc_ok) {
762  	            goto done;
763  	        }
764  	        if (!pcmk__str_empty(remainder)) {
765  	            rc = pcmk_rc_bad_input;
766  	            goto done;
767  	        }
768  	    }
769  	
770  	    if (length == 1) {
771  	        // String contains only a single number, which is both start and end
772  	        *end = *start;
773  	        goto done;
774  	    }
775  	
776  	    if (!pcmk__str_empty(end_s)) {
777  	        rc = scan_ll(end_s, end, PCMK__PARSE_INT_DEFAULT, &remainder);
778  	
779  	        if ((rc == pcmk_rc_ok) && !pcmk__str_empty(remainder)) {
780  	            rc = pcmk_rc_bad_input;
781  	        }
782  	    }
783  	
784  	done:
785  	    g_strfreev(split);
786  	    return rc;
787  	}
788  	
789  	/*!
790  	 * \internal
791  	 * \brief Get multiplier and divisor corresponding to given units string
792  	 *
793  	 * Multiplier and divisor convert from a number of seconds to an equivalent
794  	 * number of the unit described by the units string.
795  	 *
796  	 * \param[in]  units       String describing a unit of time (may be empty,
797  	 *                         \c "s", \c "sec", \c "ms", \c "msec", \c "us",
798  	 *                         \c "usec", \c "m", \c "min", \c "h", or \c "hr")
799  	 * \param[out] multiplier  Number of units in one second, if unit is smaller
800  	 *                         than one second, or 1 otherwise (unchanged on error)
801  	 * \param[out] divisor     Number of seconds in one unit, if unit is larger
802  	 *                         than one second, or 1 otherwise (unchanged on error)
803  	 *
804  	 * \return Standard Pacemaker return code
805  	 */
806  	static int
807  	get_multiplier_divisor(const char *units, long long *multiplier,
808  	                       long long *divisor)
809  	{
810  	    /* @COMPAT Use exact comparisons. Currently, we match too liberally, and the
811  	     * second strncasecmp() in each case is redundant.
812  	     */
813  	    if ((*units == '\0')
814  	        || (strncasecmp(units, "s", 1) == 0)
815  	        || (strncasecmp(units, "sec", 3) == 0)) {
816  	        *multiplier = 1000;
817  	        *divisor = 1;
818  	
819  	    } else if ((strncasecmp(units, "ms", 2) == 0)
820  	               || (strncasecmp(units, "msec", 4) == 0)) {
821  	        *multiplier = 1;
822  	        *divisor = 1;
823  	
824  	    } else if ((strncasecmp(units, "us", 2) == 0)
825  	               || (strncasecmp(units, "usec", 4) == 0)) {
826  	        *multiplier = 1;
827  	        *divisor = 1000;
828  	
829  	    } else if ((strncasecmp(units, "m", 1) == 0)
830  	               || (strncasecmp(units, "min", 3) == 0)) {
831  	        *multiplier = 60 * 1000;
832  	        *divisor = 1;
833  	
834  	    } else if ((strncasecmp(units, "h", 1) == 0)
835  	               || (strncasecmp(units, "hr", 2) == 0)) {
836  	        *multiplier = 60 * 60 * 1000;
837  	        *divisor = 1;
838  	
839  	    } else {
840  	        // Invalid units
841  	        return pcmk_rc_bad_input;
842  	    }
843  	
844  	    return pcmk_rc_ok;
845  	}
846  	
847  	/*!
848  	 * \internal
849  	 * \brief Parse a time and units string into a milliseconds value
850  	 *
851  	 * \param[in]  input   String with a nonnegative number and optional unit
852  	 *                     (optionally with whitespace before and/or after the
853  	 *                     number). If absent, the unit defaults to seconds.
854  	 * \param[out] result  Where to store result in milliseconds (unchanged on error
855  	 *                     except \c ERANGE)
856  	 *
857  	 * \return Standard Pacemaker return code
858  	 */
859  	int
860  	pcmk__parse_ms(const char *input, long long *result)
861  	{
862  	    long long local_result = 0;
863  	    char *units = NULL; // Do not free; will point to part of input
864  	    long long multiplier = 1000;
865  	    long long divisor = 1;
866  	    int rc = pcmk_rc_ok;
867  	
868  	    CRM_CHECK(input != NULL, return EINVAL);
869  	
870  	    rc = scan_ll(input, &local_result, 0, &units);
871  	    if ((rc == pcmk_rc_ok) || (rc == ERANGE)) {
872  	        int units_rc = pcmk_rc_ok;
873  	
874  	        /* If the number is a decimal, scan_ll() reads only the integer part.
875  	         * Skip any remaining digits or decimal characters.
876  	         *
877  	         * @COMPAT Well-formed and malformed decimals are both accepted inputs.
878  	         * For example, "3.14 ms" and "3.1.4 ms" are treated the same as "3ms"
879  	         * and parsed successfully. At a compatibility break, decide if this is
880  	         * still desired.
881  	         */
882  	        for (; isdigit(*units) || (*units == '.'); units++);
883  	
884  	        // Skip any additional whitespace after the number
885  	        for (; isspace(*units); units++);
886  	
887  	        // Validate units and get conversion constants
888  	        units_rc = get_multiplier_divisor(units, &multiplier, &divisor);
889  	        if (units_rc != pcmk_rc_ok) {
890  	            rc = units_rc;
891  	        }
892  	    }
893  	
894  	    if (rc == ERANGE) {
895  	        pcmk__warn("'%s' will be clipped to %lld", input, local_result);
896  	
897  	        /* Continue through rest of body before returning ERANGE
898  	         *
899  	         * @COMPAT Improve handling of overflow. Units won't necessarily be
900  	         * respected right now, for one thing.
901  	         */
902  	
903  	    } else if (rc != pcmk_rc_ok) {
904  	        pcmk__warn("'%s' is not a valid time duration: %s", input,
905  	                   pcmk_rc_str(rc));
906  	        return rc;
907  	    }
908  	
909  	    if (result == NULL) {
910  	        return rc;
911  	    }
912  	
913  	    // Apply units, capping at LLONG_MAX
914  	    if (local_result > (LLONG_MAX / multiplier)) {
915  	        *result = LLONG_MAX;
916  	    } else if (local_result < (LLONG_MIN / multiplier)) {
917  	        *result = LLONG_MIN;
918  	    } else {
919  	        *result = (local_result * multiplier) / divisor;
920  	    }
921  	
922  	    return rc;
923  	}
924  	
925  	/*!
926  	 * \internal
927  	 * \brief Data for \c cmp_str_in_list()
928  	 */
929  	struct str_in_list_data {
930  	    const char *str;
931  	    uint32_t flags;
932  	};
933  	
934  	/*!
935  	 * \internal
936  	 * \brief Call \c pcmk__strcmp() against an element of a \c GList
937  	 *
938  	 * \param[in] a  List element (a string)
939  	 * \param[in] b  String to compare against \p and the flags for comparison (a
940  	 *               (<tt>struct str_in_list_data</tt>)
941  	 *
942  	 * \return A negative integer if \p a comes before \p b->str, a positive integer
943  	 *         if \p a comes after \p b->str, or 0 if \p a is equal to \p b->str
944  	 *         (according to \p b->flags)
945  	 */
946  	static gint
947  	cmp_str_in_list(gconstpointer a, gconstpointer b)
948  	{
949  	    const char *element = a;
950  	    const struct str_in_list_data *data = b;
951  	
952  	    return pcmk__strcmp(element, data->str, data->flags);
953  	}
954  	
955  	/*!
956  	 * \internal
957  	 * \brief Find a string in a list of strings
958  	 *
959  	 * \param[in] str    String to search for
960  	 * \param[in] list   List to search
961  	 * \param[in] flags  Group of <tt>enum pcmk__str_flags</tt> to pass to
962  	 *                   \c pcmk__str_eq()
963  	 *
964  	 * \return \c true if \p str is in \p list, or \c false otherwise
965  	 */
966  	bool
967  	pcmk__str_in_list(const char *str, const GList *list, uint32_t flags)
968  	{
969  	    const struct str_in_list_data data = {
970  	        .str = str,
971  	        .flags = flags,
972  	    };
973  	
974  	    return (g_list_find_custom((GList *) list, &data, cmp_str_in_list) != NULL);
975  	}
976  	
977  	/*!
978  	 * \internal
979  	 * \brief Check whether a string is in an array of <tt>gchar *</tt>
980  	 *
981  	 * \param[in] strv  <tt>NULL</tt>-terminated array of strings to search
982  	 * \param[in] str   String to search for
983  	 *
984  	 * \return \c true if \p str is an element of \p strv, or \c false otherwise
985  	 */
986  	bool
987  	pcmk__g_strv_contains(gchar **strv, const gchar *str)
988  	{
989  	    // @COMPAT Replace with calls to g_strv_contains() when we require glib 2.44
990  	    CRM_CHECK((strv != NULL) && (str != NULL), return false);
991  	
992  	    for (; *strv != NULL; strv++) {
993  	        if (pcmk__str_eq(*strv, str, pcmk__str_none)) {
994  	            return true;
995  	        }
996  	    }
997  	
998  	    return false;
999  	}
1000 	
1001 	static bool
1002 	str_any_of(const char *s, va_list args, uint32_t flags)
1003 	{
1004 	    if (s == NULL) {
1005 	        return false;
1006 	    }
1007 	
1008 	    while (1) {
1009 	        const char *ele = va_arg(args, const char *);
1010 	
1011 	        if (ele == NULL) {
1012 	            break;
1013 	        } else if (pcmk__str_eq(s, ele, flags)) {
1014 	            return true;
1015 	        }
1016 	    }
1017 	
1018 	    return false;
1019 	}
1020 	
1021 	/*!
1022 	 * \internal
1023 	 * \brief Is a string a member of a list of strings?
1024 	 *
1025 	 * \param[in]  s    String to search for in \p ...
1026 	 * \param[in]  ...  Strings to compare \p s against.  The final string
1027 	 *                  must be NULL.
1028 	 *
1029 	 * \note The comparison is done case-insensitively.  The function name is
1030 	 *       meant to be reminiscent of strcasecmp.
1031 	 *
1032 	 * \return \c true if \p s is in \p ..., or \c false otherwise
1033 	 */
1034 	bool
1035 	pcmk__strcase_any_of(const char *s, ...)
1036 	{
1037 	    va_list ap;
1038 	    bool rc;
1039 	
1040 	    va_start(ap, s);
1041 	    rc = str_any_of(s, ap, pcmk__str_casei);
1042 	    va_end(ap);
1043 	    return rc;
1044 	}
1045 	
1046 	/*!
1047 	 * \internal
1048 	 * \brief Is a string a member of a list of strings?
1049 	 *
1050 	 * \param[in]  s    String to search for in \p ...
1051 	 * \param[in]  ...  Strings to compare \p s against.  The final string
1052 	 *                  must be NULL.
1053 	 *
1054 	 * \note The comparison is done taking case into account.
1055 	 *
1056 	 * \return \c true if \p s is in \p ..., or \c false otherwise
1057 	 */
1058 	bool
1059 	pcmk__str_any_of(const char *s, ...)
1060 	{
1061 	    va_list ap;
1062 	    bool rc;
1063 	
1064 	    va_start(ap, s);
1065 	    rc = str_any_of(s, ap, pcmk__str_none);
1066 	    va_end(ap);
1067 	    return rc;
1068 	}
1069 	
1070 	/*!
1071 	 * \internal
1072 	 * \brief Sort strings, with numeric portions sorted numerically
1073 	 *
1074 	 * Sort two strings case-insensitively like strcasecmp(), but with any numeric
1075 	 * portions of the string sorted numerically. This is particularly useful for
1076 	 * node names (for example, "node10" will sort higher than "node9" but lower
1077 	 * than "remotenode9").
1078 	 *
1079 	 * \param[in] s1  First string to compare (must not be NULL)
1080 	 * \param[in] s2  Second string to compare (must not be NULL)
1081 	 *
1082 	 * \retval -1 \p s1 comes before \p s2
1083 	 * \retval  0 \p s1 and \p s2 are equal
1084 	 * \retval  1 \p s1 comes after \p s2
1085 	 */
1086 	int
1087 	pcmk__numeric_strcasecmp(const char *s1, const char *s2)
1088 	{
1089 	    pcmk__assert((s1 != NULL) && (s2 != NULL));
1090 	
1091 	    while (*s1 && *s2) {
1092 	        if (isdigit(*s1) && isdigit(*s2)) {
1093 	            // If node names contain a number, sort numerically
1094 	
1095 	            char *end1 = NULL;
1096 	            char *end2 = NULL;
1097 	            long num1 = strtol(s1, &end1, 10);
1098 	            long num2 = strtol(s2, &end2, 10);
1099 	
1100 	            // allow ordering e.g. 007 > 7
1101 	            size_t len1 = end1 - s1;
1102 	            size_t len2 = end2 - s2;
1103 	
1104 	            if (num1 < num2) {
1105 	                return -1;
1106 	            } else if (num1 > num2) {
1107 	                return 1;
1108 	            } else if (len1 < len2) {
1109 	                return -1;
1110 	            } else if (len1 > len2) {
1111 	                return 1;
1112 	            }
1113 	            s1 = end1;
1114 	            s2 = end2;
1115 	        } else {
1116 	            // Compare non-digits case-insensitively
1117 	            int lower1 = tolower(*s1);
1118 	            int lower2 = tolower(*s2);
1119 	
1120 	            if (lower1 < lower2) {
1121 	                return -1;
1122 	            } else if (lower1 > lower2) {
1123 	                return 1;
1124 	            }
1125 	            ++s1;
1126 	            ++s2;
1127 	        }
1128 	    }
1129 	    if (!*s1 && *s2) {
1130 	        return -1;
1131 	    } else if (*s1 && !*s2) {
1132 	        return 1;
1133 	    }
1134 	    return 0;
1135 	}
1136 	
1137 	/*!
1138 	 * \internal
1139 	 * \brief Sort strings.
1140 	 *
1141 	 * This is your one-stop function for string comparison. By default, this
1142 	 * function works like \p g_strcmp0. That is, like \p strcmp but a \p NULL
1143 	 * string sorts before a non-<tt>NULL</tt> string.
1144 	 *
1145 	 * The \p pcmk__str_none flag produces the default behavior. Behavior can be
1146 	 * changed with various flags:
1147 	 *
1148 	 * - \p pcmk__str_regex - The second string is a regular expression that the
1149 	 *                        first string will be matched against.
1150 	 * - \p pcmk__str_casei - By default, comparisons are done taking case into
1151 	 *                        account. This flag makes comparisons case-
1152 	 *                        insensitive. This can be combined with
1153 	 *                        \p pcmk__str_regex.
1154 	 * - \p pcmk__str_null_matches - If one string is \p NULL and the other is not,
1155 	 *                               still return \p 0.
1156 	 * - \p pcmk__str_star_matches - If one string is \p "*" and the other is not,
1157 	 *                               still return \p 0.
1158 	 *
1159 	 * \param[in] s1     First string to compare
1160 	 * \param[in] s2     Second string to compare, or a regular expression to
1161 	 *                   match if \p pcmk__str_regex is set
1162 	 * \param[in] flags  A bitfield of \p pcmk__str_flags to modify operation
1163 	 *
1164 	 * \retval  negative \p s1 is \p NULL or comes before \p s2
1165 	 * \retval  0        \p s1 and \p s2 are equal, or \p s1 is found in \p s2 if
1166 	 *                   \c pcmk__str_regex is set
1167 	 * \retval  positive \p s2 is \p NULL or \p s1 comes after \p s2, or \p s2
1168 	 *                   is an invalid regular expression, or \p s1 was not found
1169 	 *                   in \p s2 if \p pcmk__str_regex is set.
1170 	 */
1171 	int
1172 	pcmk__strcmp(const char *s1, const char *s2, uint32_t flags)
1173 	{
1174 	    /* If this flag is set, the second string is a regex. */
1175 	    if (pcmk__is_set(flags, pcmk__str_regex)) {
1176 	        regex_t r_patt;
1177 	        int reg_flags = REG_EXTENDED | REG_NOSUB;
1178 	        int regcomp_rc = 0;
1179 	        int rc = 0;
1180 	
1181 	        if (s1 == NULL || s2 == NULL) {
1182 	            return 1;
1183 	        }
1184 	
1185 	        if (pcmk__is_set(flags, pcmk__str_casei)) {
1186 	            reg_flags |= REG_ICASE;
1187 	        }
1188 	        regcomp_rc = regcomp(&r_patt, s2, reg_flags);
1189 	        if (regcomp_rc != 0) {
1190 	            rc = 1;
1191 	            pcmk__err("Bad regex '%s' for update: %s", s2,
1192 	                      strerror(regcomp_rc));
1193 	        } else {
1194 	            rc = regexec(&r_patt, s1, 0, NULL, 0);
1195 	            regfree(&r_patt);
1196 	            if (rc != 0) {
1197 	                rc = 1;
1198 	            }
1199 	        }
1200 	        return rc;
1201 	    }
1202 	
1203 	    /* If the strings are the same pointer, return 0 immediately. */
1204 	    if (s1 == s2) {
1205 	        return 0;
1206 	    }
1207 	
1208 	    /* If this flag is set, return 0 if either (or both) of the input strings
1209 	     * are NULL.  If neither one is NULL, we need to continue and compare
1210 	     * them normally.
1211 	     */
1212 	    if (pcmk__is_set(flags, pcmk__str_null_matches)) {
1213 	        if (s1 == NULL || s2 == NULL) {
1214 	            return 0;
1215 	        }
1216 	    }
1217 	
1218 	    /* Handle the cases where one is NULL and the str_null_matches flag is not set.
1219 	     * A NULL string always sorts to the beginning.
1220 	     */
1221 	    if (s1 == NULL) {
1222 	        return -1;
1223 	    } else if (s2 == NULL) {
1224 	        return 1;
1225 	    }
1226 	
1227 	    /* If this flag is set, return 0 if either (or both) of the input strings
1228 	     * are "*".  If neither one is, we need to continue and compare them
1229 	     * normally.
1230 	     */
1231 	    if (pcmk__is_set(flags, pcmk__str_star_matches)) {
1232 	        if (strcmp(s1, "*") == 0 || strcmp(s2, "*") == 0) {
1233 	            return 0;
1234 	        }
1235 	    }
1236 	
1237 	    if (pcmk__is_set(flags, pcmk__str_casei)) {
1238 	        return strcasecmp(s1, s2);
1239 	    } else {
1240 	        return strcmp(s1, s2);
1241 	    }
1242 	}
1243 	
1244 	/*!
1245 	 * \internal
1246 	 * \brief Copy a string, asserting on failure
1247 	 *
1248 	 * \param[in] file      File where \p function is located
1249 	 * \param[in] function  Calling function
1250 	 * \param[in] line      Line within \p file
1251 	 * \param[in] str       String to copy (can be \c NULL)
1252 	 *
1253 	 * \return Newly allocated copy of \p str, or \c NULL if \p str is \c NULL
1254 	 *
1255 	 * \note The caller is responsible for freeing the return value using \c free().
1256 	 */
1257 	char *
1258 	pcmk__str_copy_as(const char *file, const char *function, uint32_t line,
1259 	                  const char *str)
1260 	{
(1) Event path: Condition "str != NULL", taking true branch.
1261 	    if (str != NULL) {
(2) Event alloc_fn: Storage is returned from allocation function "strdup".
(3) Event assign: Assigning: "result" = "strdup(str)".
Also see events: [return_alloc]
1262 	        char *result = strdup(str);
1263 	
(4) Event path: Condition "result == NULL", taking false branch.
1264 	        if (result == NULL) {
1265 	            crm_abort(file, function, line, "Out of memory", FALSE, TRUE);
1266 	            crm_exit(CRM_EX_OSERR);
1267 	        }
(5) Event return_alloc: Returning allocated memory "result".
Also see events: [alloc_fn][assign]
1268 	        return result;
1269 	    }
1270 	    return NULL;
1271 	}
1272 	
1273 	/*!
1274 	 * \internal
1275 	 * \brief Update a dynamically allocated string with a new value
1276 	 *
1277 	 * Given a dynamically allocated string and a new value for it, if the string
1278 	 * is different from the new value, free the string and replace it with either a
1279 	 * newly allocated duplicate of the value or NULL as appropriate.
1280 	 *
1281 	 * \param[in,out] str    Pointer to dynamically allocated string
1282 	 * \param[in]     value  New value to duplicate (or NULL)
1283 	 *
1284 	 * \note The caller remains responsibile for freeing \p *str.
1285 	 */
1286 	void
1287 	pcmk__str_update(char **str, const char *value)
1288 	{
1289 	    if ((str != NULL) && !pcmk__str_eq(*str, value, pcmk__str_none)) {
1290 	        free(*str);
1291 	        *str = pcmk__str_copy(value);
1292 	    }
1293 	}
1294 	
1295 	/*!
1296 	 * \internal
1297 	 * \brief Print to an allocated string using \c printf()-style formatting
1298 	 *
1299 	 * This is like \c asprintf() but asserts on any error. The return value cannot
1300 	 * be \c NULL, but it may be an empty string, depending on the format string and
1301 	 * variadic arguments.
1302 	 *
1303 	 * \param[in] format  \c printf() format string
1304 	 * \param[in] ...     \c printf() format arguments
1305 	 *
1306 	 * \return Newly allocated string (guaranteed not to be \c NULL).
1307 	 *
1308 	 * \note The caller is responsible for freeing the return value using \c free().
1309 	 */
1310 	char *
1311 	pcmk__assert_asprintf(const char *format, ...)
1312 	{
1313 	    char *result = NULL;
1314 	    va_list ap;
1315 	
1316 	    va_start(ap, format);
1317 	    pcmk__assert(vasprintf(&result, format, ap) >= 0);
1318 	    va_end(ap);
1319 	
1320 	    return result;
1321 	}
1322 	
1323 	/*!
1324 	 * \internal
1325 	 * \brief Append a list of strings to a destination \p GString
1326 	 *
1327 	 * \param[in,out] buffer  Where to append the strings (must not be \p NULL)
1328 	 * \param[in]     ...     A <tt>NULL</tt>-terminated list of strings
1329 	 *
1330 	 * \note This tends to be more efficient than a single call to
1331 	 *       \p g_string_append_printf().
1332 	 */
1333 	void
1334 	pcmk__g_strcat(GString *buffer, ...)
1335 	{
1336 	    va_list ap;
1337 	
1338 	    pcmk__assert(buffer != NULL);
1339 	    va_start(ap, buffer);
1340 	
1341 	    while (true) {
1342 	        const char *ele = va_arg(ap, const char *);
1343 	
1344 	        if (ele == NULL) {
1345 	            break;
1346 	        }
1347 	        g_string_append(buffer, ele);
1348 	    }
1349 	    va_end(ap);
1350 	}
1351 	
1352 	// Deprecated functions kept only for backward API compatibility
1353 	// LCOV_EXCL_START
1354 	
1355 	#include <crm/common/strings_compat.h>
1356 	
1357 	long long
1358 	crm_get_msec(const char *input)
1359 	{
1360 	    char *units = NULL; // Do not free; will point to part of input
1361 	    long long multiplier = 1000;
1362 	    long long divisor = 1;
1363 	    long long msec = PCMK__PARSE_INT_DEFAULT;
1364 	    int rc = pcmk_rc_ok;
1365 	
1366 	    if (input == NULL) {
1367 	        return PCMK__PARSE_INT_DEFAULT;
1368 	    }
1369 	
1370 	    // Skip initial whitespace
1371 	    while (isspace(*input)) {
1372 	        input++;
1373 	    }
1374 	
1375 	    rc = scan_ll(input, &msec, PCMK__PARSE_INT_DEFAULT, &units);
1376 	
1377 	    if ((rc == ERANGE) && (msec > 0)) {
1378 	        pcmk__warn("'%s' will be clipped to %lld", input, msec);
1379 	
1380 	    } else if ((rc != pcmk_rc_ok) || (msec < 0)) {
1381 	        pcmk__warn("'%s' is not a valid time duration: %s", input,
1382 	                   ((rc == pcmk_rc_ok)? "Negative" : pcmk_rc_str(rc)));
1383 	        return PCMK__PARSE_INT_DEFAULT;
1384 	    }
1385 	
1386 	    /* If the number is a decimal, scan_ll() reads only the integer part. Skip
1387 	     * any remaining digits or decimal characters.
1388 	     *
1389 	     * @COMPAT Well-formed and malformed decimals are both accepted inputs. For
1390 	     * example, "3.14 ms" and "3.1.4 ms" are treated the same as "3ms" and
1391 	     * parsed successfully. At a compatibility break, decide if this is still
1392 	     * desired.
1393 	     */
1394 	    while (isdigit(*units) || (*units == '.')) {
1395 	        units++;
1396 	    }
1397 	
1398 	    // Skip any additional whitespace after the number
1399 	    while (isspace(*units)) {
1400 	        units++;
1401 	    }
1402 	
1403 	    /* @COMPAT Use exact comparisons. Currently, we match too liberally, and the
1404 	     * second strncasecmp() in each case is redundant.
1405 	     */
1406 	    if ((*units == '\0')
1407 	        || (strncasecmp(units, "s", 1) == 0)
1408 	        || (strncasecmp(units, "sec", 3) == 0)) {
1409 	        multiplier = 1000;
1410 	        divisor = 1;
1411 	
1412 	    } else if ((strncasecmp(units, "ms", 2) == 0)
1413 	               || (strncasecmp(units, "msec", 4) == 0)) {
1414 	        multiplier = 1;
1415 	        divisor = 1;
1416 	
1417 	    } else if ((strncasecmp(units, "us", 2) == 0)
1418 	               || (strncasecmp(units, "usec", 4) == 0)) {
1419 	        multiplier = 1;
1420 	        divisor = 1000;
1421 	
1422 	    } else if ((strncasecmp(units, "m", 1) == 0)
1423 	               || (strncasecmp(units, "min", 3) == 0)) {
1424 	        multiplier = 60 * 1000;
1425 	        divisor = 1;
1426 	
1427 	    } else if ((strncasecmp(units, "h", 1) == 0)
1428 	               || (strncasecmp(units, "hr", 2) == 0)) {
1429 	        multiplier = 60 * 60 * 1000;
1430 	        divisor = 1;
1431 	
1432 	    } else {
1433 	        // Invalid units
1434 	        return PCMK__PARSE_INT_DEFAULT;
1435 	    }
1436 	
1437 	    // Apply units, capping at LLONG_MAX
1438 	    if (msec > (LLONG_MAX / multiplier)) {
1439 	        return LLONG_MAX;
1440 	    }
1441 	    return (msec * multiplier) / divisor;
1442 	}
1443 	
1444 	gboolean
1445 	crm_is_true(const char *s)
1446 	{
1447 	    gboolean ret = FALSE;
1448 	
1449 	    return (crm_str_to_boolean(s, &ret) < 0)? FALSE : ret;
1450 	}
1451 	
1452 	int
1453 	crm_str_to_boolean(const char *s, int *ret)
1454 	{
1455 	    if (s == NULL) {
1456 	        return -1;
1457 	    }
1458 	
1459 	    if (pcmk__strcase_any_of(s, PCMK_VALUE_TRUE, "on", "yes", "y", "1", NULL)) {
1460 	        if (ret != NULL) {
1461 	            *ret = TRUE;
1462 	        }
1463 	        return 1;
1464 	    }
1465 	
1466 	    if (pcmk__strcase_any_of(s, PCMK_VALUE_FALSE, PCMK_VALUE_OFF, "no", "n",
1467 	                             "0", NULL)) {
1468 	        if (ret != NULL) {
1469 	            *ret = FALSE;
1470 	        }
1471 	        return 1;
1472 	    }
1473 	    return -1;
1474 	}
1475 	
1476 	char *
1477 	crm_strdup_printf(char const *format, ...)
1478 	{
1479 	    va_list ap;
1480 	    int len = 0;
1481 	    char *string = NULL;
1482 	
1483 	    va_start(ap, format);
1484 	    len = vasprintf(&string, format, ap);
1485 	    pcmk__assert(len > 0);
1486 	    va_end(ap);
1487 	    return string;
1488 	}
1489 	
1490 	// LCOV_EXCL_STOP
1491 	// End deprecated API
1492