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