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