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 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /*
30 * Helper functions to skip white spaces, find tokens, find separators and free
31 * memory.
32 */
33
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <ctype.h>
38
39 #include "commp_util.h"
40
41
42 /*
43 * Skip to the next non-whitespace
44 */
45 int
commp_skip_white_space(const char ** begin,const char * end)46 commp_skip_white_space(const char **begin, const char *end)
47 {
48 while (*begin < end) {
49 if (!isspace(**begin))
50 return (0);
51 (*begin)++;
52 }
53 return (1);
54 }
55
56 /*
57 * Finds the token in the char buffer. *current will be pointing to the
58 * token when function returns. If the char buffer has leading token,
59 * it returns 1.
60 */
61 int
commp_find_token(const char ** begin,const char ** current,const char * end,char token,boolean_t last)62 commp_find_token(const char **begin, const char **current, const char *end,
63 char token, boolean_t last)
64 {
65 *current = *begin;
66 while (*current < end) {
67 if (!last && (**current == token))
68 break;
69 else if (isspace(**current))
70 return (1);
71 (*current)++;
72 }
73 /* Checks for leading white space */
74 if (*current == *begin)
75 return (1);
76 else
77 return (0);
78 }
79
80 /*
81 * atoi function
82 */
83 int
commp_atoi(const char * begin,const char * end,int * num)84 commp_atoi(const char *begin, const char *end, int *num)
85 {
86 boolean_t num_found = B_FALSE;
87
88 *num = 0;
89 while (begin < end) {
90 if (isdigit(*begin)) {
91 *num = (*num * 10) + (*begin - '0');
92 num_found = B_TRUE;
93 begin++;
94 } else {
95 break;
96 }
97 }
98 if (!num_found || (begin != end))
99 return (EINVAL);
100 return (0);
101 }
102
103 /*
104 * Given a string converts it to unsigned long long int.
105 */
106 int
commp_strtoull(const char * begin,const char * end,uint64_t * num)107 commp_strtoull(const char *begin, const char *end, uint64_t *num)
108 {
109 boolean_t num_found = B_FALSE;
110
111 *num = 0;
112 while (begin < end) {
113 if (isdigit(*begin)) {
114 *num = (*num * 10) + (*begin - '0');
115 num_found = B_TRUE;
116 begin++;
117 } else {
118 break;
119 }
120 }
121 if (!num_found || (begin != end))
122 return (EINVAL);
123 return (0);
124 }
125
126 /*
127 * Given a string converts it to unsigned byte
128 */
129 int
commp_strtoub(const char * begin,const char * end,uint8_t * num)130 commp_strtoub(const char *begin, const char *end, uint8_t *num)
131 {
132 boolean_t num_found = B_FALSE;
133
134 *num = 0;
135 while (begin < end) {
136 if (isdigit(*begin)) {
137 *num = (*num * 10) + (*begin - '0');
138 num_found = B_TRUE;
139 begin++;
140 } else {
141 break;
142 }
143 }
144 if (!num_found || (begin != end))
145 return (EINVAL);
146 return (0);
147 }
148
149 /*
150 * Given a string converts it to unsigned int
151 */
152 int
commp_atoui(const char * begin,const char * end,uint_t * num)153 commp_atoui(const char *begin, const char *end, uint_t *num)
154 {
155 boolean_t num_found = B_FALSE;
156
157 *num = 0;
158 while (begin < end) {
159 if (isdigit(*begin)) {
160 *num = (*num * 10) + (*begin - '0');
161 num_found = B_TRUE;
162 begin++;
163 } else {
164 break;
165 }
166 }
167 if (!num_found || (begin != end))
168 return (EINVAL);
169 return (0);
170 }
171
172 /*
173 * allocates memory and copies string to new memory
174 */
175 int
commp_add_str(char ** dest,const char * src,int len)176 commp_add_str(char **dest, const char *src, int len)
177 {
178 if (len == 0)
179 return (EINVAL);
180 (*dest) = calloc(1, len + 1);
181 if (*dest == NULL)
182 return (ENOMEM);
183 (void) strncpy(*dest, src, len);
184 return (0);
185 }
186
187 /*
188 * This function converts strings like "5d" to equivalent time in secs.
189 * For eg. 1h = 3600, 10d = 86400
190 */
191 int
commp_time_to_secs(const char * begin,const char * end,uint64_t * num)192 commp_time_to_secs(const char *begin, const char *end, uint64_t *num)
193 {
194 uint_t factor = 0;
195
196 if (!isdigit(*(end - 1))) {
197 switch (*(end - 1)) {
198 case 'd':
199 factor = COMMP_SECS_IN_DAY;
200 break;
201 case 'h':
202 factor = COMMP_SECS_IN_HOUR;
203 break;
204 case 'm':
205 factor = COMMP_SECS_IN_MIN;
206 break;
207 case 's':
208 factor = 1;
209 break;
210 default:
211 return (EINVAL);
212 }
213 --end;
214 }
215 if (commp_strtoull(begin, end, num) != 0)
216 return (EINVAL);
217 if (factor != 0)
218 (*num) = (*num) * factor;
219 return (0);
220 }
221