/*
 * Copyright (C) 2011 Karel Zak <kzak@redhat.com>
 * Originally from Ted's losetup.c
 *
 * losetup.c - setup and control loop devices
 */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <getopt.h>

#include <libsmartcols.h>

#include "c.h"
#include "nls.h"
#include "strutils.h"
#include "loopdev.h"
#include "closestream.h"
#include "optutils.h"
#include "xalloc.h"
#include "canonicalize.h"
#include "pathnames.h"

enum {
	A_CREATE = 1,		/* setup a new device */
	A_DELETE,		/* delete given device(s) */
	A_DELETE_ALL,		/* delete all devices */
	A_SHOW,			/* list devices */
	A_SHOW_ONE,		/* print info about one device */
	A_FIND_FREE,		/* find first unused */
	A_SET_CAPACITY,		/* set device capacity */
	A_SET_DIRECT_IO,	/* set accessing backing file by direct io */
	A_SET_BLOCKSIZE,	/* set logical block size of the loop device */
};

enum {
	COL_NAME = 0,
	COL_AUTOCLR,
	COL_BACK_FILE,
	COL_BACK_INO,
	COL_BACK_MAJMIN,
	COL_MAJMIN,
	COL_OFFSET,
	COL_PARTSCAN,
	COL_RO,
	COL_SIZELIMIT,
	COL_DIO,
	COL_LOGSEC,
};

/* basic output flags */
static int no_headings;
static int raw;
static int json;

struct colinfo {
	const char *name;
	double whint;
	int flags;
	const char *help;

	int json_type;	/* default is string */
};

static struct colinfo infos[] = {
	[COL_AUTOCLR]     = { "AUTOCLEAR",    1, SCOLS_FL_RIGHT, N_("autoclear flag set"), SCOLS_JSON_BOOLEAN},
	[COL_BACK_FILE]   = { "BACK-FILE",  0.3, 0, N_("device backing file")},
	[COL_BACK_INO]    = { "BACK-INO",     4, SCOLS_FL_RIGHT, N_("backing file inode number"), SCOLS_JSON_NUMBER},
	[COL_BACK_MAJMIN] = { "BACK-MAJ:MIN", 6, 0, N_("backing file major:minor device number")},
	[COL_NAME]        = { "NAME",      0.25, 0, N_("loop device name")},
	[COL_OFFSET]      = { "OFFSET",       5, SCOLS_FL_RIGHT, N_("offset from the beginning"), SCOLS_JSON_NUMBER},
	[COL_PARTSCAN]    = { "PARTSCAN",     1, SCOLS_FL_RIGHT, N_("partscan flag set"), SCOLS_JSON_BOOLEAN},
	[COL_RO]          = { "RO",           1, SCOLS_FL_RIGHT, N_("read-only device"), SCOLS_JSON_BOOLEAN},
	[COL_SIZELIMIT]   = { "SIZELIMIT",    5, SCOLS_FL_RIGHT, N_("size limit of the file in bytes"), SCOLS_JSON_NUMBER},
	[COL_MAJMIN]      = { "MAJ:MIN",      3, 0, N_("loop device major:minor number")},
	[COL_DIO]         = { "DIO",          1, SCOLS_FL_RIGHT, N_("access backing file with direct-io"), SCOLS_JSON_BOOLEAN},
	[COL_LOGSEC]      = { "LOG-SEC",      4, SCOLS_FL_RIGHT, N_("logical sector size in bytes"), SCOLS_JSON_NUMBER},
};

static int columns[ARRAY_SIZE(infos) * 2] = {-1};
static size_t ncolumns;

static int get_column_id(int num)
{
	assert(num >= 0);
	assert((size_t) num < ncolumns);
	assert(columns[num] < (int) ARRAY_SIZE(infos));
	return columns[num];
}

static struct colinfo *get_column_info(int num)
{
	return &infos[ get_column_id(num) ];
}

static int column_name_to_id(const char *name, size_t namesz)
{
	size_t i;

	for (i = 0; i < ARRAY_SIZE(infos); i++) {
		const char *cn = infos[i].name;

		if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
			return i;
	}
	warnx(_("unknown column: %s"), name);
	return -1;
}

