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 /*
     30  * Traverses /etc/vfstab in order to find default mount information about
     31  * file systems on the current host.
     32  */
     33 #include <errno.h>
     34 #include <stdlib.h>
     35 #include <stdio.h>
     36 #include <sys/vfstab.h>
     37 #include <sys/types.h>
     38 #include <strings.h>
     39 #include <thread.h>
     40 #include <synch.h>
     41 #include "libfsmgt.h"
     42 
     43 /*
     44  * Private constants
     45  */
     46 
     47 static const char sepstr[] = "\t\n";
     48 
     49 /*
     50  * Private variables
     51  */
     52 static mutex_t		vfstab_lock = DEFAULTMUTEX;
     53 
     54 
     55 /*
     56  * Private method declarations
     57  */
     58 static int cmp_fields(char *, char *, int);
     59 static fs_mntdefaults_t	*create_mntdefaults_entry(struct vfstab vfstab_entry,
     60 					    int *errp);
     61 static struct vfstab	*create_vfstab_filter(fs_mntdefaults_t *filter,
     62 					    int *errp);
     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 *);
     66 
     67 /*
     68  * Public methods
     69  */
     70 
     71 void fs_free_mntdefaults_list(fs_mntdefaults_t *headp) {
     72 	fs_mntdefaults_t	*tmp;
     73 
     74 	while (headp != NULL) {
     75 		tmp = headp->next;
     76 		free(headp->resource);
     77 		free(headp->fsckdevice);
     78 		free(headp->mountp);
     79 		free(headp->fstype);
     80 		free(headp->fsckpass);
     81 		free(headp->mountatboot);
     82 		free(headp->mntopts);
     83 		headp->next = NULL;
     84 		free(headp);
     85 
     86 		headp = tmp;
     87 	}
     88 } /* fs_free_mntdefaults_list */
     89 
     90 /*
     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.
     93  */
     94 fs_mntdefaults_t *fs_get_filtered_mount_defaults(fs_mntdefaults_t *filter,
     95     int *errp) {
     96 
     97 	fs_mntdefaults_t	*newp;
     98 	fs_mntdefaults_t	*headp;
     99 	fs_mntdefaults_t	*tailp;
    100 	FILE			*fp;
    101 
    102 	headp = NULL;
    103 	tailp = NULL;
    104 
    105 
    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) {
    112 			/*
    113 			 * Out of memory, the error pointer (errp) gets
    114 			 * set in create_vfstab_filter.
    115 			 */
    116 			fs_free_mntdefaults_list(headp);
    117 			(void) mutex_unlock(&vfstab_lock);
    118 			(void) fclose(fp);
    119 			return (NULL);
    120 		}
    121 
    122 		while (getvfsany(fp, &vfstab_entry, search_entry) == 0) {
    123 			/*
    124 			 * Add to list to be returned
    125 			 */
    126 			newp = create_mntdefaults_entry(vfstab_entry, errp);
    127 			if (newp == NULL) {
    128 				/*
    129 				 * Out of memory, the error pointer (errp)
    130 				 * gets set in create_mntdefaults_entry.
    131 				 */
    132 				fs_free_mntdefaults_list(headp);
    133 				(void) mutex_unlock(&vfstab_lock);
    134 				(void) fclose(fp);
    135 				return (NULL);
    136 			}
    137 
    138 			if (headp == NULL) {
    139 				headp = newp;
    140 				tailp = newp;
    141 			} else {
    142 				tailp->next = newp;
    143 				tailp = newp;
    144 			}
    145 		}
    146 		free_vfstab_entry(search_entry);
    147 		(void) mutex_unlock(&vfstab_lock);
    148 		(void) fclose(fp);
    149 
    150 	} else {
    151 		*errp = errno;
    152 	} /* if ((fp = fopen(VFSTAB, "r")) != NULL) */
    153 
    154 	return (headp);
    155 } /* fs_get_filtered_mount_defaults */
    156 
    157 
    158 fs_mntdefaults_t *
    159 fs_get_mount_defaults(int *errp)
    160 {
    161 	fs_mntdefaults_t	*newp;
    162 	fs_mntdefaults_t	*headp;
    163 	fs_mntdefaults_t	*tailp;
    164 	FILE			*fp;
    165 
    166 	headp = NULL;
    167 	tailp = NULL;
    168 
    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) {
    173 			/*
    174 			 * Add entry to list
    175 			 */
    176 			newp = create_mntdefaults_entry(vfstab_entry, errp);
    177 
    178 			if (newp == NULL) {
    179 				/*
    180 				 * Out of memory, the error pointer (errp)
    181 				 * gets set in create_mntdefaults_entry.
    182 				 */
    183 				(void) fclose(fp);
    184 				(void) mutex_unlock(&vfstab_lock);
    185 				fs_free_mntdefaults_list(headp);
    186 				return (NULL);
    187 			}
    188 
    189 			if (headp == NULL) {
    190 				headp = newp;
    191 				tailp = newp;
    192 			} else {
    193 				tailp->next = newp;
    194 				tailp = newp;
    195 			}
    196 		}
    197 		(void) fclose(fp);
    198 		(void) mutex_unlock(&vfstab_lock);
    199 	} else {
    200 		*errp = errno;
    201 	} /* if ((fp = fopen(VFSTAB, "r")) != NULL) */
    202 
    203 	/*
    204 	 * Caller must free the returned list
    205 	 */
    206 	return (headp);
    207 
    208 } /* fs_get_mount_defaults */
    209 
    210 fs_mntdefaults_t *
    211 fs_add_mount_default(fs_mntdefaults_t *newp, int *errp) {
    212 
    213 	FILE *fp;
    214 	struct vfstab *new_entry;
    215 	fs_mntdefaults_t *ret_val;
    216 
    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);
    223 			(void) fclose(fp);
    224 			(void) mutex_unlock(&vfstab_lock);
    225 			ret_val = fs_get_mount_defaults(errp);
    226 		} else {
    227 			*errp = errno;
    228 			free_vfstab_entry(new_entry);
    229 			ret_val = NULL;
    230 		}
    231 	} else {
    232 		ret_val = NULL;
    233 	}
    234 	return (ret_val);
    235 } /* fs_add_mount_default */
    236 
    237 
    238 fs_mntdefaults_t *
    239 fs_edit_mount_defaults(
    240     fs_mntdefaults_t *old_vfstab_ent,
    241     fs_mntdefaults_t *new_vfstab_ent,
    242     int *errp)
    243 {
    244 	FILE *fp;
    245 	fs_mntdefaults_t *ret_val;
    246 	char vfstab_line[VFS_LINE_MAX];
    247 	char **temp_vfstab = NULL;
    248 	char *new_line;
    249 	struct vfstab vfstabp, *new_vfstab;
    250 	int line_found = 0;
    251 
    252 	if ((fp = fopen(VFSTAB, "r")) != NULL) {
    253 		char *tmp;
    254 		int count = 0;
    255 		(void) mutex_lock(&vfstab_lock);
    256 		while (fgets(vfstab_line, VFS_LINE_MAX, fp) != NULL) {
    257 			char *charp;
    258 			struct vfstab *vp;
    259 			char *orig_line = strdup(vfstab_line);
    260 			if (orig_line == NULL) {
    261 				*errp = ENOMEM;
    262 				(void) fclose(fp);
    263 				(void) mutex_unlock(&vfstab_lock);
    264 				return (NULL);
    265 			}
    266 			vp = &vfstabp;
    267 			for (charp = vfstab_line;
    268 			    *charp == ' ' || *charp == '\t'; charp++);
    269 			if (*charp == '#' || *charp == '\n') {
    270 				/*
    271 				 * Write comments out to temp vfstab
    272 				 * image
    273 				 */
    274 				if (!fileutil_add_string_to_array(
    275 				    &temp_vfstab, vfstab_line, &count, errp)) {
    276 				    ret_val = NULL;
    277 				    line_found = 0;
    278 					break;
    279 				}
    280 				continue;
    281 			}
    282 			vp->vfs_special = (char *)strtok_r(
    283 			    vfstab_line, sepstr, &tmp);
    284 			vp->vfs_fsckdev = (char *)strtok_r(
    285 			    NULL, sepstr, &tmp);
    286 			vp->vfs_mountp = (char *)strtok_r(
    287 			    NULL, sepstr, &tmp);
    288 			vp->vfs_fstype = (char *)strtok_r(
    289 			    NULL, sepstr, &tmp);
    290 			vp->vfs_fsckpass = (char *)strtok_r(
    291 			    NULL, sepstr, &tmp);
    292 			vp->vfs_automnt = (char *)strtok_r(
    293 			    NULL, sepstr, &tmp);
    294 			vp->vfs_mntopts = (char *)strtok_r(
    295 			    NULL, sepstr, &tmp);
    296 			if (strtok_r(NULL, sepstr, &tmp) != NULL) {
    297 				/*
    298 				 * Invalid vfstab line.
    299 				 */
    300 				*errp = EINVAL;
    301 				(void) mutex_unlock(&vfstab_lock);
    302 				(void) fclose(fp);
    303 				return (NULL);
    304 			}
    305 
    306 			if (vfstab_line_cmp(old_vfstab_ent, vp)) {
    307 				line_found = 1;
    308 				new_vfstab =
    309 				    create_vfstab_filter(
    310 				    new_vfstab_ent, errp);
    311 				new_line =
    312 				    create_vfstab_entry_line(new_vfstab, errp);
    313 				if (!fileutil_add_string_to_array(
    314 				    &temp_vfstab, new_line, &count, errp)) {
    315 					ret_val = NULL;
    316 					line_found = 0;
    317 					free(new_line);
    318 					break;
    319 				}
    320 				free(new_line);
    321 			} else {
    322 				if (!fileutil_add_string_to_array(
    323 				    &temp_vfstab, orig_line, &count, errp)) {
    324 					ret_val = NULL;
    325 					line_found = 0;
    326 					break;
    327 				}
    328 			}
    329 			free(orig_line);
    330 		}
    331 		(void) fclose(fp);
    332 
    333 		if (line_found && temp_vfstab != NULL) {
    334 			if ((fp = fopen(VFSTAB, "w")) != NULL) {
    335 				int i;
    336 				for (i = 0; i < count; i++) {
    337 					fprintf(fp, "%s", temp_vfstab[i]);
    338 				}
    339 				(void) fclose(fp);
    340 				(void) mutex_unlock(&vfstab_lock);
    341 				ret_val = fs_get_mount_defaults(errp);
    342 				fileutil_free_string_array(temp_vfstab, count);
    343 			} else {
    344 				*errp = errno;
    345 				(void) mutex_unlock(&vfstab_lock);
    346 				ret_val = NULL;
    347 			}
    348 		} else {
    349 			*errp = errno;
    350 			(void) mutex_unlock(&vfstab_lock);
    351 			ret_val = NULL;
    352 		}
    353 	} else {
    354 		*errp = errno;
    355 		ret_val = NULL;
    356 	}
    357 	return (ret_val);
    358 } /* fs_edit_mount_defaults */
    359 
    360 fs_mntdefaults_t *
    361 fs_del_mount_default_ent(fs_mntdefaults_t *old_vfstab_ent, int *errp)
    362 {
    363 	FILE *fp;
    364 	fs_mntdefaults_t *ret_val;
    365 	char vfstab_line[VFS_LINE_MAX];
    366 	struct vfstab vfstabp;
    367 	int line_found = 0;
    368 
    369 	if ((fp = fopen(VFSTAB, "r")) != NULL) {
    370 		struct vfstab *vp;
    371 		char *tmp;
    372 		char *charp;
    373 		char *orig_line = NULL;
    374 		char **temp_vfstab = NULL;
    375 		int count = 0;
    376 		vp = &vfstabp;
    377 		(void) mutex_lock(&vfstab_lock);
    378 		while (fgets(vfstab_line, VFS_LINE_MAX, fp) != NULL) {
    379 
    380 			orig_line = strdup(vfstab_line);
    381 			if (orig_line == NULL) {
    382 				*errp = ENOMEM;
    383 				(void) fclose(fp);
    384 				(void) mutex_unlock(&vfstab_lock);
    385 				return (NULL);
    386 			}
    387 
    388 			for (charp = vfstab_line;
    389 			    *charp == ' ' || *charp == '\t'; charp++);
    390 
    391 			if (*charp == '#' || *charp == '\n') {
    392 				/*
    393 				 * Write comments out to temp vfstab
    394 				 * image
    395 				 */
    396 				if (!fileutil_add_string_to_array(
    397 				    &temp_vfstab, vfstab_line, &count, errp)) {
    398 					ret_val = NULL;
    399 					line_found = 0;
    400 					free(orig_line);
    401 					break;
    402 				}
    403 				continue;
    404 			}
    405 
    406 			vp->vfs_special = (char *)strtok_r(
    407 			    vfstab_line, sepstr, &tmp);
    408 			vp->vfs_fsckdev = (char *)strtok_r(
    409 			    NULL, sepstr, &tmp);
    410 			vp->vfs_mountp = (char *)strtok_r(
    411 			    NULL, sepstr, &tmp);
    412 			vp->vfs_fstype = (char *)strtok_r(
    413 			    NULL, sepstr, &tmp);
    414 			vp->vfs_fsckpass = (char *)strtok_r(
    415 			    NULL, sepstr, &tmp);
    416 			vp->vfs_automnt = (char *)strtok_r(
    417 			    NULL, sepstr, &tmp);
    418 			vp->vfs_mntopts = (char *)strtok_r(
    419 			    NULL, sepstr, &tmp);
    420 
    421 			if (strtok_r(NULL, sepstr, &tmp) != NULL) {
    422 				/*
    423 				 * Invalid vfstab line.
    424 				 */
    425 				*errp = EINVAL;
    426 				free(orig_line);
    427 				(void) fclose(fp);
    428 				(void) mutex_unlock(&vfstab_lock);
    429 				return (NULL);
    430 			}
    431 
    432 			if (vfstab_line_cmp(old_vfstab_ent, vp)) {
    433 				line_found = 1;
    434 			} else {
    435 				if (!fileutil_add_string_to_array(
    436 				    &temp_vfstab, orig_line, &count, errp)) {
    437 					ret_val = NULL;
    438 					line_found = 0;
    439 					free(orig_line);
    440 					break;
    441 				}
    442 			}
    443 			free(orig_line);
    444 		}
    445 
    446 		(void) fclose(fp);
    447 
    448 		if (line_found && temp_vfstab != NULL) {
    449 			if ((fp = fopen(VFSTAB, "w")) != NULL) {
    450 				int i;
    451 				for (i = 0; i < count; i++) {
    452 					fprintf(fp, "%s", temp_vfstab[i]);
    453 				}
    454 				(void) fclose(fp);
    455 				(void) mutex_unlock(&vfstab_lock);
    456 				ret_val = fs_get_mount_defaults(errp);
    457 				fileutil_free_string_array(temp_vfstab, count);
    458 			} else {
    459 				*errp = errno;
    460 				(void) mutex_unlock(&vfstab_lock);
    461 				fileutil_free_string_array(temp_vfstab, count);
    462 				ret_val = NULL;
    463 			}
    464 		} else {
    465 			(void) mutex_unlock(&vfstab_lock);
    466 			if (temp_vfstab != NULL) {
    467 				fileutil_free_string_array(temp_vfstab, count);
    468 			}
    469 			ret_val = NULL;
    470 		}
    471 	} else {
    472 		*errp = errno;
    473 		ret_val = NULL;
    474 	}
    475 	return (ret_val);
    476 }
    477 
    478 /*
    479  * Private methods
    480  */
    481 
    482 static fs_mntdefaults_t *
    483 create_mntdefaults_entry(struct vfstab vfstab_entry, int *errp) {
    484 	fs_mntdefaults_t	*newp;
    485 
    486 	newp = (fs_mntdefaults_t *)calloc((size_t)1,
    487 	    (size_t)sizeof (fs_mntdefaults_t));
    488 
    489 	if (newp == NULL) {
    490 		/*
    491 		 * Out of memory
    492 		 */
    493 		*errp = errno;
    494 		return (NULL);
    495 	}
    496 
    497 
    498 	if (vfstab_entry.vfs_special != NULL) {
    499 		newp->resource = strdup(vfstab_entry.vfs_special);
    500 		if (newp->resource == NULL) {
    501 			/*
    502 			 * Out of memory
    503 			 */
    504 			*errp = errno;
    505 			fs_free_mntdefaults_list(newp);
    506 			return (NULL);
    507 		}
    508 	}
    509 
    510 
    511 	if (vfstab_entry.vfs_fsckdev != NULL) {
    512 		newp->fsckdevice = strdup(vfstab_entry.vfs_fsckdev);
    513 		if (newp->fsckdevice == NULL) {
    514 			/*
    515 			 * Out of memory
    516 			 */
    517 			*errp = errno;
    518 			fs_free_mntdefaults_list(newp);
    519 			return (NULL);
    520 		}
    521 	}
    522 
    523 	if (vfstab_entry.vfs_mountp != NULL) {
    524 		newp->mountp = strdup(vfstab_entry.vfs_mountp);
    525 		if (newp->mountp == NULL) {
    526 			/*
    527 			 * Out of memory
    528 			 */
    529 			*errp = errno;
    530 			fs_free_mntdefaults_list(newp);
    531 			return (NULL);
    532 		}
    533 	}
    534 
    535 	if (vfstab_entry.vfs_fstype != NULL) {
    536 		newp->fstype = strdup(vfstab_entry.vfs_fstype);
    537 		if (newp->fstype == NULL) {
    538 			/*
    539 			 * Out of memory
    540 			 */
    541 			*errp = errno;
    542 			fs_free_mntdefaults_list(newp);
    543 			return (NULL);
    544 		}
    545 	}
    546 
    547 	if (vfstab_entry.vfs_fsckpass != NULL) {
    548 		newp->fsckpass = strdup(vfstab_entry.vfs_fsckpass);
    549 		if (newp->fsckpass == NULL) {
    550 			/*
    551 			 * Out of memory
    552 			 */
    553 			*errp = errno;
    554 			fs_free_mntdefaults_list(newp);
    555 			return (NULL);
    556 		}
    557 	}
    558 
    559 	if (vfstab_entry.vfs_automnt != NULL) {
    560 		newp->mountatboot = strdup(vfstab_entry.vfs_automnt);
    561 		if (newp->mountatboot == NULL) {
    562 			/*
    563 			 * Out of memory
    564 			 */
    565 			*errp = errno;
    566 			fs_free_mntdefaults_list(newp);
    567 			return (NULL);
    568 		}
    569 	}
    570 
    571 	if (vfstab_entry.vfs_mntopts != NULL) {
    572 		newp->mntopts = strdup(vfstab_entry.vfs_mntopts);
    573 		if (newp->mntopts == NULL) {
    574 			/*
    575 			 * Out of memory
    576 			 */
    577 			*errp = errno;
    578 			fs_free_mntdefaults_list(newp);
    579 			return (NULL);
    580 		}
    581 	}
    582 	newp->next = NULL;
    583 
    584 	return (newp);
    585 
    586 } /* create_mntdefaults_entry */
    587 
    588 static struct vfstab *
    589 create_vfstab_filter(fs_mntdefaults_t *filter, int *errp) {
    590 	struct vfstab *search_entry;
    591 
    592 	search_entry = (struct vfstab *)calloc((size_t)1,
    593 	    (size_t)sizeof (struct vfstab));
    594 	if (search_entry == NULL) {
    595 		/*
    596 		 * Out of memory
    597 		 */
    598 		*errp = errno;
    599 		return (NULL);
    600 	}
    601 
    602 	/*
    603 	 * Populate the filter criteria
    604 	 */
    605 	if (filter->resource != NULL) {
    606 		search_entry->vfs_special = strdup(filter->resource);
    607 		if (search_entry->vfs_special == NULL) {
    608 			/*
    609 			 * Out of memory
    610 			 */
    611 			*errp = errno;
    612 			free_vfstab_entry(search_entry);
    613 			return (NULL);
    614 		}
    615 
    616 	}
    617 
    618 	if (filter->fsckdevice != NULL) {
    619 		search_entry->vfs_fsckdev = strdup(filter->fsckdevice);
    620 		if (search_entry->vfs_fsckdev ==  NULL) {
    621 			/*
    622 			 * Out of memory
    623 			 */
    624 			*errp = errno;
    625 			free_vfstab_entry(search_entry);
    626 			return (NULL);
    627 		}
    628 	}
    629 
    630 	if (filter->mountp != NULL) {
    631 		search_entry->vfs_mountp = strdup(filter->mountp);
    632 		if (search_entry->vfs_mountp == NULL) {
    633 			/*
    634 			 * Out of memory
    635 			 */
    636 			*errp = errno;
    637 			free_vfstab_entry(search_entry);
    638 			return (NULL);
    639 		}
    640 	}
    641 
    642 	if (filter->fstype != NULL) {
    643 		search_entry->vfs_fstype = strdup(filter->fstype);
    644 		if (search_entry->vfs_fstype == NULL) {
    645 			/*
    646 			 * Out of memory
    647 			 */
    648 			*errp = errno;
    649 			free_vfstab_entry(search_entry);
    650 			return (NULL);
    651 		}
    652 	}
    653 
    654 	if (filter->fsckpass != NULL) {
    655 		search_entry->vfs_fsckpass = strdup(filter->fsckpass);
    656 		if (search_entry->vfs_fsckpass == NULL) {
    657 			/*
    658 			 * Out of memory
    659 			 */
    660 			*errp = errno;
    661 			free_vfstab_entry(search_entry);
    662 			return (NULL);
    663 		}
    664 	}
    665 
    666 	if (filter->mountatboot != NULL) {
    667 		search_entry->vfs_automnt = strdup(filter->mountatboot);
    668 		if (search_entry->vfs_automnt == NULL) {
    669 			/*
    670 			 * Out of memory
    671 			 */
    672 			*errp = errno;
    673 			free_vfstab_entry(search_entry);
    674 			return (NULL);
    675 		}
    676 	}
    677 
    678 	if (filter->mntopts != NULL) {
    679 		search_entry->vfs_mntopts = strdup(filter->mntopts);
    680 		if (search_entry->vfs_mntopts == NULL) {
    681 			/*
    682 			 * Out of memory
    683 			 */
    684 			*errp = errno;
    685 			free_vfstab_entry(search_entry);
    686 			return (NULL);
    687 		}
    688 	}
    689 
    690 	return (search_entry);
    691 } /* create_vfstab_filter */
    692 
    693 static void free_vfstab_entry(struct vfstab *vfstab_entry) {
    694 
    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);
    702 
    703 	free(vfstab_entry);
    704 } /* free_vfstab_entry */
    705 
    706 static int
    707 vfstab_line_cmp(fs_mntdefaults_t *mntdftp, struct vfstab *vp) {
    708 
    709 	int ret_val = 1;
    710 
    711 	ret_val = cmp_fields(mntdftp->resource, vp->vfs_special, ret_val);
    712 	ret_val = cmp_fields(mntdftp->mountp, vp->vfs_mountp, ret_val);
    713 
    714 	return (ret_val);
    715 } /* vfstab_line_cmp */
    716 
    717 /*
    718  * Helper function for comparing fields in a fs_mntdefaults_t to a
    719  * vfstab structure. Used in vfstab_line_cmp().
    720  */
    721 static int
    722 cmp_fields(char *mntdflt_str, char *vfstab_str, int ret_val) {
    723 	if (ret_val != 0) {
    724 		if (mntdflt_str != NULL && vfstab_str != NULL) {
    725 			if (strcmp(mntdflt_str, vfstab_str) != 0) {
    726 				ret_val = 0;
    727 			}
    728 		} else if (mntdflt_str == NULL || vfstab_str == NULL) {
    729 			ret_val = 0;
    730 		}
    731 	}
    732 	return (ret_val);
    733 } /* cmp_fields */
    734 
    735 /*
    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.
    738  */
    739 char *
    740 create_vfstab_entry_line(struct vfstab *vfstab_ent, int *errp) {
    741 	char *line;
    742 	int line_length;
    743 	line_length = (
    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);
    759 	if (line != NULL) {
    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 : "-");
    768 	} else {
    769 		*errp = errno;
    770 	}
    771 	return (line);
    772 } /* create_vfstab_entry_line */
    773