4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
34 #include <sys/types.h>
36 #include <sys/vfstab.h>
45 #define GETTOK_R(xx, ll, tmp)\
46 if ((vp->xx = (char *)strtok_r(ll, sepstr, tmp)) == NULL)\
48 if (strcmp(vp->xx, dash) == 0)\
50 #define GETTOK(xx, ll)\
51 if ((vp->xx = strtok(ll, sepstr)) == NULL)\
53 if (strcmp(vp->xx, dash) == 0)\
56 (vrefp->xx != NULL && (vgetp->xx == NULL ||\
57 strcmp(vrefp->xx, vgetp->xx) != 0))
58 #define SDIFF(xx, typem, typer)\
59 (vgetp->xx == NULL || stat64(vgetp->xx, &statb) == -1 ||\
60 (statb.st_mode & S_IFMT) != typem ||\
61 statb.st_rdev != typer)
63 static const char sepstr
[] = " \t\n";
64 static const char dash
[] = "-";
66 static int getaline(char *, FILE *);
69 getvfsspec(FILE *fd
, struct vfstab
*vgetp
, char *special
)
77 if (special
&& stat64(special
, &statb
) == 0 &&
78 ((bmode
= (statb
.st_mode
& S_IFMT
)) == S_IFBLK
||
81 brdev
= statb
.st_rdev
;
85 while ((ret
= getvfsent(fd
, vgetp
)) == 0 &&
87 (special
!= NULL
&& (vgetp
->vfs_special
== NULL
||
88 strcmp(special
, vgetp
->vfs_special
) != 0))) ||
90 (vgetp
->vfs_special
== NULL
||
91 stat64(vgetp
->vfs_special
, &statb
) == -1 ||
92 (statb
.st_mode
& S_IFMT
) != bmode
||
93 statb
.st_rdev
!= brdev
))))
99 getvfsfile(FILE *fd
, struct vfstab
*vp
, char *mountp
)
103 bzero(&vv
, (size_t)sizeof (vv
));
104 vv
.vfs_mountp
= mountp
;
105 return (getvfsany(fd
, vp
, &vv
));
109 getvfsany(FILE *fd
, struct vfstab
*vgetp
, struct vfstab
*vrefp
)
111 int ret
, bstat
, cstat
;
115 off64_t start
= ftello64(fd
);
117 /* Match by straight strcmp */
118 while ((ret
= getvfsent(fd
, vgetp
)) == 0 &&
119 (DIFF(vfs_special
) || DIFF(vfs_fsckdev
) ||
122 DIFF(vfs_fsckpass
) ||
127 /* If something other than EOF, return it */
132 * Go back to the original location in the file and try to
133 * match the devices by doing stat's (retains compatibility
134 * with original getvfsany).
136 (void) fseeko64(fd
, start
, SEEK_SET
);
138 if (vrefp
->vfs_special
&& stat64(vrefp
->vfs_special
, &statb
) == 0 &&
139 ((bmode
= (statb
.st_mode
& S_IFMT
)) == S_IFBLK
||
142 brdev
= statb
.st_rdev
;
146 if (vrefp
->vfs_fsckdev
&& stat64(vrefp
->vfs_fsckdev
, &statb
) == 0 &&
147 ((cmode
= (statb
.st_mode
& S_IFMT
)) == S_IFBLK
||
150 crdev
= statb
.st_rdev
;
154 while ((ret
= getvfsent(fd
, vgetp
)) == 0 &&
155 ((bstat
== 0 && DIFF(vfs_special
)) ||
156 (bstat
== 1 && SDIFF(vfs_special
, bmode
, brdev
)) ||
157 (cstat
== 0 && DIFF(vfs_fsckdev
)) ||
158 (cstat
== 1 && SDIFF(vfs_fsckdev
, cmode
, crdev
)) ||
161 DIFF(vfs_fsckpass
) ||
169 getvfsent(FILE *fd
, struct vfstab
*vp
)
174 line
= tsdalloc(_T_GETVFSENT
, VFS_LINE_MAX
, NULL
);
178 /* skip leading spaces and comments */
179 if ((ret
= getaline(line
, fd
)) != 0)
182 /* split up each field */
183 GETTOK_R(vfs_special
, line
, &tmp
);
184 GETTOK_R(vfs_fsckdev
, NULL
, &tmp
);
185 GETTOK_R(vfs_mountp
, NULL
, &tmp
);
186 GETTOK_R(vfs_fstype
, NULL
, &tmp
);
187 GETTOK_R(vfs_fsckpass
, NULL
, &tmp
);
188 GETTOK_R(vfs_automnt
, NULL
, &tmp
);
189 GETTOK_R(vfs_mntopts
, NULL
, &tmp
);
191 /* check for too many fields */
192 if (strtok_r(NULL
, sepstr
, &tmp
) != NULL
)
193 return (VFS_TOOMANY
);
199 getaline(char *lp
, FILE *fd
)
203 while ((lp
= fgets(lp
, VFS_LINE_MAX
, fd
)) != NULL
) {
204 if (strlen(lp
) == VFS_LINE_MAX
-1 && lp
[VFS_LINE_MAX
-2] != '\n')
205 return (VFS_TOOLONG
);
207 for (cp
= lp
; *cp
== ' ' || *cp
== '\t'; cp
++)
210 if (*cp
!= '#' && *cp
!= '\n')