static int printf_loopdev(struct loopdev_cxt *lc)
{
	uint64_t x;
	dev_t dev = 0;
	ino_t ino = 0;
	char *fname;
	uint32_t type;

	fname = loopcxt_get_backing_file(lc);
	if (!fname)
		return -EINVAL;

	if (loopcxt_get_backing_devno(lc, &dev) == 0)
		loopcxt_get_backing_inode(lc, &ino);

	if (!dev && !ino) {
		/*
		 * Probably non-root user (no permissions to
		 * call LOOP_GET_STATUS ioctls).
		 */
		printf("%s: []: (%s)",
			loopcxt_get_device(lc), fname);

		if (loopcxt_get_offset(lc, &x) == 0 && x)
				printf(_(", offset %ju"), x);

		if (loopcxt_get_sizelimit(lc, &x) == 0 && x)
				printf(_(", sizelimit %ju"), x);
		printf("\n");
		return 0;
	}

	printf("%s: [%04d]:%" PRIu64 " (%s)",
		loopcxt_get_device(lc), (int) dev, ino, fname);

	if (loopcxt_get_offset(lc, &x) == 0 && x)
			printf(_(", offset %ju"), x);

	if (loopcxt_get_sizelimit(lc, &x) == 0 && x)
			printf(_(", sizelimit %ju"), x);

	if (loopcxt_get_encrypt_type(lc, &type) == 0) {
		const char *e = loopcxt_get_crypt_name(lc);

		if ((!e || !*e) && type == 1)
			e = "XOR";
		if (e && *e)
			printf(_(", encryption %s (type %u)"), e, type);
	}
	printf("\n");
	return 0;
}

static int show_all_loops(struct loopdev_cxt *lc, const char *file,
			  uint64_t offset, int flags)
{
	struct stat sbuf, *st = &sbuf;
	char *cn_file = NULL;

	if (loopcxt_init_iterator(lc, LOOPITER_FL_USED))
		return -1;

	if (!file || stat(file, st))
		st = NULL;

	while (loopcxt_next(lc) == 0) {
		if (file) {
			int used;
			const char *bf = cn_file ? cn_file : file;

			used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
			if (!used && !cn_file) {
				bf = cn_file = canonicalize_path(file);
				used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
			}
			if (!used)
				continue;
		}
		printf_loopdev(lc);
	}
	loopcxt_deinit_iterator(lc);
	free(cn_file);
	return 0;
}

static int delete_loop(struct loopdev_cxt *lc)
{
	if (loopcxt_delete_device(lc))
		warn(_("%s: detach failed"), loopcxt_get_device(lc));
	else
		return 0;

	return -1;
}

static int delete_all_loops(struct loopdev_cxt *lc)
{
	int res = 0;

	if (loopcxt_init_iterator(lc, LOOPITER_FL_USED))
		return -1;

	while (loopcxt_next(lc) == 0)
		res += delete_loop(lc);

	loopcxt_deinit_iterator(lc);
	return res;
}

static int set_scols_data(struct loopdev_cxt *lc, struct libscols_line *ln)
{
	size_t i;

	for (i = 0; i < ncolumns; i++) {
		const char *p = NULL;			/* external data */
		char *np = NULL;			/* allocated here */
		uint64_t x = 0;
		int rc = 0;

		switch(get_column_id(i)) {
		case COL_NAME:
			p = loopcxt_get_device(lc);
			break;
		case COL_BACK_FILE:
			p = loopcxt_get_backing_file(lc);
			break;
		case COL_OFFSET:
			if (loopcxt_get_offset(lc, &x) == 0)
				xasprintf(&np, "%jd", x);
			break;
		case COL_SIZELIMIT:
			if (loopcxt_get_sizelimit(lc, &x) == 0)
				xasprintf(&np, "%jd", x);
			break;
		case COL_BACK_MAJMIN:
		{
			dev_t dev = 0;
			if (loopcxt_get_backing_devno(lc, &dev) == 0 && dev)
				xasprintf(&np, "%8u:%-3u", major(dev), minor(dev));
			break;
		}
		case COL_MAJMIN:
		{
			struct stat st;

			if (loopcxt_get_device(lc)
			    && stat(loopcxt_get_device(lc), &st) == 0
			    && S_ISBLK(st.st_mode)
			    && major(st.st_rdev) == LOOPDEV_MAJOR)
				xasprintf(&np, "%3u:%-3u", major(st.st_rdev),
						           minor(st.st_rdev));
			break;
		}
		case COL_BACK_INO:
		{
			ino_t ino = 0;
			if (loopcxt_get_backing_inode(lc, &ino) == 0 && ino)
				xasprintf(&np, "%ju", ino);
			break;
		}
		case COL_AUTOCLR:
			p = loopcxt_is_autoclear(lc) ? "1" : "0";
			break;
		case COL_RO:
			p = loopcxt_is_readonly(lc) ? "1" : "0";
			break;
		case COL_DIO:
			p = loopcxt_is_dio(lc) ? "1" : "0";
			break;
		case COL_PARTSCAN:
			p = loopcxt_is_partscan(lc) ? "1" : "0";
			break;
		case COL_LOGSEC:
			if (loopcxt_get_blocksize(lc, &x) == 0)
				xasprintf(&np, "%jd", x);
			break;
		default:
			return -EINVAL;
		}


		if (p)
			rc = scols_line_set_data(ln, i, p);	/* calls strdup() */
		else if (np)
			rc = scols_line_refer_data(ln, i, np);	/* only refers */

		if (rc)
			err(EXIT_FAILURE, _("failed to add output data"));
	}

	return 0;
}

