25 #include <sys/types.h>    43 scan_ll(
const char *text, 
long long *result, 
long long default_value,
    46     long long local_result = default_value;
    47     char *local_end_text = NULL;
    52         local_result = strtoll(text, &local_end_text, 10);
    53         if (errno == ERANGE) {
    55             crm_warn(
"Integer parsed from '%s' was clipped to %lld",
    58         } 
else if (errno != 0) {
    60             local_result = default_value;
    61             crm_warn(
"Could not parse integer from '%s' (using %lld instead): "    64         } 
else if (local_end_text == text) {
    66             local_result = default_value;
    67             crm_warn(
"Could not parse integer from '%s' (using %lld instead): "    68                     "No digits found", text, default_value);
    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);
    77     if (end_text != NULL) {
    78         *end_text = local_end_text;
    81         *result = local_result;
    97 pcmk__scan_ll(
const char *text, 
long long *result, 
long long default_value)
    99     long long local_result = default_value;
   103         rc = scan_ll(text, &local_result, default_value, NULL);
   105             local_result = default_value;
   108     if (result != NULL) {
   109         *result = local_result;
   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;
   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;
   144     if (result != NULL) {
   145         *result = (int) result_ll;
   167         && ((port_ll < 0LL) || (port_ll > 65535LL))) {
   168         crm_warn(
"Ignoring port specification '%s' "   169                  "not in valid range (0-65535)", text);
   174         *port = (int) port_ll;
   203     char *local_end_text = NULL;
   208     text = (text != NULL) ? text : default_text;
   212         crm_debug(
"No text and no default conversion value supplied");
   216         *result = strtod(text, &local_end_text);
   218         if (errno == ERANGE) {
   228             const char *over_under;
   230             if (fabs(*result) > DBL_MIN) {
   235                 over_under = 
"under";
   238             crm_debug(
"Floating-point value parsed from '%s' would %sflow "   239                       "(using %g instead)", text, over_under, *result);
   241         } 
else if (errno != 0) {
   246             crm_debug(
"Could not parse floating-point value from '%s' (using "   250         } 
else if (local_end_text == text) {
   255             crm_debug(
"Could not parse floating-point value from '%s' (using "   256                       "%.1f instead): No digits found", text,
   259         } 
else if (fabs(*result) <= DBL_MIN) {
   272             for (
const char *p = text; p != local_end_text; p++) {
   273                 if (strchr(
"0.eE", *p) == NULL) {
   275                     crm_debug(
"Floating-point value parsed from '%s' would "   276                               "underflow (using %g instead)", text, *result);
   282             crm_trace(
"Floating-point value parsed successfully from "   283                       "'%s': %g", text, *result);
   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);
   292     if (end_text != NULL) {
   293         *end_text = local_end_text;
   318     CRM_CHECK((table != NULL) && (key != NULL), 
return EINVAL);
   320     if (result != NULL) {
   321         *result = default_val;
   324     value = g_hash_table_lookup(table, key);
   334     if ((value_ll < 0) || (value_ll > G_MAXUINT)) {
   335         crm_warn(
"Could not parse non-negative integer from %s", value);
   339     if (result != NULL) {
   340         *result = (guint) value_ll;
   346 #  define   NUMCHARS    "0123456789."   350 #  define   WHITESPACE  " \t\n\r\f"   366     const char *num_start = NULL;
   368     long long multiplier = 1000;
   369     long long divisor = 1;
   372     char *end_text = NULL;
   378     num_start = input + strspn(input, 
WHITESPACE);
   379     num_len = strspn(num_start, 
NUMCHARS);
   383     units = num_start + num_len;
   386     if (!strncasecmp(units, 
"ms", 2) || !strncasecmp(units, 
"msec", 4)) {
   389     } 
else if (!strncasecmp(units, 
"us", 2) || !strncasecmp(units, 
"usec", 4)) {
   392     } 
else if (!strncasecmp(units, 
"s", 1) || !strncasecmp(units, 
"sec", 3)) {
   395     } 
else if (!strncasecmp(units, 
"m", 1) || !strncasecmp(units, 
"min", 3)) {
   396         multiplier = 60 * 1000;
   398     } 
else if (!strncasecmp(units, 
"h", 1) || !strncasecmp(units, 
"hr", 2)) {
   399         multiplier = 60 * 60 * 1000;
   401     } 
else if ((*units != 
'\0') && (*units != 
'\n') && (*units != 
'\r')) {
   406     if (msec > (LLONG_MAX / multiplier)) {
   418     gboolean ret = FALSE;
   432     } 
else if (strcasecmp(s, 
"true") == 0
   433                || strcasecmp(s, 
"on") == 0
   434                || strcasecmp(s, 
"yes") == 0 || strcasecmp(s, 
"y") == 0 || strcasecmp(s, 
"1") == 0) {
   438     } 
else if (strcasecmp(s, 
"false") == 0
   439                || strcasecmp(s, 
"off") == 0
   440                || strcasecmp(s, 
"no") == 0 || strcasecmp(s, 
"n") == 0 || strcasecmp(s, 
"0") == 0) {
   464     for (len = strlen(str) - 1; len >= 0 && str[len] == 
'\n'; len--) {
   487     const char *p = prefix;
   501 ends_with(
const char *s, 
const char *match, 
bool as_extension)
   503     if (pcmk__str_empty(match)) {
   505     } 
else if (s == NULL) {
   514             s = strrchr(s, match[0]);
   515             return (s == NULL)? false : !strcmp(s, match);
   518         mlen = strlen(match);
   520         return ((slen >= mlen) && !strcmp(s + slen - mlen, match));
   538     return ends_with(s, match, 
false);
   565     return ends_with(s, match, 
true);
   588 pcmk__str_hash(gconstpointer v)
   590     const signed char *p;
   593     for (p = v; *p != 
'\0'; p++)
   594         h = (h << 5) - h + *p;
   612                    GDestroyNotify value_destroy_func)
   614     return g_hash_table_new_full(pcmk__str_hash, g_str_equal,
   615                                  key_destroy_func, value_destroy_func);
   620 pcmk__strcase_equal(gconstpointer a, gconstpointer b)
   622     return pcmk__str_eq((
const char *)a, (
const char *)b, 
pcmk__str_casei);
   626 pcmk__strcase_hash(gconstpointer v)
   628     const signed char *p;
   631     for (p = v; *p != 
'\0'; p++)
   632         h = (h << 5) - h + g_ascii_tolower(*p);
   650                     GDestroyNotify value_destroy_func)
   652     return g_hash_table_new_full(pcmk__strcase_hash, pcmk__strcase_equal,
   653                                  key_destroy_func, value_destroy_func);
   657 copy_str_table_entry(gpointer key, gpointer value, gpointer user_data)
   659     if (key && value && user_data) {
   660         g_hash_table_insert((GHashTable*)user_data, strdup(key), strdup(value));
   677     GHashTable *new_table = NULL;
   681         g_hash_table_foreach(old_table, copy_str_table_entry, new_table);
   704                          const char *separator)
   706     size_t orig_len, new_len;
   710     if (pcmk__str_empty(word)) {
   715     orig_len = (len != NULL)? *len : ((*list == NULL)? 0 : strlen(*list));
   722     } 
else if (separator == NULL) {
   726     new_len = orig_len + strlen(separator) + strlen(word);
   732     *list = pcmk__realloc(*list, new_len + 1);
   733     sprintf(*list + orig_len, 
"%s%s", separator, word);
   750                char **result, 
unsigned int *result_len)
   753     char *compressed = NULL;
   754     char *uncompressed = strdup(
data);
   755 #ifdef CLOCK_MONOTONIC   756     struct timespec after_t;
   757     struct timespec before_t;
   761         max = (length * 1.01) + 601; 
   764 #ifdef CLOCK_MONOTONIC   765     clock_gettime(CLOCK_MONOTONIC, &before_t);
   768     compressed = calloc((
size_t) max, 
sizeof(
char));
   772     rc = BZ2_bzBuffToBuffCompress(compressed, result_len, uncompressed, length,
   776         crm_err(
"Compression of %d bytes failed: %s " CRM_XS " bzerror=%d",
   782 #ifdef CLOCK_MONOTONIC   783     clock_gettime(CLOCK_MONOTONIC, &after_t);
   785     crm_trace(
"Compressed %d bytes into %d (ratio %d:1) in %.0fms",
   786              length, *result_len, length / (*result_len),
   787              (after_t.tv_sec - before_t.tv_sec) * 1000 +
   788              (after_t.tv_nsec - before_t.tv_nsec) / 1e6);
   790     crm_trace(
"Compressed %d bytes into %d (ratio %d:1)",
   791              length, *result_len, length / (*result_len));
   794     *result = compressed;
   805     va_start(ap, format);
   806     len = vasprintf (&
string, format, ap);
   815     char *remainder = NULL;
   822     crm_trace(
"Attempting to decode: [%s]", srcstring);
   823     if (pcmk__str_empty(srcstring) || !strcmp(srcstring, 
"-")) {
   830     if (*srcstring == 
'-') {
   845     if (*remainder && *remainder == 
'-') {
   846         if (*(remainder+1)) {
   847             char *more_remainder = NULL;
   855     } 
else if (*remainder && *remainder != 
'-') {
   888     for (GList *ele = lst; ele != NULL; ele = ele->next) {
   889         if (pcmk__str_eq(s, ele->data, 
flags)) {
   898 str_any_of(
const char *s, va_list args, uint32_t 
flags)
   905         const char *ele = va_arg(args, 
const char *);
   909         } 
else if (pcmk__str_eq(s, ele, 
flags)) {
   990         const char *ele = va_arg(ap, 
const char *);
   994         } 
else if (strchr(ele, ch) != NULL) {
  1023     while (*s1 && *s2) {
  1024         if (isdigit(*s1) && isdigit(*s2)) {
  1029             long num1 = strtol(s1, &end1, 10);
  1030             long num2 = strtol(s2, &end2, 10);
  1033             size_t len1 = end1 - s1;
  1034             size_t len2 = end2 - s2;
  1038             } 
else if (num1 > num2) {
  1040             } 
else if (len1 < len2) {
  1042             } 
else if (len1 > len2) {
  1049             int lower1 = tolower(*s1);
  1050             int lower2 = tolower(*s2);
  1052             if (lower1 < lower2) {
  1054             } 
else if (lower1 > lower2) {
  1063     } 
else if (*s1 && !*s2) {
  1105         regex_t *r_patt = calloc(1, 
sizeof(regex_t));
  1106         int reg_flags = REG_EXTENDED | REG_NOSUB;
  1110         if (s1 == NULL || s2 == NULL) {
  1116             reg_flags |= REG_ICASE;
  1118         regcomp_rc = regcomp(r_patt, s2, reg_flags);
  1119         if (regcomp_rc != 0) {
  1123             rc = regexec(r_patt, s1, 0, NULL, 0);
  1145         if (s1 == NULL || s2 == NULL) {
  1155     } 
else if (s2 == NULL) {
  1164         if (strcmp(s1, 
"*") == 0 || strcmp(s2, 
"*") == 0) {
  1170         return strcasecmp(s1, s2);
  1172         return strcmp(s1, s2);
  1187     } 
else if (a == NULL || b == NULL) {
  1190     } 
else if (strcasecmp(a, b) == 0) {
  1200         return g_strcmp0(a, b) == 0;
  1203     } 
else if (a == b) {
  1206     } 
else if (a == NULL || b == NULL) {
  1210     } 
else if (strcasecmp(a, b) == 0) {
  1219     if (buffer != NULL) {
  1220         snprintf(buffer, len, 
"%d", an_int);
  1228     return pcmk__str_hash(v);
  1234     return pcmk__strcase_equal(a, b);
  1240     return pcmk__strcase_hash(v);
  1255         text = default_text;
  1257             crm_err(
"No default conversion value supplied");
  1271     if (result < INT_MIN) {
  1273         if (errno != ERANGE) {
  1274             crm_err(
"Conversion of %s was clipped: %lld", text, result);
  1279     } 
else if (result > INT_MAX) {
  1281         if (errno != ERANGE) {
  1282             crm_err(
"Conversion of %s was clipped: %lld", text, result);
  1288     return (
int) result;
 #define CRM_CHECK(expr, failure_action)
 
bool pcmk__starts_with(const char *str, const char *prefix)
Check whether a string starts with a certain sequence. 
 
const char * bz2_strerror(int rc)
 
char * crm_strdup_printf(char const *format,...)
 
int pcmk_numeric_strcasecmp(const char *s1, const char *s2)
 
guint g_str_hash_traditional(gconstpointer v)
 
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
 
#define PCMK__PARSE_DBL_DEFAULT
 
int pcmk__scan_port(const char *text, int *port)
 
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
 
int pcmk__numeric_strcasecmp(const char *s1, const char *s2)
 
bool pcmk__str_any_of(const char *s,...)
 
int pcmk__scan_double(const char *text, double *result, const char *default_text, char **end_text)
 
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code. 
 
char * strerror(int errnum)
 
#define PCMK__PARSE_INT_DEFAULT
 
#define crm_warn(fmt, args...)
 
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
 
#define crm_debug(fmt, args...)
 
int pcmk__parse_ll_range(const char *srcstring, long long *start, long long *end)
 
int pcmk__compress(const char *data, unsigned int length, unsigned int max, char **result, unsigned int *result_len)
 
#define crm_trace(fmt, args...)
 
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag. 
 
long long crm_get_msec(const char *input)
Parse a time+units string and return milliseconds equivalent. 
 
int pcmk__scan_min_int(const char *text, int *result, int minimum)
 
GHashTable * pcmk__str_table_dup(GHashTable *old_table)
 
char * crm_itoa_stack(int an_int, char *buffer, size_t len)
 
int crm_str_to_boolean(const char *s, int *ret)
 
void pcmk__add_separated_word(char **list, size_t *len, const char *word, const char *separator)
 
char * crm_strip_trailing_newline(char *str)
 
int pcmk__strcmp(const char *s1, const char *s2, uint32_t flags)
 
GHashTable * pcmk__strikey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
 
gboolean crm_is_true(const char *s)
 
bool pcmk__ends_with_ext(const char *s, const char *match)
 
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
 
int crm_parse_int(const char *text, const char *default_text)
 
long long crm_parse_ll(const char *text, const char *default_text)
 
#define crm_err(fmt, args...)
 
gboolean crm_strcase_equal(gconstpointer a, gconstpointer b)
 
gboolean pcmk__str_in_list(const gchar *s, GList *lst, uint32_t flags)
 
gboolean safe_str_neq(const char *a, const char *b)
 
guint crm_strcase_hash(gconstpointer v)
 
GHashTable * crm_str_table_dup(GHashTable *old_table)
 
char * pcmk__trim(char *str)
 
bool pcmk__char_in_any_str(int ch,...)
 
bool pcmk__ends_with(const char *s, const char *match)
 
Deprecated Pacemaker utilities. 
 
bool pcmk__strcase_any_of(const char *s,...)