1285997Sbapt/*-
2287084Sbapt * Copyright (C) 2015 Baptiste Daroussin <bapt@FreeBSD.org>
3287084Sbapt * 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
9287084Sbapt *    notice, this list of conditions and the following disclaimer
10287084Sbapt *    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 *
15287084Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16287084Sbapt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17287084Sbapt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18287084Sbapt * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19287084Sbapt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20287084Sbapt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21287084Sbapt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22287084Sbapt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23287084Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24287084Sbapt * 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
38287084Sbaptstrtounum(const char * __restrict np, uintmax_t minval, uintmax_t maxval,
39287084Sbapt    const char ** __restrict errpp)
40285997Sbapt{
41287084Sbapt	char *endp;
42287084Sbapt	uintmax_t ret;
43285997Sbapt
44287084Sbapt	*errpp = NULL;
45285997Sbapt	if (minval > maxval) {
46285997Sbapt		errno = EINVAL;
47287084Sbapt		if (errpp != NULL)
48287084Sbapt			*errpp = "invalid";
49285997Sbapt		return (0);
50285997Sbapt	}
51287084Sbapt	errno = 0;
52287084Sbapt	ret = strtoumax(np, &endp, 10);
53287084Sbapt	if (endp == np || *endp != '\0') {
54285997Sbapt		errno = EINVAL;
55287084Sbapt		if (errpp != NULL)
56287084Sbapt			*errpp = "invalid";
57285997Sbapt		return (0);
58287084Sbapt	}
59287084Sbapt	if (ret < minval) {
60285997Sbapt		errno = ERANGE;
61287084Sbapt		if (errpp != NULL)
62287084Sbapt			*errpp = "too small";
63285997Sbapt		return (0);
64287084Sbapt	}
65287084Sbapt	if (errno == ERANGE || ret > maxval) {
66285997Sbapt		errno = ERANGE;
67287084Sbapt		if (errpp != NULL)
68287084Sbapt			*errpp = "too large";
69285997Sbapt		return (0);
70285997Sbapt	}
71285997Sbapt	return (ret);
72285997Sbapt}
73