static int show_table(struct loopdev_cxt *lc,
		      const char *file,
		      uint64_t offset,
		      int flags)
{
	struct stat sbuf, *st = &sbuf;
	struct libscols_table *tb;
	struct libscols_line *ln;
	int rc = 0;
	size_t i;

	scols_init_debug(0);

	if (!(tb = scols_new_table()))
		err(EXIT_FAILURE, _("failed to allocate output table"));
	scols_table_enable_raw(tb, raw);
	scols_table_enable_json(tb, json);
	scols_table_enable_noheadings(tb, no_headings);

	if (json)
		scols_table_set_name(tb, "loopdevices");

	for (i = 0; i < ncolumns; i++) {
		struct colinfo *ci = get_column_info(i);
		struct libscols_column *cl;

		cl = scols_table_new_column(tb, ci->name, ci->whint, ci->flags);
		if (!cl)
			err(EXIT_FAILURE, _("failed to allocate output column"));
		if (json)
			scols_column_set_json_type(cl, ci->json_type);
	}

	/* only one loopdev requested (already assigned to loopdev_cxt) */
	if (loopcxt_get_device(lc)) {
		ln = scols_table_new_line(tb, NULL);
		if (!ln)
			err(EXIT_FAILURE, _("failed to allocate output line"));
		rc = set_scols_data(lc, ln);

	/* list all loopdevs */
	} else {
		char *cn_file = NULL;

		rc = loopcxt_init_iterator(lc, LOOPITER_FL_USED);
		if (rc)
			goto done;
		if (!file || stat(file, st))
			st = NULL;

		while (loopcxt_next(lc) == 0) {
			if (file) {
				int used;
				const char *bf = cn_file ? cn_file : file;

				used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
				if (!used && !cn_file) {
					bf = cn_file = canonicalize_path(file);
					used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
				}
				if (!used)
					continue;
			}

			ln = scols_table_new_line(tb, NULL);
			if (!ln)
				err(EXIT_FAILURE, _("failed to allocate output line"));
			rc = set_scols_data(lc, ln);
			if (rc)
				break;
		}

		loopcxt_deinit_iterator(lc);
		free(cn_file);
	}
done:
	if (rc == 0)
		rc = scols_print_table(tb);
	scols_unref_table(tb);
	return rc;
}

