mount_devfs - Complete functionality; integrate rule support
[dragonfly.git] / sbin / mount_devfs / mount_devfs.c
1 /*
2  * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Alex Hornung <ahornung@gmail.com>
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  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 #include <sys/param.h>
35 #include <sys/mount.h>
36
37 #if 0
38 #include <vfs/devfs/devfs.h>
39 #endif
40
41 #include <err.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <sysexits.h>
46 #include <unistd.h>
47
48 #include "mntopts.h"
49
50 #define DEVFS_MNT_RULESET       0x01
51 #define DEVFS_MNT_JAIL          0x02
52 #if 0
53 #define MOPT_UPDATE         { "update",     0, MNT_UPDATE, 0 }
54 #endif
55 #define MOPT_DEVFSOPTS          \
56         { "ruleset=", 0, DEVFS_MNT_RULESET, 1 },        \
57         { "jail", 0, DEVFS_MNT_JAIL, 1 }
58
59
60 struct mntopt mopts[] = {
61         MOPT_STDOPTS,
62         MOPT_DEVFSOPTS,
63 #if 0
64         MOPT_UPDATE,
65 #endif
66         MOPT_NULL
67 };
68
69 static void     usage(void);
70
71 struct devfs_mount_info {
72         int flags;
73 };
74
75 int
76 main(int argc, char **argv)
77 {
78         struct statfs sfb;
79         struct devfs_mount_info info;
80         int ch, mntflags;
81         char *ptr;
82         char mntpoint[MAXPATHLEN];
83         char rule_file[MAXPATHLEN];
84         struct vfsconf vfc;
85         int error;
86         info.flags = 0;
87         int i,k;
88         int mounted = 0;
89
90         mntflags = 0;
91
92         while ((ch = getopt(argc, argv, "o:")) != -1)
93                 switch(ch) {
94                 case 'o':
95                         getmntopts(optarg, mopts, &mntflags, &info.flags);
96                         ptr = strstr(optarg, "ruleset=");
97                         if (ptr) {
98                                 ptr += 8;
99                                 for (i = 0, k = 0;
100                                     (ptr[i] != '\0') && (ptr[i] != ',') && (i < MAXPATHLEN);
101                                     i++) {
102                                         rule_file[k++] = ptr[i];
103
104                                 }
105                                 rule_file[k] = '\0';
106                         }
107                         break;
108                 case '?':
109                 default:
110                         usage();
111                 }
112         argc -= optind;
113         argv += optind;
114
115         if (argc < 1)
116                 usage();
117
118         /* resolve mount point with realpath(3) */
119         checkpath(argv[0], mntpoint);
120
121
122         error = getvfsbyname("devfs", &vfc);
123         if (error && vfsisloadable("devfs")) {
124                 if(vfsload("devfs"))
125                         err(EX_OSERR, "vfsload(devfs)");
126                 endvfsent();
127                 error = getvfsbyname("devfs", &vfc);
128         }
129         if (error)
130                 errx(EX_OSERR, "devfs filesystem is not available");
131
132         error = statfs(mntpoint, &sfb);
133
134         if (error)
135                 err(EX_OSERR, "could not statfs() the mount point");
136
137         if ((!strcmp(sfb.f_fstypename, "devfs")) &&
138             (!strcmp(sfb.f_mntfromname, "devfs"))) {
139                 mounted = 1;
140         }
141
142         if (!mounted) {
143                 if (mount(vfc.vfc_name, mntpoint, mntflags, &info))
144                         err(1, NULL);
145         }
146
147         if (fork() == 0) {
148                 execlp("devfsctl", "devfsctl",
149                     "-m", mntpoint,
150                         "-c",
151                         "-r",
152                         NULL);
153         }
154
155         if (info.flags & DEVFS_MNT_RULESET) {
156                 if (fork() == 0) {
157                         execlp("devfsctl", "devfsctl",
158                             "-m", mntpoint,
159                                 "-a",
160                                 "-f", rule_file,
161                             NULL);
162                 }
163         }
164         exit(0);
165 }
166
167 static void
168 usage(void)
169 {
170         fprintf(stderr,
171             "usage: mount_devfs [-o options] mount_point\n");
172         exit(1);
173 }