This source file includes following definitions.
- crm_concat
- crm_itoa_stack
- crm_itoa
- g_hash_destroy_str
- crm_int_helper
- crm_parse_int
- safe_str_neq
- crm_is_true
- crm_str_to_boolean
- crm_strip_trailing_newline
- crm_str_eq
- null2emptystr
- crm_starts_with
- crm_ends_with_internal
- crm_ends_with
- crm_ends_with_ext
- g_str_hash_traditional
- crm_strcase_hash
- copy_str_table_entry
- crm_str_table_dup
- add_list_element
- crm_compress_string
- crm_alpha_sort
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <crm_internal.h>
20
21 #ifndef _GNU_SOURCE
22 # define _GNU_SOURCE
23 #endif
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <bzlib.h>
29 #include <sys/types.h>
30
31 char *
32 crm_concat(const char *prefix, const char *suffix, char join)
33 {
34 int len = 0;
35 char *new_str = NULL;
36
37 CRM_ASSERT(prefix != NULL);
38 CRM_ASSERT(suffix != NULL);
39 len = strlen(prefix) + strlen(suffix) + 2;
40
41 new_str = malloc(len);
42 if(new_str) {
43 sprintf(new_str, "%s%c%s", prefix, join, suffix);
44 new_str[len - 1] = 0;
45 }
46 return new_str;
47 }
48
49 char *
50 crm_itoa_stack(int an_int, char *buffer, size_t len)
51 {
52 if (buffer != NULL) {
53 snprintf(buffer, len, "%d", an_int);
54 }
55
56 return buffer;
57 }
58
59 char *
60 crm_itoa(int an_int)
61 {
62 int len = 32;
63 char *buffer = NULL;
64
65 buffer = malloc(len + 1);
66 if (buffer != NULL) {
67 snprintf(buffer, len, "%d", an_int);
68 }
69
70 return buffer;
71 }
72
73 void
74 g_hash_destroy_str(gpointer data)
75 {
76 free(data);
77 }
78
79 long long
80 crm_int_helper(const char *text, char **end_text)
81 {
82 long long result = -1;
83 char *local_end_text = NULL;
84 int saved_errno = 0;
85
86 errno = 0;
87
88 if (text != NULL) {
89 #ifdef ANSI_ONLY
90 if (end_text != NULL) {
91 result = strtol(text, end_text, 10);
92 } else {
93 result = strtol(text, &local_end_text, 10);
94 }
95 #else
96 if (end_text != NULL) {
97 result = strtoll(text, end_text, 10);
98 } else {
99 result = strtoll(text, &local_end_text, 10);
100 }
101 #endif
102
103 saved_errno = errno;
104 if (errno == EINVAL) {
105 crm_err("Conversion of %s failed", text);
106 result = -1;
107
108 } else if (errno == ERANGE) {
109 crm_err("Conversion of %s was clipped: %lld", text, result);
110
111 } else if (errno != 0) {
112 crm_perror(LOG_ERR, "Conversion of %s failed", text);
113 }
114
115 if (local_end_text != NULL && local_end_text[0] != '\0') {
116 crm_err("Characters left over after parsing '%s': '%s'", text, local_end_text);
117 }
118
119 errno = saved_errno;
120 }
121 return result;
122 }
123
124 int
125 crm_parse_int(const char *text, const char *default_text)
126 {
127 int atoi_result = -1;
128
129 if (text != NULL) {
130 atoi_result = crm_int_helper(text, NULL);
131 if (errno == 0) {
132 return atoi_result;
133 }
134 }
135
136 if (default_text != NULL) {
137 atoi_result = crm_int_helper(default_text, NULL);
138 if (errno == 0) {
139 return atoi_result;
140 }
141
142 } else {
143 crm_err("No default conversion value supplied");
144 }
145
146 return -1;
147 }
148
149 gboolean
150 safe_str_neq(const char *a, const char *b)
151 {
152 if (a == b) {
153 return FALSE;
154
155 } else if (a == NULL || b == NULL) {
156 return TRUE;
157
158 } else if (strcasecmp(a, b) == 0) {
159 return FALSE;
160 }
161 return TRUE;
162 }
163
164 gboolean
165 crm_is_true(const char *s)
166 {
167 gboolean ret = FALSE;
168
169 if (s != NULL) {
170 crm_str_to_boolean(s, &ret);
171 }
172 return ret;
173 }
174
175 int
176 crm_str_to_boolean(const char *s, int *ret)
177 {
178 if (s == NULL) {
179 return -1;
180
181 } else if (strcasecmp(s, "true") == 0
182 || strcasecmp(s, "on") == 0
183 || strcasecmp(s, "yes") == 0 || strcasecmp(s, "y") == 0 || strcasecmp(s, "1") == 0) {
184 *ret = TRUE;
185 return 1;
186
187 } else if (strcasecmp(s, "false") == 0
188 || strcasecmp(s, "off") == 0
189 || strcasecmp(s, "no") == 0 || strcasecmp(s, "n") == 0 || strcasecmp(s, "0") == 0) {
190 *ret = FALSE;
191 return 1;
192 }
193 return -1;
194 }
195
196 char *
197 crm_strip_trailing_newline(char *str)
198 {
199 int len;
200
201 if (str == NULL) {
202 return str;
203 }
204
205 for (len = strlen(str) - 1; len >= 0 && str[len] == '\n'; len--) {
206 str[len] = '\0';
207 }
208
209 return str;
210 }
211
212 gboolean
213 crm_str_eq(const char *a, const char *b, gboolean use_case)
214 {
215 if (use_case) {
216 return g_strcmp0(a, b) == 0;
217
218
219 } else if (a == b) {
220 return TRUE;
221
222 } else if (a == NULL || b == NULL) {
223
224 return FALSE;
225
226 } else if (strcasecmp(a, b) == 0) {
227 return TRUE;
228 }
229 return FALSE;
230 }
231
232 static inline const char * null2emptystr(const char *);
233 static inline const char *
234 null2emptystr(const char *input)
235 {
236 return (input == NULL) ? "" : input;
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251 bool
252 crm_starts_with(const char *str, const char *prefix)
253 {
254 const char *s = str;
255 const char *p = prefix;
256
257 if (!s || !p) {
258 return FALSE;
259 }
260 while (*s && *p) {
261 if (*s++ != *p++) {
262 return FALSE;
263 }
264 }
265 return (*p == 0);
266 }
267
268 static inline int crm_ends_with_internal(const char *, const char *, gboolean);
269 static inline int
270 crm_ends_with_internal(const char *s, const char *match, gboolean as_extension)
271 {
272 if ((s == NULL) || (match == NULL)) {
273 return 0;
274 } else {
275 size_t slen, mlen;
276
277 if (match[0] != '\0'
278 && (as_extension
279 ))
280 return !strcmp(null2emptystr(strrchr(s, match[0])), match);
281
282 if ((mlen = strlen(match)) == 0)
283 return 1;
284 slen = strlen(s);
285 return ((slen >= mlen) && !strcmp(s + slen - mlen, match));
286 }
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300
301 gboolean
302 crm_ends_with(const char *s, const char *match)
303 {
304 return crm_ends_with_internal(s, match, FALSE);
305 }
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 gboolean
331 crm_ends_with_ext(const char *s, const char *match)
332 {
333 return crm_ends_with_internal(s, match, TRUE);
334 }
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 guint
350 g_str_hash_traditional(gconstpointer v)
351 {
352 const signed char *p;
353 guint32 h = 0;
354
355 for (p = v; *p != '\0'; p++)
356 h = (h << 5) - h + *p;
357
358 return h;
359 }
360
361 guint
362 crm_strcase_hash(gconstpointer v)
363 {
364 const signed char *p;
365 guint32 h = 0;
366
367 for (p = v; *p != '\0'; p++)
368 h = (h << 5) - h + g_ascii_tolower(*p);
369
370 return h;
371 }
372
373 static void
374 copy_str_table_entry(gpointer key, gpointer value, gpointer user_data)
375 {
376 if (key && value && user_data) {
377 g_hash_table_insert((GHashTable*)user_data, strdup(key), strdup(value));
378 }
379 }
380
381 GHashTable *
382 crm_str_table_dup(GHashTable *old_table)
383 {
384 GHashTable *new_table = NULL;
385
386 if (old_table) {
387 new_table = crm_str_table_new();
388 g_hash_table_foreach(old_table, copy_str_table_entry, new_table);
389 }
390 return new_table;
391 }
392
393 char *
394 add_list_element(char *list, const char *value)
395 {
396 int len = 0;
397 int last = 0;
398
399 if (value == NULL) {
400 return list;
401 }
402 if (list) {
403 last = strlen(list);
404 }
405 len = last + 2;
406 len += strlen(value);
407 list = realloc_safe(list, len);
408 sprintf(list + last, " %s", value);
409 return list;
410 }
411
412 bool
413 crm_compress_string(const char *data, int length, int max, char **result, unsigned int *result_len)
414 {
415 int rc;
416 char *compressed = NULL;
417 char *uncompressed = strdup(data);
418 struct timespec after_t;
419 struct timespec before_t;
420
421 if(max == 0) {
422 max = (length * 1.1) + 600;
423 }
424
425 #ifdef CLOCK_MONOTONIC
426 clock_gettime(CLOCK_MONOTONIC, &before_t);
427 #endif
428
429
430 compressed = malloc(max);
431
432 *result_len = max;
433 rc = BZ2_bzBuffToBuffCompress(compressed, result_len, uncompressed, length, CRM_BZ2_BLOCKS, 0,
434 CRM_BZ2_WORK);
435
436 free(uncompressed);
437
438 if (rc != BZ_OK) {
439 crm_err("Compression of %d bytes failed: %s (%d)", length, bz2_strerror(rc), rc);
440 free(compressed);
441 return FALSE;
442 }
443
444 #ifdef CLOCK_MONOTONIC
445 clock_gettime(CLOCK_MONOTONIC, &after_t);
446
447 crm_trace("Compressed %d bytes into %d (ratio %d:1) in %.0fms",
448 length, *result_len, length / (*result_len),
449 difftime (after_t.tv_sec, before_t.tv_sec) * 1000 +
450 (after_t.tv_nsec - before_t.tv_nsec) / 1e6);
451 #else
452 crm_trace("Compressed %d bytes into %d (ratio %d:1)",
453 length, *result_len, length / (*result_len));
454 #endif
455
456 *result = compressed;
457 return TRUE;
458 }
459
460
461
462
463
464
465
466
467
468
469
470
471 gint
472 crm_alpha_sort(gconstpointer a, gconstpointer b)
473 {
474 if (!a && !b) {
475 return 0;
476 } else if (!a) {
477 return -1;
478 } else if (!b) {
479 return 1;
480 }
481 return strcasecmp(a, b);
482 }