static void __attribute__((__noreturn__)) usage(void)
{
	FILE *out = stdout;
	size_t i;

	fputs(USAGE_HEADER, out);

	fprintf(out,
	      _(" %1$s [options] [<loopdev>]\n"
		" %1$s [options] -f | <loopdev> <file>\n"),
		program_invocation_short_name);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("Set up and control loop devices.\n"), out);

	/* commands */
	fputs(USAGE_OPTIONS, out);
	fputs(_(" -a, --all                     list all used devices\n"), out);
	fputs(_(" -d, --detach <loopdev>...     detach one or more devices\n"), out);
	fputs(_(" -D, --detach-all              detach all used devices\n"), out);
	fputs(_(" -f, --find                    find first unused device\n"), out);
	fputs(_(" -c, --set-capacity <loopdev>  resize the device\n"), out);
	fputs(_(" -j, --associated <file>       list all devices associated with <file>\n"), out);
	fputs(_(" -L, --nooverlap               avoid possible conflict between devices\n"), out);

	/* commands options */
	fputs(USAGE_SEPARATOR, out);
	fputs(_(" -o, --offset <num>            start at offset <num> into file\n"), out);
	fputs(_("     --sizelimit <num>         device is limited to <num> bytes of the file\n"), out);
	fputs(_(" -b  --sector-size <num>       set the logical sector size to <num>\n"), out);
	fputs(_(" -P, --partscan                create a partitioned loop device\n"), out);
	fputs(_(" -r, --read-only               set up a read-only loop device\n"), out);
	fputs(_("     --direct-io[=<on|off>]    open backing file with O_DIRECT\n"), out);
	fputs(_("     --show                    print device name after setup (with -f)\n"), out);
	fputs(_(" -v, --verbose                 verbose mode\n"), out);

	/* output options */
	fputs(USAGE_SEPARATOR, out);
	fputs(_(" -J, --json                    use JSON --list output format\n"), out);
	fputs(_(" -l, --list                    list info about all or specified (default)\n"), out);
	fputs(_(" -n, --noheadings              don't print headings for --list output\n"), out);
	fputs(_(" -O, --output <cols>           specify columns to output for --list\n"), out);
	fputs(_("     --output-all              output all columns\n"), out);
	fputs(_("     --raw                     use raw --list output format\n"), out);

	fputs(USAGE_SEPARATOR, out);
	printf(USAGE_HELP_OPTIONS(31));

	fputs(USAGE_COLUMNS, out);
	for (i = 0; i < ARRAY_SIZE(infos); i++)
		fprintf(out, " %12s  %s\n", infos[i].name, _(infos[i].help));

	printf(USAGE_MAN_TAIL("losetup(8)"));

	exit(EXIT_SUCCESS);
}

static void warn_size(const char *filename, uint64_t size)
{
	struct stat st;

	if (!size) {
		if (stat(filename, &st) || S_ISBLK(st.st_mode))
			return;
		size = st.st_size;
	}

	if (size < 512)
		warnx(_("%s: Warning: file is smaller than 512 bytes; the loop device "
			"may be useless or invisible for system tools."),
			filename);
	else if (size % 512)
		warnx(_("%s: Warning: file does not fit into a 512-byte sector; "
		        "the end of the file will be ignored."),
			filename);
}

