mnttab.c revision 168404
1/*- 2 * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * This file implements Solaris compatible getmntany() and hasmntopt() 29 * functions. 30 */ 31 32#include <sys/cdefs.h> 33__FBSDID("$FreeBSD: head/cddl/compat/opensolaris/misc/mnttab.c 168404 2007-04-06 01:09:06Z pjd $"); 34 35#include <sys/param.h> 36#include <sys/mount.h> 37#include <sys/mntent.h> 38#include <sys/mnttab.h> 39#include <stdio.h> 40 41static char * 42mntopt(char **p) 43{ 44 char *cp = *p; 45 char *retstr; 46 47 while (*cp && isspace(*cp)) 48 cp++; 49 50 retstr = cp; 51 while (*cp && *cp != ',') 52 cp++; 53 54 if (*cp) { 55 *cp = '\0'; 56 cp++; 57 } 58 59 *p = cp; 60 return (retstr); 61} 62 63char * 64hasmntopt(struct mnttab *mnt, char *opt) 65{ 66 char tmpopts[MNT_LINE_MAX]; 67 char *f, *opts = tmpopts; 68 69 if (mnt->mnt_mntopts == NULL) 70 return (NULL); 71 (void) strcpy(opts, mnt->mnt_mntopts); 72 f = mntopt(&opts); 73 for (; *f; f = mntopt(&opts)) { 74 if (strncmp(opt, f, strlen(opt)) == 0) 75 return (f - tmpopts + mnt->mnt_mntopts); 76 } 77 return (NULL); 78} 79 80static void 81optadd(char *mntopts, size_t size, const char *opt) 82{ 83 84 if (mntopts[0] != '\0') 85 strlcat(mntopts, ",", size); 86 strlcat(mntopts, opt, size); 87} 88 89int 90getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp) 91{ 92 static struct statfs *sfs = NULL; 93 static char mntopts[MNTMAXSTR]; 94 struct opt *o; 95 long i, n, flags; 96 97 if (sfs != NULL) { 98 free(sfs); 99 sfs = NULL; 100 } 101 mntopts[0] = '\0'; 102 103 n = getfsstat(NULL, 0, MNT_NOWAIT); 104 if (n == -1) 105 return (-1); 106 n = sizeof(*sfs) * (n + 8); 107 sfs = malloc(n); 108 if (sfs == NULL) 109 return (-1); 110 n = getfsstat(sfs, n, MNT_WAIT); 111 if (n == -1) { 112 free(sfs); 113 sfs = NULL; 114 return (-1); 115 } 116 for (i = 0; i < n; i++) { 117 if (mrefp->mnt_special != NULL && 118 strcmp(mrefp->mnt_special, sfs[i].f_mntfromname) != 0) { 119 continue; 120 } 121 if (mrefp->mnt_mountp != NULL && 122 strcmp(mrefp->mnt_mountp, sfs[i].f_mntonname) != 0) { 123 continue; 124 } 125 if (mrefp->mnt_fstype != NULL && 126 strcmp(mrefp->mnt_fstype, sfs[i].f_fstypename) != 0) { 127 continue; 128 } 129 flags = sfs[i].f_flags; 130#define OPTADD(opt) optadd(mntopts, sizeof(mntopts), (opt)) 131 if (flags & MNT_RDONLY) 132 OPTADD(MNTOPT_RO); 133 else 134 OPTADD(MNTOPT_RW); 135 if (flags & MNT_NOSUID) 136 OPTADD(MNTOPT_NOSUID); 137 else 138 OPTADD(MNTOPT_SETUID); 139 if (flags & MNT_UPDATE) 140 OPTADD(MNTOPT_REMOUNT); 141 if (flags & MNT_NOATIME) 142 OPTADD(MNTOPT_NOATIME); 143 else 144 OPTADD(MNTOPT_ATIME); 145 OPTADD(MNTOPT_NOXATTR); 146 if (flags & MNT_NOEXEC) 147 OPTADD(MNTOPT_NOEXEC); 148 else 149 OPTADD(MNTOPT_EXEC); 150#undef OPTADD 151 mgetp->mnt_special = sfs[i].f_mntfromname; 152 mgetp->mnt_mountp = sfs[i].f_mntonname; 153 mgetp->mnt_fstype = sfs[i].f_fstypename; 154 mgetp->mnt_mntopts = mntopts; 155 return (0); 156 } 157 free(sfs); 158 sfs = NULL; 159 return (-1); 160} 161