xref: /illumos-gate/usr/src/lib/libc/port/gen/getmntent.c (revision 4a38094c)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
574ed3e96Skeerthi  * Common Development and Distribution License (the "License").
674ed3e96Skeerthi  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2174ed3e96Skeerthi 
227c478bd9Sstevel@tonic-gate /*
2323a1cceaSRoger A. Faulkner  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*	Copyright (c) 1988 AT&T	*/
27*4a38094cSToomas Soome /*	  All Rights Reserved	*/
287c478bd9Sstevel@tonic-gate 
297257d1b4Sraf #include "lint.h"
307c478bd9Sstevel@tonic-gate #include <mtlib.h>
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <sys/stat.h>
347c478bd9Sstevel@tonic-gate #include <sys/mnttab.h>
357c478bd9Sstevel@tonic-gate #include <sys/mntio.h>
367c478bd9Sstevel@tonic-gate #include <string.h>
377c478bd9Sstevel@tonic-gate #include <ctype.h>
387c478bd9Sstevel@tonic-gate #include <errno.h>
397c478bd9Sstevel@tonic-gate #include <stdlib.h>
407c478bd9Sstevel@tonic-gate #include <thread.h>
417c478bd9Sstevel@tonic-gate #include <synch.h>
427c478bd9Sstevel@tonic-gate #include <libc.h>
437c478bd9Sstevel@tonic-gate #include <unistd.h>
447c478bd9Sstevel@tonic-gate #include "tsd.h"
45835ee219SRobert Harris #include <atomic.h>
46835ee219SRobert Harris #include <strings.h>
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate static int getmntent_compat(FILE *fp, struct mnttab *mp);
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #define	GETTOK_R(xx, ll, tmp)\
517c478bd9Sstevel@tonic-gate 	if ((mp->xx = (char *)strtok_r(ll, sepstr, tmp)) == NULL)\
527c478bd9Sstevel@tonic-gate 		return (MNT_TOOFEW);\
537c478bd9Sstevel@tonic-gate 	if (strcmp(mp->xx, dash) == 0)\
547c478bd9Sstevel@tonic-gate 		mp->xx = NULL
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate #define	DIFF(xx)\
577c478bd9Sstevel@tonic-gate 	(mrefp->xx != NULL && (mgetp->xx == NULL ||\
587c478bd9Sstevel@tonic-gate 	    strcmp(mrefp->xx, mgetp->xx) != 0))
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate #define	SDIFF(xx, typem, typer)\
617c478bd9Sstevel@tonic-gate 	((mgetp->xx == NULL) || (stat64(mgetp->xx, &statb) == -1) ||\
627c478bd9Sstevel@tonic-gate 	((statb.st_mode & S_IFMT) != typem) ||\
637c478bd9Sstevel@tonic-gate 	    (statb.st_rdev != typer))
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate static const char	sepstr[] = " \t\n";
667c478bd9Sstevel@tonic-gate static const char	dash[] = "-";
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate typedef struct {
697c478bd9Sstevel@tonic-gate 	size_t	buflen;
707c478bd9Sstevel@tonic-gate 	char	*buf;
717c478bd9Sstevel@tonic-gate } thread_data_t;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate static void
destroy_thread_data(void * arg)747c478bd9Sstevel@tonic-gate destroy_thread_data(void *arg)
757c478bd9Sstevel@tonic-gate {
767c478bd9Sstevel@tonic-gate 	thread_data_t *thread_data = arg;
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	if (thread_data->buf != NULL) {
797c478bd9Sstevel@tonic-gate 		free(thread_data->buf);
807c478bd9Sstevel@tonic-gate 		thread_data->buf = NULL;
817c478bd9Sstevel@tonic-gate 	}
827c478bd9Sstevel@tonic-gate 	thread_data->buflen = 0;
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate static char *
getmntbuf(size_t size)867c478bd9Sstevel@tonic-gate getmntbuf(size_t size)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	thread_data_t *thread_data;
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	thread_data = tsdalloc(_T_GETMNTENT,
917c478bd9Sstevel@tonic-gate 	    sizeof (thread_data_t), destroy_thread_data);
927c478bd9Sstevel@tonic-gate 	if (thread_data == NULL)
937c478bd9Sstevel@tonic-gate 		return (NULL);
947c478bd9Sstevel@tonic-gate 	if (thread_data->buf == NULL ||
957c478bd9Sstevel@tonic-gate 	    thread_data->buflen < size) {
967c478bd9Sstevel@tonic-gate 		if (thread_data->buf != NULL)
977c478bd9Sstevel@tonic-gate 			free(thread_data->buf);
987c478bd9Sstevel@tonic-gate 		thread_data->buflen = 0;
997c478bd9Sstevel@tonic-gate 		if ((thread_data->buf = malloc(size)) == NULL)
1007c478bd9Sstevel@tonic-gate 			return (NULL);
1017c478bd9Sstevel@tonic-gate 		thread_data->buflen = size;
1027c478bd9Sstevel@tonic-gate 	}
1037c478bd9Sstevel@tonic-gate 	return (thread_data->buf);
1047c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate 
106835ee219SRobert Harris static int
getmntany_compat(FILE * fp,struct mnttab * mgetp,struct mnttab * mrefp)107835ee219SRobert Harris getmntany_compat(FILE *fp, struct mnttab *mgetp, struct mnttab *mrefp)
1087c478bd9Sstevel@tonic-gate {
1097c478bd9Sstevel@tonic-gate 	int	ret, bstat;
1107c478bd9Sstevel@tonic-gate 	mode_t	bmode;
1117c478bd9Sstevel@tonic-gate 	dev_t	brdev;
1127c478bd9Sstevel@tonic-gate 	struct stat64	statb;
1137c478bd9Sstevel@tonic-gate 
114b72c1761Seschrock 	/*
115b72c1761Seschrock 	 * Ignore specials that don't correspond to real devices to avoid doing
116b72c1761Seschrock 	 * unnecessary lookups in stat64().
117b72c1761Seschrock 	 */
118b72c1761Seschrock 	if (mrefp->mnt_special && mrefp->mnt_special[0] == '/' &&
119b72c1761Seschrock 	    stat64(mrefp->mnt_special, &statb) == 0 &&
1207c478bd9Sstevel@tonic-gate 	    ((bmode = (statb.st_mode & S_IFMT)) == S_IFBLK ||
1217c478bd9Sstevel@tonic-gate 	    bmode == S_IFCHR)) {
1227c478bd9Sstevel@tonic-gate 		bstat = 1;
1237c478bd9Sstevel@tonic-gate 		brdev = statb.st_rdev;
1247c478bd9Sstevel@tonic-gate 	} else {
1257c478bd9Sstevel@tonic-gate 		bstat = 0;
1267c478bd9Sstevel@tonic-gate 	}
1277c478bd9Sstevel@tonic-gate 
128835ee219SRobert Harris 	while ((ret = getmntent_compat(fp, mgetp)) == 0 &&
1297c478bd9Sstevel@tonic-gate 	    ((bstat == 0 && DIFF(mnt_special)) ||
1307c478bd9Sstevel@tonic-gate 	    (bstat == 1 && SDIFF(mnt_special, bmode, brdev)) ||
1317c478bd9Sstevel@tonic-gate 	    DIFF(mnt_mountp) ||
1327c478bd9Sstevel@tonic-gate 	    DIFF(mnt_fstype) ||
1337c478bd9Sstevel@tonic-gate 	    DIFF(mnt_mntopts) ||
1347c478bd9Sstevel@tonic-gate 	    DIFF(mnt_time)))
1357c478bd9Sstevel@tonic-gate 		;
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	return (ret);
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate int
getmntany(FILE * fp,struct mnttab * mgetp,struct mnttab * mrefp)141835ee219SRobert Harris getmntany(FILE *fp, struct mnttab *mgetp, struct mnttab *mrefp)
1427c478bd9Sstevel@tonic-gate {
143835ee219SRobert Harris 	struct mntentbuf embuf;
144835ee219SRobert Harris 	char *copyp, *bufp;
145835ee219SRobert Harris 	int ret;
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 
148835ee219SRobert Harris 	/*
149835ee219SRobert Harris 	 * We collect all of the text strings pointed to by members of the
150835ee219SRobert Harris 	 * user's preferences struct into a single buffer. At the same time
151835ee219SRobert Harris 	 * populate the members of the results struct to point to the
152835ee219SRobert Harris 	 * corresponding words. We then ask the kernel to figure out the
153835ee219SRobert Harris 	 * rest; if this is a non-mntfs file then we handover to
154835ee219SRobert Harris 	 * getmntany_compat().
155835ee219SRobert Harris 	 */
156835ee219SRobert Harris 	if ((copyp = bufp = getmntbuf(MNT_LINE_MAX)) == NULL) {
157835ee219SRobert Harris 		errno = ENOMEM;
158835ee219SRobert Harris 		return (-1);
159835ee219SRobert Harris 	}
160835ee219SRobert Harris 	bzero(mgetp, sizeof (struct mnttab));
161835ee219SRobert Harris 	if (mrefp->mnt_special) {
162835ee219SRobert Harris 		mgetp->mnt_special = copyp;
163835ee219SRobert Harris 		copyp += snprintf(mgetp->mnt_special, MNT_LINE_MAX, "%s",
164835ee219SRobert Harris 		    mrefp->mnt_special) + 1;
165835ee219SRobert Harris 	}
166835ee219SRobert Harris 	if (mrefp->mnt_mountp) {
167835ee219SRobert Harris 		mgetp->mnt_mountp = copyp;
168835ee219SRobert Harris 		copyp += snprintf(mgetp->mnt_mountp,
169835ee219SRobert Harris 		    bufp + MNT_LINE_MAX - copyp, "%s", mrefp->mnt_mountp) + 1;
170835ee219SRobert Harris 	}
171835ee219SRobert Harris 	if (mrefp->mnt_fstype) {
172835ee219SRobert Harris 		mgetp->mnt_fstype = copyp;
173835ee219SRobert Harris 		copyp += snprintf(mgetp->mnt_fstype,
174835ee219SRobert Harris 		    bufp + MNT_LINE_MAX - copyp, "%s", mrefp->mnt_fstype) + 1;
175835ee219SRobert Harris 	}
176835ee219SRobert Harris 	if (mrefp->mnt_mntopts) {
177835ee219SRobert Harris 		mgetp->mnt_mntopts = copyp;
178835ee219SRobert Harris 		copyp += snprintf(mgetp->mnt_mntopts,
179835ee219SRobert Harris 		    bufp + MNT_LINE_MAX - copyp, "%s", mrefp->mnt_mntopts) + 1;
180835ee219SRobert Harris 	}
181835ee219SRobert Harris 	if (mrefp->mnt_time) {
182835ee219SRobert Harris 		mgetp->mnt_time = copyp;
183835ee219SRobert Harris 		(void) snprintf(mgetp->mnt_time, bufp + MNT_LINE_MAX - copyp,
184835ee219SRobert Harris 		    "%s", mrefp->mnt_time);
185835ee219SRobert Harris 	}
186835ee219SRobert Harris 
187835ee219SRobert Harris 	embuf.mbuf_emp = (struct extmnttab *)mgetp;
188835ee219SRobert Harris 	embuf.mbuf_bufsize = MNT_LINE_MAX;
189835ee219SRobert Harris 	embuf.mbuf_buf = bufp;
190835ee219SRobert Harris 
191835ee219SRobert Harris 	switch (ret = ioctl(fileno(fp), MNTIOC_GETMNTANY, &embuf)) {
192835ee219SRobert Harris 	case 0:
193835ee219SRobert Harris 		/* Success. */
194835ee219SRobert Harris 		return (0);
195835ee219SRobert Harris 	case MNTFS_EOF:
196835ee219SRobert Harris 		return (-1);
197835ee219SRobert Harris 	case MNTFS_TOOLONG:
198835ee219SRobert Harris 		return (MNT_TOOLONG);
199835ee219SRobert Harris 	default:
200835ee219SRobert Harris 		/* A failure of some kind. */
201835ee219SRobert Harris 		if (errno == ENOTTY)
202835ee219SRobert Harris 			return (getmntany_compat(fp, mgetp, mrefp));
203835ee219SRobert Harris 		else
204835ee219SRobert Harris 			return (ret);
205835ee219SRobert Harris 	}
206835ee219SRobert Harris }
207835ee219SRobert Harris 
208835ee219SRobert Harris /*
209835ee219SRobert Harris  * Common code for getmntent() and getextmntent().
210835ee219SRobert Harris  *
211835ee219SRobert Harris  * These functions serve to populate a structure supplied by the user. Common
212835ee219SRobert Harris  * to both struct mnttab and struct extmnttab is a set of pointers to the
213835ee219SRobert Harris  * individual text fields that form an entry in /etc/mnttab. We arrange for the
214835ee219SRobert Harris  * text itself to be stored in some thread-local storage, and for the kernel to
215835ee219SRobert Harris  * populate both this buffer and the structure directly.
216835ee219SRobert Harris  *
217835ee219SRobert Harris  * If getmntent() passes a file that isn't provided by mntfs then we assume that
218835ee219SRobert Harris  * it is a simple text file and give it to getmntent_compat() to parse. For
219835ee219SRobert Harris  * getextmntent() we give up; it requires major and minor numbers that only the
220835ee219SRobert Harris  * kernel can provide.
221835ee219SRobert Harris  */
222835ee219SRobert Harris static int
getmntent_common(FILE * fp,struct extmnttab * emp,int command)223835ee219SRobert Harris getmntent_common(FILE *fp, struct extmnttab *emp, int command)
224835ee219SRobert Harris {
225835ee219SRobert Harris 	struct mntentbuf embuf;
226835ee219SRobert Harris 	static size_t bufsize = MNT_LINE_MAX;
227835ee219SRobert Harris 	int ret;
228835ee219SRobert Harris 
229835ee219SRobert Harris 	embuf.mbuf_emp = emp;
230835ee219SRobert Harris 	embuf.mbuf_bufsize = bufsize;
231835ee219SRobert Harris 	if ((embuf.mbuf_buf = getmntbuf(embuf.mbuf_bufsize)) == NULL) {
232835ee219SRobert Harris 		errno = ENOMEM;
233835ee219SRobert Harris 		return (-1);
234835ee219SRobert Harris 	}
235835ee219SRobert Harris 
236835ee219SRobert Harris 	while ((ret = ioctl(fileno(fp), command, &embuf)) == MNTFS_TOOLONG) {
237835ee219SRobert Harris 		/* The buffer wasn't large enough. */
238835ee219SRobert Harris 		(void) atomic_swap_ulong((unsigned long *)&bufsize,
239835ee219SRobert Harris 		    2 * embuf.mbuf_bufsize);
240835ee219SRobert Harris 		embuf.mbuf_bufsize = bufsize;
241835ee219SRobert Harris 		if ((embuf.mbuf_buf = getmntbuf(embuf.mbuf_bufsize)) == NULL) {
242835ee219SRobert Harris 			errno = ENOMEM;
2437c478bd9Sstevel@tonic-gate 			return (-1);
244835ee219SRobert Harris 		}
245835ee219SRobert Harris 	}
246835ee219SRobert Harris 
247835ee219SRobert Harris 	switch (ret) {
248835ee219SRobert Harris 	case 0:
249835ee219SRobert Harris 		/*
250835ee219SRobert Harris 		 * We were successful, but we may have to enforce getmntent()'s
251835ee219SRobert Harris 		 * documented limit on the line length.
252835ee219SRobert Harris 		 */
253835ee219SRobert Harris 		if (command == MNTIOC_GETMNTENT &&
254835ee219SRobert Harris 		    (emp->mnt_time + strlen(emp->mnt_time) + 1 -
255835ee219SRobert Harris 		    emp->mnt_special > MNT_LINE_MAX))
256835ee219SRobert Harris 			return (MNT_TOOLONG);
257835ee219SRobert Harris 		else
258835ee219SRobert Harris 			return (0);
259835ee219SRobert Harris 	case MNTFS_EOF:
260835ee219SRobert Harris 		/* EOF. */
261835ee219SRobert Harris 		return (-1);
262835ee219SRobert Harris 	default:
263835ee219SRobert Harris 		/* A non-mntfs file. */
264835ee219SRobert Harris 		if (command == MNTIOC_GETMNTENT)
265835ee219SRobert Harris 			return (getmntent_compat(fp, (struct mnttab *)emp));
266835ee219SRobert Harris 		else
267835ee219SRobert Harris 			return (ret);
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate 
271835ee219SRobert Harris int
getmntent(FILE * fp,struct mnttab * mp)272835ee219SRobert Harris getmntent(FILE *fp, struct mnttab *mp)
273835ee219SRobert Harris {
274835ee219SRobert Harris 	return (getmntent_common(fp, (struct extmnttab *)mp, MNTIOC_GETMNTENT));
275835ee219SRobert Harris }
276835ee219SRobert Harris 
277835ee219SRobert Harris int
getextmntent(FILE * fp,struct extmnttab * emp,size_t len __unused)278*4a38094cSToomas Soome getextmntent(FILE *fp, struct extmnttab *emp, size_t len __unused)
279835ee219SRobert Harris {
280835ee219SRobert Harris 	return (getmntent_common(fp, emp, MNTIOC_GETEXTMNTENT));
281835ee219SRobert Harris }
282835ee219SRobert Harris 
2837c478bd9Sstevel@tonic-gate char *
mntopt(char ** p)2847c478bd9Sstevel@tonic-gate mntopt(char **p)
2857c478bd9Sstevel@tonic-gate {
2867c478bd9Sstevel@tonic-gate 	char *cp = *p;
2877c478bd9Sstevel@tonic-gate 	char *retstr;
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate 	while (*cp && isspace(*cp))
2907c478bd9Sstevel@tonic-gate 		cp++;
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	retstr = cp;
2937c478bd9Sstevel@tonic-gate 	while (*cp && *cp != ',')
2947c478bd9Sstevel@tonic-gate 		cp++;
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate 	if (*cp) {
2977c478bd9Sstevel@tonic-gate 		*cp = '\0';
2987c478bd9Sstevel@tonic-gate 		cp++;
2997c478bd9Sstevel@tonic-gate 	}
3007c478bd9Sstevel@tonic-gate 
3017c478bd9Sstevel@tonic-gate 	*p = cp;
3027c478bd9Sstevel@tonic-gate 	return (retstr);
3037c478bd9Sstevel@tonic-gate }
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate char *
hasmntopt(struct mnttab * mnt,char * opt)3067c478bd9Sstevel@tonic-gate hasmntopt(struct mnttab *mnt, char *opt)
3077c478bd9Sstevel@tonic-gate {
3087c478bd9Sstevel@tonic-gate 	char tmpopts[MNT_LINE_MAX];
3097c478bd9Sstevel@tonic-gate 	char *f, *opts = tmpopts;
31074ed3e96Skeerthi 	size_t	len;
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 	if (mnt->mnt_mntopts == NULL)
3137c478bd9Sstevel@tonic-gate 		return (NULL);
3147c478bd9Sstevel@tonic-gate 	(void) strcpy(opts, mnt->mnt_mntopts);
31574ed3e96Skeerthi 	len = strlen(opt);
3167c478bd9Sstevel@tonic-gate 	f = mntopt(&opts);
3177c478bd9Sstevel@tonic-gate 	for (; *f; f = mntopt(&opts)) {
31874ed3e96Skeerthi 		/*
31974ed3e96Skeerthi 		 * Match only complete substrings. For options
32074ed3e96Skeerthi 		 * which use a delimiter (such as 'retry=3'),
32174ed3e96Skeerthi 		 * treat the delimiter as the end of the substring.
32274ed3e96Skeerthi 		 */
32374ed3e96Skeerthi 		if (strncmp(opt, f, len) == 0 &&
32474ed3e96Skeerthi 		    (f[len] == '\0' || !isalnum(f[len])))
3257c478bd9Sstevel@tonic-gate 			return (f - tmpopts + mnt->mnt_mntopts);
3267c478bd9Sstevel@tonic-gate 	}
3277c478bd9Sstevel@tonic-gate 	return (NULL);
3287c478bd9Sstevel@tonic-gate }
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate void
resetmnttab(FILE * fp)3317c478bd9Sstevel@tonic-gate resetmnttab(FILE *fp)
3327c478bd9Sstevel@tonic-gate {
3337c478bd9Sstevel@tonic-gate 	rewind(fp);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate /*
3377c478bd9Sstevel@tonic-gate  * Compatibility for non-mntfs files.  For backwards compatibility, we continue
3387c478bd9Sstevel@tonic-gate  * to have to support this broken interface.  Note that getextmntent() has
3397c478bd9Sstevel@tonic-gate  * always failed when using a file other than /etc/mnttab, because it relies on
3407c478bd9Sstevel@tonic-gate  * an ioctl() call.
3417c478bd9Sstevel@tonic-gate  */
3427c478bd9Sstevel@tonic-gate static int
getaline(char * lp,FILE * fp)34323a1cceaSRoger A. Faulkner getaline(char *lp, FILE *fp)
3447c478bd9Sstevel@tonic-gate {
3457c478bd9Sstevel@tonic-gate 	char	*cp;
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 	while ((lp = fgets(lp, MNT_LINE_MAX, fp)) != NULL) {
3487c478bd9Sstevel@tonic-gate 		if (strlen(lp) == MNT_LINE_MAX-1 && lp[MNT_LINE_MAX-2] != '\n')
3497c478bd9Sstevel@tonic-gate 			return (MNT_TOOLONG);
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 		for (cp = lp; *cp == ' ' || *cp == '\t'; cp++)
3527c478bd9Sstevel@tonic-gate 			;
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate 		if (*cp != '#' && *cp != '\n')
3557c478bd9Sstevel@tonic-gate 			return (0);
3567c478bd9Sstevel@tonic-gate 	}
3577c478bd9Sstevel@tonic-gate 	return (-1);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate 
3607c478bd9Sstevel@tonic-gate static int
getmntent_compat(FILE * fp,struct mnttab * mp)3617c478bd9Sstevel@tonic-gate getmntent_compat(FILE *fp, struct mnttab *mp)
3627c478bd9Sstevel@tonic-gate {
3637c478bd9Sstevel@tonic-gate 	int	ret;
3647c478bd9Sstevel@tonic-gate 	char	*tmp;
3657c478bd9Sstevel@tonic-gate 	char	*line = getmntbuf(MNT_LINE_MAX);
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	if (line == NULL) {
3687c478bd9Sstevel@tonic-gate 		errno = ENOMEM;
3697c478bd9Sstevel@tonic-gate 		return (-1);
3707c478bd9Sstevel@tonic-gate 	}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	/* skip leading spaces and comments */
37323a1cceaSRoger A. Faulkner 	if ((ret = getaline(line, fp)) != 0)
3747c478bd9Sstevel@tonic-gate 		return (ret);
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	/* split up each field */
3777c478bd9Sstevel@tonic-gate 	GETTOK_R(mnt_special, line, &tmp);
3787c478bd9Sstevel@tonic-gate 	GETTOK_R(mnt_mountp, NULL, &tmp);
3797c478bd9Sstevel@tonic-gate 	GETTOK_R(mnt_fstype, NULL, &tmp);
3807c478bd9Sstevel@tonic-gate 	GETTOK_R(mnt_mntopts, NULL, &tmp);
3817c478bd9Sstevel@tonic-gate 	GETTOK_R(mnt_time, NULL, &tmp);
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 	/* check for too many fields */
3847c478bd9Sstevel@tonic-gate 	if (strtok_r(NULL, sepstr, &tmp) != NULL)
3857c478bd9Sstevel@tonic-gate 		return (MNT_TOOMANY);
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	return (0);
3887c478bd9Sstevel@tonic-gate }
389