]> granicus.if.org Git - shadow/blob - libmisc/getrange.c
* libmisc/loginprompt.c: Use exit(EXIT_FAILURE) instead of
[shadow] / libmisc / getrange.c
1 /*
2  * Copyright (c) 2008       , Nicolas François
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the copyright holders or contributors may not be used to
14  *    endorse or promote products derived from this software without
15  *    specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
21  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <config.h>
31
32 #ident "$Id: $"
33
34 #include <ctype.h>
35 #include <stdlib.h>
36
37 #include "defines.h"
38 #include "prototypes.h"
39
40 /*
41  * Parse a range and indicate if the range is valid.
42  * Valid ranges are in the form:
43  *     <long>          -> min=max=long         has_min  has_max
44  *     -<long>         -> max=long            !has_min  has_max
45  *     <long>-         -> min=long             has_min !has_max
46  *     <long1>-<long2> -> min=long1 max=long2  has_min  has_max
47  *
48  * If the range is valid, getrange returns 1.
49  * If the range is not valid, getrange returns 0.
50  */
51 int getrange (char *range,
52               unsigned long *min, bool *has_min,
53               unsigned long *max, bool *has_max)
54 {
55         char *endptr;
56         unsigned long n;
57
58         if (NULL == range) {
59                 return 0;
60         }
61
62         if ('-' == range[0]) {
63                 if (!isdigit(range[1])) {
64                         /* invalid */
65                         return 0;
66                 }
67                 errno = 0;
68                 n = strtoul (&range[1], &endptr, 10);
69                 if (('\0' != *endptr) || (ERANGE == errno)) {
70                         /* invalid */
71                         return 0;
72                 }
73                 /* -<long> */
74                 *has_min = false;
75                 *has_max = true;
76                 *max = n;
77         } else {
78                 errno = 0;
79                 n = strtoul (range, &endptr, 10);
80                 if (ERANGE == errno) {
81                         /* invalid */
82                         return 0;
83                 }
84                 switch (*endptr) {
85                         case '\0':
86                                 /* <long> */
87                                 *has_min = true;
88                                 *has_max = true;
89                                 *min = n;
90                                 *max = n;
91                                 break;
92                         case '-':
93                                 endptr++;
94                                 if ('\0' == *endptr) {
95                                         /* <long>- */
96                                         *has_min = true;
97                                         *has_max = false;
98                                         *min = n;
99                                 } else if (!isdigit (*endptr)) {
100                                         /* invalid */
101                                         return 0;
102                                 } else {
103                                         *has_min = true;
104                                         *min = n;
105                                         errno = 0;
106                                         n = strtoul (endptr, &endptr, 10);
107                                         if (   ('\0' != *endptr)
108                                             || (ERANGE == errno)) {
109                                                 /* invalid */
110                                                 return 0;
111                                         }
112                                         /* <long>-<long> */
113                                         *has_max = true;
114                                         *max = n;
115                                 }
116                                 break;
117                         default:
118                                 return 0;
119                 }
120         }
121
122         return 1;
123 }
124