/*
 * umount(8) -- mount a filesystem
 *
 * Copyright (C) 2011 Red Hat, Inc. All rights reserved.
 * Written by 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 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it would 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 02110-1301 USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <sys/types.h>

#include <libmount.h>

#include "nls.h"
#include "c.h"
#include "env.h"
#include "closestream.h"
#include "pathnames.h"
#include "canonicalize.h"

#define XALLOC_EXIT_CODE MNT_EX_SYSERR
#include "xalloc.h"

#define OPTUTILS_EXIT_CODE MNT_EX_USAGE
#include "optutils.h"

static int table_parser_errcb(struct libmnt_table *tb __attribute__((__unused__)),
			const char *filename, int line)
{
	if (filename)
		warnx(_("%s: parse error at line %d -- ignored"), filename, line);
	return 1;
}


static void __attribute__((__noreturn__)) print_version(void)
{
	const char *ver = NULL;
	const char **features = NULL, **p;

	mnt_get_library_version(&ver);
	mnt_get_library_features(&features);

	printf(_("%s from %s (libmount %s"),
			program_invocation_short_name,
			PACKAGE_STRING,
			ver);
	p = features;
	while (p && *p) {
		fputs(p == features ? ": " : ", ", stdout);
		fputs(*p++, stdout);
	}
	fputs(")\n", stdout);
	exit(MNT_EX_SUCCESS);
}
static void __attribute__((__noreturn__)) usage(void)
{
	FILE *out = stdout;
	fputs(USAGE_HEADER, out);
	fprintf(out, _(
		" %1$s [-hV]\n"
		" %1$s -a [options]\n"
		" %1$s [options] <source> | <directory>\n"),
		program_invocation_short_name);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("Unmount filesystems.\n"), out);

	fputs(USAGE_OPTIONS, out);
	fputs(_(" -a, --all               unmount all filesystems\n"), out);
	fputs(_(" -A, --all-targets       unmount all mountpoints for the given device in the\n"
	        "                           current namespace\n"), out);
	fputs(_(" -c, --no-canonicalize   don't canonicalize paths\n"), out);
	fputs(_(" -d, --detach-loop       if mounted loop device, also free this loop device\n"), out);
	fputs(_("     --fake              dry run; skip the umount(2) syscall\n"), out);
	fputs(_(" -f, --force             force unmount (in case of an unreachable NFS system)\n"), out);
	fputs(_(" -i, --internal-only     don't call the umount.<type> helpers\n"), out);
	fputs(_(" -n, --no-mtab           don't write to /etc/mtab\n"), out);
	fputs(_(" -l, --lazy              detach the filesystem now, clean up things later\n"), out);
	fputs(_(" -O, --test-opts <list>  limit the set of filesystems (use with -a)\n"), out);
	fputs(_(" -R, --recursive         recursively unmount a target with all its children\n"), out);
	fputs(_(" -r, --read-only         in case unmounting fails, try to remount read-only\n"), out);
	fputs(_(" -t, --types <list>      limit the set of filesystem types\n"), out);
	fputs(_(" -v, --verbose           say what is being done\n"), out);
	fputs(_(" -N, --namespace <ns>    perform umount in another namespace\n"), out);

	fputs(USAGE_SEPARATOR, out);
	printf(USAGE_HELP_OPTIONS(25));
	printf(USAGE_MAN_TAIL("umount(8)"));

	exit(MNT_EX_SUCCESS);
}

static void __attribute__((__noreturn__)) exit_non_root(const char *option)
{
	const uid_t ruid = getuid();
	const uid_t euid = geteuid();

	if (ruid == 0 && euid != 0) {
		/* user is root, but setuid to non-root */
		if (option)
			errx(MNT_EX_USAGE,
				_("only root can use \"--%s\" option "
				 "(effective UID is %u)"),
					option, euid);
		errx(MNT_EX_USAGE, _("only root can do that "
				 "(effective UID is %u)"), euid);
	}
	if (option)
		errx(MNT_EX_USAGE, _("only root can use \"--%s\" option"), option);
	errx(MNT_EX_USAGE, _("only root can do that"));
}

static void success_message(struct libmnt_context *cxt)
{
	const char *tgt, *src;

	if (mnt_context_helper_executed(cxt)
	    || mnt_context_get_status(cxt) != 1)
		return;

	tgt = mnt_context_get_target(cxt);
	if (!tgt)
		return;

	src = mnt_context_get_source(cxt);
	if (src)
		warnx(_("%s (%s) unmounted"), tgt, src);
	else
		warnx(_("%s unmounted"), tgt);
}

