xref: /original-bsd/usr.sbin/amd/amd/mount_fs.c (revision 3d46ae69)
1 /*
2  * $Id: mount_fs.c,v 5.2 90/06/23 22:19:42 jsp Rel $
3  *
4  * Copyright (c) 1990 Jan-Simon Pendry
5  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
6  * Copyright (c) 1990 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * Jan-Simon Pendry at Imperial College, London.
11  *
12  * %sccs.include.redist.c%
13  *
14  *	@(#)mount_fs.c	5.1 (Berkeley) 06/29/90
15  */
16 
17 #include "am.h"
18 #ifdef NFS_3
19 typedef nfs_fh fhandle_t;
20 #endif /* NFS_3 */
21 #include <sys/mount.h>
22 
23 /*
24  * System Vr4 / SunOS 4.1 compatibility
25  * - put dev= in the options list
26  *
27  * From: Brent Callaghan <brent@eng.sun.com>
28  */
29 #define	MNTINFO_DEV	"dev"
30 #include <sys/stat.h>
31 
32 /*
33  * Standard mount flags
34  */
35 #ifdef hpux
36 /*
37  * HP-UX has an annoying feature of printing
38  * error msgs on /dev/console
39  */
40 #undef M_NOSUID
41 #endif /* hpux */
42 
43 struct opt_tab mnt_flags[] = {
44 	{ "ro", M_RDONLY },
45 #ifdef M_CACHE
46 	{ "nocache", M_NOCACHE },
47 #endif /* M_CACHE */
48 #ifdef M_GRPID
49 	{ "grpid", M_GRPID },
50 #endif /* M_GRPID */
51 #ifdef M_MULTI
52 	{ "multi", M_MULTI },
53 #endif /* M_MULTI */
54 #ifdef M_NODEV
55 	{ "nodev", M_NODEV },
56 #endif /* M_NODEV */
57 #ifdef M_NOEXEC
58 	{ "noexec", M_NOEXEC },
59 #endif /* M_NOEXEC */
60 #ifdef M_NOSUB
61 	{ "nosub", M_NOSUB },
62 #endif /* M_NOSUB */
63 #ifdef M_NOSUID
64 	{ "nosuid", M_NOSUID },
65 #endif /* M_NOSUID */
66 #ifdef M_SYNC
67 	{ "sync", M_SYNC },
68 #endif /* M_SYNC */
69 	{ 0, 0 }
70 };
71 
72 int compute_mount_flags(mnt)
73 struct mntent *mnt;
74 {
75 	struct opt_tab *opt;
76 	int flags;
77 #ifdef NFS_4
78 	flags = M_NEWTYPE;
79 #else
80 	flags = 0;
81 #endif /* NFS_4 */
82 
83 	/*
84 	 * Crack basic mount options
85 	 */
86 	for (opt = mnt_flags; opt->opt; opt++)
87 		flags |= hasmntopt(mnt, opt->opt) ? opt->flag : 0;
88 
89 	return flags;
90 }
91 
92 int mount_fs(mnt, flags, mnt_data, retry, type)
93 struct mntent *mnt;
94 int flags;
95 caddr_t mnt_data;
96 int retry;
97 MTYPE_TYPE type;
98 {
99 	int error = 0;
100 	int automount = 0;
101 #ifdef MNTINFO_DEV
102 	struct stat stb;
103 	char *xopts = 0;
104 #endif /* MNTINFO_DEV */
105 
106 #ifdef DEBUG
107 #ifdef NFS_4
108 	dlog("%s fstype %s (%s) flags %#x (%s)",
109 		mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
110 #else
111 	dlog("%s fstype %d (%s) flags %#x (%s)",
112 		mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts);
113 #endif /* NFS_4 */
114 #endif /* DEBUG */
115 
116 	/*
117 	 * Fake some mount table entries for the automounter
118 	 */
119 	if (STREQ(mnt->mnt_type, MNTTYPE_AUTO)) {
120 		automount = 1;
121 		mnt->mnt_fsname = pid_fsname;
122 		/*
123 		 * Try it with the normal name
124 		 */
125 #ifdef notdef
126 		/*
127 		 * This is notdef'ed because some systems use
128 		 * the mount table in getwd() (esp. SunOS4) and
129 		 * if all the mount points are not marked it can
130 		 * cause major confusion.  This can probably
131 		 * be changed when no-one is running SunOS 4.0
132 		 * any more.
133 		 */
134 		mnt->mnt_type = MNTTYPE_IGNORE;
135 #endif /* notdef */
136 		mnt->mnt_type = MNTTYPE_NFS;
137 		/*
138 		 * Background the mount, so that the stat of the
139 		 * mountpoint is done in a background process.
140 		 */
141 		if (background())
142 			return 0;
143 	}
144 
145 again:
146 	clock_valid = 0;
147 	error = MOUNT_TRAP(type, mnt, flags, mnt_data);
148 	if (error < 0)
149 		plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir);
150 	if (error < 0 && --retry > 0) {
151 		sleep(1);
152 		goto again;
153 	}
154 	if (error < 0) {
155 		if (automount)
156 			going_down(errno);
157 		return errno;
158 	}
159 
160 #ifdef UPDATE_MTAB
161 #ifdef MNTINFO_DEV
162 	/*
163 	 * Add the extra dev= field to the mount table.
164 	 */
165 	if (lstat(mnt->mnt_dir, &stb) == 0) {
166 		char *zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 32);
167 		xopts = mnt->mnt_opts;
168 		if (sizeof(stb.st_dev) == 2) {
169 			/* SunOS 4.1 */
170 			sprintf(zopts, "%s,%s=%04lx", xopts, MNTINFO_DEV,
171 					(u_long) stb.st_dev & 0xffff);
172 		} else {
173 			/* System Vr4 */
174 			sprintf(zopts, "%s,%s=%08lx", xopts, MNTINFO_DEV,
175 					(u_long) stb.st_dev);
176 		}
177 		mnt->mnt_opts = zopts;
178 	}
179 #endif /* MNTINFO_DEV */
180 
181 #ifdef hpux
182 	/*
183 	 * Yet another gratuitously incompatible change in HP-UX
184 	 */
185 	mnt->mnt_time = clocktime();
186 #endif /* hpux */
187 	write_mntent(mnt);
188 #ifdef MNTINFO_DEV
189 	if (xopts) {
190 		free(mnt->mnt_opts);
191 		mnt->mnt_opts = xopts;
192 	}
193 #endif /* MNTINFO_DEV */
194 #endif /* UPDATE_MTAB */
195 
196 	/*
197 	 * Needed this way since mnt may contain a pointer
198 	 * to a local variable in this stack frame.
199 	 */
200 	if (automount)
201 		going_down(0);
202 	return 0;
203 }
204 
205 #ifdef NEED_MNTOPT_PARSER
206 /*
207  * Some systems don't provide these to the user,
208  * but amd needs them, so...
209  *
210  * From: Piete Brooks <pb@cl.cam.ac.uk>
211  */
212 
213 #include <ctype.h>
214 
215 static char *nextmntopt(p)
216 char **p;
217 {
218 	char *cp = *p;
219 	char *rp;
220 	/*
221 	 * Skip past white space
222 	 */
223 	while (*cp && isspace(*cp))
224 		cp++;
225 	/*
226 	 * Word starts here
227 	 */
228 	rp = cp;
229 	/*
230 	 * Scan to send of string or separator
231 	 */
232 	while (*cp && *cp != ',')
233 		cp++;
234 	/*
235 	 * If separator found the overwrite with nul char.
236 	 */
237 	if (*cp) {
238 		*cp = '\0';
239 		cp++;
240 	}
241 	/*
242 	 * Return value for next call
243 	 */
244 	*p = cp;
245 	return rp;
246 }
247 
248 char *hasmntopt(mnt, opt)
249 struct mntent *mnt;
250 char *opt;
251 {
252 	char t[MNTMAXSTR];
253 	char *f;
254 	char *o = t;
255 	int l = strlen(opt);
256 	strcpy(t, mnt->mnt_opts);
257 
258 	while (*(f = nextmntopt(&o)))
259 		if (strncmp(opt, f, l) == 0)
260 			return f - t + mnt->mnt_opts;
261 
262 	return 0;
263 }
264 #endif /* NEED_MNTOPT_PARSER */
265 
266 #ifdef MOUNT_AIX3
267 
268 #include "aix3-nfs.h"
269 
270 static int aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args)
271 char *p;
272 int gfstype;
273 int flags;
274 char *object;
275 char *stub;
276 char *host;
277 char *info;
278 int info_size;
279 char *args;
280 {
281 	struct vmount *vp = (struct vmount *) p;
282 	bzero((voidp) vp, sizeof(*vp));
283 	/*
284 	 * Fill in standard fields
285 	 */
286 	vp->vmt_revision = VMT_REVISION;
287 	vp->vmt_flags = flags;
288 	vp->vmt_gfstype = gfstype;
289 
290 #define	VMT_ROUNDUP(len) (4 * ((len + 3) / 4))
291 #define VMT_ASSIGN(vp, idx, data, size) \
292 	vp->vmt_data[idx].vmt_off = p - (char *) vp; \
293 	vp->vmt_data[idx].vmt_size = size; \
294 	bcopy(data, p, size); \
295 	p += VMT_ROUNDUP(size);
296 
297 	/*
298 	 * Fill in all variable length data
299 	 */
300 	p += sizeof(*vp);
301 
302 	VMT_ASSIGN(vp, VMT_OBJECT, object, strlen(object) + 1);
303 	VMT_ASSIGN(vp, VMT_STUB, stub, strlen(stub) + 1);
304 	VMT_ASSIGN(vp, VMT_HOST, host, strlen(host) + 1);
305 	VMT_ASSIGN(vp, VMT_HOSTNAME, host, strlen(host) + 1);
306 	VMT_ASSIGN(vp, VMT_INFO, info, info_size);
307 	VMT_ASSIGN(vp, VMT_ARGS, args, strlen(args) + 1);
308 
309 #undef VMT_ASSIGN
310 #undef VMT_ROUNDUP
311 
312 	/*
313 	 * Return length
314 	 */
315 	return vp->vmt_length = p - (char *) vp;
316 }
317 
318 /*
319  * Map from conventional mount arguments
320  * to AIX 3-style arguments.
321  */
322 aix3_mount(fsname, dir, flags, type, data, args)
323 char *fsname;
324 char *dir;
325 int flags;
326 int type;
327 void *data;
328 char *args;
329 {
330 	char buf[4096];
331 	int size;
332 
333 #ifdef DEBUG
334 	dlog("aix3_mount: fsname %s, dir %s, type %d", fsname, dir, type);
335 #endif /* DEBUG */
336 
337 /* aix3_mkvp(p, gfstype, flags, object, stub, host, info, info_size, args) */
338 
339 	switch (type) {
340 
341 	case MOUNT_TYPE_NFS: {
342 		char *host = strdup(fsname);
343 		char *rfs = strchr(host, ':');
344 		*rfs++ = '\0';
345 
346 		size = aix3_mkvp(buf, type, flags, rfs, dir, host, data, sizeof(struct nfs_args), args);
347 		free(host);
348 
349 		} break;
350 
351 	case MOUNT_TYPE_UFS:
352 		/* Need to open block device and extract log device info from sblk. */
353 		return EINVAL;
354 
355 	default:
356 		return EINVAL;
357 	}
358 #ifdef DEBUG
359 	/*dlog("aix3_mkvp: flags %#x, size %d, args %s", flags, size, args);*/
360 #endif /* DEBUG */
361 
362 	return vmount(buf, size);
363 }
364 #endif /* MOUNT_AIX3 */
365