/*
 * 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 "optutils.h"
#include "exitcodes.h"
#include "closestream.h"
#include "pathnames.h"
#include "canonicalize.h"
#include "xalloc.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(MOUNT_EX_SUCCESS);
}
static void __attribute__((__noreturn__)) usage(FILE *out)
{
	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(USAGE_SEPARATOR, out);
	fputs(USAGE_HELP, out);
	fputs(USAGE_VERSION, out);
	fprintf(out, USAGE_MAN_TAIL("umount(8)"));

	exit(out == stderr ? MOUNT_EX_USAGE : MOUNT_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(MOUNT_EX_USAGE,
				_("only root can use \"--%s\" option "
				 "(effective UID is %u)"),
					option, euid);
		errx(MOUNT_EX_USAGE, _("only root can do that "
				 "(effective UID is %u)"), euid);
	}
	if (option)
		errx(MOUNT_EX_USAGE, _("only root can use \"--%s\" option"), option);
	errx(MOUNT_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);
}

/*
 * Handles generic errors like ENOMEM, ...
 *
 * rc = 0 success
 *     <0 error (usually -errno)
 *
 * Returns exit status (MOUNT_EX_*) and prints error message.
 */
static int handle_generic_errors(int rc, const char *msg, ...)
{
	va_list va;

	va_start(va, msg);
	errno = -rc;

	switch(errno) {
	case EINVAL:
	case EPERM:
		vwarn(msg, va);
		rc = MOUNT_EX_USAGE;
		break;
	case ENOMEM:
		vwarn(msg, va);
		rc = MOUNT_EX_SYSERR;
		break;
	default:
		vwarn(msg, va);
		rc = MOUNT_EX_FAIL;
		break;
	}
	va_end(va);
	return rc;
}

static int mk_exit_code(struct libmnt_context *cxt, int rc)
{
	int syserr;
	const char *tgt = mnt_context_get_target(cxt);

	if (mnt_context_helper_executed(cxt))
		/*
		 * /sbin/umount.<type> called, return status
		 */
		return mnt_context_get_helper_status(cxt);

	if (rc == 0 && mnt_context_get_status(cxt) == 1)
		/*
		 * Libmount success && syscall success.
		 */
		return MOUNT_EX_SUCCESS;


	if (!mnt_context_syscall_called(cxt)) {
		/*
		 * libmount errors (extra library checks)
		 */
		if (rc == -EPERM && !mnt_context_tab_applied(cxt)) {
			/* failed to evaluate permissions because not found
			 * relevant entry in mtab */
			warnx(_("%s: not mounted"), tgt);
			return MOUNT_EX_USAGE;
		}
		return handle_generic_errors(rc, _("%s: umount failed"), tgt);

	} else if (mnt_context_get_syscall_errno(cxt) == 0) {
		/*
		 * umount(2) syscall success, but something else failed
		 * (probably error in mtab processing).
		 */
		if (rc < 0)
			return handle_generic_errors(rc,
				_("%s: filesystem was unmounted, but mount(8) failed"),
				tgt);

		return MOUNT_EX_SOFTWARE;	/* internal error */

	}

	/*
	 * umount(2) errors
	 */
	syserr = mnt_context_get_syscall_errno(cxt);

	switch(syserr) {
	case ENXIO:
		warnx(_("%s: invalid block device"), tgt);	/* ??? */
		break;
	case EINVAL:
		warnx(_("%s: not mounted"), tgt);
		break;
	case EIO:
		warnx(_("%s: can't write superblock"), tgt);
		break;
	case EBUSY:
		warnx(_("%s: target is busy\n"
		       "        (In some cases useful info about processes that\n"
		       "         use the device is found by lsof(8) or fuser(1).)"),
			tgt);
		break;
	case ENOENT:
		if (tgt && *tgt)
			warnx(_("%s: mountpoint not found"), tgt);
		else
			warnx(_("undefined mountpoint"));
		break;
	case EPERM:
		warnx(_("%s: must be superuser to unmount"), tgt);
		break;
	case EACCES:
		warnx(_("%s: block devices are not permitted on filesystem"), tgt);
		break;
	default:
		errno = syserr;
		warn("%s", tgt);
		break;
	}
	return MOUNT_EX_FAIL;
}

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 MOUNT_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 == MOUNT_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 MOUNT_EX_SOFTWARE;

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

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

	if (rc == MOUNT_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 = mnt_new_table();
	if (!tb)
		err(MOUNT_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;
	}

	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 = MOUNT_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(MOUNT_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 = MOUNT_EX_SOFTWARE;
			goto done;
		} else if (rc == 1)
			break;		/* no more children */

		rc = umount_do_recurse(cxt, tb, child);
		if (rc != MOUNT_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 MOUNT_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 = MOUNT_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 = MOUNT_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(MOUNT_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(MOUNT_EX_SYSERR, _("libmount iterator allocation failed"));

	/* get on @cxt independent mountinfo */
	tb = new_mountinfo(cxt);
	if (!tb) {
		rc = MOUNT_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 != MOUNT_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(MOUNT_EX_USAGE, "%s", path);

	return p;
}

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", 0, 0, 'a' },
		{ "all-targets", 0, 0, 'A' },
		{ "detach-loop", 0, 0, 'd' },
		{ "fake", 0, 0, UMOUNT_OPT_FAKE },
		{ "force", 0, 0, 'f' },
		{ "help", 0, 0, 'h' },
		{ "internal-only", 0, 0, 'i' },
		{ "lazy", 0, 0, 'l' },
		{ "no-canonicalize", 0, 0, 'c' },
		{ "no-mtab", 0, 0, 'n' },
		{ "read-only", 0, 0, 'r' },
		{ "recursive", 0, 0, 'R' },
		{ "test-opts", 1, 0, 'O' },
		{ "types", 1, 0, 't' },
		{ "verbose", 0, 0, 'v' },
		{ "version", 0, 0, 'V' },
		{ NULL, 0, 0, 0 }
	};

	static const ul_excl_t excl[] = {       /* rows and cols in 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(MOUNT_EX_SYSERR, _("libmount context allocation failed"));

	mnt_context_set_tables_errcb(cxt, table_parser_errcb);

	while ((c = getopt_long(argc, argv, "aAcdfhilnRrO:t:vV",
					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(stdout);
			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(MOUNT_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;
		default:
			usage(stderr);
			break;
		}
	}

	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) {
		usage(stderr);

	} 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;
}

