1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright 2010 Lennart Poettering
12 //#include <sys/socket.h>
14 #include "alloc-util.h"
15 #include "errno-list.h"
16 //#include "extract-word.h"
17 #include "locale-util.h"
19 //#include "missing.h"
20 #include "parse-util.h"
21 #include "process-util.h"
22 #include "string-util.h"
24 /// Additional includes needed by elogind
25 #include "musl_missing.h"
27 int parse_boolean(const char *v) {
30 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
32 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
38 int parse_pid(const char *s, pid_t* ret_pid) {
46 r = safe_atolu(s, &ul);
52 if ((unsigned long) pid != ul)
55 if (!pid_is_valid(pid))
62 int parse_mode(const char *s, mode_t *ret) {
69 s += strspn(s, WHITESPACE);
77 if (!x || x == s || *x != 0)
79 if (l < 0 || l > 07777)
86 int parse_ifindex(const char *s, int *ret) {
89 r = safe_atoi(s, &ifi);
99 int parse_mtu(int family, const char *s, uint32_t *ret) {
104 r = parse_size(s, 1024, &u);
111 if (family == AF_INET6)
112 m = IPV6_MIN_MTU; /* This is 1280 */
114 m = IPV4_MIN_MTU; /* For all other protocols, including 'unspecified' we assume the IPv4 minimal MTU */
123 int parse_size(const char *t, uint64_t base, uint64_t *size) {
125 /* Soo, sometimes we want to parse IEC binary suffixes, and
126 * sometimes SI decimal suffixes. This function can parse
127 * both. Which one is the right way depends on the
128 * context. Wikipedia suggests that SI is customary for
129 * hardware metrics and network speeds, while IEC is
130 * customary for most data sizes used by software and volatile
131 * (RAM) memory. Hence be careful which one you pick!
133 * In either case we use just K, M, G as suffix, and not Ki,
134 * Mi, Gi or so (as IEC would suggest). That's because that's
135 * frickin' ugly. But this means you really need to make sure
136 * to document which base you are parsing when you use this
141 unsigned long long factor;
144 static const struct table iec[] = {
145 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
146 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
147 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
148 { "G", 1024ULL*1024ULL*1024ULL },
149 { "M", 1024ULL*1024ULL },
155 static const struct table si[] = {
156 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
157 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
158 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
159 { "G", 1000ULL*1000ULL*1000ULL },
160 { "M", 1000ULL*1000ULL },
166 const struct table *table;
168 unsigned long long r = 0;
169 unsigned n_entries, start_pos = 0;
172 assert(IN_SET(base, 1000, 1024));
177 n_entries = ELEMENTSOF(si);
180 n_entries = ELEMENTSOF(iec);
185 unsigned long long l, tmp;
190 p += strspn(p, WHITESPACE);
193 l = strtoull(p, &e, 10);
204 /* strtoull() itself would accept space/+/- */
205 if (*e >= '0' && *e <= '9') {
206 unsigned long long l2;
209 l2 = strtoull(e, &e2, 10);
213 /* Ignore failure. E.g. 10.M is valid */
220 e += strspn(e, WHITESPACE);
222 for (i = start_pos; i < n_entries; i++)
223 if (startswith(e, table[i].suffix))
229 if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
232 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
233 if (tmp > ULLONG_MAX - r)
237 if ((unsigned long long) (uint64_t) r != r)
240 p = e + strlen(table[i].suffix);
251 #if 0 /// UNNEEDED by elogind
252 int parse_range(const char *t, unsigned *lower, unsigned *upper) {
253 _cleanup_free_ char *word = NULL;
260 /* Extract the lower bound. */
261 r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
267 r = safe_atou(word, &l);
271 /* Check for the upper bound and extract it if needed */
273 /* Single number with no dashes. */
276 /* Trailing dash is an error. */
279 r = safe_atou(t, &u);
290 int parse_errno(const char *t) {
295 r = errno_from_name(t);
299 r = safe_atoi(t, &e);
303 /* 0 is also allowed here */
304 if (!errno_is_valid(e) && e != 0)
310 int parse_syscall_and_errno(const char *in, char **name, int *error) {
311 _cleanup_free_ char *n = NULL;
320 * This parse "syscall:errno" like "uname:EILSEQ", "@sync:255".
321 * If errno is omitted, then error is set to -1.
322 * Empty syscall name is not allowed.
323 * Here, we do not check that the syscall name is valid or not.
328 e = parse_errno(p + 1);
332 n = strndup(in, p - in);
348 char *format_bytes(char *buf, size_t l, uint64_t t) {
351 /* This only does IEC units so far */
353 static const struct {
357 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
358 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
359 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
360 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
361 { "M", UINT64_C(1024)*UINT64_C(1024) },
362 { "K", UINT64_C(1024) },
365 if (t == (uint64_t) -1)
368 for (i = 0; i < ELEMENTSOF(table); i++) {
370 if (t >= table[i].factor) {
372 "%" PRIu64 ".%" PRIu64 "%s",
374 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
381 snprintf(buf, l, "%" PRIu64 "B", t);
389 int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
397 /* strtoul() is happy to parse negative values, and silently
398 * converts them to unsigned values without generating an
399 * error. We want a clean error, hence let's look for the "-"
400 * prefix on our own, and generate an error. But let's do so
401 * only after strtoul() validated that the string is clean
402 * otherwise, so that we return EINVAL preferably over
405 s += strspn(s, WHITESPACE);
408 l = strtoul(s, &x, base);
411 if (!x || x == s || *x != 0)
415 if ((unsigned long) (unsigned) l != l)
418 *ret_u = (unsigned) l;
422 int safe_atoi(const char *s, int *ret_i) {
430 l = strtol(s, &x, 0);
433 if (!x || x == s || *x != 0)
435 if ((long) (int) l != l)
442 int safe_atollu(const char *s, long long unsigned *ret_llu) {
444 unsigned long long l;
449 s += strspn(s, WHITESPACE);
452 l = strtoull(s, &x, 0);
455 if (!x || x == s || *x != 0)
464 int safe_atolli(const char *s, long long int *ret_lli) {
472 l = strtoll(s, &x, 0);
475 if (!x || x == s || *x != 0)
482 int safe_atou8(const char *s, uint8_t *ret) {
489 s += strspn(s, WHITESPACE);
492 l = strtoul(s, &x, 0);
495 if (!x || x == s || *x != 0)
499 if ((unsigned long) (uint8_t) l != l)
506 int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
514 s += strspn(s, WHITESPACE);
517 l = strtoul(s, &x, base);
520 if (!x || x == s || *x != 0)
524 if ((unsigned long) (uint16_t) l != l)
531 int safe_atoi16(const char *s, int16_t *ret) {
539 l = strtol(s, &x, 0);
542 if (!x || x == s || *x != 0)
544 if ((long) (int16_t) l != l)
551 int safe_atod(const char *s, double *ret_d) {
552 _cleanup_(freelocalep) locale_t loc = (locale_t) 0;
559 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
560 if (loc == (locale_t) 0)
564 d = strtod_l(s, &x, loc);
567 if (!x || x == s || *x != 0)
574 int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
581 /* accept any number of digits, strtoull is limted to 19 */
582 for (i=0; i < digits; i++,s++) {
583 if (*s < '0' || *s > '9') {
587 /* too few digits, pad with 0 */
588 for (; i < digits; i++)
599 if (*s >= '5' && *s <= '9')
602 s += strspn(s, DIGITS);
610 int parse_percent_unbounded(const char *p) {
614 pc = endswith(p, "%");
618 n = strndupa(p, pc - p);
619 r = safe_atoi(n, &v);
628 int parse_percent(const char *p) {
631 v = parse_percent_unbounded(p);
638 int parse_permille_unbounded(const char *p) {
639 const char *pc, *pm, *dot, *n;
642 pm = endswith(p, "‰");
644 n = strndupa(p, pm - p);
645 r = safe_atoi(n, &v);
649 pc = endswith(p, "%");
653 dot = memchr(p, '.', pc - p);
657 if (dot[1] < '0' || dot[1] > '9')
660 n = strndupa(p, dot - p);
663 n = strndupa(p, pc - p);
665 r = safe_atoi(n, &v);
668 if (v > (INT_MAX - q) / 10)
680 int parse_permille(const char *p) {
683 v = parse_permille_unbounded(p);
690 #if 0 /// UNNEEDED by elogind
691 int parse_nice(const char *p, int *ret) {
694 r = safe_atoi(p, &n);
698 if (!nice_is_valid(n))
705 int parse_ip_port(const char *s, uint16_t *ret) {
709 r = safe_atou16(s, &l);
722 int parse_dev(const char *s, dev_t *ret) {
726 if (sscanf(s, "%u:%u", &x, &y) != 2)
730 if ((unsigned) major(d) != x || (unsigned) minor(d) != y)
737 int parse_oom_score_adjust(const char *s, int *ret) {
743 r = safe_atoi(s, &v);
747 if (v < OOM_SCORE_ADJ_MIN || v > OOM_SCORE_ADJ_MAX)