static int create_loop(struct loopdev_cxt *lc,
		       int nooverlap, int lo_flags, int flags,
		       const char *file, uint64_t offset, uint64_t sizelimit)
{
	int hasdev = loopcxt_has_device(lc);
	int rc = 0;

	/* losetup --find --noverlap file.img */
	if (!hasdev && nooverlap) {
		rc = loopcxt_find_overlap(lc, file, offset, sizelimit);
		switch (rc) {
		case 0: /* not found */
			break;

		case 1:	/* overlap */
			loopcxt_deinit(lc);
			errx(EXIT_FAILURE, _("%s: overlapping loop device exists"), file);

		case 2: /* overlap -- full size and offset match (reuse) */
		{
			uint32_t lc_encrypt_type;

			/* Once a loop is initialized RO, there is no
			 * way to change its parameters. */
			if (loopcxt_is_readonly(lc)
			    && !(lo_flags & LO_FLAGS_READ_ONLY)) {
				loopcxt_deinit(lc);
				errx(EXIT_FAILURE, _("%s: overlapping read-only loop device exists"), file);
			}

			/* This is no more supported, but check to be safe. */
			if (loopcxt_get_encrypt_type(lc, &lc_encrypt_type) == 0
			    && lc_encrypt_type != LO_CRYPT_NONE) {
				loopcxt_deinit(lc);
				errx(EXIT_FAILURE, _("%s: overlapping encrypted loop device exists"), file);
			}

			lc->info.lo_flags &= ~LO_FLAGS_AUTOCLEAR;
			if (loopcxt_set_status(lc)) {
				loopcxt_deinit(lc);
				errx(EXIT_FAILURE, _("%s: failed to re-use loop device"), file);
			}
			return 0;	/* success, re-use */
		}
		default: /* error */
			loopcxt_deinit(lc);
			errx(EXIT_FAILURE, _("failed to inspect loop devices"));
			return -errno;
		}
	}

	if (hasdev && !is_loopdev(loopcxt_get_device(lc)))
		loopcxt_add_device(lc);

	/* losetup --noverlap /dev/loopN file.img */
	if (hasdev && nooverlap) {
		struct loopdev_cxt lc2;

		if (loopcxt_init(&lc2, 0)) {
			loopcxt_deinit(lc);
			err(EXIT_FAILURE, _("failed to initialize loopcxt"));
		}
		rc = loopcxt_find_overlap(&lc2, file, offset, sizelimit);
		loopcxt_deinit(&lc2);

		if (rc) {
			loopcxt_deinit(lc);
			if (rc > 0)
				errx(EXIT_FAILURE, _("%s: overlapping loop device exists"), file);
			err(EXIT_FAILURE, _("%s: failed to check for conflicting loop devices"), file);
		}
	}

	/* Create a new device */
	do {
		const char *errpre;

		/* Note that loopcxt_{find_unused,set_device}() resets
		 * loopcxt struct.
		 */
		if (!hasdev && (rc = loopcxt_find_unused(lc))) {
			warnx(_("cannot find an unused loop device"));
			break;
		}
		if (flags & LOOPDEV_FL_OFFSET)
			loopcxt_set_offset(lc, offset);
		if (flags & LOOPDEV_FL_SIZELIMIT)
			loopcxt_set_sizelimit(lc, sizelimit);
		if (lo_flags)
			loopcxt_set_flags(lc, lo_flags);
		if ((rc = loopcxt_set_backing_file(lc, file))) {
			warn(_("%s: failed to use backing file"), file);
			break;
		}
		errno = 0;
		rc = loopcxt_setup_device(lc);
		if (rc == 0)
			break;			/* success */
		if (errno == EBUSY && !hasdev)
			continue;

		/* errors */
		errpre = hasdev && loopcxt_get_fd(lc) < 0 ?
				 loopcxt_get_device(lc) : file;
		warn(_("%s: failed to set up loop device"), errpre);
		break;
	} while (hasdev == 0);

	return rc;
}

