1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
14 //#include <sys/socket.h>
16 #include "alloc-util.h"
17 #include "errno-list.h"
18 //#include "extract-word.h"
19 #include "locale-util.h"
21 //#include "missing.h"
22 #include "parse-util.h"
23 #include "process-util.h"
24 #include "string-util.h"
26 /// Additional includes needed by elogind
27 #include "musl_missing.h"
29 int parse_boolean(const char *v) {
32 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
34 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
40 int parse_pid(const char *s, pid_t* ret_pid) {
48 r = safe_atolu(s, &ul);
54 if ((unsigned long) pid != ul)
57 if (!pid_is_valid(pid))
64 int parse_mode(const char *s, mode_t *ret) {
71 s += strspn(s, WHITESPACE);
79 if (!x || x == s || *x != 0)
81 if (l < 0 || l > 07777)
88 int parse_ifindex(const char *s, int *ret) {
91 r = safe_atoi(s, &ifi);
101 int parse_mtu(int family, const char *s, uint32_t *ret) {
106 r = parse_size(s, 1024, &u);
113 if (family == AF_INET6)
114 m = IPV6_MIN_MTU; /* This is 1280 */
116 m = IPV4_MIN_MTU; /* For all other protocols, including 'unspecified' we assume the IPv4 minimal MTU */
125 int parse_size(const char *t, uint64_t base, uint64_t *size) {
127 /* Soo, sometimes we want to parse IEC binary suffixes, and
128 * sometimes SI decimal suffixes. This function can parse
129 * both. Which one is the right way depends on the
130 * context. Wikipedia suggests that SI is customary for
131 * hardware metrics and network speeds, while IEC is
132 * customary for most data sizes used by software and volatile
133 * (RAM) memory. Hence be careful which one you pick!
135 * In either case we use just K, M, G as suffix, and not Ki,
136 * Mi, Gi or so (as IEC would suggest). That's because that's
137 * frickin' ugly. But this means you really need to make sure
138 * to document which base you are parsing when you use this
143 unsigned long long factor;
146 static const struct table iec[] = {
147 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
148 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
149 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
150 { "G", 1024ULL*1024ULL*1024ULL },
151 { "M", 1024ULL*1024ULL },
157 static const struct table si[] = {
158 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
159 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
160 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
161 { "G", 1000ULL*1000ULL*1000ULL },
162 { "M", 1000ULL*1000ULL },
168 const struct table *table;
170 unsigned long long r = 0;
171 unsigned n_entries, start_pos = 0;
174 assert(IN_SET(base, 1000, 1024));
179 n_entries = ELEMENTSOF(si);
182 n_entries = ELEMENTSOF(iec);
187 unsigned long long l, tmp;
192 p += strspn(p, WHITESPACE);
195 l = strtoull(p, &e, 10);
206 /* strtoull() itself would accept space/+/- */
207 if (*e >= '0' && *e <= '9') {
208 unsigned long long l2;
211 l2 = strtoull(e, &e2, 10);
215 /* Ignore failure. E.g. 10.M is valid */
222 e += strspn(e, WHITESPACE);
224 for (i = start_pos; i < n_entries; i++)
225 if (startswith(e, table[i].suffix))
231 if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
234 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
235 if (tmp > ULLONG_MAX - r)
239 if ((unsigned long long) (uint64_t) r != r)
242 p = e + strlen(table[i].suffix);
253 #if 0 /// UNNEEDED by elogind
254 int parse_range(const char *t, unsigned *lower, unsigned *upper) {
255 _cleanup_free_ char *word = NULL;
262 /* Extract the lower bound. */
263 r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
269 r = safe_atou(word, &l);
273 /* Check for the upper bound and extract it if needed */
275 /* Single number with no dashes. */
278 /* Trailing dash is an error. */
281 r = safe_atou(t, &u);
292 int parse_errno(const char *t) {
297 r = errno_from_name(t);
301 r = safe_atoi(t, &e);
305 /* 0 is also allowed here */
306 if (!errno_is_valid(e) && e != 0)
312 int parse_syscall_and_errno(const char *in, char **name, int *error) {
313 _cleanup_free_ char *n = NULL;
322 * This parse "syscall:errno" like "uname:EILSEQ", "@sync:255".
323 * If errno is omitted, then error is set to -1.
324 * Empty syscall name is not allowed.
325 * Here, we do not check that the syscall name is valid or not.
330 e = parse_errno(p + 1);
334 n = strndup(in, p - in);
350 char *format_bytes(char *buf, size_t l, uint64_t t) {
353 /* This only does IEC units so far */
355 static const struct {
359 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
360 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
361 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
362 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
363 { "M", UINT64_C(1024)*UINT64_C(1024) },
364 { "K", UINT64_C(1024) },
367 if (t == (uint64_t) -1)
370 for (i = 0; i < ELEMENTSOF(table); i++) {
372 if (t >= table[i].factor) {
374 "%" PRIu64 ".%" PRIu64 "%s",
376 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
383 snprintf(buf, l, "%" PRIu64 "B", t);
391 int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
399 /* strtoul() is happy to parse negative values, and silently
400 * converts them to unsigned values without generating an
401 * error. We want a clean error, hence let's look for the "-"
402 * prefix on our own, and generate an error. But let's do so
403 * only after strtoul() validated that the string is clean
404 * otherwise, so that we return EINVAL preferably over
407 s += strspn(s, WHITESPACE);
410 l = strtoul(s, &x, base);
413 if (!x || x == s || *x != 0)
417 if ((unsigned long) (unsigned) l != l)
420 *ret_u = (unsigned) l;
424 int safe_atoi(const char *s, int *ret_i) {
432 l = strtol(s, &x, 0);
435 if (!x || x == s || *x != 0)
437 if ((long) (int) l != l)
444 int safe_atollu(const char *s, long long unsigned *ret_llu) {
446 unsigned long long l;
451 s += strspn(s, WHITESPACE);
454 l = strtoull(s, &x, 0);
457 if (!x || x == s || *x != 0)
466 int safe_atolli(const char *s, long long int *ret_lli) {
474 l = strtoll(s, &x, 0);
477 if (!x || x == s || *x != 0)
484 int safe_atou8(const char *s, uint8_t *ret) {
491 s += strspn(s, WHITESPACE);
494 l = strtoul(s, &x, 0);
497 if (!x || x == s || *x != 0)
501 if ((unsigned long) (uint8_t) l != l)
508 int safe_atou16_full(const char *s, unsigned base, uint16_t *ret) {
516 s += strspn(s, WHITESPACE);
519 l = strtoul(s, &x, base);
522 if (!x || x == s || *x != 0)
526 if ((unsigned long) (uint16_t) l != l)
533 int safe_atoi16(const char *s, int16_t *ret) {
541 l = strtol(s, &x, 0);
544 if (!x || x == s || *x != 0)
546 if ((long) (int16_t) l != l)
553 int safe_atod(const char *s, double *ret_d) {
554 _cleanup_(freelocalep) locale_t loc = (locale_t) 0;
561 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
562 if (loc == (locale_t) 0)
566 d = strtod_l(s, &x, loc);
569 if (!x || x == s || *x != 0)
576 int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
583 /* accept any number of digits, strtoull is limted to 19 */
584 for (i=0; i < digits; i++,s++) {
585 if (*s < '0' || *s > '9') {
589 /* too few digits, pad with 0 */
590 for (; i < digits; i++)
601 if (*s >= '5' && *s <= '9')
604 s += strspn(s, DIGITS);
612 int parse_percent_unbounded(const char *p) {
616 pc = endswith(p, "%");
620 n = strndupa(p, pc - p);
621 r = safe_atoi(n, &v);
630 int parse_percent(const char *p) {
633 v = parse_percent_unbounded(p);
640 int parse_permille_unbounded(const char *p) {
641 const char *pc, *pm, *dot, *n;
644 pm = endswith(p, "‰");
646 n = strndupa(p, pm - p);
647 r = safe_atoi(n, &v);
651 pc = endswith(p, "%");
655 dot = memchr(p, '.', pc - p);
659 if (dot[1] < '0' || dot[1] > '9')
662 n = strndupa(p, dot - p);
665 n = strndupa(p, pc - p);
667 r = safe_atoi(n, &v);
670 if (v > (INT_MAX - q) / 10)
682 int parse_permille(const char *p) {
685 v = parse_permille_unbounded(p);
692 #if 0 /// UNNEEDED by elogind
693 int parse_nice(const char *p, int *ret) {
696 r = safe_atoi(p, &n);
700 if (!nice_is_valid(n))
707 int parse_ip_port(const char *s, uint16_t *ret) {
711 r = safe_atou16(s, &l);
724 int parse_dev(const char *s, dev_t *ret) {
728 if (sscanf(s, "%u:%u", &x, &y) != 2)
732 if ((unsigned) major(d) != x || (unsigned) minor(d) != y)
739 int parse_oom_score_adjust(const char *s, int *ret) {
745 r = safe_atoi(s, &v);
749 if (v < OOM_SCORE_ADJ_MIN || v > OOM_SCORE_ADJ_MAX)