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 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 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 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 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 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 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 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 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