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 35 #include <sys/param.h> 36 #include <sys/mount.h> 37 #include <sys/devfs.h> 38 39 #include <err.h> 40 #include <mntopts.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <string.h> 44 #include <sysexits.h> 45 #include <unistd.h> 46 47 #if 0 48 #define MOPT_UPDATE { "update", 0, MNT_UPDATE, 0 } 49 #endif 50 #define MOPT_DEVFSOPTS \ 51 { "ruleset=", 0, DEVFS_MNT_RULESET, 1 }, \ 52 { "jail", 0, DEVFS_MNT_JAIL, 1 } 53 54 55 struct mntopt mopts[] = { 56 MOPT_STDOPTS, 57 MOPT_DEVFSOPTS, 58 #if 0 59 MOPT_UPDATE, 60 #endif 61 MOPT_NULL 62 }; 63 64 static void usage(void); 65 66 int 67 main(int argc, char **argv) 68 { 69 struct statfs sfb; 70 struct devfs_mount_info info; 71 int ch, mntflags; 72 char *ptr, *mntto; 73 char mntpoint[MAXPATHLEN]; 74 char rule_file[MAXPATHLEN]; 75 struct vfsconf vfc; 76 int error; 77 info.flags = 0; 78 int i,k; 79 int mounted = 0; 80 81 mntflags = 0; 82 83 while ((ch = getopt(argc, argv, "o:")) != -1) 84 switch(ch) { 85 case 'o': 86 getmntopts(optarg, mopts, &mntflags, &info.flags); 87 ptr = strstr(optarg, "ruleset="); 88 if (ptr) { 89 ptr += 8; 90 for (i = 0, k = 0; 91 (ptr[i] != '\0') && (ptr[i] != ',') && (i < MAXPATHLEN); 92 i++) { 93 rule_file[k++] = ptr[i]; 94 95 } 96 rule_file[k] = '\0'; 97 } 98 break; 99 case '?': 100 default: 101 usage(); 102 } 103 argc -= optind; 104 argv += optind; 105 106 if (argc < 1) 107 usage(); 108 109 /* resolve mount point with realpath(3) */ 110 switch(argc) { 111 case 1: 112 mntto = argv[0]; 113 break; 114 case 2: 115 mntto = argv[1]; 116 break; 117 default: 118 mntto = NULL; 119 usage(); 120 /* NOTREACHED */ 121 } 122 123 checkpath(mntto, mntpoint); 124 125 error = getvfsbyname("devfs", &vfc); 126 if (error && vfsisloadable("devfs")) { 127 if(vfsload("devfs")) 128 err(EX_OSERR, "vfsload(devfs)"); 129 endvfsent(); 130 error = getvfsbyname("devfs", &vfc); 131 } 132 if (error) 133 errx(EX_OSERR, "devfs filesystem is not available"); 134 135 error = statfs(mntpoint, &sfb); 136 137 if (error) 138 err(EX_OSERR, "could not statfs() the mount point"); 139 140 if ((!strcmp(sfb.f_fstypename, "devfs")) && 141 (!strcmp(sfb.f_mntfromname, "devfs"))) { 142 mounted = 1; 143 } 144 145 if (!mounted) { 146 if (mount(vfc.vfc_name, mntpoint, mntflags, &info)) 147 err(1, NULL); 148 } else { 149 if (fork() == 0) { 150 execlp("devfsctl", "devfsctl", 151 "-m", mntpoint, 152 "-c", 153 "-r", 154 NULL); 155 } 156 } 157 158 if (info.flags & DEVFS_MNT_RULESET) { 159 if (fork() == 0) { 160 execlp("devfsctl", "devfsctl", 161 "-m", mntpoint, 162 "-a", 163 "-f", rule_file, 164 NULL); 165 } 166 } 167 exit(0); 168 } 169 170 static void 171 usage(void) 172 { 173 fprintf(stderr, 174 "usage: mount_devfs [-o options] [mount_from] mount_point\n"); 175 exit(1); 176 } 177