parse-util.c revision 93cc7779e0c121b75183920173f37cd1ee9d59cf
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering/***
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering This file is part of systemd.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering Copyright 2010 Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering systemd is free software; you can redistribute it and/or modify it
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering under the terms of the GNU Lesser General Public License as published by
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering (at your option) any later version.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering systemd is distributed in the hope that it will be useful, but
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering Lesser General Public License for more details.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering You should have received a copy of the GNU Lesser General Public License
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering***/
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <errno.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <inttypes.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <locale.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <stdio.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <stdlib.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <string.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include <xlocale.h>
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger#include "alloc-util.h"
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger#include "extract-word.h"
11c3a36649e5e5e77db499c92f3cdcbd619efd3aThomas Hindoe Paaboel Andersen#include "macro.h"
93cc7779e0c121b75183920173f37cd1ee9d59cfThomas Hindoe Paaboel Andersen#include "parse-util.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "string-util.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint parse_boolean(const char *v) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(v);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 1;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -EINVAL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint parse_pid(const char *s, pid_t* ret_pid) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long ul = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering pid_t pid;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering int r;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret_pid);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering r = safe_atolu(s, &ul);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (r < 0)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return r;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering pid = (pid_t) ul;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if ((unsigned long) pid != ul)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (pid <= 0)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret_pid = pid;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint parse_mode(const char *s, mode_t *ret) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering s += strspn(s, WHITESPACE);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (s[0] == '-')
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -ERANGE;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtol(s, &x, 8);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (errno != 0)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -errno;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (!x || x == s || *x)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -EINVAL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (l < 0 || l > 07777)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret = (mode_t) l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poetteringint parse_ifindex(const char *s, int *ret) {
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering int ifi, r;
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering r = safe_atoi(s, &ifi);
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering if (r < 0)
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering return r;
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering if (ifi <= 0)
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering return -EINVAL;
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering *ret = ifi;
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering return 0;
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering}
6ad623a3f77e087e308f334525fd4046811f2a9aLennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint parse_size(const char *t, uint64_t base, uint64_t *size) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering /* Soo, sometimes we want to parse IEC binary suffixes, and
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * sometimes SI decimal suffixes. This function can parse
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * both. Which one is the right way depends on the
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * context. Wikipedia suggests that SI is customary for
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * hardware metrics and network speeds, while IEC is
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * customary for most data sizes used by software and volatile
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * (RAM) memory. Hence be careful which one you pick!
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * In either case we use just K, M, G as suffix, and not Ki,
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * Mi, Gi or so (as IEC would suggest). That's because that's
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * frickin' ugly. But this means you really need to make sure
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * to document which base you are parsing when you use this
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering * call. */
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering struct table {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering const char *suffix;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long long factor;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering };
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering static const struct table iec[] = {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "G", 1024ULL*1024ULL*1024ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "M", 1024ULL*1024ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "K", 1024ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "B", 1ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "", 1ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering };
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering static const struct table si[] = {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "G", 1000ULL*1000ULL*1000ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "M", 1000ULL*1000ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "K", 1000ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "B", 1ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "", 1ULL },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering };
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering const struct table *table;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering const char *p;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long long r = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned n_entries, start_pos = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(t);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(base == 1000 || base == 1024);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(size);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (base == 1000) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering table = si;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering n_entries = ELEMENTSOF(si);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering } else {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering table = iec;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering n_entries = ELEMENTSOF(iec);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering }
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering p = t;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering do {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long long l, tmp;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering double frac = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *e;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned i;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering p += strspn(p, WHITESPACE);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtoull(p, &e, 10);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -errno;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (e == p)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -EINVAL;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (*p == '-')
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (*e == '.') {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering e++;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering /* strtoull() itself would accept space/+/- */
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (*e >= '0' && *e <= '9') {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long long l2;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *e2;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l2 = strtoull(e, &e2, 10);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -errno;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering /* Ignore failure. E.g. 10.M is valid */
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering frac = l2;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering for (; e < e2; e++)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering frac /= 10;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering }
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering }
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering e += strspn(e, WHITESPACE);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering for (i = start_pos; i < n_entries; i++)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (startswith(e, table[i].suffix))
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering break;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (i >= n_entries)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -EINVAL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (tmp > ULLONG_MAX - r)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering r += tmp;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if ((unsigned long long) (uint64_t) r != r)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering p = e + strlen(table[i].suffix);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering start_pos = i + 1;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering } while (*p);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *size = r;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburgerint parse_range(const char *t, unsigned *lower, unsigned *upper) {
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger _cleanup_free_ char *word = NULL;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger unsigned l, u;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger int r;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger assert(lower);
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger assert(upper);
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger /* Extract the lower bound. */
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger if (r < 0)
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger return r;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger if (r == 0)
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger return -EINVAL;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger r = safe_atou(word, &l);
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger if (r < 0)
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger return r;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger /* Check for the upper bound and extract it if needed */
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger if (!t)
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger /* Single number with no dashes. */
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger u = l;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger else if (!*t)
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger /* Trailing dash is an error. */
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger return -EINVAL;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger else {
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger r = safe_atou(t, &u);
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger if (r < 0)
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger return r;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger }
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger *lower = l;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger *upper = u;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger return 0;
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger}
28cb17ef0281efc3a46e5d0e702b0b0ddeaafaa4Filipe Brandenburger
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringchar *format_bytes(char *buf, size_t l, uint64_t t) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned i;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering /* This only does IEC units so far */
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering static const struct {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering const char *suffix;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering uint64_t factor;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering } table[] = {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "M", UINT64_C(1024)*UINT64_C(1024) },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering { "K", UINT64_C(1024) },
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering };
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (t == (uint64_t) -1)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering for (i = 0; i < ELEMENTSOF(table); i++) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (t >= table[i].factor) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering snprintf(buf, l,
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering "%" PRIu64 ".%" PRIu64 "%s",
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering t / table[i].factor,
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering table[i].suffix);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering goto finish;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering }
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering }
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering snprintf(buf, l, "%" PRIu64 "B", t);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringfinish:
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering buf[l-1] = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return buf;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atou(const char *s, unsigned *ret_u) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret_u);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering /* strtoul() is happy to parse negative values, and silently
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering * converts them to unsigned values without generating an
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering * error. We want a clean error, hence let's look for the "-"
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering * prefix on our own, and generate an error. But let's do so
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering * only after strtoul() validated that the string is clean
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering * otherwise, so that we return EINVAL preferably over
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering * ERANGE. */
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering s += strspn(s, WHITESPACE);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering errno = 0;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering l = strtoul(s, &x, 0);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (s[0] == '-')
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if ((unsigned long) (unsigned) l != l)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret_u = (unsigned) l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atoi(const char *s, int *ret_i) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret_i);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtol(s, &x, 0);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if ((long) (int) l != l)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret_i = (int) l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atollu(const char *s, long long unsigned *ret_llu) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret_llu);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering s += strspn(s, WHITESPACE);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtoull(s, &x, 0);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (*s == '-')
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret_llu = l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atolli(const char *s, long long int *ret_lli) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering long long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret_lli);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtoll(s, &x, 0);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret_lli = l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atou8(const char *s, uint8_t *ret) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering s += strspn(s, WHITESPACE);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtoul(s, &x, 0);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (s[0] == '-')
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if ((unsigned long) (uint8_t) l != l)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret = (uint8_t) l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atou16(const char *s, uint16_t *ret) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering unsigned long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering s += strspn(s, WHITESPACE);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtoul(s, &x, 0);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (s[0] == '-')
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if ((unsigned long) (uint16_t) l != l)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret = (uint16_t) l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atoi16(const char *s, int16_t *ret) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering long l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering l = strtol(s, &x, 0);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x)
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if ((long) (int16_t) l != l)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -ERANGE;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret = (int16_t) l;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringint safe_atod(const char *s, double *ret_d) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char *x = NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering double d = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering locale_t loc;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(s);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering assert(ret_d);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (loc == (locale_t) 0)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return -errno;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering errno = 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering d = strtod_l(s, &x, loc);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (errno != 0) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering freelocale(loc);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -errno;
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering }
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering if (!x || x == s || *x) {
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering freelocale(loc);
2d49a208f8ad9d1c4e79fa4302451e35d06de707Lennart Poettering return -EINVAL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering }
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering freelocale(loc);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering *ret_d = (double) d;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return 0;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering}
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venevint parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev size_t i;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev unsigned val = 0;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev const char *s;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev s = *p;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev /* accept any number of digits, strtoull is limted to 19 */
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev for(i=0; i < digits; i++,s++) {
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev if (*s < '0' || *s > '9') {
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev if (i == 0)
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev return -EINVAL;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev /* too few digits, pad with 0 */
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev for (; i < digits; i++)
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev val *= 10;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev break;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev }
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev val *= 10;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev val += *s - '0';
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev }
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev /* maybe round up */
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev if (*s >= '5' && *s <= '9')
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev val++;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev s += strspn(s, DIGITS);
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev *p = s;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev *res = val;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev return 0;
436dd70f5331ec541ebdd84e106abaa63203f6f1Hristo Venev}