int main(int argc, char **argv)
{
	struct loopdev_cxt lc;
	int act = 0, flags = 0, no_overlap = 0, c;
	char *file = NULL;
	uint64_t offset = 0, sizelimit = 0, blocksize = 0;
	int res = 0, showdev = 0, lo_flags = 0;
	char *outarg = NULL;
	int list = 0;
	unsigned long use_dio = 0, set_dio = 0, set_blocksize = 0;

	enum {
		OPT_SIZELIMIT = CHAR_MAX + 1,
		OPT_SHOW,
		OPT_RAW,
		OPT_DIO,
		OPT_OUTPUT_ALL
	};
	static const struct option longopts[] = {
		{ "all",          no_argument,       NULL, 'a'           },
		{ "set-capacity", required_argument, NULL, 'c'           },
		{ "detach",       required_argument, NULL, 'd'           },
		{ "detach-all",   no_argument,       NULL, 'D'           },
		{ "find",         no_argument,       NULL, 'f'           },
		{ "nooverlap",    no_argument,       NULL, 'L'           },
		{ "help",         no_argument,       NULL, 'h'           },
		{ "associated",   required_argument, NULL, 'j'           },
		{ "json",         no_argument,       NULL, 'J'           },
		{ "list",         no_argument,       NULL, 'l'           },
		{ "sector-size",  required_argument, NULL, 'b'      },
		{ "noheadings",   no_argument,       NULL, 'n'           },
		{ "offset",       required_argument, NULL, 'o'           },
		{ "output",       required_argument, NULL, 'O'           },
		{ "output-all",   no_argument,       NULL, OPT_OUTPUT_ALL },
		{ "sizelimit",    required_argument, NULL, OPT_SIZELIMIT },
		{ "partscan",     no_argument,       NULL, 'P'           },
		{ "read-only",    no_argument,       NULL, 'r'           },
		{ "direct-io",    optional_argument, NULL, OPT_DIO       },
		{ "raw",          no_argument,       NULL, OPT_RAW       },
		{ "show",         no_argument,       NULL, OPT_SHOW      },
		{ "verbose",      no_argument,       NULL, 'v'           },
		{ "version",      no_argument,       NULL, 'V'           },
		{ NULL, 0, NULL, 0 }
	};

	static const ul_excl_t excl[] = {	/* rows and cols in ASCII order */
		{ 'D','a','c','d','f','j' },
		{ 'D','c','d','f','l' },
		{ 'D','c','d','f','O' },
		{ 'J',OPT_RAW },
		{ 0 }
	};
	int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	if (loopcxt_init(&lc, 0))
		err(EXIT_FAILURE, _("failed to initialize loopcxt"));

	while ((c = getopt_long(argc, argv, "ab:c:d:Dfhj:JlLno:O:PrvV",
				longopts, NULL)) != -1) {

		err_exclusive_options(c, longopts, excl, excl_st);

		switch (c) {
		case 'a':
			act = A_SHOW;
			break;
		case 'b':
			set_blocksize = 1;
			blocksize = strtosize_or_err(optarg, _("failed to parse logical block size"));
			break;
		case 'c':
			act = A_SET_CAPACITY;
			if (!is_loopdev(optarg) ||
			    loopcxt_set_device(&lc, optarg))
				err(EXIT_FAILURE, _("%s: failed to use device"),
						optarg);
			break;
		case 'r':
			lo_flags |= LO_FLAGS_READ_ONLY;
			break;
		case 'd':
			act = A_DELETE;
			if (!is_loopdev(optarg) ||
			    loopcxt_set_device(&lc, optarg))
				err(EXIT_FAILURE, _("%s: failed to use device"),
						optarg);
			break;
		case 'D':
			act = A_DELETE_ALL;
			break;
		case 'f':
			act = A_FIND_FREE;
			break;
		case 'h':
			usage();
			break;
		case 'J':
			json = 1;
			break;
		case 'j':
			act = A_SHOW;
			file = optarg;
			break;
		case 'l':
			list = 1;
			break;
		case 'L':
			no_overlap = 1;
			break;
		case 'n':
			no_headings = 1;
			break;
		case OPT_RAW:
			raw = 1;
			break;
		case 'o':
			offset = strtosize_or_err(optarg, _("failed to parse offset"));
			flags |= LOOPDEV_FL_OFFSET;
			break;
		case 'O':
			outarg = optarg;
			list = 1;
			break;
		case OPT_OUTPUT_ALL:
			for (ncolumns = 0; ncolumns < ARRAY_SIZE(infos); ncolumns++)
				columns[ncolumns] = ncolumns;
			break;
		case 'P':
			lo_flags |= LO_FLAGS_PARTSCAN;
			break;
		case OPT_SHOW:
			showdev = 1;
			break;
		case OPT_DIO:
			use_dio = set_dio = 1;
			if (optarg)
				use_dio = parse_switch(optarg, _("argument error"), "on", "off", NULL);
			break;
		case 'v':
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case OPT_SIZELIMIT:			/* --sizelimit */
			sizelimit = strtosize_or_err(optarg, _("failed to parse size"));
			flags |= LOOPDEV_FL_SIZELIMIT;
                        break;
		default:
			errtryhelp(EXIT_FAILURE);
		}
	}

	ul_path_init_debug();
	ul_sysfs_init_debug();

	/* default is --list --all */
	if (argc == 1) {
		act = A_SHOW;
		list = 1;
	}

	if (!act && argc == 2 && (raw || json)) {
		act = A_SHOW;
		list = 1;
	}

	/* default --list output columns */
	if (list && !ncolumns) {
		columns[ncolumns++] = COL_NAME;
		columns[ncolumns++] = COL_SIZELIMIT;
		columns[ncolumns++] = COL_OFFSET;
		columns[ncolumns++] = COL_AUTOCLR;
		columns[ncolumns++] = COL_RO;
		columns[ncolumns++] = COL_BACK_FILE;
		columns[ncolumns++] = COL_DIO;
		columns[ncolumns++] = COL_LOGSEC;
	}

	if (act == A_FIND_FREE && optind < argc) {
		/*
		 * losetup -f <backing_file>
		 */
		act = A_CREATE;
		file = argv[optind++];

		if (optind < argc)
			errx(EXIT_FAILURE, _("unexpected arguments"));
	}

	if (list && !act && optind == argc)
		/*
		 * losetup --list	defaults to --all
		 */
		act = A_SHOW;

	if (!act && optind + 1 == argc) {
		/*
		 * losetup [--list] <device>
		 * OR
		 * losetup {--direct-io[=off]|--logical-blocksize=size}... <device>
		 */
		if (!(set_dio || set_blocksize))
			act = A_SHOW_ONE;
		if (set_dio)
			act = A_SET_DIRECT_IO;
		if (set_blocksize)
			act = A_SET_BLOCKSIZE;
		if (!is_loopdev(argv[optind]) ||
		    loopcxt_set_device(&lc, argv[optind]))
			err(EXIT_FAILURE, _("%s: failed to use device"),
					argv[optind]);
		optind++;
	}
	if (!act) {
		/*
		 * losetup <loopdev> <backing_file>
		 */
		act = A_CREATE;

		if (optind >= argc)
			errx(EXIT_FAILURE, _("no loop device specified"));
		/* don't use is_loopdev() here, the device does not have exist yet */
		if (loopcxt_set_device(&lc, argv[optind]))
			err(EXIT_FAILURE, _("%s: failed to use device"),
					argv[optind]);
		optind++;

		if (optind >= argc)
			errx(EXIT_FAILURE, _("no file specified"));
		file = argv[optind++];
	}

	if (act != A_CREATE &&
	    (sizelimit || lo_flags || showdev))
		errx(EXIT_FAILURE,
			_("the options %s are allowed during loop device setup only"),
			"--{sizelimit,read-only,show}");

	if ((flags & LOOPDEV_FL_OFFSET) &&
	    act != A_CREATE && (act != A_SHOW || !file))
		errx(EXIT_FAILURE, _("the option --offset is not allowed in this context"));

	if (outarg && string_add_to_idarray(outarg, columns, ARRAY_SIZE(columns),
					 &ncolumns, column_name_to_id) < 0)
		return EXIT_FAILURE;

	switch (act) {
	case A_CREATE:
		res = create_loop(&lc, no_overlap, lo_flags, flags, file, offset, sizelimit);
		if (res == 0) {
			if (showdev)
				printf("%s\n", loopcxt_get_device(&lc));
			warn_size(file, sizelimit);
			if (set_dio || set_blocksize)
				goto lo_set_post;
		}
		break;
	case A_DELETE:
		res = delete_loop(&lc);
		while (optind < argc) {
			if (!is_loopdev(argv[optind]) ||
			    loopcxt_set_device(&lc, argv[optind]))
				warn(_("%s: failed to use device"),
						argv[optind]);
			optind++;
			res += delete_loop(&lc);
		}
		break;
	case A_DELETE_ALL:
		res = delete_all_loops(&lc);
		break;
	case A_FIND_FREE:
		res = loopcxt_find_unused(&lc);
		if (res) {
			int errsv = errno;

			if (access(_PATH_DEV_LOOPCTL, F_OK) == 0 &&
			    access(_PATH_DEV_LOOPCTL, W_OK) != 0)
				;
			else
				errno = errsv;

			warn(_("cannot find an unused loop device"));
		} else
			printf("%s\n", loopcxt_get_device(&lc));
		break;
	case A_SHOW:
		if (list)
			res = show_table(&lc, file, offset, flags);
		else
			res = show_all_loops(&lc, file, offset, flags);
		break;
	case A_SHOW_ONE:
		if (list)
			res = show_table(&lc, NULL, 0, 0);
		else
			res = printf_loopdev(&lc);
		if (res)
			warn("%s", loopcxt_get_device(&lc));
		break;
	case A_SET_CAPACITY:
		res = loopcxt_set_capacity(&lc);
		if (res)
			warn(_("%s: set capacity failed"),
			        loopcxt_get_device(&lc));
		break;
	case A_SET_DIRECT_IO:
	case A_SET_BLOCKSIZE:
 lo_set_post:
		if (set_dio) {
			res = loopcxt_set_dio(&lc, use_dio);
			if (res)
				warn(_("%s: set direct io failed"),
				        loopcxt_get_device(&lc));
		}
		if (set_blocksize) {
			res = loopcxt_set_blocksize(&lc, blocksize);
			if (res)
				warn(_("%s: set logical block size failed"),
				        loopcxt_get_device(&lc));
		}
		break;
	default:
		warnx(_("bad usage"));
		errtryhelp(EXIT_FAILURE);
		break;
	}

	loopcxt_deinit(&lc);
	return res ? EXIT_FAILURE : EXIT_SUCCESS;
}

