/* 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_raw(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);
  }
}
