/* losetup.c - Loopback setup
 *
 * Copyright 2012 Rob Landley <rob@landley.net>
 *
 * No standard. (Sigh.)

USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdcaD[!afj]", TOYFLAG_SBIN))

config LOSETUP
  bool "losetup"
  default y
  help
    usage: losetup [-cdrs] [-o OFFSET] [-S SIZE] {-d DEVICE...|-j FILE|-af|{DEVICE FILE}}

    Associate a loopback device with a file, or show current file (if any)
    associated with a loop device.

    Instead of a device:
    -a	Iterate through all loopback devices
    -f	Find first unused loop device (may create one)
    -j FILE	Iterate through all loopback devices associated with FILE

    existing:
    -c	Check capacity (file size changed)
    -d DEV	Detach loopback device
    -D	Detach all loopback devices

    new:
    -s	Show device name (alias --show)
    -o OFF	Start association at offset OFF into FILE
    -r	Read only
    -S SIZE	Limit SIZE of loopback association (alias --sizelimit)
*/

#define FOR_losetup
#include "toys.h"
#include <linux/loop.h>

GLOBALS(
  char *j;
  long o, S;

  int openflags;
  dev_t jdev;
  ino_t jino;
  char *dir;
)

// -f: *device is NULL

// Perform requested operation on one device. Returns 1 if handled, 0 if error
static int loopback_setup(char *device, char *file)
{
  struct loop_info64 *loop = (void *)(toybuf+32);
  int lfd = -1, ffd = -1;
  int racy = !device;

  // Open file (ffd) and loop device (lfd)

  if (file) ffd = xopen(file, TT.openflags);
  if (!device) {
    int i, cfd = open("/dev/loop-control", O_RDWR);

    // We assume /dev is devtmpfs so device creation has no lag. Otherwise
    // just preallocate loop devices and stay within them.

    // mount -o loop depends on found device being at the start of toybuf.
    if (cfd != -1) {
      if (0 <= (i = ioctl(cfd, LOOP_CTL_GET_FREE))) {
        sprintf(device = toybuf, "%s/loop%d", TT.dir, i);
      }
      close(cfd);
    }
  }

  if (device) lfd = open(device, TT.openflags);

  // Stat the loop device to see if there's a current association.
  memset(loop, 0, sizeof(struct loop_info64));
  if (-1 == lfd || ioctl(lfd, LOOP_GET_STATUS64, loop)) {
    if (errno == ENXIO && (FLAG(a) || FLAG(j))) goto done;
    // ENXIO expected if we're just trying to print the first unused device.
    if (errno == ENXIO && FLAG(f) && !file) {
      puts(device);
      goto done;
    }
    if (errno != ENXIO || !file) {
      perror_msg_raw(device ? device : "-f");
      goto done;
    }
  }

  // Skip -j filtered devices
  if (TT.j && (loop->lo_device != TT.jdev || loop->lo_inode != TT.jino))
    goto done;

  // Check size of file or delete existing association
  if (FLAG(c) || FLAG(d)) {
    // The constant is LOOP_SET_CAPACITY
    if (ioctl(lfd, FLAG(c) ? 0x4C07 : LOOP_CLR_FD, 0)) {
      perror_msg_raw(device);
      goto done;
    }
  // Associate file with this device?
  } else if (file) {
    char *f_path = xabspath(file, 1);

    if (!f_path) perror_exit("file"); // already opened, but if deleted since...
    if (ioctl(lfd, LOOP_SET_FD, ffd)) {
      free(f_path);
      if (racy && errno == EBUSY) return 1;
      perror_exit("%s=%s", device, file);
    }
    xstrncpy((char *)loop->lo_file_name, f_path, LO_NAME_SIZE);
    free(f_path);
    loop->lo_offset = TT.o;
    loop->lo_sizelimit = TT.S;
    if (ioctl(lfd, LOOP_SET_STATUS64, loop)) perror_exit("%s=%s", device, file);
    if (FLAG(s)) puts(device);
  }
  else {
    xprintf("%s: [%lld]:%llu (%s)", device, (long long)loop->lo_device,
      (long long)loop->lo_inode, loop->lo_file_name);
    if (loop->lo_offset) xprintf(", offset %llu",
      (unsigned long long)loop->lo_offset);
    if (loop->lo_sizelimit) xprintf(", sizelimit %llu",
      (unsigned long long)loop->lo_sizelimit);
    xputc('\n');
  }

done:
  xclose(ffd);
  xclose(lfd);
  return 0;
}

// Perform an action on all currently existing loop devices
static int dash_a(struct dirtree *node)
{
  char *s = node->name;

  // Initial /dev node needs to recurse down one level, then only loop[0-9]*
  if (!node->parent) return DIRTREE_RECURSE;
  if (strncmp(s, "loop", 4) || !isdigit(s[4])) return 0;

  s = dirtree_path(node, 0);
  loopback_setup(s, 0);
  free(s);

  return 0;
}

void losetup_main(void)
{
  char **s;

  TT.dir = CFG_TOYBOX_ON_ANDROID ? "/dev/block" : "/dev";
  TT.openflags = FLAG(r) ? O_RDONLY : O_RDWR;

  if (TT.j) {
    struct stat st;

    xstat(TT.j, &st);
    TT.jdev = st.st_dev;
    TT.jino = st.st_ino;
  }

  // With just device, display current association
  // -a, -f substitute for device
  // -j substitute for device

  // new association: S size o offset rs - need a file
  // existing association: cd

  // -f(dc FILE)

  if (FLAG(D)) toys.optflags |= FLAG_a | FLAG_d;

  if (FLAG(f)) {
    if (toys.optc > 1) perror_exit("max 1 arg");
    while (loopback_setup(NULL, *toys.optargs));
  } else if (FLAG(a) || FLAG(j)) {
    if (toys.optc) error_exit("bad args");
    dirtree_read(TT.dir, dash_a);
  // Do we need one DEVICE argument?
  } else {
    char *file = (FLAG(c) || FLAG(d)) ? NULL : toys.optargs[1];

    if (!toys.optc || (file && toys.optc != 2))
      help_exit("needs %d arg%s", 1+!!file, file ? "s" : "");
    for (s = toys.optargs; *s; s++) {
      loopback_setup(*s, file);
      if (file) break;
    }
  }
}
