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/>.
28 #include "alloc-util.h"
29 #include "extract-word.h"
31 #include "parse-util.h"
32 #include "string-util.h"
34 int parse_boolean(const char *v
) {
37 if (streq(v
, "1") || strcaseeq(v
, "yes") || strcaseeq(v
, "y") || strcaseeq(v
, "true") || strcaseeq(v
, "t") || strcaseeq(v
, "on"))
39 else if (streq(v
, "0") || strcaseeq(v
, "no") || strcaseeq(v
, "n") || strcaseeq(v
, "false") || strcaseeq(v
, "f") || strcaseeq(v
, "off"))
45 int parse_pid(const char *s
, pid_t
* ret_pid
) {
53 r
= safe_atolu(s
, &ul
);
59 if ((unsigned long) pid
!= ul
)
69 int parse_mode(const char *s
, mode_t
*ret
) {
76 s
+= strspn(s
, WHITESPACE
);
84 if (!x
|| x
== s
|| *x
)
86 if (l
< 0 || l
> 07777)
93 int parse_ifindex(const char *s
, int *ret
) {
96 r
= safe_atoi(s
, &ifi
);
106 int parse_size(const char *t
, uint64_t base
, uint64_t *size
) {
108 /* Soo, sometimes we want to parse IEC binary suffixes, and
109 * sometimes SI decimal suffixes. This function can parse
110 * both. Which one is the right way depends on the
111 * context. Wikipedia suggests that SI is customary for
112 * hardware metrics and network speeds, while IEC is
113 * customary for most data sizes used by software and volatile
114 * (RAM) memory. Hence be careful which one you pick!
116 * In either case we use just K, M, G as suffix, and not Ki,
117 * Mi, Gi or so (as IEC would suggest). That's because that's
118 * frickin' ugly. But this means you really need to make sure
119 * to document which base you are parsing when you use this
124 unsigned long long factor
;
127 static const struct table iec
[] = {
128 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
129 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
130 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
131 { "G", 1024ULL*1024ULL*1024ULL },
132 { "M", 1024ULL*1024ULL },
138 static const struct table si
[] = {
139 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
140 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
141 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
142 { "G", 1000ULL*1000ULL*1000ULL },
143 { "M", 1000ULL*1000ULL },
149 const struct table
*table
;
151 unsigned long long r
= 0;
152 unsigned n_entries
, start_pos
= 0;
155 assert(base
== 1000 || base
== 1024);
160 n_entries
= ELEMENTSOF(si
);
163 n_entries
= ELEMENTSOF(iec
);
168 unsigned long long l
, tmp
;
173 p
+= strspn(p
, WHITESPACE
);
176 l
= strtoull(p
, &e
, 10);
187 /* strtoull() itself would accept space/+/- */
188 if (*e
>= '0' && *e
<= '9') {
189 unsigned long long l2
;
192 l2
= strtoull(e
, &e2
, 10);
196 /* Ignore failure. E.g. 10.M is valid */
203 e
+= strspn(e
, WHITESPACE
);
205 for (i
= start_pos
; i
< n_entries
; i
++)
206 if (startswith(e
, table
[i
].suffix
))
212 if (l
+ (frac
> 0) > ULLONG_MAX
/ table
[i
].factor
)
215 tmp
= l
* table
[i
].factor
+ (unsigned long long) (frac
* table
[i
].factor
);
216 if (tmp
> ULLONG_MAX
- r
)
220 if ((unsigned long long) (uint64_t) r
!= r
)
223 p
= e
+ strlen(table
[i
].suffix
);
234 int parse_range(const char *t
, unsigned *lower
, unsigned *upper
) {
235 _cleanup_free_
char *word
= NULL
;
242 /* Extract the lower bound. */
243 r
= extract_first_word(&t
, &word
, "-", EXTRACT_DONT_COALESCE_SEPARATORS
);
249 r
= safe_atou(word
, &l
);
253 /* Check for the upper bound and extract it if needed */
255 /* Single number with no dashes. */
258 /* Trailing dash is an error. */
261 r
= safe_atou(t
, &u
);
271 char *format_bytes(char *buf
, size_t l
, uint64_t t
) {
274 /* This only does IEC units so far */
276 static const struct {
280 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
281 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
282 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
283 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
284 { "M", UINT64_C(1024)*UINT64_C(1024) },
285 { "K", UINT64_C(1024) },
288 if (t
== (uint64_t) -1)
291 for (i
= 0; i
< ELEMENTSOF(table
); i
++) {
293 if (t
>= table
[i
].factor
) {
295 "%" PRIu64
".%" PRIu64
"%s",
297 ((t
*UINT64_C(10)) / table
[i
].factor
) % UINT64_C(10),
304 snprintf(buf
, l
, "%" PRIu64
"B", t
);
312 int safe_atou(const char *s
, unsigned *ret_u
) {
319 /* strtoul() is happy to parse negative values, and silently
320 * converts them to unsigned values without generating an
321 * error. We want a clean error, hence let's look for the "-"
322 * prefix on our own, and generate an error. But let's do so
323 * only after strtoul() validated that the string is clean
324 * otherwise, so that we return EINVAL preferably over
327 s
+= strspn(s
, WHITESPACE
);
330 l
= strtoul(s
, &x
, 0);
333 if (!x
|| x
== s
|| *x
)
337 if ((unsigned long) (unsigned) l
!= l
)
340 *ret_u
= (unsigned) l
;
344 int safe_atoi(const char *s
, int *ret_i
) {
352 l
= strtol(s
, &x
, 0);
355 if (!x
|| x
== s
|| *x
)
357 if ((long) (int) l
!= l
)
364 int safe_atollu(const char *s
, long long unsigned *ret_llu
) {
366 unsigned long long l
;
371 s
+= strspn(s
, WHITESPACE
);
374 l
= strtoull(s
, &x
, 0);
377 if (!x
|| x
== s
|| *x
)
386 int safe_atolli(const char *s
, long long int *ret_lli
) {
394 l
= strtoll(s
, &x
, 0);
397 if (!x
|| x
== s
|| *x
)
404 int safe_atou8(const char *s
, uint8_t *ret
) {
411 s
+= strspn(s
, WHITESPACE
);
414 l
= strtoul(s
, &x
, 0);
417 if (!x
|| x
== s
|| *x
)
421 if ((unsigned long) (uint8_t) l
!= l
)
428 int safe_atou16(const char *s
, uint16_t *ret
) {
435 s
+= strspn(s
, WHITESPACE
);
438 l
= strtoul(s
, &x
, 0);
441 if (!x
|| x
== s
|| *x
)
445 if ((unsigned long) (uint16_t) l
!= l
)
452 int safe_atoi16(const char *s
, int16_t *ret
) {
460 l
= strtol(s
, &x
, 0);
463 if (!x
|| x
== s
|| *x
)
465 if ((long) (int16_t) l
!= l
)
472 int safe_atod(const char *s
, double *ret_d
) {
480 loc
= newlocale(LC_NUMERIC_MASK
, "C", (locale_t
) 0);
481 if (loc
== (locale_t
) 0)
485 d
= strtod_l(s
, &x
, loc
);
490 if (!x
|| x
== s
|| *x
) {
500 int parse_fractional_part_u(const char **p
, size_t digits
, unsigned *res
) {
507 /* accept any number of digits, strtoull is limted to 19 */
508 for (i
=0; i
< digits
; i
++,s
++) {
509 if (*s
< '0' || *s
> '9') {
513 /* too few digits, pad with 0 */
514 for (; i
< digits
; i
++)
525 if (*s
>= '5' && *s
<= '9')
528 s
+= strspn(s
, DIGITS
);
536 int parse_percent_unbounded(const char *p
) {
541 pc
= endswith(p
, "%");
545 n
= strndupa(p
, pc
- p
);
546 r
= safe_atou(n
, &v
);
553 int parse_percent(const char *p
) {
554 int v
= parse_percent_unbounded(p
);