static int mk_exit_code(struct libmnt_context *cxt, int rc)
{
	char buf[BUFSIZ] = { 0 };

	rc = mnt_context_get_excode(cxt, rc, buf, sizeof(buf));
	if (*buf) {
		const char *spec = mnt_context_get_target(cxt);
		if (!spec)
			spec = mnt_context_get_source(cxt);
		if (!spec)
			spec = "???";
		warnx("%s: %s.", spec, buf);
	}
	return rc;
}

static int umount_all(struct libmnt_context *cxt)
{
	struct libmnt_iter *itr;
	struct libmnt_fs *fs;
	int mntrc, ignored, rc = 0;

	itr = mnt_new_iter(MNT_ITER_BACKWARD);
	if (!itr) {
		warn(_("failed to initialize libmount iterator"));
		return MNT_EX_SYSERR;
	}

	while (mnt_context_next_umount(cxt, itr, &fs, &mntrc, &ignored) == 0) {

		const char *tgt = mnt_fs_get_target(fs);

		if (ignored) {
			if (mnt_context_is_verbose(cxt))
				printf(_("%-25s: ignored\n"), tgt);
		} else {
			int xrc = mk_exit_code(cxt, mntrc);

			if (xrc == MNT_EX_SUCCESS
			    && mnt_context_is_verbose(cxt))
				printf("%-25s: successfully unmounted\n", tgt);
			rc |= xrc;
		}
	}

	mnt_free_iter(itr);
	return rc;
}

static int umount_one(struct libmnt_context *cxt, const char *spec)
{
	int rc;

	if (!spec)
		return MNT_EX_SOFTWARE;

	if (mnt_context_set_target(cxt, spec))
		err(MNT_EX_SYSERR, _("failed to set umount target"));

	rc = mnt_context_umount(cxt);
	rc = mk_exit_code(cxt, rc);

	if (rc == MNT_EX_SUCCESS && mnt_context_is_verbose(cxt))
		success_message(cxt);

	mnt_reset_context(cxt);
	return rc;
}

static struct libmnt_table *new_mountinfo(struct libmnt_context *cxt)
{
	struct libmnt_table *tb;
	struct libmnt_ns *ns_old = mnt_context_switch_target_ns(cxt);

	if (!ns_old)
		err(MNT_EX_SYSERR, _("failed to switch namespace"));

	tb = mnt_new_table();
	if (!tb)
		err(MNT_EX_SYSERR, _("libmount table allocation failed"));

	mnt_table_set_parser_errcb(tb, table_parser_errcb);
	mnt_table_set_cache(tb, mnt_context_get_cache(cxt));

	if (mnt_table_parse_file(tb, _PATH_PROC_MOUNTINFO)) {
		warn(_("failed to parse %s"), _PATH_PROC_MOUNTINFO);
		mnt_unref_table(tb);
		tb = NULL;
	}

	if (!mnt_context_switch_ns(cxt, ns_old))
		err(MNT_EX_SYSERR, _("failed to switch namespace"));

	return tb;
}

/*
 * like umount_one() but does not return error is @spec not mounted
 */
static int umount_one_if_mounted(struct libmnt_context *cxt, const char *spec)
{
	int rc;
	struct libmnt_fs *fs;

	rc = mnt_context_find_umount_fs(cxt, spec, &fs);
	if (rc == 1) {
		rc = MNT_EX_SUCCESS;		/* already unmounted */
		mnt_reset_context(cxt);
	} else if (rc < 0) {
		rc = mk_exit_code(cxt, rc);	/* error */
		mnt_reset_context(cxt);
	} else
		rc = umount_one(cxt, mnt_fs_get_target(fs));

	return rc;
}

static int umount_do_recurse(struct libmnt_context *cxt,
		struct libmnt_table *tb, struct libmnt_fs *fs)
{
	struct libmnt_fs *child;
	struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_BACKWARD);
	int rc;

	if (!itr)
		err(MNT_EX_SYSERR, _("libmount iterator allocation failed"));

	/* umount all children */
	for (;;) {
		rc = mnt_table_next_child_fs(tb, itr, fs, &child);
		if (rc < 0) {
			warnx(_("failed to get child fs of %s"),
					mnt_fs_get_target(fs));
			rc = MNT_EX_SOFTWARE;
			goto done;
		} else if (rc == 1)
			break;		/* no more children */

		rc = umount_do_recurse(cxt, tb, child);
		if (rc != MNT_EX_SUCCESS)
			goto done;
	}

	rc = umount_one_if_mounted(cxt, mnt_fs_get_target(fs));
