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