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