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