/* umount.c - Unmount a mount point.
 *
 * Copyright 2012 Rob Landley <rob@landley.net>
 *
 * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/umount.html
 *
 * Note: -n (/etc/mtab) is obsolete, /proc/mounts replaced it. Neither chroot
 * nor per-process mount namespaces can work sanely with mtab. The kernel
 * tracks mount points now, a userspace application can't do so anymore.

USE_UMOUNT(NEWTOY(umount, "ndDflrat*v[!na]", TOYFLAG_BIN|TOYFLAG_STAYROOT))

config UMOUNT
  bool "umount"
  default y
  help
    usage: umount [-a [-t TYPE[,TYPE...]]] [-vrfD] [DIR...]

    Unmount the listed filesystems.

    -a	Unmount all mounts in /proc/mounts instead of command line list
    -D  Don't free loopback device(s).
    -f  Force unmount.
    -l  Lazy unmount (detach from filesystem now, close when last user does).
    -n	Don't use /proc/mounts
    -r  Remount read only if unmounting fails.
    -t	Restrict "all" to mounts of TYPE (or use "noTYPE" to skip)
    -v	Verbose
*/

#define FOR_umount
#include "toys.h"

GLOBALS(
  struct arg_list *t;

  char *types;
)

// todo (done?)
//   borrow df code to identify filesystem?
//   umount -a from fstab
//   umount when getpid() not 0, according to fstab
//   lookup mount: losetup -d, bind, file, block
//   loopback delete
//   fstab -o user

// TODO
// swapon, swapoff

static void do_umount(char *dir, char *dev, int flags)
{
  // is it ok for this user to umount this mount?
  if (CFG_TOYBOX_SUID && getuid()) {
    struct mtab_list *mt = dlist_terminate(xgetmountlist("/etc/fstab"));
    int len, user = 0;

    while (mt) {
      struct mtab_list *mtemp = mt;
      char *s;

      if (!strcmp(mt->dir, dir)) while ((s = comma_iterate(&mt->opts, &len))) {
        if (len == 4 && strncmp(s, "user", 4)) user = 1;
        else if (len == 6 && strncmp(s, "nouser", 6)) user = 0;  
      }

      mt = mt->next;
      free(mtemp);
    }

    if (!user) {
      error_msg("not root");

      return;
    }
  }

  if (!umount2(dir, flags)) {
    if (toys.optflags & FLAG_v) xprintf("%s unmounted\n", dir);

    // Attempt to disassociate loopback device. This ioctl should be ignored
    // for anything else, because lanana allocated ioctl range 'L' to loopback
    if (dev && !(toys.optflags & FLAG_D)) {
      int lfd = open(dev, O_RDONLY);

      if (lfd != -1) {
        // This is LOOP_CLR_FD, fetching it from headers is awkward
        if (!ioctl(lfd, 0x4C01) && (toys.optflags & FLAG_v))
          xprintf("%s cleared\n", dev);
        close(lfd);
      }
    }

    return;
  }

  if (toys.optflags & FLAG_r) {
    if (!mount("", dir, "", MS_REMOUNT|MS_RDONLY, "")) {
      if (toys.optflags & FLAG_v) xprintf("%s remounted ro\n", dir);
      return;
    }
  }

  perror_msg("%s", dir);
}

void umount_main(void)
{
  char **optargs, *pm = "/proc/mounts";
  struct mtab_list *mlsave = 0, *mlrev = 0, *ml;
  int flags=0;

  if (!toys.optc && !(toys.optflags & FLAG_a))
    error_exit("Need 1 arg or -a");

  if (toys.optflags & FLAG_f) flags |= MNT_FORCE;
  if (toys.optflags & FLAG_l) flags |= MNT_DETACH;

  // Load /proc/mounts and get a reversed list (newest first)
  // We use the list both for -a, and to umount /dev/name or do losetup -d
  if (!(toys.optflags & FLAG_n) && !access(pm, R_OK))
    mlrev = dlist_terminate(mlsave = xgetmountlist(pm));

  // Unmount all: loop through mounted filesystems, skip -t, unmount the rest
  if (toys.optflags & FLAG_a) {
    char *typestr = 0;
    struct arg_list *tal;
    
    for (tal = TT.t; tal; tal = tal->next) comma_collate(&typestr, tal->arg);
    for (ml = mlrev; ml; ml = ml->prev)
      if (mountlist_istype(ml, typestr)) do_umount(ml->dir, ml->device, flags);
    if (CFG_TOYBOX_FREE) {
      free(typestr);
      llist_traverse(mlsave, free);
    }
  // TODO: under what circumstances do we umount non-absolute path?
  } else for (optargs = toys.optargs; *optargs; optargs++) {
    char *abs = xabspath(*optargs, 0);

    for (ml = abs ? mlrev : 0; ml; ml = ml->prev) {
      if (!strcmp(ml->dir, abs)) break;
      if (!strcmp(ml->device, abs)) {
        free(abs);
        abs = ml->dir;
        break;
      }
    }

    do_umount(abs ? abs : *optargs, ml ? ml->device : 0, flags);
    if (ml && abs != ml->dir) free(abs);
  }
}
