/*
 * mount_libmount.c -- Linux NFS [u]mount based on libmount
 *
 * Copyright (C) 2011 Karel Zak <kzak@redhat.com>
 *
 * 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 <config.h>
#endif

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>

#include <libmount/libmount.h>

#include "nls.h"
#include "mount_config.h"

#include "nfs_mount.h"
#include "nfs4_mount.h"
#include "stropts.h"
#include "version.h"
#include "xcommon.h"

#include "error.h"
#include "utils.h"

char *progname;
int nfs_mount_data_version;
int verbose;
int sloppy;
int string;
int nomtab;

#define FOREGROUND	(0)
#define BACKGROUND	(1)

/*
 * Store mount options to mtab (or /dev/.mount/utab), called from mount.nfs.
 *
 * Note that on systems without /etc/mtab the fs-specific options are not
 * managed by libmount at all. We have to use "mount attributes" that are
 * private for mount.<type> helpers.
 */
static void store_mount_options(struct libmnt_fs *fs, const char *nfs_opts)
{
	char *o = NULL;

	mnt_fs_set_attributes(fs, nfs_opts);	/* for non-mtab systems */

	/* for mtab create a new options list */
	mnt_optstr_append_option(&o, mnt_fs_get_vfs_options(fs), NULL);
	mnt_optstr_append_option(&o, nfs_opts, NULL);
	mnt_optstr_append_option(&o, mnt_fs_get_user_options(fs), NULL);

	mnt_fs_set_options(fs, o);
	free(o);
}

/*
 * Retrieve mount options from mtab (or /dev/.mount/utab) called from umount.nfs.
 *
 * The result can passed to free().
 */
char *retrieve_mount_options(struct libmnt_fs *fs)
{
	const char *opts;

	if (!fs)
		return NULL;

	opts = mnt_fs_get_attributes(fs);	/* /dev/.mount/utab */
	if (opts)
		return strdup(opts);

	return mnt_fs_strdup_options(fs);	/* /etc/mtab */
}

static int try_mount(struct libmnt_context *cxt, int bg)
{
	struct libmnt_fs *fs;
	const char *p;
	char *src = NULL, *tgt = NULL, *type = NULL, *opts = NULL;
	unsigned long flags = 0;
	int fake, ret = 0;

	fs = mnt_context_get_fs(cxt);

	/* libmount returns read-only pointers (const char)
	 * so, reallocate for nfsmount() functions.
	 */
	if ((p = mnt_fs_get_source(fs)))	/* spec */
		src = strdup(p);
	if ((p = mnt_fs_get_target(fs)))	/* mountpoint */
		tgt = strdup(p);
	if ((p = mnt_fs_get_fstype(fs)))	/* FS type */
		type = strdup(p);
	if ((p = mnt_fs_get_fs_options(fs)))	/* mount options */
		opts = strdup(p);

	mnt_context_get_mflags(cxt, &flags);	/* mount(2) flags */
	fake = mnt_context_is_fake(cxt);

	if (string)
		ret = nfsmount_string(src, tgt, type, flags, &opts, fake, bg);

	else if (strcmp(type, "nfs4") == 0)
		ret = nfs4mount(src, tgt, flags, &opts, fake, bg);
	else
		ret = nfsmount(src, tgt, flags, &opts, fake, bg);

	/* Store mount options if not called with mount --no-mtab */
	if (!ret && !mnt_context_is_nomtab(cxt))
		store_mount_options(fs, opts);

	free(src);
	free(tgt);
	free(type);
	free(opts);

	return ret;
}

/* returns: error = -1, success = 1 , not vers4 == 0 */
static int is_vers4(struct libmnt_context *cxt)
{
	struct libmnt_fs *fs = mnt_context_get_fs(cxt);
	struct libmnt_table *tb = NULL;
	const char *src = mnt_context_get_source(cxt),
		   *tgt = mnt_context_get_target(cxt);
	int rc = 0;

	if (!src || !tgt)
		return -1;

	if (!mnt_fs_is_kernel(fs)) {
		struct libmnt_table *tb = mnt_new_table_from_file("/proc/mounts");

		if (!tb)
			return -1;
		fs = mnt_table_find_pair(tb, src, tgt, MNT_ITER_BACKWARD);
	}

	if (fs) {
		const char *type = mnt_fs_get_fstype(fs);
		if (type && strcmp(type, "nfs4") == 0)
			rc = 1;
	}
	mnt_free_table(tb);
	return rc;
}

