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