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