2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #if defined(__GLIBC__)
28 #endif // defined(__GLIBC__)
30 #include "alloc-util.h"
31 //#include "extract-word.h"
33 #include "parse-util.h"
34 #include "string-util.h"
36 /// Additional includes needed by elogind
37 #include "musl_missing.h"
39 int parse_boolean(const char *v) {
42 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
44 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
50 int parse_pid(const char *s, pid_t* ret_pid) {
58 r = safe_atolu(s, &ul);
64 if ((unsigned long) pid != ul)
74 int parse_mode(const char *s, mode_t *ret) {
81 s += strspn(s, WHITESPACE);
89 if (!x || x == s || *x)
91 if (l < 0 || l > 07777)
98 int parse_ifindex(const char *s, int *ret) {
101 r = safe_atoi(s, &ifi);
111 int parse_size(const char *t, uint64_t base, uint64_t *size) {
113 /* Soo, sometimes we want to parse IEC binary suffixes, and
114 * sometimes SI decimal suffixes. This function can parse
115 * both. Which one is the right way depends on the
116 * context. Wikipedia suggests that SI is customary for
117 * hardware metrics and network speeds, while IEC is
118 * customary for most data sizes used by software and volatile
119 * (RAM) memory. Hence be careful which one you pick!
121 * In either case we use just K, M, G as suffix, and not Ki,
122 * Mi, Gi or so (as IEC would suggest). That's because that's
123 * frickin' ugly. But this means you really need to make sure
124 * to document which base you are parsing when you use this
129 unsigned long long factor;
132 static const struct table iec[] = {
133 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
134 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
135 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
136 { "G", 1024ULL*1024ULL*1024ULL },
137 { "M", 1024ULL*1024ULL },
143 static const struct table si[] = {
144 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
145 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
146 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
147 { "G", 1000ULL*1000ULL*1000ULL },
148 { "M", 1000ULL*1000ULL },
154 const struct table *table;
156 unsigned long long r = 0;
157 unsigned n_entries, start_pos = 0;
160 assert(base == 1000 || base == 1024);
165 n_entries = ELEMENTSOF(si);
168 n_entries = ELEMENTSOF(iec);
173 unsigned long long l, tmp;
178 p += strspn(p, WHITESPACE);
181 l = strtoull(p, &e, 10);
192 /* strtoull() itself would accept space/+/- */
193 if (*e >= '0' && *e <= '9') {
194 unsigned long long l2;
197 l2 = strtoull(e, &e2, 10);
201 /* Ignore failure. E.g. 10.M is valid */
208 e += strspn(e, WHITESPACE);
210 for (i = start_pos; i < n_entries; i++)
211 if (startswith(e, table[i].suffix))
217 if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
220 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
221 if (tmp > ULLONG_MAX - r)
225 if ((unsigned long long) (uint64_t) r != r)
228 p = e + strlen(table[i].suffix);
239 #if 0 /// UNNEEDED by elogind
240 int parse_range(const char *t, unsigned *lower, unsigned *upper) {
241 _cleanup_free_ char *word = NULL;
248 /* Extract the lower bound. */
249 r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
255 r = safe_atou(word, &l);
259 /* Check for the upper bound and extract it if needed */
261 /* Single number with no dashes. */
264 /* Trailing dash is an error. */
267 r = safe_atou(t, &u);
277 char *format_bytes(char *buf, size_t l, uint64_t t) {
280 /* This only does IEC units so far */
282 static const struct {
286 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
287 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
288 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
289 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
290 { "M", UINT64_C(1024)*UINT64_C(1024) },
291 { "K", UINT64_C(1024) },
294 if (t == (uint64_t) -1)
297 for (i = 0; i < ELEMENTSOF(table); i++) {
299 if (t >= table[i].factor) {
301 "%" PRIu64 ".%" PRIu64 "%s",
303 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
310 snprintf(buf, l, "%" PRIu64 "B", t);
319 int safe_atou(const char *s, unsigned *ret_u) {
326 /* strtoul() is happy to parse negative values, and silently
327 * converts them to unsigned values without generating an
328 * error. We want a clean error, hence let's look for the "-"
329 * prefix on our own, and generate an error. But let's do so
330 * only after strtoul() validated that the string is clean
331 * otherwise, so that we return EINVAL preferably over
334 s += strspn(s, WHITESPACE);
337 l = strtoul(s, &x, 0);
340 if (!x || x == s || *x)
344 if ((unsigned long) (unsigned) l != l)
347 *ret_u = (unsigned) l;
351 int safe_atoi(const char *s, int *ret_i) {
359 l = strtol(s, &x, 0);
362 if (!x || x == s || *x)
364 if ((long) (int) l != l)
371 int safe_atollu(const char *s, long long unsigned *ret_llu) {
373 unsigned long long l;
378 s += strspn(s, WHITESPACE);
381 l = strtoull(s, &x, 0);
384 if (!x || x == s || *x)
393 int safe_atolli(const char *s, long long int *ret_lli) {
401 l = strtoll(s, &x, 0);
404 if (!x || x == s || *x)
411 int safe_atou8(const char *s, uint8_t *ret) {
418 s += strspn(s, WHITESPACE);
421 l = strtoul(s, &x, 0);
424 if (!x || x == s || *x)
428 if ((unsigned long) (uint8_t) l != l)
435 int safe_atou16(const char *s, uint16_t *ret) {
442 s += strspn(s, WHITESPACE);
445 l = strtoul(s, &x, 0);
448 if (!x || x == s || *x)
452 if ((unsigned long) (uint16_t) l != l)
459 int safe_atoi16(const char *s, int16_t *ret) {
467 l = strtol(s, &x, 0);
470 if (!x || x == s || *x)
472 if ((long) (int16_t) l != l)
479 int safe_atod(const char *s, double *ret_d) {
487 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
488 if (loc == (locale_t) 0)
492 d = strtod_l(s, &x, loc);
497 if (!x || x == s || *x) {
507 int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
514 /* accept any number of digits, strtoull is limted to 19 */
515 for (i=0; i < digits; i++,s++) {
516 if (*s < '0' || *s > '9') {
520 /* too few digits, pad with 0 */
521 for (; i < digits; i++)
532 if (*s >= '5' && *s <= '9')
535 s += strspn(s, DIGITS);
543 int parse_percent_unbounded(const char *p) {
548 pc = endswith(p, "%");
552 n = strndupa(p, pc - p);
553 r = safe_atou(n, &v);
560 int parse_percent(const char *p) {
563 v = parse_percent_unbounded(p);
570 #if 0 /// UNNEEDED by elogind
571 int parse_nice(const char *p, int *ret) {
574 r = safe_atoi(p, &n);
578 if (!nice_is_valid(n))
586 int parse_ip_port(const char *s, uint16_t *ret) {
590 r = safe_atou16(s, &l);