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
fileutil_free_string_array(char ** arrayp,int num_elements)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 **
fileutil_get_first_column_data(FILE * fp,int * num_elements,int * errp)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 *
fileutil_getfs(FILE * fp)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 *
fileutil_getline(FILE * fp,char * line,int linesz)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 *
fileutil_get_cmd_from_string(char * input_stringp)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
fileutil_add_string_to_array(char *** string_array,char * line,int * count,int * err)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 *
get_first_column_data(char * line)238 get_first_column_data(char *line)
239 {
240 return (strtok(line, "\t "));
241 } /* get_first_column_data */
242
243 static char *
retrieve_string(FILE * fp,char * line,int buffersize)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 *
trim_trailing_whitespace(char * input_string)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