mount_fs.c revision 1.10
1/* 2 * Copyright (c) 1990 Jan-Simon Pendry 3 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Jan-Simon Pendry at Imperial College, London. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#)mount_fs.c 8.1 (Berkeley) 6/6/93 35 * $Id: mount_fs.c,v 1.10 2007/03/20 04:00:32 tedu Exp $ 36 */ 37 38#include "am.h" 39#ifdef NFS_3 40typedef nfs_fh fhandle_t; 41#endif /* NFS_3 */ 42 43#include <unistd.h> 44#include <sys/stat.h> 45 46/* 47 * Standard mount flags 48 */ 49#ifdef hpux 50/* 51 * HP-UX has an annoying feature of printing 52 * error msgs on /dev/console 53 */ 54#undef M_NOSUID 55#endif /* hpux */ 56 57struct opt_tab mnt_flags[] = { 58 { "ro", M_RDONLY }, 59#ifdef M_CACHE 60 { "nocache", M_NOCACHE }, 61#endif /* M_CACHE */ 62#ifdef M_GRPID 63 { "grpid", M_GRPID }, 64#endif /* M_GRPID */ 65#ifdef M_MULTI 66 { "multi", M_MULTI }, 67#endif /* M_MULTI */ 68#ifdef M_NODEV 69 { "nodev", M_NODEV }, 70#endif /* M_NODEV */ 71#ifdef M_NOEXEC 72 { "noexec", M_NOEXEC }, 73#endif /* M_NOEXEC */ 74#ifdef M_NOSUB 75 { "nosub", M_NOSUB }, 76#endif /* M_NOSUB */ 77#ifdef M_NOSUID 78 { "nosuid", M_NOSUID }, 79#endif /* M_NOSUID */ 80#ifdef M_SYNC 81 { "sync", M_SYNC }, 82#endif /* M_SYNC */ 83 { 0, 0 } 84}; 85 86int 87compute_mount_flags(struct mntent *mnt) 88{ 89 struct opt_tab *opt; 90 int flags; 91#ifdef NFS_4 92 flags = M_NEWTYPE; 93#else 94 flags = 0; 95#endif /* NFS_4 */ 96 97 /* 98 * Crack basic mount options 99 */ 100 for (opt = mnt_flags; opt->opt; opt++) 101 flags |= hasmntopt(mnt, opt->opt) ? opt->flag : 0; 102 103 return flags; 104} 105 106int 107mount_fs(struct mntent *mnt, int flags, caddr_t mnt_data, int retry, 108 MTYPE_TYPE type) 109{ 110 int error = 0; 111#ifdef MNTINFO_DEV 112 struct stat stb; 113 char *xopts = 0; 114#endif /* MNTINFO_DEV */ 115 116#ifdef DEBUG 117#ifdef NFS_4 118 dlog("%s fstype %s (%s) flags %#x (%s)", 119 mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); 120#else 121 dlog("%s fstype %d (%s) flags %#x (%s)", 122 mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); 123#endif /* NFS_4 */ 124#endif /* DEBUG */ 125 126 /* 127 * Fake some mount table entries for the automounter 128 */ 129#ifdef FASCIST_DF_COMMAND 130 /* 131 * Some systems have a df command which blows up when 132 * presented with an unknown mount type. 133 */ 134 if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) { 135 /* 136 * Try it with the normal name 137 */ 138 mnt->mnt_type = FASCIST_DF_COMMAND; 139 } 140#endif /* FASCIST_DF_COMMAND */ 141 142again: 143 clock_valid = 0; 144 error = MOUNT_TRAP(type, mnt, flags, mnt_data); 145 if (error < 0) 146 plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir); 147 if (error < 0 && --retry > 0) { 148 sleep(1); 149 goto again; 150 } 151 if (error < 0) { 152#ifdef notdef 153 if (automount) 154 going_down(errno); 155#endif 156 return errno; 157 } 158 159#ifdef UPDATE_MTAB 160#ifdef MNTINFO_DEV 161 /* 162 * Add the extra dev= field to the mount table. 163 */ 164 if (lstat(mnt->mnt_dir, &stb) == 0) { 165 char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32); 166 xopts = mnt->mnt_opts; 167 if (sizeof(stb.st_dev) == 2) { 168 /* e.g. SunOS 4.1 */ 169 snprintf(zopts, strlen(mnt->mnt_opts) + 32, 170 "%s,%s=%s%04x", xopts, MNTINFO_DEV, 171 MNTINFO_PREF, (u_int) stb.st_dev & 0xffff); 172 } else { 173 /* e.g. System Vr4 */ 174 snprintf(zopts, strlen(mnt->mnt_opts) + 32, 175 "%s,%s=%s%08x", xopts, MNTINFO_DEV, 176 MNTINFO_PREF, (u_int) stb.st_dev); 177 } 178 mnt->mnt_opts = zopts; 179 } 180#endif /* MNTINFO_DEV */ 181 182#ifdef FIXUP_MNTENT 183 /* 184 * Additional fields in struct mntent 185 * are fixed up here 186 */ 187 FIXUP_MNTENT(mnt); 188#endif 189 190 write_mntent(mnt); 191#ifdef MNTINFO_DEV 192 if (xopts) { 193 free(mnt->mnt_opts); 194 mnt->mnt_opts = xopts; 195 } 196#endif /* MNTINFO_DEV */ 197#endif /* UPDATE_MTAB */ 198 199 return 0; 200} 201 202#ifdef NEED_MNTOPT_PARSER 203/* 204 * Some systems don't provide these to the user, 205 * but amd needs them, so... 206 * 207 * From: Piete Brooks <pb@cl.cam.ac.uk> 208 */ 209 210#include <ctype.h> 211 212static char * 213nextmntopt(char **p) 214{ 215 char *cp = *p; 216 char *rp; 217 /* 218 * Skip past white space 219 */ 220 while (isspace(*cp)) 221 cp++; 222 /* 223 * Word starts here 224 */ 225 rp = cp; 226 /* 227 * Scan to send of string or separator 228 */ 229 while (*cp && *cp != ',') 230 cp++; 231 /* 232 * If separator found the overwrite with nul char. 233 */ 234 if (*cp) { 235 *cp = '\0'; 236 cp++; 237 } 238 /* 239 * Return value for next call 240 */ 241 *p = cp; 242 return rp; 243} 244 245char * 246hasmntopt(struct mntent *mnt, char *opt) 247{ 248 char t[MNTMAXSTR]; 249 char *f; 250 char *o = t; 251 int l = strlen(opt); 252 253 strlcpy(t, mnt->mnt_opts, sizeof(t)); 254 255 while (*(f = nextmntopt(&o))) 256 if (strncmp(opt, f, l) == 0) 257 return f - t + mnt->mnt_opts; 258 259 return 0; 260} 261#endif /* NEED_MNTOPT_PARSER */ 262 263#ifdef MOUNT_HELPER_SOURCE 264#include MOUNT_HELPER_SOURCE 265#endif /* MOUNT_HELPER_SOURCE */ 266