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