done:
	mnt_free_iter(itr);
	return rc;
}

static int umount_recursive(struct libmnt_context *cxt, const char *spec)
{
	struct libmnt_table *tb;
	struct libmnt_fs *fs;
	int rc;

	tb = new_mountinfo(cxt);
	if (!tb)
		return MNT_EX_SOFTWARE;

	/* it's always real mountpoint, don't assume that the target maybe a device */
	mnt_context_disable_swapmatch(cxt, 1);

	fs = mnt_table_find_target(tb, spec, MNT_ITER_BACKWARD);
	if (fs)
		rc = umount_do_recurse(cxt, tb, fs);
	else {
		rc = MNT_EX_USAGE;
		warnx(access(spec, F_OK) == 0 ?
				_("%s: not mounted") :
				_("%s: not found"), spec);
	}

	mnt_unref_table(tb);
	return rc;
}

static int umount_alltargets(struct libmnt_context *cxt, const char *spec, int rec)
{
	struct libmnt_fs *fs;
	struct libmnt_table *tb;
	struct libmnt_iter *itr = NULL;
	dev_t devno = 0;
	int rc;

	/* Convert @spec to device name, Use the same logic like regular
	 * "umount <spec>".
	 */
	rc = mnt_context_find_umount_fs(cxt, spec, &fs);
	if (rc == 1) {
		rc = MNT_EX_USAGE;
		warnx(access(spec, F_OK) == 0 ?
				_("%s: not mounted") :
				_("%s: not found"), spec);
		return rc;
	}
	if (rc < 0)
		return mk_exit_code(cxt, rc);		/* error */

	if (!mnt_fs_get_srcpath(fs) || !mnt_fs_get_devno(fs))
		errx(MNT_EX_USAGE, _("%s: failed to determine source "
				"(--all-targets is unsupported on systems with "
				"regular mtab file)."), spec);

	itr = mnt_new_iter(MNT_ITER_BACKWARD);
	if (!itr)
		err(MNT_EX_SYSERR, _("libmount iterator allocation failed"));

	/* get on @cxt independent mountinfo */
	tb = new_mountinfo(cxt);
	if (!tb) {
		rc = MNT_EX_SOFTWARE;
		goto done;
	}

	/* Note that @fs is from mount context and the context will be reset
	 * after each umount() call */
	devno = mnt_fs_get_devno(fs);
	fs = NULL;

	mnt_reset_context(cxt);

	while (mnt_table_next_fs(tb, itr, &fs) == 0) {
		if (mnt_fs_get_devno(fs) != devno)
			continue;
		mnt_context_disable_swapmatch(cxt, 1);
		if (rec)
			rc = umount_do_recurse(cxt, tb, fs);
		else
			rc = umount_one_if_mounted(cxt, mnt_fs_get_target(fs));

		if (rc != MNT_EX_SUCCESS)
			break;
	}

done:
	mnt_free_iter(itr);
	mnt_unref_table(tb);

	return rc;
}

/*
 * Check path -- non-root user should not be able to resolve path which is
 * unreadable for him.
 */
static char *sanitize_path(const char *path)
{
	char *p;

	if (!path)
		return NULL;

	p = canonicalize_path_restricted(path);
	if (!p)
		err(MNT_EX_USAGE, "%s", path);

	return p;
}

static pid_t parse_pid(const char *str)
{
	char *end;
	pid_t ret;

	errno = 0;
	ret = strtoul(str, &end, 10);

	if (ret < 0 || errno || end == str || (end && *end))
		return 0;
	return ret;
}

