8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libfsmgt / common / fs_dfstab.c
blob970031a6d1035b043142675c836c810c604b4e33
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <sys/types.h>
33 #include <ctype.h>
34 #include <string.h>
35 #include <strings.h>
36 #include <thread.h>
37 #include <synch.h>
38 #include "libfsmgt.h"
41 * Private datastructures.
43 typedef struct dfstab_entry {
44 struct dfstab_entry *next;
45 char *path;
46 char *resource;
47 char *fstype;
48 char *options;
49 char *description;
50 } dfstab_entry_t;
52 static const char *whitespace = " \t";
53 static mutex_t dfstab_lock = DEFAULTMUTEX;
56 * Private functions
58 static dfstab_entry_t *get_dfstab_ents(int *);
59 static void free_dfstab_list(dfstab_entry_t *);
60 static dfstab_entry_t *dfstab_line_to_dfstab_entry(char *, int *);
61 static char *create_share_cmd(dfstab_entry_t *, char *, int *);
62 static dfstab_entry_t *change_dfstab_ent(dfstab_entry_t *,
63 dfstab_entry_t *, int *);
64 static void add_entry_to_dfstab(dfstab_entry_t *, int *);
67 static dfstab_entry_t *
68 get_dfstab_ents(int *err)
70 dfstab_entry_t *dfstablist, *headptr, *tailptr = NULL;
71 FILE *dfp; /* fp for dfs list */
72 static char cmd[BUFSIZE];
73 *err = 0;
75 if ((dfp = fopen(DFSTAB, "r")) != NULL) {
76 char *share_cmd;
77 (void) mutex_lock(&dfstab_lock);
78 while ((share_cmd =
79 fileutil_getline(dfp, cmd, BUFSIZE)) != NULL) {
80 if ((dfstablist =
81 dfstab_line_to_dfstab_entry(share_cmd, err)) !=
82 NULL) {
83 if (tailptr == NULL) {
84 headptr = dfstablist;
85 tailptr = dfstablist;
86 } else {
87 tailptr->next = dfstablist;
88 tailptr = dfstablist;
90 dfstablist = dfstablist->next;
91 } else {
92 free(share_cmd);
93 break;
95 free(share_cmd);
97 if (tailptr == NULL) {
98 headptr = tailptr;
100 (void) mutex_unlock(&dfstab_lock);
101 fclose(dfp);
102 } else {
103 *err = errno;
104 (void) fprintf(stderr, "%s: cannot open %s\n", cmd, DFSTAB);
105 headptr = NULL;
107 return (headptr);
108 } /* get_dfstab_ents */
110 static void
111 add_entry_to_dfstab(dfstab_entry_t *list, int *err)
113 FILE *dfp; /* fp for dfs list */
115 if ((dfp = fopen(DFSTAB, "a")) != NULL) {
116 char *share_cmd;
117 if ((share_cmd = create_share_cmd(list, NULL, err)) != NULL) {
118 (void) mutex_lock(&dfstab_lock);
119 fprintf(dfp, "%s", share_cmd);
120 fclose(dfp);
121 (void) mutex_unlock(&dfstab_lock);
122 free(share_cmd);
123 } else {
124 *err = errno;
126 } else {
127 *err = errno;
130 } /* add_entry_to_dfstab */
132 static void
133 free_dfstab_list(dfstab_entry_t *headp)
135 dfstab_entry_t *tmp = headp;
137 while (headp != NULL) {
138 tmp = headp->next;
139 if (headp->path != NULL) {
140 free(headp->path);
142 if (headp->resource != NULL) {
143 free(headp->resource);
145 if (headp->fstype != NULL) {
146 free(headp->fstype);
148 if (headp->options != NULL) {
149 free(headp->options);
151 if (headp->description != NULL) {
152 free(headp->description);
154 headp->next = NULL;
155 free(headp);
156 headp = tmp;
158 } /* free_dfstab_list */
160 static char *
161 create_share_cmd(dfstab_entry_t *new_entry, char *temp_line, int *err)
163 char tempstr[BUFSIZE];
164 char *cmd, *ret_val;
166 cmd = (char *)calloc((size_t)1, BUFSIZE);
167 if (cmd == NULL) {
168 *err = errno;
169 return (NULL);
171 sprintf(cmd, "share ");
172 if (new_entry->fstype) {
173 sprintf(tempstr, "-F %s ", new_entry->fstype);
174 strlcat(cmd, tempstr, BUFSIZE);
176 if (new_entry->options) {
177 sprintf(tempstr, "-o %s ", new_entry->options);
178 strlcat(cmd, tempstr, BUFSIZE);
180 if (new_entry->description) {
181 sprintf(tempstr, "-d %s ",
182 new_entry->description);
183 strlcat(cmd, tempstr, BUFSIZE);
185 sprintf(tempstr, "%s\n", new_entry->path);
186 strlcat(cmd, tempstr, BUFSIZE);
187 if (temp_line != NULL && strchr(temp_line, '#')) {
188 sprintf(tempstr, " %s", strchr(temp_line, '#'));
189 strlcat(cmd, tempstr, BUFSIZE);
191 ret_val = strdup(cmd);
192 free(cmd);
193 return (ret_val);
194 } /* create_share_cmd */
197 * dfstab_line_to_dfstab_entry - parses a line from dfstab and fills in
198 * the fields of a dfstab_entry_t structure
199 * Parameters:
200 * char *cmd - the share command or dfstab line to be parsed
201 * int *err - a pointer for returning any error codes encountered
203 static dfstab_entry_t *
204 dfstab_line_to_dfstab_entry(char *cmd, int *err)
207 dfstab_entry_t *dfstablist;
208 extern char *optarg;
209 extern int optind;
210 int c, argcount = 0;
211 char *temp_str;
212 char *arglist[LINESZ];
214 c = 0;
215 optind = 1;
217 temp_str = strdup(cmd);
218 if (temp_str == NULL) {
219 *err = ENOMEM;
220 return (NULL);
223 for (arglist[argcount] = strtok(temp_str, whitespace);
224 arglist[argcount] != NULL; /* CSTYLED */) {
225 arglist[++argcount] = strtok(NULL, whitespace);
227 argcount--;
228 dfstablist =
229 (dfstab_entry_t *)calloc((size_t)1,
230 sizeof (dfstab_entry_t));
231 if (dfstablist == NULL) {
232 *err = ENOMEM;
233 free(temp_str);
234 return (NULL);
236 while ((c = getopt(argcount, arglist, "F:d:o:")) != -1) {
237 switch (c) {
238 case 'F':
239 /* file system type */
240 /* at most one -F */
241 *err |= (dfstablist->fstype != NULL);
242 dfstablist->fstype = strdup(optarg);
243 if (dfstablist->fstype == NULL) {
244 *err = ENOMEM;
245 free_dfstab_list(dfstablist);
246 free(temp_str);
247 return (NULL);
249 break;
250 case 'd': /* description */
251 /* at most one -d */
252 *err |= (dfstablist->description != NULL);
253 dfstablist->description = strdup(optarg);
254 if (dfstablist->description == NULL) {
255 *err = ENOMEM;
256 free_dfstab_list(dfstablist);
257 free(temp_str);
258 return (NULL);
260 break;
261 case 'o': /* fs specific options */
262 /* at most one - o */
263 *err |= (dfstablist->options != NULL);
264 dfstablist->options = strdup(optarg);
265 if (dfstablist->options == NULL) {
266 *err = ENOMEM;
267 free_dfstab_list(dfstablist);
268 free(temp_str);
269 return (NULL);
271 break;
272 case '?':
273 *err = 1;
274 break;
277 if (dfstablist->fstype == NULL) {
278 FILE *fp;
280 if ((fp = fopen(DFSTYPES, "r")) == NULL) {
281 (void) fprintf(stderr, "%s: cannot open %s\n",
282 cmd, DFSTYPES);
283 free_dfstab_list(dfstablist);
284 free(temp_str);
285 return (NULL);
287 (void) mutex_lock(&dfstab_lock);
288 dfstablist->fstype = strdup(fileutil_getfs(fp));
289 (void) mutex_unlock(&dfstab_lock);
290 fclose(fp);
292 dfstablist->path = strdup(arglist[argcount]);
293 if (dfstablist->path == NULL) {
294 *err = ENOMEM;
295 free_dfstab_list(dfstablist);
296 free(temp_str);
297 return (NULL);
299 free(temp_str);
300 return (dfstablist);
301 } /* dfstab_line_to_dfstab_entry */
303 static dfstab_entry_t *
304 change_dfstab_ent(
305 dfstab_entry_t *old_entry,
306 dfstab_entry_t *new_entry,
307 int *err)
310 FILE *fp;
311 dfstab_entry_t *temp_list, *ret_val;
312 char cmd[BUFSIZE];
313 char **temp_dfstab = NULL;
314 int line_found = 0;
316 if ((fp = fopen(DFSTAB, "r")) != NULL) {
317 char *share_cmd;
318 int count = 0;
319 (void) mutex_lock(&dfstab_lock);
320 while (fgets(cmd, BUFSIZE, fp) != NULL) {
321 if ((share_cmd =
322 fileutil_get_cmd_from_string(cmd)) == NULL) {
323 if (!fileutil_add_string_to_array(
324 &temp_dfstab, cmd, &count, err)) {
325 ret_val = NULL;
326 line_found = 0;
327 break;
329 continue;
331 if ((temp_list =
332 dfstab_line_to_dfstab_entry(share_cmd, err)) ==
333 NULL) {
334 free(share_cmd);
335 ret_val = NULL;
336 break;
338 if (strcmp(old_entry->path,
339 temp_list->path) == 0) {
340 char *new_cmd = NULL;
341 line_found = 1;
342 if (new_entry != NULL && (new_cmd =
343 create_share_cmd(new_entry, cmd,
344 err)) != NULL) {
345 if (!fileutil_add_string_to_array(
346 &temp_dfstab, new_cmd, &count,
347 err)) {
348 ret_val = NULL;
349 line_found = 0;
350 free(share_cmd);
351 free(new_cmd);
352 break;
354 free(new_cmd);
356 } else {
357 if (!fileutil_add_string_to_array(
358 &temp_dfstab, cmd, &count, err)) {
359 free(share_cmd);
360 ret_val = NULL;
361 line_found = 0;
362 break;
365 free_dfstab_list(temp_list);
366 free(share_cmd);
368 fclose(fp);
370 if (line_found && temp_dfstab != NULL) {
371 if ((fp = fopen(DFSTAB, "w")) != NULL) {
372 int i;
373 for (i = 0; i < count; i++) {
374 fprintf(fp, "%s", temp_dfstab[i]);
376 fclose(fp);
377 (void) mutex_unlock(&dfstab_lock);
378 ret_val = get_dfstab_ents(err);
379 fileutil_free_string_array(temp_dfstab, count);
380 } else {
381 *err = errno;
382 (void) mutex_unlock(&dfstab_lock);
383 fileutil_free_string_array(temp_dfstab, count);
384 ret_val = NULL;
386 } else {
387 (void) mutex_unlock(&dfstab_lock);
388 if (temp_dfstab != NULL) {
389 fileutil_free_string_array(temp_dfstab, count);
391 ret_val = NULL;
393 } else {
394 *err = errno;
395 ret_val = NULL;
397 return (ret_val);
398 } /* change_dfstab_ent */
401 * Public accessor functions.
405 * fs_add_DFStab_ent - adds an entry to dfstab and to the list of dfstab
406 * entries. Returns a pointer to the head of the dfstab entry list.
407 * Parameters:
408 * char *cmd - the same command to be added to dstab
409 * int *err - an error pointer for retruning any errors
411 fs_dfstab_entry_t
412 fs_add_DFStab_ent(char *cmd, int *err)
414 dfstab_entry_t *dfstab_ent;
416 dfstab_ent = dfstab_line_to_dfstab_entry(cmd, err);
417 if (dfstab_ent == NULL) {
418 *err = errno;
419 return (NULL);
421 add_entry_to_dfstab(dfstab_ent, err);
422 if (*err != 0) {
423 free_dfstab_list(dfstab_ent);
424 return (NULL);
426 free_dfstab_list(dfstab_ent);
427 return (get_dfstab_ents(err));
431 * set_DFStab_ent - adds an entry to dfstab and to the list of dfstab entries.
432 * returns a pointer to the head of the dfstab entry list.
434 fs_dfstab_entry_t
435 fs_set_DFStab_ent(
436 char *path,
437 char *fstype,
438 char *options,
439 char *description,
440 int *err)
443 dfstab_entry_t *new_entry;
444 new_entry = (dfstab_entry_t *)calloc((size_t)1,
445 sizeof (dfstab_entry_t));
446 if (new_entry == NULL) {
447 *err = ENOMEM;
448 return (NULL);
450 if (path != NULL) {
451 new_entry->path = strdup(path);
452 } else {
453 *err = EINVAL;
454 free_dfstab_list(new_entry);
455 return (NULL);
457 if (fstype != NULL) {
458 new_entry->fstype = strdup(fstype);
459 } else {
460 FILE *fp;
462 if ((fp = fopen(DFSTYPES, "r")) == NULL) {
463 /* change this to error handler */
464 (void) fprintf(stderr, "cannot open %s\n",
465 DFSTYPES);
466 free_dfstab_list(new_entry);
467 return (NULL);
469 (void) mutex_lock(&dfstab_lock);
470 new_entry->fstype = strdup(fileutil_getfs(fp));
471 (void) mutex_unlock(&dfstab_lock);
472 fclose(fp);
474 if (options != NULL) {
475 new_entry->options = strdup(options);
477 if (description != NULL) {
478 new_entry->description = strdup(description);
480 add_entry_to_dfstab(new_entry, err);
481 if (*err != 0) {
482 free_dfstab_list(new_entry);
483 return (NULL);
485 free_dfstab_list(new_entry);
486 return (get_dfstab_ents(err));
487 } /* set_DFStab_ent */
490 * Accessor function for path element of dfstab entry.
492 char *
493 fs_get_DFStab_ent_Path(void *entry)
495 dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
496 if (entryptr == NULL) {
497 return (NULL);
499 return (entryptr->path);
500 } /* get_DFStab_ent_Path */
503 * Accessor function for fstype element of dfstab entry.
505 char *
506 fs_get_DFStab_ent_Fstype(void *entry)
508 dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
509 if (entryptr == NULL) {
510 return (NULL);
512 return (entryptr->fstype);
516 * Accessor function for options element of dfstab entry.
518 char *
519 fs_get_DFStab_ent_Options(void *entry)
521 dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
522 if (entryptr == NULL) {
523 return (NULL);
525 return (entryptr->options);
529 * Accessor function for description element of dfstab entry.
531 char *
532 fs_get_DFStab_ent_Desc(void *entry)
534 dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
535 if (entryptr == NULL) {
536 return (NULL);
538 return (entryptr->description);
542 * Accessor function for resource element of dfstab entry.
544 char *
545 fs_get_DFStab_ent_Res(void *entry)
547 dfstab_entry_t *entryptr = (dfstab_entry_t *)entry;
548 if (entryptr == NULL) {
549 return (NULL);
551 return (entryptr->resource);
556 * Calls get_dfstab_ents to create the list of dfstab
557 * entries and returns that list.
559 fs_dfstab_entry_t
560 fs_get_DFStab_ents(int *err)
562 dfstab_entry_t *list;
563 list = get_dfstab_ents(err);
564 return (list);
568 * Retrives and returns the next entry in the list.
570 fs_dfstab_entry_t
571 fs_get_DFStab_ent_Next(void *list)
573 dfstab_entry_t *listptr = (dfstab_entry_t *)list;
574 if (listptr == NULL) {
575 return (NULL);
577 return (listptr->next);
581 * Retrives and returns a share command based on the dfstab entry passed in.
583 char *
584 fs_get_Dfstab_share_cmd(fs_dfstab_entry_t dfstab_ent, int *err)
586 char *share_cmd;
587 if (dfstab_ent == NULL) {
588 return (NULL);
590 share_cmd = create_share_cmd((dfstab_entry_t *)dfstab_ent, NULL, err);
591 return (share_cmd);
592 } /* fs_get_Dfstab_share_cmd */
595 * edit_DFStab_ent - changes an entry in dfstab.
597 fs_dfstab_entry_t
598 fs_edit_DFStab_ent(char *old_cmd, char *new_cmd, int *err)
600 dfstab_entry_t *old_dfstabent, *new_dfstabent, *ret_val;
602 if ((old_dfstabent =
603 dfstab_line_to_dfstab_entry(old_cmd, err)) == NULL) {
604 return (NULL);
606 if ((new_dfstabent =
607 dfstab_line_to_dfstab_entry(new_cmd, err)) == NULL) {
608 return (NULL);
610 if ((ret_val =
611 change_dfstab_ent(old_dfstabent, new_dfstabent, err)) == NULL) {
612 return (NULL);
614 free_dfstab_list(old_dfstabent);
615 free_dfstab_list(new_dfstabent);
616 return (ret_val);
620 * del_DFStab_ent - deletes an entry in dfstab.
622 fs_dfstab_entry_t
623 fs_del_DFStab_ent(char *del_cmd, int *err)
625 dfstab_entry_t *del_dfstabent, *ret_val;
627 if ((del_dfstabent =
628 dfstab_line_to_dfstab_entry(del_cmd, err)) == NULL) {
629 return (NULL);
631 if ((ret_val =
632 change_dfstab_ent(del_dfstabent, NULL, err)) == NULL) {
633 return (NULL);
635 free_dfstab_list(del_dfstabent);
636 return (ret_val);
640 * del_All_DFStab_ents_with_Path - deletes all duplicate entries with
641 * the specified path.
643 fs_dfstab_entry_t
644 fs_del_All_DFStab_ents_with_Path(char *path, int *err)
646 dfstab_entry_t del_dfstabent, *ret_val;
648 if (path != NULL) {
649 if ((del_dfstabent.path = strdup(path)) != NULL) {
650 if ((ret_val = change_dfstab_ent(&del_dfstabent,
651 NULL, err)) == NULL) {
652 ret_val = NULL;
654 free(del_dfstabent.path);
655 } else {
656 *err = ENOMEM;
657 ret_val = NULL;
659 } else {
660 *err = EINVAL;
661 ret_val = NULL;
663 return (ret_val);
668 fs_check_for_duplicate_DFStab_paths(char *path, int *err)
670 dfstab_entry_t *dfstablist;
671 int count = 0;
673 *err = 0;
674 if (path == NULL) {
675 count = -1;
677 dfstablist = get_dfstab_ents(err);
678 if (dfstablist != NULL) {
679 while (dfstablist != NULL) {
680 if (strcmp(dfstablist->path, path) == 0) {
681 count++;
683 dfstablist = dfstablist->next;
686 free_dfstab_list(dfstablist);
687 } else {
688 if (err != 0)
689 count = *err;
690 else
691 count = 0;
693 return (count);
696 void
697 fs_free_DFStab_ents(void *list)
699 dfstab_entry_t *headp = (dfstab_entry_t *)list;
700 free_dfstab_list(headp);
704 * used for debugging only
706 void
707 fs_print_dfstab_entries(void *list)
709 while (list != NULL) {
711 if (fs_get_DFStab_ent_Fstype(list) != NULL)
712 printf("fstype: %s", fs_get_DFStab_ent_Fstype(list));
713 if (fs_get_DFStab_ent_Desc(list) != NULL)
714 printf(" description: %s",
715 fs_get_DFStab_ent_Desc(list));
716 if (fs_get_DFStab_ent_Options(list) != NULL)
717 printf(" options: %s",
718 fs_get_DFStab_ent_Options(list));
719 if (fs_get_DFStab_ent_Path(list) != NULL)
720 printf(" shared path is: %s\n",
721 fs_get_DFStab_ent_Path(list));
722 list = (void *)fs_get_DFStab_ent_Next(list);