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 /* 23*23a1cceaSRoger 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 */ 277c478bd9Sstevel@tonic-gate /* 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 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 * 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 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 141835ee219SRobert Harris getmntany(FILE *fp, struct mnttab *mgetp, struct mnttab *mrefp) 1427c478bd9Sstevel@tonic-gate { 143835ee219SRobert Harris struct mntentbuf embuf; 144835ee219SRobert Harris char *copyp, *bufp; 1457c478bd9Sstevel@tonic-gate int ret; 1467c478bd9Sstevel@tonic-gate 147835ee219SRobert Harris 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 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; 243835ee219SRobert Harris return (-1); 244835ee219SRobert Harris } 245835ee219SRobert Harris } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate switch (ret) { 2487c478bd9Sstevel@tonic-gate 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. */ 2617c478bd9Sstevel@tonic-gate return (-1); 2627c478bd9Sstevel@tonic-gate 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 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 /*ARGSUSED*/ 278835ee219SRobert Harris int 279835ee219SRobert Harris getextmntent(FILE *fp, struct extmnttab *emp, size_t len) 280835ee219SRobert Harris { 281835ee219SRobert Harris return (getmntent_common(fp, emp, MNTIOC_GETEXTMNTENT)); 282835ee219SRobert Harris } 283835ee219SRobert Harris 2847c478bd9Sstevel@tonic-gate char * 2857c478bd9Sstevel@tonic-gate mntopt(char **p) 2867c478bd9Sstevel@tonic-gate { 2877c478bd9Sstevel@tonic-gate char *cp = *p; 2887c478bd9Sstevel@tonic-gate char *retstr; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate while (*cp && isspace(*cp)) 2917c478bd9Sstevel@tonic-gate cp++; 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate retstr = cp; 2947c478bd9Sstevel@tonic-gate while (*cp && *cp != ',') 2957c478bd9Sstevel@tonic-gate cp++; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate if (*cp) { 2987c478bd9Sstevel@tonic-gate *cp = '\0'; 2997c478bd9Sstevel@tonic-gate cp++; 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate *p = cp; 3037c478bd9Sstevel@tonic-gate return (retstr); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate char * 3077c478bd9Sstevel@tonic-gate hasmntopt(struct mnttab *mnt, char *opt) 3087c478bd9Sstevel@tonic-gate { 3097c478bd9Sstevel@tonic-gate char tmpopts[MNT_LINE_MAX]; 3107c478bd9Sstevel@tonic-gate char *f, *opts = tmpopts; 31174ed3e96Skeerthi size_t len; 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate if (mnt->mnt_mntopts == NULL) 3147c478bd9Sstevel@tonic-gate return (NULL); 3157c478bd9Sstevel@tonic-gate (void) strcpy(opts, mnt->mnt_mntopts); 31674ed3e96Skeerthi len = strlen(opt); 3177c478bd9Sstevel@tonic-gate f = mntopt(&opts); 3187c478bd9Sstevel@tonic-gate for (; *f; f = mntopt(&opts)) { 31974ed3e96Skeerthi /* 32074ed3e96Skeerthi * Match only complete substrings. For options 32174ed3e96Skeerthi * which use a delimiter (such as 'retry=3'), 32274ed3e96Skeerthi * treat the delimiter as the end of the substring. 32374ed3e96Skeerthi */ 32474ed3e96Skeerthi if (strncmp(opt, f, len) == 0 && 32574ed3e96Skeerthi (f[len] == '\0' || !isalnum(f[len]))) 3267c478bd9Sstevel@tonic-gate return (f - tmpopts + mnt->mnt_mntopts); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate return (NULL); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate void 3327c478bd9Sstevel@tonic-gate resetmnttab(FILE *fp) 3337c478bd9Sstevel@tonic-gate { 3347c478bd9Sstevel@tonic-gate rewind(fp); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate 3377c478bd9Sstevel@tonic-gate /* 3387c478bd9Sstevel@tonic-gate * Compatibility for non-mntfs files. For backwards compatibility, we continue 3397c478bd9Sstevel@tonic-gate * to have to support this broken interface. Note that getextmntent() has 3407c478bd9Sstevel@tonic-gate * always failed when using a file other than /etc/mnttab, because it relies on 3417c478bd9Sstevel@tonic-gate * an ioctl() call. 3427c478bd9Sstevel@tonic-gate */ 3437c478bd9Sstevel@tonic-gate static int 344*23a1cceaSRoger A. Faulkner getaline(char *lp, FILE *fp) 3457c478bd9Sstevel@tonic-gate { 3467c478bd9Sstevel@tonic-gate char *cp; 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate while ((lp = fgets(lp, MNT_LINE_MAX, fp)) != NULL) { 3497c478bd9Sstevel@tonic-gate if (strlen(lp) == MNT_LINE_MAX-1 && lp[MNT_LINE_MAX-2] != '\n') 3507c478bd9Sstevel@tonic-gate return (MNT_TOOLONG); 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate for (cp = lp; *cp == ' ' || *cp == '\t'; cp++) 3537c478bd9Sstevel@tonic-gate ; 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate if (*cp != '#' && *cp != '\n') 3567c478bd9Sstevel@tonic-gate return (0); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate return (-1); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate static int 3627c478bd9Sstevel@tonic-gate getmntent_compat(FILE *fp, struct mnttab *mp) 3637c478bd9Sstevel@tonic-gate { 3647c478bd9Sstevel@tonic-gate int ret; 3657c478bd9Sstevel@tonic-gate char *tmp; 3667c478bd9Sstevel@tonic-gate char *line = getmntbuf(MNT_LINE_MAX); 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate if (line == NULL) { 3697c478bd9Sstevel@tonic-gate errno = ENOMEM; 3707c478bd9Sstevel@tonic-gate return (-1); 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate /* skip leading spaces and comments */ 374*23a1cceaSRoger A. Faulkner if ((ret = getaline(line, fp)) != 0) 3757c478bd9Sstevel@tonic-gate return (ret); 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /* split up each field */ 3787c478bd9Sstevel@tonic-gate GETTOK_R(mnt_special, line, &tmp); 3797c478bd9Sstevel@tonic-gate GETTOK_R(mnt_mountp, NULL, &tmp); 3807c478bd9Sstevel@tonic-gate GETTOK_R(mnt_fstype, NULL, &tmp); 3817c478bd9Sstevel@tonic-gate GETTOK_R(mnt_mntopts, NULL, &tmp); 3827c478bd9Sstevel@tonic-gate GETTOK_R(mnt_time, NULL, &tmp); 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate /* check for too many fields */ 3857c478bd9Sstevel@tonic-gate if (strtok_r(NULL, sepstr, &tmp) != NULL) 3867c478bd9Sstevel@tonic-gate return (MNT_TOOMANY); 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate return (0); 3897c478bd9Sstevel@tonic-gate } 390