int main(int argc, char **argv)
{
	int c, rc = 0, all = 0, recursive = 0, alltargets = 0;
	struct libmnt_context *cxt;
	char *types = NULL;

	enum {
		UMOUNT_OPT_FAKE = CHAR_MAX + 1,
	};

	static const struct option longopts[] = {
		{ "all",             no_argument,       NULL, 'a'             },
		{ "all-targets",     no_argument,       NULL, 'A'             },
		{ "detach-loop",     no_argument,       NULL, 'd'             },
		{ "fake",            no_argument,       NULL, UMOUNT_OPT_FAKE },
		{ "force",           no_argument,       NULL, 'f'             },
		{ "help",            no_argument,       NULL, 'h'             },
		{ "internal-only",   no_argument,       NULL, 'i'             },
		{ "lazy",            no_argument,       NULL, 'l'             },
		{ "no-canonicalize", no_argument,       NULL, 'c'             },
		{ "no-mtab",         no_argument,       NULL, 'n'             },
		{ "read-only",       no_argument,       NULL, 'r'             },
		{ "recursive",       no_argument,       NULL, 'R'             },
		{ "test-opts",       required_argument, NULL, 'O'             },
		{ "types",           required_argument, NULL, 't'             },
		{ "verbose",         no_argument,       NULL, 'v'             },
		{ "version",         no_argument,       NULL, 'V'             },
		{ "namespace",       required_argument, NULL, 'N'             },
		{ NULL, 0, NULL, 0 }
	};

	static const ul_excl_t excl[] = {       /* rows and cols in ASCII order */
		{ 'A','a' },			/* all-targets,all */
		{ 'R','a' },			/* recursive,all */
		{ 'O','R','t'},			/* options,recursive,types */
		{ 'R','r' },			/* recursive,read-only */
		{ 0 }
	};
	int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;

	sanitize_env();
	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	mnt_init_debug(0);
	cxt = mnt_new_context();
	if (!cxt)
		err(MNT_EX_SYSERR, _("libmount context allocation failed"));

	mnt_context_set_tables_errcb(cxt, table_parser_errcb);

	while ((c = getopt_long(argc, argv, "aAcdfhilnRrO:t:vVN:",
					longopts, NULL)) != -1) {


		/* only few options are allowed for non-root users */
		if (mnt_context_is_restricted(cxt) && !strchr("hdilVv", c))
			exit_non_root(option_to_longopt(c, longopts));

		err_exclusive_options(c, longopts, excl, excl_st);

		switch(c) {
		case 'a':
			all = 1;
			break;
		case 'A':
			alltargets = 1;
			break;
		case 'c':
			mnt_context_disable_canonicalize(cxt, TRUE);
			break;
		case 'd':
			mnt_context_enable_loopdel(cxt, TRUE);
			break;
		case UMOUNT_OPT_FAKE:
			mnt_context_enable_fake(cxt, TRUE);
			break;
		case 'f':
			mnt_context_enable_force(cxt, TRUE);
			break;
		case 'h':
			usage();
			break;
		case 'i':
			mnt_context_disable_helpers(cxt, TRUE);
			break;
		case 'l':
			mnt_context_enable_lazy(cxt, TRUE);
			break;
		case 'n':
			mnt_context_disable_mtab(cxt, TRUE);
			break;
		case 'r':
			mnt_context_enable_rdonly_umount(cxt, TRUE);
			break;
		case 'R':
			recursive = TRUE;
			break;
		case 'O':
			if (mnt_context_set_options_pattern(cxt, optarg))
				err(MNT_EX_SYSERR, _("failed to set options pattern"));
			break;
		case 't':
			types = optarg;
			break;
		case 'v':
			mnt_context_enable_verbose(cxt, TRUE);
			break;
		case 'V':
			print_version();
			break;
		case 'N':
		{
			char path[PATH_MAX];
			pid_t pid = parse_pid(optarg);

			if (pid)
				snprintf(path, sizeof(path), "/proc/%i/ns/mnt", pid);

			if (mnt_context_set_target_ns(cxt, pid ? path : optarg))
				err(MNT_EX_SYSERR, _("failed to set target namespace to %s"), pid ? path : optarg);
			break;
		}
		default:
			errtryhelp(MNT_EX_USAGE);
		}
	}

	argc -= optind;
	argv += optind;

	if (all) {
		if (!types)
			types = "noproc,nodevfs,nodevpts,nosysfs,norpc_pipefs,nonfsd,noselinuxfs";

		mnt_context_set_fstype_pattern(cxt, types);
		rc = umount_all(cxt);

	} else if (argc < 1) {
		warnx(_("bad usage"));
		errtryhelp(MNT_EX_USAGE);

	} else if (alltargets) {
		while (argc--)
			rc += umount_alltargets(cxt, *argv++, recursive);
	} else if (recursive) {
		while (argc--)
			rc += umount_recursive(cxt, *argv++);
	} else {
		while (argc--) {
			char *path = *argv;

			if (mnt_context_is_restricted(cxt)
			    && !mnt_tag_is_valid(path))
				path = sanitize_path(path);

			rc += umount_one(cxt, path);

			if (path != *argv)
				free(path);
			argv++;
		}
	}

	mnt_free_context(cxt);
	return (rc < 256) ? rc : 255;
}

