1/* 2 * Copyright (c) 1990, 1992 Jan-Simon Pendry 3 * Copyright (c) 1992, 1993, 1994 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Jan-Simon Pendry. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35static const char copyright[] = 36"@(#) Copyright (c) 1992, 1993, 1994\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#include <sys/cdefs.h> 41__FBSDID("$FreeBSD$"); 42 43#include <sys/param.h> 44#include <sys/mount.h> 45#include <sys/uio.h> 46 47#include <err.h> 48#include <errno.h> 49#include <stdio.h> 50#include <signal.h> 51#include <stdlib.h> 52#include <string.h> 53#include <sysexits.h> 54#include <unistd.h> 55 56#include "mntopts.h" 57 58static struct mntopt mopts[] = { 59 MOPT_STDOPTS, 60 MOPT_END 61}; 62 63static char *fsname; 64static volatile sig_atomic_t caughtsig; 65 66static void usage(void) __dead2; 67 68static void 69catchsig(int s __unused) 70{ 71 caughtsig = 1; 72} 73 74int 75main(int argc, char *argv[]) 76{ 77 int ch, mntflags; 78 char mntpath[MAXPATHLEN]; 79 struct iovec iov[4]; 80 int error; 81 82 /* 83 * XXX 84 * mount(8) calls the mount programs with an argv[0] which is 85 * /just/ the file system name. So, if there is no underscore 86 * in argv[0], we assume that we are being called from mount(8) 87 * and that argv[0] is thus the name of the file system type. 88 */ 89 fsname = strrchr(argv[0], '_'); 90 if (fsname) { 91 if (strcmp(fsname, "_std") == 0) 92 errx(EX_USAGE, "argv[0] must end in _fsname"); 93 fsname++; 94 } else { 95 fsname = argv[0]; 96 } 97 98 mntflags = 0; 99 while ((ch = getopt(argc, argv, "o:")) != -1) 100 switch (ch) { 101 case 'o': 102 getmntopts(optarg, mopts, &mntflags, 0); 103 break; 104 case '?': 105 default: 106 usage(); 107 } 108 argc -= optind; 109 argv += optind; 110 111 if (argc != 2) 112 usage(); 113 114 /* resolve the mountpoint with realpath(3) */ 115 (void)checkpath(argv[1], mntpath); 116 117 iov[0].iov_base = "fstype"; 118 iov[0].iov_len = sizeof("fstype"); 119 iov[1].iov_base = fsname; 120 iov[1].iov_len = strlen(iov[1].iov_base) + 1; 121 iov[2].iov_base = "fspath"; 122 iov[2].iov_len = sizeof("fspath"); 123 iov[3].iov_base = mntpath; 124 iov[3].iov_len = strlen(mntpath) + 1; 125 126 /* 127 * nmount(2) would kill us with SIGSYS if the kernel doesn't have it. 128 * This design bug is inconvenient. We must catch the signal and not 129 * just ignore it because of a plain bug: nmount(2) would return 130 * EINVAL instead of the correct ENOSYS if the kernel doesn't have it 131 * and we don't let the signal kill us. EINVAL is too ambiguous. 132 * This bug in 4.4BSD-Lite1 was fixed in 4.4BSD-Lite2 but is still in 133 * FreeBSD-5.0. 134 */ 135 signal(SIGSYS, catchsig); 136 error = nmount(iov, 4, mntflags); 137 signal(SIGSYS, SIG_DFL); 138 139 /* 140 * Try with the old mount syscall in the case 141 * this file system has not been converted yet, 142 * or the user didn't recompile his kernel. 143 */ 144 if (error && (errno == EOPNOTSUPP || errno == ENOSYS || caughtsig)) 145 error = mount(fsname, mntpath, mntflags, NULL); 146 147 if (error) 148 err(EX_OSERR, NULL); 149 exit(0); 150} 151 152void 153usage(void) 154{ 155 (void)fprintf(stderr, 156 "usage: mount_%s [-o options] what_to_mount mount_point\n", 157 fsname); 158 exit(EX_USAGE); 159} 160