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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <strings.h> 31 #include <errno.h> 32 #include <sys/types.h> 33 #include <ctype.h> 34 #include <thread.h> 35 #include <synch.h> 36 #include "libfsmgt.h" 37 38 /* 39 * Private method declarations 40 */ 41 static char *get_first_column_data(char *line); 42 static char *retrieve_string(FILE *fp, char *line, int buffersize); 43 static char *trim_trailing_whitespace(char *line); 44 45 /* 46 * Public methods 47 */ 48 49 void 50 fileutil_free_string_array(char **arrayp, int num_elements) 51 { 52 if (arrayp != NULL) { 53 int i = 0; 54 55 for (i = 0; i < num_elements && arrayp[i] != NULL; i++) { 56 free(arrayp[i]); 57 } 58 59 free(arrayp); 60 } 61 } /* fileutil_free_string_array */ 62 63 char ** 64 fileutil_get_first_column_data(FILE *fp, int *num_elements, int *errp) 65 { 66 char line[BUFSIZE]; 67 char *returned_string; 68 char **return_array = NULL; 69 70 *errp = 0; 71 *num_elements = 0; 72 73 while ((returned_string = 74 retrieve_string(fp, line, BUFSIZE)) != NULL) { 75 76 char **tmp_array; 77 78 tmp_array = realloc(return_array, 79 (size_t)(((*num_elements) + 1) * sizeof (char *))); 80 if (tmp_array == NULL) { 81 *errp = errno; 82 fileutil_free_string_array(return_array, *num_elements); 83 *num_elements = 0; 84 return (NULL); 85 } 86 return_array = tmp_array; 87 88 return_array[(*num_elements)] = strdup(returned_string); 89 if (return_array[(*num_elements)] == NULL) { 90 *errp = ENOMEM; 91 fileutil_free_string_array(return_array, *num_elements); 92 free(returned_string); 93 *num_elements = 0; 94 return (NULL); 95 } 96 97 free(returned_string); 98 *num_elements = *num_elements + 1; 99 } 100 101 /* 102 * Caller must free the space allocated to return_array by calling 103 * fileutil_free_string_array. 104 */ 105 return (return_array); 106 } /* fileutil_get_first_column_data */ 107 108 /* 109 * Convenience function for retrieving the default fstype from /etc/fstypes. 110 */ 111 char * 112 fileutil_getfs(FILE *fp) 113 { 114 char *s; 115 static char buff[BUFSIZE]; /* line buffer */ 116 117 while (s = fgets(buff, BUFSIZE, fp)) { 118 while (isspace(*s) || *s != '\0') /* skip leading whitespace */ 119 ++s; 120 if (*s != '#') { /* not a comment */ 121 char *t = s; 122 while (!isspace(*t) && *t != '\0') /* get the token */ 123 ++t; 124 *t = '\0'; /* ignore rest of line */ 125 return (s); 126 } 127 } 128 return (NULL); /* that's all, folks! */ 129 } /* fileutil_getfs */ 130 131 char * 132 fileutil_getline(FILE *fp, char *line, int linesz) 133 { 134 char *share_cmd, *p = line; 135 *p = '\0'; 136 137 while (fgets(line, linesz, fp) != NULL) { 138 share_cmd = fileutil_get_cmd_from_string(line); 139 if (share_cmd != NULL) 140 return (share_cmd); 141 } 142 return (NULL); 143 } /* fileutil_getline */ 144 145 /* 146 * fileutil_get_cmd_from_string - retieves the command string minus any 147 * comments from the original string. 148 * 149 * Parameters: 150 * char *input_string - the original string. 151 */ 152 char * 153 fileutil_get_cmd_from_string(char *input_stringp) 154 { 155 /* 156 * Comments begin with '#'. Strip them off. 157 */ 158 159 char *returned_stringp; 160 char *start_of_commentp; 161 char *current_string; 162 163 if ((input_stringp == NULL) || (strlen(input_stringp) == 0)) { 164 return (NULL); 165 } 166 167 current_string = strdup(input_stringp); 168 169 if (current_string == NULL) { 170 return (NULL); 171 } 172 173 start_of_commentp = strchr(current_string, '#'); 174 if (start_of_commentp != NULL) { 175 *start_of_commentp = '\0'; 176 } 177 178 returned_stringp = trim_trailing_whitespace(current_string); 179 free(current_string); 180 return (returned_stringp); 181 } 182 183 /* 184 * NOTE: the caller of this function is responsible for freeing any 185 * memory allocated by calling fileutil_free_string_array() 186 * 187 * fileutil_add_string_to_array - adds one line to the file image 188 * string array 189 * Parameters: 190 * char ***string_array - reference to the string array 191 * char *line - the line to be added to the temporary dfstab 192 * int *count - the number of elements in the string array 193 * int *err - error pointer for returning any errors encountered 194 * 195 * Returns: 196 * B_TRUE on success, B_FALSE on failure. 197 */ 198 boolean_t 199 fileutil_add_string_to_array(char ***string_array, char *line, int *count, 200 int *err) 201 { 202 int i; 203 char **ret_val = NULL; 204 char **temp_array = NULL; 205 206 temp_array = *string_array; 207 208 ret_val = calloc(((*count) + 1), sizeof (char *)); 209 if (ret_val != NULL) { 210 for (i = 0; i < *count; i ++) { 211 ret_val[i] = temp_array[i]; 212 } 213 ret_val[*count] = strdup(line); 214 if (ret_val[*count] != NULL) { 215 (*count)++; 216 if (temp_array != NULL) { 217 free(temp_array); 218 } 219 *string_array = ret_val; 220 } else { 221 *err = ENOMEM; 222 free(ret_val); 223 return (B_FALSE); 224 } 225 } else { 226 *err = ENOMEM; 227 return (B_FALSE); 228 } 229 return (B_TRUE); 230 } /* fileutil_add_string_to_array */ 231 232 /* 233 * Private methods 234 */ 235 static char * 236 get_first_column_data(char *line) 237 { 238 return (strtok(line, "\t ")); 239 } /* get_first_column_data */ 240 241 static char * 242 retrieve_string(FILE *fp, char *line, int buffersize) 243 { 244 char *data; 245 char *returned_string; 246 247 while ((returned_string = 248 fileutil_getline(fp, line, buffersize)) != NULL) { 249 250 data = get_first_column_data(returned_string); 251 if (data != NULL) 252 return (data); 253 } 254 255 return (NULL); 256 } /* retrieve_string */ 257 258 /* 259 * trim_trailing_whitespace - helper function to remove trailing 260 * whitespace from a line 261 * 262 * Parameters: 263 * char *input_stringp - the line to be trimed 264 */ 265 static char * 266 trim_trailing_whitespace(char *input_string) 267 { 268 char *last_nonspace; 269 char *return_string; 270 int string_length; 271 272 273 if (input_string == NULL) { 274 return (NULL); 275 } 276 string_length = strlen(input_string); 277 278 if (string_length == 0 || *input_string == '\n') { 279 return (NULL); 280 } 281 282 return_string = strdup(input_string); 283 if (return_string == NULL) { 284 return (NULL); 285 } 286 287 /* 288 * Truncates the last character which will always be '\0' 289 */ 290 last_nonspace = return_string + (string_length - 1); 291 292 while (isspace(*last_nonspace)) { 293 last_nonspace--; 294 } 295 *(last_nonspace + 1) = '\0'; 296 return (return_string); 297 } 298