static int umount_main(struct libmnt_context *cxt, int argc, char **argv)
{
	int rc, c;
	char *spec = NULL, *opts = NULL;
	int ret = EX_FAIL;

	static const struct option longopts[] = {
		{ "force", 0, 0, 'f' },
		{ "help", 0, 0, 'h' },
		{ "no-mtab", 0, 0, 'n' },
		{ "verbose", 0, 0, 'v' },
		{ "read-only", 0, 0, 'r' },
		{ "lazy", 0, 0, 'l' },
		{ "types", 1, 0, 't' },
		{ NULL, 0, 0, 0 }
	};

	mnt_context_init_helper(cxt, MNT_ACT_UMOUNT, 0);

	while ((c = getopt_long (argc, argv, "fvnrlh", longopts, NULL)) != -1) {

		rc = mnt_context_helper_setopt(cxt, c, optarg);
		if (rc == 0)		/* valid option */
			continue;
		if (rc < 0)		/* error (probably ENOMEM) */
			goto err;
					/* rc==1 means unknow option */
		umount_usage();
		return EX_USAGE;
	}

	if (optind < argc)
		spec = argv[optind++];

	if (!spec || (*spec != '/' && strchr(spec,':') == NULL)) {
		nfs_error(_("%s: no mount point provided"), progname);
		return EX_USAGE;
	}

	if (mnt_context_set_target(cxt, spec))
		goto err;

	/* read mtab/fstab, evaluate permissions, etc. */
	rc = mnt_context_prepare_umount(cxt);
	if (rc) {
		nfs_error(_("%s: failed to prepare umount: %s\n"),
					progname, strerror(-rc));
		goto err;
	}

	if (mnt_context_get_fstype(cxt) &&
	    !mnt_match_fstype(mnt_context_get_fstype(cxt), "nfs,nfs4")) {

		nfs_error(_("%s: %s: is not an NFS filesystem"), progname, spec);
		ret = EX_USAGE;
		goto err;
	}

	opts = retrieve_mount_options(mnt_context_get_fs(cxt));

	if (!mnt_context_is_lazy(cxt)) {
		if (opts) {
			/* we have full FS description (e.g. from mtab or /proc) */
			switch (is_vers4(cxt)) {
			case 0:
				/* We ignore the error from nfs_umount23.
				 * If the actual umount succeeds (in del_mtab),
				 * we don't want to signal an error, as that
				 * could cause /sbin/mount to retry!
				 */
				nfs_umount23(mnt_context_get_source(cxt), opts);
				break;
			case 1:			/* unknown */
				break;
			default:		/* error */
				goto err;
			}
		} else
			/* strange, no entry in mtab or /proc not mounted */
			nfs_umount23(spec, "tcp,v3");
	}

	ret = EX_FILEIO;
	rc = mnt_context_do_umount(cxt);	/* call umount(2) syscall */
	mnt_context_finalize_mount(cxt);	/* mtab update */

	if (rc && !mnt_context_get_status(cxt)) {
		/* mnt_context_do_umount() returns errno if umount(2) failed */
		umount_error(rc, spec);
		goto err;
	}
	ret = EX_SUCCESS;
err:
	free(opts);
	return ret;
}

