1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Helper functions to skip white spaces, find tokens, find separators and free
29 * memory.
30 */
31
32 #include <errno.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36
37 #include "commp_util.h"
38
39
40 /*
41 * Skip to the next non-whitespace
42 */
43 int
commp_skip_white_space(const char ** begin,const char * end)44 commp_skip_white_space(const char **begin, const char *end)
45 {
46 while (*begin < end) {
47 if (!isspace(**begin))
48 return (0);
49 (*begin)++;
50 }
51 return (1);
52 }
53
54 /*
55 * Finds the token in the char buffer. *current will be pointing to the
56 * token when function returns. If the char buffer has leading token,
57 * it returns 1.
58 */
59 int
commp_find_token(const char ** begin,const char ** current,const char * end,char token,boolean_t last)60 commp_find_token(const char **begin, const char **current, const char *end,
61 char token, boolean_t last)
62 {
63 *current = *begin;
64 while (*current < end) {
65 if (!last && (**current == token))
66 break;
67 else if (isspace(**current))
68 return (1);
69 (*current)++;
70 }
71 /* Checks for leading white space */
72 if (*current == *begin)
73 return (1);
74 else
75 return (0);
76 }
77
78 /*
79 * atoi function
80 */
81 int
commp_atoi(const char * begin,const char * end,int * num)82 commp_atoi(const char *begin, const char *end, int *num)
83 {
84 boolean_t num_found = B_FALSE;
85
86 *num = 0;
87 while (begin < end) {
88 if (isdigit(*begin)) {
89 *num = (*num * 10) + (*begin - '0');
90 num_found = B_TRUE;
91 begin++;
92 } else {
93 break;
94 }
95 }
96 if (!num_found || (begin != end))
97 return (EINVAL);
98 return (0);
99 }
100
101 /*
102 * Given a string converts it to unsigned long long int.
103 */
104 int
commp_strtoull(const char * begin,const char * end,uint64_t * num)105 commp_strtoull(const char *begin, const char *end, uint64_t *num)
106 {
107 boolean_t num_found = B_FALSE;
108
109 *num = 0;
110 while (begin < end) {
111 if (isdigit(*begin)) {
112 *num = (*num * 10) + (*begin - '0');
113 num_found = B_TRUE;
114 begin++;
115 } else {
116 break;
117 }
118 }
119 if (!num_found || (begin != end))
120 return (EINVAL);
121 return (0);
122 }
123
124 /*
125 * Given a string converts it to unsigned byte
126 */
127 int
commp_strtoub(const char * begin,const char * end,uint8_t * num)128 commp_strtoub(const char *begin, const char *end, uint8_t *num)
129 {
130 boolean_t num_found = B_FALSE;
131
132 *num = 0;
133 while (begin < end) {
134 if (isdigit(*begin)) {
135 *num = (*num * 10) + (*begin - '0');
136 num_found = B_TRUE;
137 begin++;
138 } else {
139 break;
140 }
141 }
142 if (!num_found || (begin != end))
143 return (EINVAL);
144 return (0);
145 }
146
147 /*
148 * Given a string converts it to unsigned int
149 */
150 int
commp_atoui(const char * begin,const char * end,uint_t * num)151 commp_atoui(const char *begin, const char *end, uint_t *num)
152 {
153 boolean_t num_found = B_FALSE;
154
155 *num = 0;
156 while (begin < end) {
157 if (isdigit(*begin)) {
158 *num = (*num * 10) + (*begin - '0');
159 num_found = B_TRUE;
160 begin++;
161 } else {
162 break;
163 }
164 }
165 if (!num_found || (begin != end))
166 return (EINVAL);
167 return (0);
168 }
169
170 /*
171 * allocates memory and copies string to new memory
172 */
173 int
commp_add_str(char ** dest,const char * src,int len)174 commp_add_str(char **dest, const char *src, int len)
175 {
176 if (len == 0)
177 return (EINVAL);
178 (*dest) = calloc(1, len + 1);
179 if (*dest == NULL)
180 return (ENOMEM);
181 (void) strncpy(*dest, src, len);
182 return (0);
183 }
184
185 /*
186 * This function converts strings like "5d" to equivalent time in secs.
187 * For eg. 1h = 3600, 10d = 86400
188 */
189 int
commp_time_to_secs(const char * begin,const char * end,uint64_t * num)190 commp_time_to_secs(const char *begin, const char *end, uint64_t *num)
191 {
192 uint_t factor = 0;
193
194 if (!isdigit(*(end - 1))) {
195 switch (*(end - 1)) {
196 case 'd':
197 factor = COMMP_SECS_IN_DAY;
198 break;
199 case 'h':
200 factor = COMMP_SECS_IN_HOUR;
201 break;
202 case 'm':
203 factor = COMMP_SECS_IN_MIN;
204 break;
205 case 's':
206 factor = 1;
207 break;
208 default:
209 return (EINVAL);
210 }
211 --end;
212 }
213 if (commp_strtoull(begin, end, num) != 0)
214 return (EINVAL);
215 if (factor != 0)
216 (*num) = (*num) * factor;
217 return (0);
218 }
219