1/* 2 * Copyright (c) 1997-2014 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * 36 * File: am-utils/amd/ops_pcfs.c 37 * 38 */ 39 40/* 41 * PC (MS-DOS) file system 42 */ 43 44#ifdef HAVE_CONFIG_H 45# include <config.h> 46#endif /* HAVE_CONFIG_H */ 47#include <am_defs.h> 48#include <amd.h> 49 50/* forward definitions */ 51static char *pcfs_match(am_opts *fo); 52static int pcfs_mount(am_node *am, mntfs *mf); 53static int pcfs_umount(am_node *am, mntfs *mf); 54 55/* 56 * Ops structure 57 */ 58am_ops pcfs_ops = 59{ 60 "pcfs", 61 pcfs_match, 62 0, /* pcfs_init */ 63 pcfs_mount, 64 pcfs_umount, 65 amfs_error_lookup_child, 66 amfs_error_mount_child, 67 amfs_error_readdir, 68 0, /* pcfs_readlink */ 69 0, /* pcfs_mounted */ 70 0, /* pcfs_umounted */ 71 amfs_generic_find_srvr, 72 0, /* pcfs_get_wchan */ 73 FS_MKMNT | FS_UBACKGROUND | FS_AMQINFO, /* nfs_fs_flags */ 74#ifdef HAVE_FS_AUTOFS 75 AUTOFS_PCFS_FS_FLAGS, 76#endif /* HAVE_FS_AUTOFS */ 77}; 78 79 80 81/* 82 * PCFS needs remote filesystem. 83 */ 84static char * 85pcfs_match(am_opts *fo) 86{ 87 if (!fo->opt_dev) { 88 plog(XLOG_USER, "pcfs: no source device specified"); 89 return 0; 90 } 91 dlog("PCFS: mounting device \"%s\" on \"%s\"", fo->opt_dev, fo->opt_fs); 92 93 /* 94 * Determine magic cookie to put in mtab 95 */ 96 return xstrdup(fo->opt_dev); 97} 98 99 100static int 101mount_pcfs(char *mntdir, char *fs_name, char *opts, int on_autofs) 102{ 103 pcfs_args_t pcfs_args; 104 mntent_t mnt; 105 int flags; 106#if defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) 107 int mask; 108#endif /* defined(HAVE_PCFS_ARGS_T_MASK) || defined(HAVE_PCFS_ARGS_T_DIRMASK) */ 109#if defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) 110 char *str; 111#endif /* defined(HAVE_PCFS_ARGS_T_UID) || defined(HAVE_PCFS_ARGS_T_UID) */ 112 113 /* 114 * Figure out the name of the file system type. 115 */ 116 MTYPE_TYPE type = MOUNT_TYPE_PCFS; 117 118 memset((voidp) &pcfs_args, 0, sizeof(pcfs_args)); /* Paranoid */ 119 120 /* 121 * Fill in the mount structure 122 */ 123 memset((voidp) &mnt, 0, sizeof(mnt)); 124 mnt.mnt_dir = mntdir; 125 mnt.mnt_fsname = fs_name; 126 mnt.mnt_type = MNTTAB_TYPE_PCFS; 127 mnt.mnt_opts = opts; 128 129 flags = compute_mount_flags(&mnt); 130#ifdef HAVE_FS_AUTOFS 131 if (on_autofs) 132 flags |= autofs_compute_mount_flags(&mnt); 133#endif /* HAVE_FS_AUTOFS */ 134 if (amuDebug(D_TRACE)) 135 plog(XLOG_DEBUG, "mount_pcfs: flags=0x%x", (u_int) flags); 136 137#ifdef HAVE_PCFS_ARGS_T_FSPEC 138 pcfs_args.fspec = fs_name; 139#endif /* HAVE_PCFS_ARGS_T_FSPEC */ 140 141#ifdef HAVE_PCFS_ARGS_T_MASK 142 pcfs_args.mask = 0777; /* this may be the msdos file modes */ 143 if ((mask = hasmntval(&mnt, MNTTAB_OPT_MASK)) > 0) 144 pcfs_args.mask = mask; 145 if (amuDebug(D_TRACE)) 146 plog(XLOG_DEBUG, "mount_pcfs: mask=%o (octal)", (u_int) pcfs_args.mask); 147#endif /* HAVE_PCFS_ARGS_T_MASK */ 148 149#ifdef HAVE_PCFS_ARGS_T_DIRMASK 150 pcfs_args.dirmask = 0777; /* this may be the msdos dir modes */ 151 if ((mask = hasmntval(&mnt, MNTTAB_OPT_DIRMASK)) > 0) 152 pcfs_args.dirmask = mask; 153 if (amuDebug(D_TRACE)) 154 plog(XLOG_DEBUG, "mount_pcfs: dirmask=%o (octal)", (u_int) pcfs_args.dirmask); 155#endif /* HAVE_PCFS_ARGS_T_DIRMASK */ 156 157#ifdef HAVE_PCFS_ARGS_T_UID 158 pcfs_args.uid = 0; /* default to root */ 159 if ((str = hasmntstr(&mnt, MNTTAB_OPT_USER)) != NULL) { 160 struct passwd *pw; 161 if ((pw = getpwnam(str)) != NULL) 162 pcfs_args.uid = pw->pw_uid; 163 else /* maybe used passed a UID number, not user name */ 164 pcfs_args.uid = atoi(str); /* atoi returns '0' if it failed */ 165 XFREE(str); 166 } 167 if (amuDebug(D_TRACE)) 168 plog(XLOG_DEBUG, "mount_pcfs: uid=%d", (int) pcfs_args.uid); 169#endif /* HAVE_PCFS_ARGS_T_UID */ 170 171#ifdef HAVE_PCFS_ARGS_T_GID 172 pcfs_args.gid = 0; /* default to wheel/root group */ 173 if ((str = hasmntstr(&mnt, MNTTAB_OPT_GROUP)) != NULL) { 174 struct group *gr; 175 if ((gr = getgrnam(str)) != NULL) 176 pcfs_args.gid = gr->gr_gid; 177 else /* maybe used passed a GID number, not group name */ 178 pcfs_args.gid = atoi(str); /* atoi returns '0' if it failed */ 179 XFREE(str); 180 } 181 if (amuDebug(D_TRACE)) 182 plog(XLOG_DEBUG, "mount_pcfs: gid=%d", (int) pcfs_args.gid); 183#endif /* HAVE_PCFS_ARGS_T_GID */ 184 185#ifdef HAVE_PCFS_ARGS_T_SECONDSWEST 186 pcfs_args.secondswest = 0; /* XXX: fill in correct values */ 187#endif /* HAVE_PCFS_ARGS_T_SECONDSWEST */ 188#ifdef HAVE_PCFS_ARGS_T_DSTTIME 189 pcfs_args.dsttime = 0; /* XXX: fill in correct values */ 190#endif /* HAVE_PCFS_ARGS_T_DSTTIME */ 191 192 /* 193 * Call generic mount routine 194 */ 195 return mount_fs(&mnt, flags, (caddr_t) & pcfs_args, 0, type, 0, NULL, mnttab_file_name, on_autofs); 196} 197 198 199static int 200pcfs_mount(am_node *am, mntfs *mf) 201{ 202 int on_autofs = mf->mf_flags & MFF_ON_AUTOFS; 203 int error; 204 205 error = mount_pcfs(mf->mf_mount, mf->mf_info, mf->mf_mopts, on_autofs); 206 if (error) { 207 errno = error; 208 plog(XLOG_ERROR, "mount_pcfs: %m"); 209 return error; 210 } 211 212 return 0; 213} 214 215 216static int 217pcfs_umount(am_node *am, mntfs *mf) 218{ 219 int unmount_flags = (mf->mf_flags & MFF_ON_AUTOFS) ? AMU_UMOUNT_AUTOFS : 0; 220 221 return UMOUNT_FS(mf->mf_mount, mnttab_file_name, unmount_flags); 222} 223