/* * Copyright (C) 2010 Karel Zak * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 0211-1301 USA * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include "sockaddr.h" #include "nfs_mount.h" #include "nls.h" #include "xcommon.h" #include "version.h" #include "error.h" #include "utils.h" #include "mount.h" #include "network.h" #include "parse_dev.h" extern int verbose; extern char *progname; /* * Choose the version of the nfs_mount_data structure that is appropriate * for the kernel that is doing the mount. * * NFS_MOUNT_VERSION: maximum version supported by these sources * nfs_mount_data_version: maximum version supported by the running kernel */ int discover_nfs_mount_data_version(int *string_ver) { unsigned int kernel_version = linux_version_code(); int ver = 0; *string_ver = 0; if (kernel_version) { if (kernel_version < MAKE_VERSION(2, 1, 32)) ver = 1; else if (kernel_version < MAKE_VERSION(2, 2, 18)) ver = 3; else if (kernel_version < MAKE_VERSION(2, 3, 0)) ver = 4; else if (kernel_version < MAKE_VERSION(2, 3, 99)) ver = 3; else if (kernel_version < MAKE_VERSION(2, 6, 3)) ver = 4; else ver = 6; } if (ver > NFS_MOUNT_VERSION) ver = NFS_MOUNT_VERSION; else if (kernel_version > MAKE_VERSION(2, 6, 22)) (*string_ver)++; return ver; } void print_one(char *spec, char *node, char *type, char *opts) { if (!verbose) return; if (opts) printf(_("%s on %s type %s (%s)\n"), spec, node, type, opts); else printf(_("%s on %s type %s\n"), spec, node, type); } void mount_usage(void) { printf(_("usage: %s remotetarget dir [-rvVwfnsih] [-o nfsoptions]\n"), progname); printf(_("options:\n")); printf(_("\t-r\t\tMount file system readonly\n")); printf(_("\t-v\t\tVerbose\n")); printf(_("\t-V\t\tPrint version\n")); printf(_("\t-w\t\tMount file system read-write\n")); printf(_("\t-f\t\tFake mount, do not actually mount\n")); printf(_("\t-n\t\tDo not update /etc/mtab\n")); printf(_("\t-s\t\tTolerate sloppy mount options rather than fail\n")); printf(_("\t-h\t\tPrint this help\n")); printf(_("\tnfsoptions\tRefer to mount.nfs(8) or nfs(5)\n\n")); } void umount_usage(void) { printf(_("usage: %s dir [-fvnrlh]\n"), progname); printf(_("options:\n\t-f\t\tforce unmount\n")); printf(_("\t-v\tverbose\n")); printf(_("\t-n\tDo not update /etc/mtab\n")); printf(_("\t-r\tremount\n")); printf(_("\t-l\tlazy unmount\n")); printf(_("\t-h\tprint this help\n\n")); } int chk_mountpoint(const char *mount_point) { struct stat sb; if (stat(mount_point, &sb) < 0){ mount_error(NULL, mount_point, errno); return 1; } if (S_ISDIR(sb.st_mode) == 0){ mount_error(NULL, mount_point, ENOTDIR); return 1; } if (access(mount_point, X_OK) < 0) { mount_error(NULL, mount_point, errno); return 1; } return 0; } /* * Pick up certain mount options used during the original mount * from /etc/mtab. The basics include the server's IP address and * the server pathname of the share to unregister. * * These options might also describe the mount port, mount protocol * version, and transport protocol used to punch through a firewall. * We will need this information to get through the firewall again * to do the umount. * * Note that option parsing failures won't necessarily cause the * umount request to fail. Those values will be left zero in the * pmap tuple. If the GETPORT call later fails to disambiguate them, * then we fail. */ int nfs_umount23(const char *devname, char *string) { char *hostname = NULL, *dirname = NULL; struct mount_options *options; int result = EX_FAIL; if (!nfs_parse_devname(devname, &hostname, &dirname)) return EX_USAGE; options = po_split(string); if (options) { result = nfs_umount_do_umnt(options, &hostname, &dirname); po_destroy(options); } else nfs_error(_("%s: option parsing error"), progname); free(hostname); free(dirname); return result; }