/* 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>
 *
 * This program is licensed under the GNU General Public license (GPL)
 * version 2 or later, see http://www.fsf.org/licensing/licenses/gpl.html
 * or the file "LICENSE" in the busybox source tarball for the full text.
 *
 */

#include <limits.h>
#include <stdio.h>
#include <mntent.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <getopt.h>
#include "busybox.h"

#define OPTION_STRING		"flDnrva"
#define OPT_FORCE			1
#define OPT_LAZY			2
#define OPT_DONTFREELOOP	4
#define OPT_NO_MTAB			8
#define OPT_REMOUNT			16
#define OPT_IGNORED			32	// -v is ignored
#define OPT_ALL				(ENABLE_FEATURE_UMOUNT_ALL ? 64 : 0)

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

	/* Parse any options */

	opt = bb_getopt_ulflags (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(opt & OPT_ALL) {

		/* 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")))
			bb_error_msg_and_die("Cannot open %s", bb_path_mtab_file);
		while (getmntent_r(fp,&me,path,sizeof(path))) {
			m=xmalloc(sizeof(struct mtab_list));
			m->next=mtl;
			m->device=bb_xstrdup(me.mnt_fsname);
			m->dir=bb_xstrdup(me.mnt_dir);
			mtl=m;
		}
		endmntent(fp);

	/* If we're not mounting all, we need at least one argument. */
	} else if(argc <= 0) bb_show_usage();
	
	// Loop through everything we're supposed to umount, and do so.
	for(;;) {
		int curstat;

		// 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 {
			// Get next command line argument (and look it up in mtab list)
			realpath(*argv++, path);
			if (ENABLE_FEATURE_MTAB_SUPPORT)
				for(m = mtl; m; m = m->next)
					if(!strcmp(path, m->dir) || !strcmp(path, m->device))
						break;
		}

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

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

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

		/* 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(curstat) {
			/* Yes, the ENABLE is redundant here, but the optimizer for ARM
			 * can't do simple constant propagation in local variables... */
			if(ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m)
				erase_mtab(m->dir);
			status = EXIT_FAILURE;
			bb_perror_msg("Couldn't umount %s", path);
		}
		// Find next matching mtab entry for -a or umount /dev
		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;
}
