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