static int mount_main(struct libmnt_context *cxt, int argc, char **argv)
{
	int rc, c;
	struct libmnt_fs *fs;
	char *spec = NULL, *mount_point = NULL, *opts = NULL;

	static const struct option longopts[] = {
	  { "fake", 0, 0, 'f' },
	  { "help", 0, 0, 'h' },
	  { "no-mtab", 0, 0, 'n' },
	  { "read-only", 0, 0, 'r' },
	  { "ro", 0, 0, 'r' },
	  { "verbose", 0, 0, 'v' },
	  { "version", 0, 0, 'V' },
	  { "read-write", 0, 0, 'w' },
	  { "rw", 0, 0, 'w' },
	  { "options", 1, 0, 'o' },
	  { "sloppy", 0, 0, 's' },
	  { NULL, 0, 0, 0 }
	};

	mount_config_init(progname);
	mnt_context_init_helper(cxt, MNT_ACT_MOUNT, 0);

	while ((c = getopt_long(argc, argv, "fhnrVvwo:s", longopts, NULL)) != -1) {

		rc = mnt_context_helper_setopt(cxt, c, optarg);
		if (rc == 0)		/* valid option */
			continue;
		if (rc < 0)		/* error (probably ENOMEM) */
			goto err;
					/* rc==1 means unknow option */
		switch (c) {
		case 'V':
			printf("%s: ("PACKAGE_STRING")\n", progname);
			return EX_SUCCESS;
		case 'h':
		default:
			mount_usage();
			return EX_USAGE;
		}
	}

	if (optind < argc)
		spec = argv[optind++];
	if (optind < argc)
		mount_point = argv[optind++];

	if (!mount_point) {
		nfs_error(_("%s: no mount point provided"), progname);
		goto err;
	}
	if (!spec) {
		nfs_error(_("%s: no mount spec provided"), progname);
		goto err;
	}

	if (geteuid() != 0) {
		nfs_error(_("%s: not installed setuid - "
			    "\"user\" NFS mounts not supported."), progname);
		goto err;
	}

	verbose = mnt_context_is_verbose(cxt);
	sloppy = mnt_context_is_sloppy(cxt);
	nomtab = mnt_context_is_nomtab(cxt);

	if (strcmp(progname, "mount.nfs4") == 0)
		mnt_context_set_fstype(cxt, "nfs4");
	else
		mnt_context_set_fstype(cxt, "nfs");	/* default */

	rc = mnt_context_set_source(cxt, spec);
	if (!rc)
		mnt_context_set_target(cxt, mount_point);
	if (rc) {
		nfs_error(_("%s: failed to set spec or mountpoint: %s"),
				progname, strerror(errno));
		goto err;
	}

	mount_point = mnt_resolve_path(mount_point,
				       mnt_context_get_cache(cxt));

	if (chk_mountpoint(mount_point))
		goto err;

	/*
	 * The libmount strictly uses only options from fstab if running in
	 * restricted mode (suid, non-root user). This is done in
	 * mnt_context_prepare_mount() by default.
	 *
	 * We have to read fstab before nfsmount.conf, otherwise the options
	 * from nfsmount.conf will be ignored (overwrited).
	 */
	rc = mnt_context_apply_fstab(cxt);
	if (rc) {
		nfs_error(_("%s: failed to apply fstab options\n"), progname);
		goto err;
	}

	/*
	 * Concatenate mount options from the configuration file
	 */
	fs = mnt_context_get_fs(cxt);
	if (fs) {
		opts = mnt_fs_strdup_options(fs);

		opts = mount_config_opts(spec, mount_point, opts);
		mnt_fs_set_options(fs, opts);
	}

	rc = mnt_context_prepare_mount(cxt);
	if (rc) {
		nfs_error(_("%s: failed to prepare mount: %s\n"),
					progname, strerror(-rc));
		goto err;
	}

	rc = try_mount(cxt, FOREGROUND);

	if (rc == EX_BG) {
		printf(_("%s: backgrounding \"%s\"\n"),
			progname, mnt_context_get_source(cxt));
		printf(_("%s: mount options: \"%s\"\n"),
			progname, opts);

		fflush(stdout);

		if (daemon(0, 0)) {
			nfs_error(_("%s: failed to start "
					"background process: %s\n"),
					progname, strerror(errno));
			exit(EX_FAIL);
		}

		rc = try_mount(cxt, BACKGROUND);

		if (verbose && rc)
			printf(_("%s: giving up \"%s\"\n"),
				progname, mnt_context_get_source(cxt));
	}

	mnt_context_set_syscall_status(cxt, rc == EX_SUCCESS ? 0 : -1);
	mnt_context_finalize_mount(cxt);	/* mtab update */
	return rc;
err:
	return EX_FAIL;
}

int main(int argc, char *argv[])
{
	struct libmnt_context *cxt;
	int rc;

	mnt_init_debug(0);
	cxt = mnt_new_context();
	if (!cxt) {
		nfs_error(_("Can't initilize libmount: %s"),
					strerror(errno));
		rc = EX_FAIL;
		goto done;
	}

	progname = basename(argv[0]);
	nfs_mount_data_version = discover_nfs_mount_data_version(&string);

	if(strncmp(progname, "umount", 6) == 0)
		rc = umount_main(cxt, argc, argv);
	else
		rc = mount_main(cxt, argc, argv);
done:
	mnt_free_context(cxt);
	return rc;
}
