/* vi: set sw=4 ts=4: */
/*
 * Mini umount implementation for busybox
 *
 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
 * Copyright (C) 2005 by Rob Landley <rob@landley.net>
 *
 * Licensed under GPL version 2, see file LICENSE in this tarball for details.
 */

#include "busybox.h"
#include <mntent.h>
#include <getopt.h>

#define OPTION_STRING		"flDnravd"
#define OPT_FORCE			1
#define OPT_LAZY			2
#define OPT_DONTFREELOOP	4
#define OPT_NO_MTAB			8
#define OPT_REMOUNT			16
#define OPT_ALL				(ENABLE_FEATURE_UMOUNT_ALL ? 32 : 0)

int umount_main(int argc, char **argv)
{
	int doForce;
	char path[2*PATH_MAX];
	struct mntent me;
	FILE *fp;
	int status = EXIT_SUCCESS;
	unsigned opt;
	struct mtab_list {
		char *dir;
		char *device;
		struct mtab_list *next;
	} *mtl, *m;

	/* Parse any options */

	opt = getopt32(argc, argv, OPTION_STRING);

	argc -= optind;
	argv += optind;

	doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY));

	/* Get a list of mount points from mtab.  We read them all in now mostly
	 * for umount -a (so we don't have to worry about the list changing while
	 * we iterate over it, or about getting stuck in a loop on the same failing
	 * entry.  Notice that this also naturally reverses the list so that -a
	 * umounts the most recent entries first. */

	m = mtl = 0;

	/* If we're umounting all, then m points to the start of the list and
	 * the argument list should be empty (which will match all). */

	if (!(fp = setmntent(bb_path_mtab_file, "r"))) {
		if (opt & OPT_ALL)
			bb_error_msg_and_die("cannot open %s", bb_path_mtab_file);
	} else {
		while (getmntent_r(fp,&me,path,sizeof(path))) {
			m = xmalloc(sizeof(struct mtab_list));
			m->next = mtl;
			m->device = xstrdup(me.mnt_fsname);
			m->dir = xstrdup(me.mnt_dir);
			mtl = m;
		}
		endmntent(fp);
	}

	/* If we're not mounting all, we need at least one argument. */
	if (!(opt & OPT_ALL)) {
		m = 0;
		if (!argc) bb_show_usage();
	}

	// Loop through everything we're supposed to umount, and do so.
	for (;;) {
		int curstat;
		char *zapit = *argv;

		// Do we already know what to umount this time through the loop?
		if (m) safe_strncpy(path, m->dir, PATH_MAX);
		// For umount -a, end of mtab means time to exit.
		else if (opt & OPT_ALL) break;
		// Get next command line argument (and look it up in mtab list)
		else if (!argc--) break;
		else {
			argv++;
			realpath(zapit, path);
			for (m = mtl; m; m = m->next)
				if (!strcmp(path, m->dir) || !strcmp(path, m->device))
					break;
		}
		// If we couldn't find this sucker in /etc/mtab, punt by passing our
		// command line argument straight to the umount syscall.  Otherwise,
		// umount the directory even if we were given the block device.
		if (m) zapit = m->dir;

		// Let's ask the thing nicely to unmount.
		curstat = umount(zapit);

		// Force the unmount, if necessary.
		if (curstat && doForce) {
			curstat = umount2(zapit, doForce);
			if (curstat)
				bb_error_msg_and_die("forced umount of %s failed!", zapit);
		}

		// If still can't umount, maybe remount read-only?
		if (curstat && (opt & OPT_REMOUNT) && errno == EBUSY && m) {
			curstat = mount(m->device, zapit, NULL, MS_REMOUNT|MS_RDONLY, NULL);
			bb_error_msg(curstat ? "cannot remount %s read-only" :
						 "%s busy - remounted read-only", m->device);
		}

		if (curstat) {
			status = EXIT_FAILURE;
			bb_perror_msg("cannot umount %s", zapit);
		} else {
			/* De-allocate the loop device.  This ioctl should be ignored on
			 * any non-loop block devices. */
			if (ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONTFREELOOP) && m)
				del_loop(m->device);
			if (ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m)
				erase_mtab(m->dir);
		}

		// Find next matching mtab entry for -a or umount /dev
		// Note this means that "umount /dev/blah" will unmount all instances
		// of /dev/blah, not just the most recent.
		while (m && (m = m->next))
			if ((opt & OPT_ALL) || !strcmp(path,m->device))
				break;
	}

	// Free mtab list if necessary

	if (ENABLE_FEATURE_CLEAN_UP) {
		while (mtl) {
			m = mtl->next;
			free(mtl->device);
			free(mtl->dir);
			free(mtl);
			mtl = m;
		}
	}

	return status;
}
