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
fs_free_mntdefaults_list(fs_mntdefaults_t * headp)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 */
fs_get_filtered_mount_defaults(fs_mntdefaults_t * filter,int * errp)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 *
fs_get_mount_defaults(int * errp)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 *
fs_add_mount_default(fs_mntdefaults_t * newp,int * errp)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 *
fs_edit_mount_defaults(fs_mntdefaults_t * old_vfstab_ent,fs_mntdefaults_t * new_vfstab_ent,int * errp)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 *
fs_del_mount_default_ent(fs_mntdefaults_t * old_vfstab_ent,int * errp)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 *
create_mntdefaults_entry(struct vfstab vfstab_entry,int * errp)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 *
create_vfstab_filter(fs_mntdefaults_t * filter,int * errp)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
free_vfstab_entry(struct vfstab * vfstab_entry)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
vfstab_line_cmp(fs_mntdefaults_t * mntdftp,struct vfstab * vp)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
cmp_fields(char * mntdflt_str,char * vfstab_str,int ret_val)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 *
create_vfstab_entry_line(struct vfstab * vfstab_ent,int * errp)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