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