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 /* 28 * Helper functions to skip white spaces, find tokens, find separators and free 29 * memory. 30 */ 31 32 #include <errno.h> 33 #include <stdlib.h> 34 #include <string.h> 35 #include <ctype.h> 36 37 #include "commp_util.h" 38 39 40 /* 41 * Skip to the next non-whitespace 42 */ 43 int 44 commp_skip_white_space(const char **begin, const char *end) 45 { 46 while (*begin < end) { 47 if (!isspace(**begin)) 48 return (0); 49 (*begin)++; 50 } 51 return (1); 52 } 53 54 /* 55 * Finds the token in the char buffer. *current will be pointing to the 56 * token when function returns. If the char buffer has leading token, 57 * it returns 1. 58 */ 59 int 60 commp_find_token(const char **begin, const char **current, const char *end, 61 char token, boolean_t last) 62 { 63 *current = *begin; 64 while (*current < end) { 65 if (!last && (**current == token)) 66 break; 67 else if (isspace(**current)) 68 return (1); 69 (*current)++; 70 } 71 /* Checks for leading white space */ 72 if (*current == *begin) 73 return (1); 74 else 75 return (0); 76 } 77 78 /* 79 * atoi function 80 */ 81 int 82 commp_atoi(const char *begin, const char *end, int *num) 83 { 84 boolean_t num_found = B_FALSE; 85 86 *num = 0; 87 while (begin < end) { 88 if (isdigit(*begin)) { 89 *num = (*num * 10) + (*begin - '0'); 90 num_found = B_TRUE; 91 begin++; 92 } else { 93 break; 94 } 95 } 96 if (!num_found || (begin != end)) 97 return (EINVAL); 98 return (0); 99 } 100 101 /* 102 * Given a string converts it to unsigned long long int. 103 */ 104 int 105 commp_strtoull(const char *begin, const char *end, uint64_t *num) 106 { 107 boolean_t num_found = B_FALSE; 108 109 *num = 0; 110 while (begin < end) { 111 if (isdigit(*begin)) { 112 *num = (*num * 10) + (*begin - '0'); 113 num_found = B_TRUE; 114 begin++; 115 } else { 116 break; 117 } 118 } 119 if (!num_found || (begin != end)) 120 return (EINVAL); 121 return (0); 122 } 123 124 /* 125 * Given a string converts it to unsigned byte 126 */ 127 int 128 commp_strtoub(const char *begin, const char *end, uint8_t *num) 129 { 130 boolean_t num_found = B_FALSE; 131 132 *num = 0; 133 while (begin < end) { 134 if (isdigit(*begin)) { 135 *num = (*num * 10) + (*begin - '0'); 136 num_found = B_TRUE; 137 begin++; 138 } else { 139 break; 140 } 141 } 142 if (!num_found || (begin != end)) 143 return (EINVAL); 144 return (0); 145 } 146 147 /* 148 * Given a string converts it to unsigned int 149 */ 150 int 151 commp_atoui(const char *begin, const char *end, uint_t *num) 152 { 153 boolean_t num_found = B_FALSE; 154 155 *num = 0; 156 while (begin < end) { 157 if (isdigit(*begin)) { 158 *num = (*num * 10) + (*begin - '0'); 159 num_found = B_TRUE; 160 begin++; 161 } else { 162 break; 163 } 164 } 165 if (!num_found || (begin != end)) 166 return (EINVAL); 167 return (0); 168 } 169 170 /* 171 * allocates memory and copies string to new memory 172 */ 173 int 174 commp_add_str(char **dest, const char *src, int len) 175 { 176 if (len == 0) 177 return (EINVAL); 178 (*dest) = calloc(1, len + 1); 179 if (*dest == NULL) 180 return (ENOMEM); 181 (void) strncpy(*dest, src, len); 182 return (0); 183 } 184 185 /* 186 * This function converts strings like "5d" to equivalent time in secs. 187 * For eg. 1h = 3600, 10d = 86400 188 */ 189 int 190 commp_time_to_secs(const char *begin, const char *end, uint64_t *num) 191 { 192 uint_t factor = 0; 193 194 if (!isdigit(*(end - 1))) { 195 switch (*(end - 1)) { 196 case 'd': 197 factor = COMMP_SECS_IN_DAY; 198 break; 199 case 'h': 200 factor = COMMP_SECS_IN_HOUR; 201 break; 202 case 'm': 203 factor = COMMP_SECS_IN_MIN; 204 break; 205 case 's': 206 factor = 1; 207 break; 208 default: 209 return (EINVAL); 210 } 211 --end; 212 } 213 if (commp_strtoull(begin, end, num) != 0) 214 return (EINVAL); 215 if (factor != 0) 216 (*num) = (*num) * factor; 217 return (0); 218 } 219