1710b4c75SMatthew Dillon /*
2710b4c75SMatthew Dillon * Copyright (c) 2009 The DragonFly Project. All rights reserved.
3710b4c75SMatthew Dillon *
4710b4c75SMatthew Dillon * This code is derived from software contributed to The DragonFly Project
5710b4c75SMatthew Dillon * by Alex Hornung <ahornung@gmail.com>
6710b4c75SMatthew Dillon *
7710b4c75SMatthew Dillon * Redistribution and use in source and binary forms, with or without
8710b4c75SMatthew Dillon * modification, are permitted provided that the following conditions
9710b4c75SMatthew Dillon * are met:
10710b4c75SMatthew Dillon *
11710b4c75SMatthew Dillon * 1. Redistributions of source code must retain the above copyright
12710b4c75SMatthew Dillon * notice, this list of conditions and the following disclaimer.
13710b4c75SMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
14710b4c75SMatthew Dillon * notice, this list of conditions and the following disclaimer in
15710b4c75SMatthew Dillon * the documentation and/or other materials provided with the
16710b4c75SMatthew Dillon * distribution.
17710b4c75SMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its
18710b4c75SMatthew Dillon * contributors may be used to endorse or promote products derived
19710b4c75SMatthew Dillon * from this software without specific, prior written permission.
20710b4c75SMatthew Dillon *
21710b4c75SMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22710b4c75SMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23710b4c75SMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24710b4c75SMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25710b4c75SMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26710b4c75SMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27710b4c75SMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28710b4c75SMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29710b4c75SMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30710b4c75SMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31710b4c75SMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32710b4c75SMatthew Dillon * SUCH DAMAGE.
33710b4c75SMatthew Dillon */
342dc55a02SSascha Wildner
35710b4c75SMatthew Dillon #include <sys/param.h>
36710b4c75SMatthew Dillon #include <sys/mount.h>
372c1e28ddSAlex Hornung #include <sys/devfs.h>
38710b4c75SMatthew Dillon
39710b4c75SMatthew Dillon #include <err.h>
402dc55a02SSascha Wildner #include <mntopts.h>
41710b4c75SMatthew Dillon #include <stdio.h>
42710b4c75SMatthew Dillon #include <stdlib.h>
43710b4c75SMatthew Dillon #include <string.h>
44710b4c75SMatthew Dillon #include <sysexits.h>
45710b4c75SMatthew Dillon #include <unistd.h>
46710b4c75SMatthew Dillon
4785819c59SAlex Hornung #if 0
4885819c59SAlex Hornung #define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 }
4985819c59SAlex Hornung #endif
5085819c59SAlex Hornung #define MOPT_DEVFSOPTS \
5185819c59SAlex Hornung { "ruleset=", 0, DEVFS_MNT_RULESET, 1 }, \
5285819c59SAlex Hornung { "jail", 0, DEVFS_MNT_JAIL, 1 }
5385819c59SAlex Hornung
5485819c59SAlex Hornung
55710b4c75SMatthew Dillon struct mntopt mopts[] = {
56710b4c75SMatthew Dillon MOPT_STDOPTS,
5785819c59SAlex Hornung MOPT_DEVFSOPTS,
5885819c59SAlex Hornung #if 0
5985819c59SAlex Hornung MOPT_UPDATE,
6085819c59SAlex Hornung #endif
61710b4c75SMatthew Dillon MOPT_NULL
62710b4c75SMatthew Dillon };
63710b4c75SMatthew Dillon
64710b4c75SMatthew Dillon static void usage(void);
65710b4c75SMatthew Dillon
66710b4c75SMatthew Dillon int
main(int argc,char ** argv)67710b4c75SMatthew Dillon main(int argc, char **argv)
68710b4c75SMatthew Dillon {
6985819c59SAlex Hornung struct statfs sfb;
7085819c59SAlex Hornung struct devfs_mount_info info;
71710b4c75SMatthew Dillon int ch, mntflags;
72ecbd263aSAlex Hornung char *ptr, *mntto;
73710b4c75SMatthew Dillon char mntpoint[MAXPATHLEN];
7485819c59SAlex Hornung char rule_file[MAXPATHLEN];
75710b4c75SMatthew Dillon struct vfsconf vfc;
76710b4c75SMatthew Dillon int error;
7785819c59SAlex Hornung info.flags = 0;
7885819c59SAlex Hornung int i,k;
7985819c59SAlex Hornung int mounted = 0;
80710b4c75SMatthew Dillon
81710b4c75SMatthew Dillon mntflags = 0;
82710b4c75SMatthew Dillon
83710b4c75SMatthew Dillon while ((ch = getopt(argc, argv, "o:")) != -1)
84710b4c75SMatthew Dillon switch(ch) {
85710b4c75SMatthew Dillon case 'o':
8685819c59SAlex Hornung getmntopts(optarg, mopts, &mntflags, &info.flags);
8785819c59SAlex Hornung ptr = strstr(optarg, "ruleset=");
8885819c59SAlex Hornung if (ptr) {
8985819c59SAlex Hornung ptr += 8;
9085819c59SAlex Hornung for (i = 0, k = 0;
91*e0b1d537SSascha Wildner (i < MAXPATHLEN) && (ptr[i] != '\0') && (ptr[i] != ',');
9285819c59SAlex Hornung i++) {
9385819c59SAlex Hornung rule_file[k++] = ptr[i];
9485819c59SAlex Hornung
9585819c59SAlex Hornung }
9685819c59SAlex Hornung rule_file[k] = '\0';
9785819c59SAlex Hornung }
98710b4c75SMatthew Dillon break;
99710b4c75SMatthew Dillon case '?':
100710b4c75SMatthew Dillon default:
101710b4c75SMatthew Dillon usage();
102710b4c75SMatthew Dillon }
103710b4c75SMatthew Dillon argc -= optind;
104710b4c75SMatthew Dillon argv += optind;
105710b4c75SMatthew Dillon
106710b4c75SMatthew Dillon if (argc < 1)
107710b4c75SMatthew Dillon usage();
108710b4c75SMatthew Dillon
109710b4c75SMatthew Dillon /* resolve mount point with realpath(3) */
110ecbd263aSAlex Hornung switch(argc) {
111ecbd263aSAlex Hornung case 1:
112ecbd263aSAlex Hornung mntto = argv[0];
113ecbd263aSAlex Hornung break;
114ecbd263aSAlex Hornung case 2:
115ecbd263aSAlex Hornung mntto = argv[1];
116ecbd263aSAlex Hornung break;
117ecbd263aSAlex Hornung default:
118ecbd263aSAlex Hornung mntto = NULL;
119ecbd263aSAlex Hornung usage();
120ecbd263aSAlex Hornung /* NOTREACHED */
121ecbd263aSAlex Hornung }
122710b4c75SMatthew Dillon
123ecbd263aSAlex Hornung checkpath(mntto, mntpoint);
124710b4c75SMatthew Dillon
125710b4c75SMatthew Dillon error = getvfsbyname("devfs", &vfc);
126710b4c75SMatthew Dillon if (error && vfsisloadable("devfs")) {
127710b4c75SMatthew Dillon if(vfsload("devfs"))
128710b4c75SMatthew Dillon err(EX_OSERR, "vfsload(devfs)");
129710b4c75SMatthew Dillon endvfsent();
130710b4c75SMatthew Dillon error = getvfsbyname("devfs", &vfc);
131710b4c75SMatthew Dillon }
132710b4c75SMatthew Dillon if (error)
133710b4c75SMatthew Dillon errx(EX_OSERR, "devfs filesystem is not available");
134710b4c75SMatthew Dillon
13585819c59SAlex Hornung error = statfs(mntpoint, &sfb);
13685819c59SAlex Hornung
13785819c59SAlex Hornung if (error)
13885819c59SAlex Hornung err(EX_OSERR, "could not statfs() the mount point");
13985819c59SAlex Hornung
14085819c59SAlex Hornung if ((!strcmp(sfb.f_fstypename, "devfs")) &&
14185819c59SAlex Hornung (!strcmp(sfb.f_mntfromname, "devfs"))) {
14285819c59SAlex Hornung mounted = 1;
14385819c59SAlex Hornung }
14485819c59SAlex Hornung
14585819c59SAlex Hornung if (!mounted) {
14685819c59SAlex Hornung if (mount(vfc.vfc_name, mntpoint, mntflags, &info))
147710b4c75SMatthew Dillon err(1, NULL);
14884dcbb75SAlex Hornung } else {
14985819c59SAlex Hornung if (fork() == 0) {
15085819c59SAlex Hornung execlp("devfsctl", "devfsctl",
15185819c59SAlex Hornung "-m", mntpoint,
15285819c59SAlex Hornung "-c",
15385819c59SAlex Hornung "-r",
15485819c59SAlex Hornung NULL);
15585819c59SAlex Hornung }
15684dcbb75SAlex Hornung }
15785819c59SAlex Hornung
15885819c59SAlex Hornung if (info.flags & DEVFS_MNT_RULESET) {
15985819c59SAlex Hornung if (fork() == 0) {
16085819c59SAlex Hornung execlp("devfsctl", "devfsctl",
16185819c59SAlex Hornung "-m", mntpoint,
16285819c59SAlex Hornung "-a",
16385819c59SAlex Hornung "-f", rule_file,
16485819c59SAlex Hornung NULL);
16585819c59SAlex Hornung }
16685819c59SAlex Hornung }
167710b4c75SMatthew Dillon exit(0);
168710b4c75SMatthew Dillon }
169710b4c75SMatthew Dillon
170710b4c75SMatthew Dillon static void
usage(void)171710b4c75SMatthew Dillon usage(void)
172710b4c75SMatthew Dillon {
173710b4c75SMatthew Dillon fprintf(stderr,
174ecbd263aSAlex Hornung "usage: mount_devfs [-o options] [mount_from] mount_point\n");
175710b4c75SMatthew Dillon exit(1);
176710b4c75SMatthew Dillon }
177