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