parse-util.c revision 28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2010 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8bdbb8d9cbe1d35708385573d70984ab4533812dLennart Poettering#include "alloc-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "extract-word.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "parse-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "string-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringint parse_boolean(const char *v) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(v);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return 1;
eef46c372f64f40dd75415b2c504c73138719c8dLennart Poettering else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poetteringint parse_pid(const char *s, pid_t* ret_pid) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen unsigned long ul = 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen pid_t pid;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(s);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(ret_pid);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering r = safe_atolu(s, &ul);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering pid = (pid_t) ul;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if ((unsigned long) pid != ul)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -ERANGE;
0b452006de98294d1690f045f6ea2f7f6630ec3bRonny Chevalier
288a74cce597f81d3ba01d8a5ca7d2ba5b654b7eRonny Chevalier if (pid <= 0)
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering return -ERANGE;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *ret_pid = pid;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersenint parse_mode(const char *s, mode_t *ret) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char *x;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering long l;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(s);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(ret);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering errno = 0;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering l = strtol(s, &x, 8);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (errno != 0)
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return -errno;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering if (!x || x == s || *x)
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return -EINVAL;
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering if (l < 0 || l > 07777)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ERANGE;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *ret = (mode_t) l;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint parse_size(const char *t, uint64_t base, uint64_t *size) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Soo, sometimes we want to parse IEC binary suffixes, and
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * sometimes SI decimal suffixes. This function can parse
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * both. Which one is the right way depends on the
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * context. Wikipedia suggests that SI is customary for
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * hardware metrics and network speeds, while IEC is
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * customary for most data sizes used by software and volatile
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * (RAM) memory. Hence be careful which one you pick!
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering *
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * In either case we use just K, M, G as suffix, and not Ki,
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * Mi, Gi or so (as IEC would suggest). That's because that's
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * frickin' ugly. But this means you really need to make sure
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * to document which base you are parsing when you use this
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * call. */
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering struct table {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering const char *suffix;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering unsigned long long factor;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering };
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering static const struct table iec[] = {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "G", 1024ULL*1024ULL*1024ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "M", 1024ULL*1024ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "K", 1024ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "B", 1ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "", 1ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering };
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering static const struct table si[] = {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "G", 1000ULL*1000ULL*1000ULL },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "M", 1000ULL*1000ULL },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "K", 1000ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering { "B", 1ULL },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "", 1ULL },
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering };
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const struct table *table;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering const char *p;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering unsigned long long r = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned n_entries, start_pos = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(t);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(base == 1000 || base == 1024);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(size);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (base == 1000) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen table = si;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen n_entries = ELEMENTSOF(si);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen } else {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen table = iec;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen n_entries = ELEMENTSOF(iec);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering p = t;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen do {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen unsigned long long l, tmp;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering double frac = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char *e;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned i;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen p += strspn(p, WHITESPACE);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering if (*p == '-')
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ERANGE;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering errno = 0;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering l = strtoull(p, &e, 10);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (errno > 0)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (e == p)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -EINVAL;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (*e == '.') {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering e++;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering /* strtoull() itself would accept space/+/- */
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (*e >= '0' && *e <= '9') {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering unsigned long long l2;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering char *e2;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering l2 = strtoull(e, &e2, 10);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (errno > 0)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -errno;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering /* Ignore failure. E.g. 10.M is valid */
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering frac = l2;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering for (; e < e2; e++)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering frac /= 10;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen e += strspn(e, WHITESPACE);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering for (i = start_pos; i < n_entries; i++)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (startswith(e, table[i].suffix))
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering break;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (i >= n_entries)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -EINVAL;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -ERANGE;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (tmp > ULLONG_MAX - r)
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering return -ERANGE;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r += tmp;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if ((unsigned long long) (uint64_t) r != r)
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen return -ERANGE;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering p = e + strlen(table[i].suffix);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering start_pos = i + 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering } while (*p);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering *size = r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringint parse_range(const char *t, unsigned *lower, unsigned *upper) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering _cleanup_free_ char *word = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering unsigned l, u;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(lower);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(upper);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering /* Extract the lower bound. */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r == 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = safe_atou(word, &l);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return r;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* Check for the upper bound and extract it if needed */
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (!t)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering /* Single number with no dashes. */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering u = l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering else if (!*t)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* Trailing dash is an error. */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering else {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = safe_atou(t, &u);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering *lower = l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering *upper = u;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringchar *format_bytes(char *buf, size_t l, uint64_t t) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering unsigned i;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* This only does IEC units so far */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering static const struct {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering const char *suffix;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering uint64_t factor;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering } table[] = {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "M", UINT64_C(1024)*UINT64_C(1024) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "K", UINT64_C(1024) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering };
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (t == (uint64_t) -1)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return NULL;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering for (i = 0; i < ELEMENTSOF(table); i++) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (t >= table[i].factor) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering snprintf(buf, l,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering "%" PRIu64 ".%" PRIu64 "%s",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering t / table[i].factor,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering table[i].suffix);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto finish;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering snprintf(buf, l, "%" PRIu64 "B", t);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poetteringfinish:
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering buf[l-1] = 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return buf;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringint safe_atou(const char *s, unsigned *ret_u) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering char *x = NULL;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering unsigned long l;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering assert(s);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering assert(ret_u);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering errno = 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering l = strtoul(s, &x, 0);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!x || x == s || *x || errno)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return errno > 0 ? -errno : -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if ((unsigned long) (unsigned) l != l)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -ERANGE;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering *ret_u = (unsigned) l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poetteringint safe_atoi(const char *s, int *ret_i) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering char *x = NULL;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering long l;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(s);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(ret_i);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering errno = 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering l = strtol(s, &x, 0);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (!x || x == s || *x || errno)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return errno > 0 ? -errno : -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
8937e7b68940d0fa0d0aab90eb7425fa7dccebc9Lennart Poettering if ((long) (int) l != l)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return -ERANGE;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering *ret_i = (int) l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringint safe_atollu(const char *s, long long unsigned *ret_llu) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char *x = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering unsigned long long l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(s);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering assert(ret_llu);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen errno = 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering l = strtoull(s, &x, 0);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering if (!x || x == s || *x || errno)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return errno ? -errno : -EINVAL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering *ret_llu = l;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringint safe_atolli(const char *s, long long int *ret_lli) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering char *x = NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering long long l;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(s);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(ret_lli);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering errno = 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering l = strtoll(s, &x, 0);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (!x || x == s || *x || errno)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return errno ? -errno : -EINVAL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen *ret_lli = l;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringint safe_atou8(const char *s, uint8_t *ret) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering char *x = NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering unsigned long l;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering assert(s);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering assert(ret);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering errno = 0;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering l = strtoul(s, &x, 0);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (!x || x == s || *x || errno)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering return errno > 0 ? -errno : -EINVAL;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if ((unsigned long) (uint8_t) l != l)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return -ERANGE;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering *ret = (uint8_t) l;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringint safe_atou16(const char *s, uint16_t *ret) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering char *x = NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering unsigned long l;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(s);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(ret);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering errno = 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering l = strtoul(s, &x, 0);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!x || x == s || *x || errno)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return errno > 0 ? -errno : -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if ((unsigned long) (uint16_t) l != l)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -ERANGE;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering *ret = (uint16_t) l;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringint safe_atoi16(const char *s, int16_t *ret) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char *x = NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering long l;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(s);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(ret);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering errno = 0;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering l = strtol(s, &x, 0);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!x || x == s || *x || errno)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return errno > 0 ? -errno : -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if ((long) (int16_t) l != l)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -ERANGE;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering *ret = (int16_t) l;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringint safe_atod(const char *s, double *ret_d) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char *x = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering double d = 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering locale_t loc;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(s);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(ret_d);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (loc == (locale_t) 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -errno;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering errno = 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering d = strtod_l(s, &x, loc);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!x || x == s || *x || errno) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering freelocale(loc);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return errno ? -errno : -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering freelocale(loc);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering *ret_d = (double) d;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering