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