1285997Sbapt/*-
2286196Sbapt * Copyright (C) 2015 Baptiste Daroussin <bapt@FreeBSD.org>
3286045Sbapt * All rights reserved.
4285997Sbapt *
5285997Sbapt * Redistribution and use in source and binary forms, with or without
6285997Sbapt * modification, are permitted provided that the following conditions
7285997Sbapt * are met:
8285997Sbapt * 1. Redistributions of source code must retain the above copyright
9286045Sbapt *    notice, this list of conditions and the following disclaimer
10286045Sbapt *    in this position and unchanged.
11285997Sbapt * 2. Redistributions in binary form must reproduce the above copyright
12285997Sbapt *    notice, this list of conditions and the following disclaimer in the
13285997Sbapt *    documentation and/or other materials provided with the distribution.
14285997Sbapt *
15286045Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16286045Sbapt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17286045Sbapt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18286045Sbapt * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19286045Sbapt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20286045Sbapt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21286045Sbapt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22286045Sbapt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23286045Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24286045Sbapt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25285997Sbapt */
26285997Sbapt
27285997Sbapt#include <sys/cdefs.h>
28285997Sbapt__FBSDID("$FreeBSD$");
29285997Sbapt
30285997Sbapt#include <errno.h>
31285997Sbapt#include <inttypes.h>
32285997Sbapt#include <limits.h>
33285997Sbapt#include <stdlib.h>
34285997Sbapt
35285997Sbapt#include "pw.h"
36285997Sbapt
37285997Sbaptuintmax_t
38286066Sbaptstrtounum(const char * __restrict np, uintmax_t minval, uintmax_t maxval,
39286066Sbapt    const char ** __restrict errpp)
40285997Sbapt{
41286066Sbapt	char *endp;
42286066Sbapt	uintmax_t ret;
43285997Sbapt
44286993Sbapt	*errpp = NULL;
45285997Sbapt	if (minval > maxval) {
46285997Sbapt		errno = EINVAL;
47286066Sbapt		if (errpp != NULL)
48286066Sbapt			*errpp = "invalid";
49285997Sbapt		return (0);
50285997Sbapt	}
51286066Sbapt	errno = 0;
52286066Sbapt	ret = strtoumax(np, &endp, 10);
53286066Sbapt	if (endp == np || *endp != '\0') {
54285997Sbapt		errno = EINVAL;
55286066Sbapt		if (errpp != NULL)
56286066Sbapt			*errpp = "invalid";
57285997Sbapt		return (0);
58286066Sbapt	}
59286066Sbapt	if (ret < minval) {
60285997Sbapt		errno = ERANGE;
61286066Sbapt		if (errpp != NULL)
62286066Sbapt			*errpp = "too small";
63285997Sbapt		return (0);
64286066Sbapt	}
65286066Sbapt	if (errno == ERANGE || ret > maxval) {
66285997Sbapt		errno = ERANGE;
67286066Sbapt		if (errpp != NULL)
68286066Sbapt			*errpp = "too large";
69285997Sbapt		return (0);
70285997Sbapt	}
71285997Sbapt	return (ret);
72285997Sbapt}
73