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
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]
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Traverses /etc/vfstab in order to find default mount information about
31 * file systems on the current host.
36 #include <sys/vfstab.h>
37 #include <sys/types.h>
47 static const char sepstr
[] = "\t\n";
52 static mutex_t vfstab_lock
= DEFAULTMUTEX
;
56 * Private method declarations
58 static int cmp_fields(char *, char *, int);
59 static fs_mntdefaults_t
*create_mntdefaults_entry(struct vfstab vfstab_entry
,
61 static struct vfstab
*create_vfstab_filter(fs_mntdefaults_t
*filter
,
63 static void free_vfstab_entry(struct vfstab
*vfstab_entry
);
64 static char *create_vfstab_entry_line(struct vfstab
*, int *);
65 static int vfstab_line_cmp(fs_mntdefaults_t
*, struct vfstab
*);
71 void fs_free_mntdefaults_list(fs_mntdefaults_t
*headp
) {
72 fs_mntdefaults_t
*tmp
;
74 while (headp
!= NULL
) {
76 free(headp
->resource
);
77 free(headp
->fsckdevice
);
80 free(headp
->fsckpass
);
81 free(headp
->mountatboot
);
88 } /* fs_free_mntdefaults_list */
91 * Filter by the fields that are filled in on the filter parameter.
92 * Fields that aren't used in filtering the defaults will be NULL.
94 fs_mntdefaults_t
*fs_get_filtered_mount_defaults(fs_mntdefaults_t
*filter
,
97 fs_mntdefaults_t
*newp
;
98 fs_mntdefaults_t
*headp
;
99 fs_mntdefaults_t
*tailp
;
106 if ((fp
= fopen(VFSTAB
, "r")) != NULL
) {
107 struct vfstab vfstab_entry
;
108 struct vfstab
*search_entry
;
109 (void) mutex_lock(&vfstab_lock
);
110 search_entry
= create_vfstab_filter(filter
, errp
);
111 if (search_entry
== NULL
) {
113 * Out of memory, the error pointer (errp) gets
114 * set in create_vfstab_filter.
116 fs_free_mntdefaults_list(headp
);
117 (void) mutex_unlock(&vfstab_lock
);
122 while (getvfsany(fp
, &vfstab_entry
, search_entry
) == 0) {
124 * Add to list to be returned
126 newp
= create_mntdefaults_entry(vfstab_entry
, errp
);
129 * Out of memory, the error pointer (errp)
130 * gets set in create_mntdefaults_entry.
132 fs_free_mntdefaults_list(headp
);
133 (void) mutex_unlock(&vfstab_lock
);
146 free_vfstab_entry(search_entry
);
147 (void) mutex_unlock(&vfstab_lock
);
152 } /* if ((fp = fopen(VFSTAB, "r")) != NULL) */
155 } /* fs_get_filtered_mount_defaults */
159 fs_get_mount_defaults(int *errp
)
161 fs_mntdefaults_t
*newp
;
162 fs_mntdefaults_t
*headp
;
163 fs_mntdefaults_t
*tailp
;
169 if ((fp
= fopen(VFSTAB
, "r")) != NULL
) {
170 struct vfstab vfstab_entry
;
171 (void) mutex_lock(&vfstab_lock
);
172 while (getvfsent(fp
, &vfstab_entry
) == 0) {
176 newp
= create_mntdefaults_entry(vfstab_entry
, errp
);
180 * Out of memory, the error pointer (errp)
181 * gets set in create_mntdefaults_entry.
184 (void) mutex_unlock(&vfstab_lock
);
185 fs_free_mntdefaults_list(headp
);
198 (void) mutex_unlock(&vfstab_lock
);
201 } /* if ((fp = fopen(VFSTAB, "r")) != NULL) */
204 * Caller must free the returned list
208 } /* fs_get_mount_defaults */
211 fs_add_mount_default(fs_mntdefaults_t
*newp
, int *errp
) {
214 struct vfstab
*new_entry
;
215 fs_mntdefaults_t
*ret_val
;
217 new_entry
= create_vfstab_filter(newp
, errp
);
218 if (new_entry
!= NULL
) {
219 if ((fp
= fopen(VFSTAB
, "a")) != NULL
) {
220 (void) mutex_lock(&vfstab_lock
);
221 putvfsent(fp
, new_entry
);
222 free_vfstab_entry(new_entry
);
224 (void) mutex_unlock(&vfstab_lock
);
225 ret_val
= fs_get_mount_defaults(errp
);
228 free_vfstab_entry(new_entry
);
235 } /* fs_add_mount_default */
239 fs_edit_mount_defaults(
240 fs_mntdefaults_t
*old_vfstab_ent
,
241 fs_mntdefaults_t
*new_vfstab_ent
,
245 fs_mntdefaults_t
*ret_val
;
246 char vfstab_line
[VFS_LINE_MAX
];
247 char **temp_vfstab
= NULL
;
249 struct vfstab vfstabp
, *new_vfstab
;
252 if ((fp
= fopen(VFSTAB
, "r")) != NULL
) {
255 (void) mutex_lock(&vfstab_lock
);
256 while (fgets(vfstab_line
, VFS_LINE_MAX
, fp
) != NULL
) {
259 char *orig_line
= strdup(vfstab_line
);
260 if (orig_line
== NULL
) {
263 (void) mutex_unlock(&vfstab_lock
);
267 for (charp
= vfstab_line
;
268 *charp
== ' ' || *charp
== '\t'; charp
++);
269 if (*charp
== '#' || *charp
== '\n') {
271 * Write comments out to temp vfstab
274 if (!fileutil_add_string_to_array(
275 &temp_vfstab
, vfstab_line
, &count
, errp
)) {
282 vp
->vfs_special
= (char *)strtok_r(
283 vfstab_line
, sepstr
, &tmp
);
284 vp
->vfs_fsckdev
= (char *)strtok_r(
286 vp
->vfs_mountp
= (char *)strtok_r(
288 vp
->vfs_fstype
= (char *)strtok_r(
290 vp
->vfs_fsckpass
= (char *)strtok_r(
292 vp
->vfs_automnt
= (char *)strtok_r(
294 vp
->vfs_mntopts
= (char *)strtok_r(
296 if (strtok_r(NULL
, sepstr
, &tmp
) != NULL
) {
298 * Invalid vfstab line.
301 (void) mutex_unlock(&vfstab_lock
);
306 if (vfstab_line_cmp(old_vfstab_ent
, vp
)) {
309 create_vfstab_filter(
310 new_vfstab_ent
, errp
);
312 create_vfstab_entry_line(new_vfstab
, errp
);
313 if (!fileutil_add_string_to_array(
314 &temp_vfstab
, new_line
, &count
, errp
)) {
322 if (!fileutil_add_string_to_array(
323 &temp_vfstab
, orig_line
, &count
, errp
)) {
333 if (line_found
&& temp_vfstab
!= NULL
) {
334 if ((fp
= fopen(VFSTAB
, "w")) != NULL
) {
336 for (i
= 0; i
< count
; i
++) {
337 fprintf(fp
, "%s", temp_vfstab
[i
]);
340 (void) mutex_unlock(&vfstab_lock
);
341 ret_val
= fs_get_mount_defaults(errp
);
342 fileutil_free_string_array(temp_vfstab
, count
);
345 (void) mutex_unlock(&vfstab_lock
);
350 (void) mutex_unlock(&vfstab_lock
);
358 } /* fs_edit_mount_defaults */
361 fs_del_mount_default_ent(fs_mntdefaults_t
*old_vfstab_ent
, int *errp
)
364 fs_mntdefaults_t
*ret_val
;
365 char vfstab_line
[VFS_LINE_MAX
];
366 struct vfstab vfstabp
;
369 if ((fp
= fopen(VFSTAB
, "r")) != NULL
) {
373 char *orig_line
= NULL
;
374 char **temp_vfstab
= NULL
;
377 (void) mutex_lock(&vfstab_lock
);
378 while (fgets(vfstab_line
, VFS_LINE_MAX
, fp
) != NULL
) {
380 orig_line
= strdup(vfstab_line
);
381 if (orig_line
== NULL
) {
384 (void) mutex_unlock(&vfstab_lock
);
388 for (charp
= vfstab_line
;
389 *charp
== ' ' || *charp
== '\t'; charp
++);
391 if (*charp
== '#' || *charp
== '\n') {
393 * Write comments out to temp vfstab
396 if (!fileutil_add_string_to_array(
397 &temp_vfstab
, vfstab_line
, &count
, errp
)) {
406 vp
->vfs_special
= (char *)strtok_r(
407 vfstab_line
, sepstr
, &tmp
);
408 vp
->vfs_fsckdev
= (char *)strtok_r(
410 vp
->vfs_mountp
= (char *)strtok_r(
412 vp
->vfs_fstype
= (char *)strtok_r(
414 vp
->vfs_fsckpass
= (char *)strtok_r(
416 vp
->vfs_automnt
= (char *)strtok_r(
418 vp
->vfs_mntopts
= (char *)strtok_r(
421 if (strtok_r(NULL
, sepstr
, &tmp
) != NULL
) {
423 * Invalid vfstab line.
428 (void) mutex_unlock(&vfstab_lock
);
432 if (vfstab_line_cmp(old_vfstab_ent
, vp
)) {
435 if (!fileutil_add_string_to_array(
436 &temp_vfstab
, orig_line
, &count
, errp
)) {
448 if (line_found
&& temp_vfstab
!= NULL
) {
449 if ((fp
= fopen(VFSTAB
, "w")) != NULL
) {
451 for (i
= 0; i
< count
; i
++) {
452 fprintf(fp
, "%s", temp_vfstab
[i
]);
455 (void) mutex_unlock(&vfstab_lock
);
456 ret_val
= fs_get_mount_defaults(errp
);
457 fileutil_free_string_array(temp_vfstab
, count
);
460 (void) mutex_unlock(&vfstab_lock
);
461 fileutil_free_string_array(temp_vfstab
, count
);
465 (void) mutex_unlock(&vfstab_lock
);
466 if (temp_vfstab
!= NULL
) {
467 fileutil_free_string_array(temp_vfstab
, count
);
482 static fs_mntdefaults_t
*
483 create_mntdefaults_entry(struct vfstab vfstab_entry
, int *errp
) {
484 fs_mntdefaults_t
*newp
;
486 newp
= (fs_mntdefaults_t
*)calloc((size_t)1,
487 (size_t)sizeof (fs_mntdefaults_t
));
498 if (vfstab_entry
.vfs_special
!= NULL
) {
499 newp
->resource
= strdup(vfstab_entry
.vfs_special
);
500 if (newp
->resource
== NULL
) {
505 fs_free_mntdefaults_list(newp
);
511 if (vfstab_entry
.vfs_fsckdev
!= NULL
) {
512 newp
->fsckdevice
= strdup(vfstab_entry
.vfs_fsckdev
);
513 if (newp
->fsckdevice
== NULL
) {
518 fs_free_mntdefaults_list(newp
);
523 if (vfstab_entry
.vfs_mountp
!= NULL
) {
524 newp
->mountp
= strdup(vfstab_entry
.vfs_mountp
);
525 if (newp
->mountp
== NULL
) {
530 fs_free_mntdefaults_list(newp
);
535 if (vfstab_entry
.vfs_fstype
!= NULL
) {
536 newp
->fstype
= strdup(vfstab_entry
.vfs_fstype
);
537 if (newp
->fstype
== NULL
) {
542 fs_free_mntdefaults_list(newp
);
547 if (vfstab_entry
.vfs_fsckpass
!= NULL
) {
548 newp
->fsckpass
= strdup(vfstab_entry
.vfs_fsckpass
);
549 if (newp
->fsckpass
== NULL
) {
554 fs_free_mntdefaults_list(newp
);
559 if (vfstab_entry
.vfs_automnt
!= NULL
) {
560 newp
->mountatboot
= strdup(vfstab_entry
.vfs_automnt
);
561 if (newp
->mountatboot
== NULL
) {
566 fs_free_mntdefaults_list(newp
);
571 if (vfstab_entry
.vfs_mntopts
!= NULL
) {
572 newp
->mntopts
= strdup(vfstab_entry
.vfs_mntopts
);
573 if (newp
->mntopts
== NULL
) {
578 fs_free_mntdefaults_list(newp
);
586 } /* create_mntdefaults_entry */
588 static struct vfstab
*
589 create_vfstab_filter(fs_mntdefaults_t
*filter
, int *errp
) {
590 struct vfstab
*search_entry
;
592 search_entry
= (struct vfstab
*)calloc((size_t)1,
593 (size_t)sizeof (struct vfstab
));
594 if (search_entry
== NULL
) {
603 * Populate the filter criteria
605 if (filter
->resource
!= NULL
) {
606 search_entry
->vfs_special
= strdup(filter
->resource
);
607 if (search_entry
->vfs_special
== NULL
) {
612 free_vfstab_entry(search_entry
);
618 if (filter
->fsckdevice
!= NULL
) {
619 search_entry
->vfs_fsckdev
= strdup(filter
->fsckdevice
);
620 if (search_entry
->vfs_fsckdev
== NULL
) {
625 free_vfstab_entry(search_entry
);
630 if (filter
->mountp
!= NULL
) {
631 search_entry
->vfs_mountp
= strdup(filter
->mountp
);
632 if (search_entry
->vfs_mountp
== NULL
) {
637 free_vfstab_entry(search_entry
);
642 if (filter
->fstype
!= NULL
) {
643 search_entry
->vfs_fstype
= strdup(filter
->fstype
);
644 if (search_entry
->vfs_fstype
== NULL
) {
649 free_vfstab_entry(search_entry
);
654 if (filter
->fsckpass
!= NULL
) {
655 search_entry
->vfs_fsckpass
= strdup(filter
->fsckpass
);
656 if (search_entry
->vfs_fsckpass
== NULL
) {
661 free_vfstab_entry(search_entry
);
666 if (filter
->mountatboot
!= NULL
) {
667 search_entry
->vfs_automnt
= strdup(filter
->mountatboot
);
668 if (search_entry
->vfs_automnt
== NULL
) {
673 free_vfstab_entry(search_entry
);
678 if (filter
->mntopts
!= NULL
) {
679 search_entry
->vfs_mntopts
= strdup(filter
->mntopts
);
680 if (search_entry
->vfs_mntopts
== NULL
) {
685 free_vfstab_entry(search_entry
);
690 return (search_entry
);
691 } /* create_vfstab_filter */
693 static void free_vfstab_entry(struct vfstab
*vfstab_entry
) {
695 free(vfstab_entry
->vfs_special
);
696 free(vfstab_entry
->vfs_fsckdev
);
697 free(vfstab_entry
->vfs_mountp
);
698 free(vfstab_entry
->vfs_fstype
);
699 free(vfstab_entry
->vfs_fsckpass
);
700 free(vfstab_entry
->vfs_automnt
);
701 free(vfstab_entry
->vfs_mntopts
);
704 } /* free_vfstab_entry */
707 vfstab_line_cmp(fs_mntdefaults_t
*mntdftp
, struct vfstab
*vp
) {
711 ret_val
= cmp_fields(mntdftp
->resource
, vp
->vfs_special
, ret_val
);
712 ret_val
= cmp_fields(mntdftp
->mountp
, vp
->vfs_mountp
, ret_val
);
715 } /* vfstab_line_cmp */
718 * Helper function for comparing fields in a fs_mntdefaults_t to a
719 * vfstab structure. Used in vfstab_line_cmp().
722 cmp_fields(char *mntdflt_str
, char *vfstab_str
, int ret_val
) {
724 if (mntdflt_str
!= NULL
&& vfstab_str
!= NULL
) {
725 if (strcmp(mntdflt_str
, vfstab_str
) != 0) {
728 } else if (mntdflt_str
== NULL
|| vfstab_str
== NULL
) {
736 * Helper fuction used by del_vfstab_ent() and edit_vfstab_ent() to
737 * create a vfstab line for writing out to the vfstab file.
740 create_vfstab_entry_line(struct vfstab
*vfstab_ent
, int *errp
) {
744 (vfstab_ent
->vfs_special
?
745 (strlen(vfstab_ent
->vfs_special
) +1) : 2) +
746 (vfstab_ent
->vfs_fsckdev
?
747 (strlen(vfstab_ent
->vfs_fsckdev
) +1) : 2) +
748 (vfstab_ent
->vfs_mountp
?
749 (strlen(vfstab_ent
->vfs_mountp
) +1) : 2) +
750 (vfstab_ent
->vfs_fstype
?
751 (strlen(vfstab_ent
->vfs_fstype
) +1) : 2) +
752 (vfstab_ent
->vfs_fsckpass
?
753 (strlen(vfstab_ent
->vfs_fsckpass
) +1) : 2) +
754 (vfstab_ent
->vfs_automnt
?
755 (strlen(vfstab_ent
->vfs_automnt
) +1) : 2) +
756 (vfstab_ent
->vfs_mntopts
?
757 (strlen(vfstab_ent
->vfs_mntopts
) +1) : 2));
758 line
= (char *)malloc(line_length
+ 1);
760 sprintf(line
, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
761 vfstab_ent
->vfs_special
? vfstab_ent
->vfs_special
: "-",
762 vfstab_ent
->vfs_fsckdev
? vfstab_ent
->vfs_fsckdev
: "-",
763 vfstab_ent
->vfs_mountp
? vfstab_ent
->vfs_mountp
: "-",
764 vfstab_ent
->vfs_fstype
? vfstab_ent
->vfs_fstype
: "-",
765 vfstab_ent
->vfs_fsckpass
? vfstab_ent
->vfs_fsckpass
: "-",
766 vfstab_ent
->vfs_automnt
? vfstab_ent
->vfs_automnt
: "-",
767 vfstab_ent
->vfs_mntopts
? vfstab_ent
->vfs_mntopts
: "-");
772 } /* create_vfstab_entry_line */