/* vi: set sw=4 ts=4: */
/*
 * Utility routines.
 *
 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
 * Copyright (C) 2005 by Rob Landley <rob@landley.net>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */
#include "libbb.h"
#include <linux/version.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)

/* For 2.6, use the cleaned up header to get the 64 bit API. */
// Commented out per Rob's request
//# include "fix_u32.h" /* some old toolchains need __u64 for linux/loop.h */
# include <linux/loop.h>
typedef struct loop_info64 bb_loop_info;
# define BB_LOOP_SET_STATUS LOOP_SET_STATUS64
# define BB_LOOP_GET_STATUS LOOP_GET_STATUS64

#else

/* For 2.4 and earlier, use the 32 bit API (and don't trust the headers) */
/* Stuff stolen from linux/loop.h for 2.4 and earlier kernels */
# include <linux/posix_types.h>
# define LO_NAME_SIZE        64
# define LO_KEY_SIZE         32
# define LOOP_SET_FD         0x4C00
# define LOOP_CLR_FD         0x4C01
# define BB_LOOP_SET_STATUS  0x4C02
# define BB_LOOP_GET_STATUS  0x4C03
typedef struct {
	int                lo_number;
	__kernel_dev_t     lo_device;
	unsigned long      lo_inode;
	__kernel_dev_t     lo_rdevice;
	int                lo_offset;
	int                lo_encrypt_type;
	int                lo_encrypt_key_size;
	int                lo_flags;
	char               lo_file_name[LO_NAME_SIZE];
	unsigned char      lo_encrypt_key[LO_KEY_SIZE];
	unsigned long      lo_init[2];
	char               reserved[4];
} bb_loop_info;
#endif

char* FAST_FUNC query_loop(const char *device)
{
	int fd;
	bb_loop_info loopinfo;
	char *dev = NULL;

	fd = open(device, O_RDONLY);
	if (fd >= 0) {
		if (ioctl(fd, BB_LOOP_GET_STATUS, &loopinfo) == 0) {
			dev = xasprintf("%"OFF_FMT"u %s", (off_t) loopinfo.lo_offset,
					(char *)loopinfo.lo_file_name);
		}
		close(fd);
	}

	return dev;
}

int FAST_FUNC del_loop(const char *device)
{
	int fd, rc;

	fd = open(device, O_RDONLY);
	if (fd < 0)
		return 1;
	rc = ioctl(fd, LOOP_CLR_FD, 0);
	close(fd);

	return rc;
}

/* Obtain an unused loop device number */
int FAST_FUNC get_free_loop(void)
{
	int fd;
	int loopdevno;

	fd = open("/dev/loop-control", O_RDWR | O_CLOEXEC);
	if (fd == -1)
		return fd - 1; /* -2: "no /dev/loop-control" */

#ifndef LOOP_CTL_GET_FREE
# define LOOP_CTL_GET_FREE 0x4C82
#endif
	loopdevno = ioctl(fd, LOOP_CTL_GET_FREE);
	close(fd);
	return loopdevno; /* can be -1 if error */
}

/* Returns opened fd to the loop device, <0 on error.
 * *device is loop device to use, or if *device==NULL finds a loop device to
 * mount it on and sets *device to a strdup of that loop device name.  This
 * search will re-use an existing loop device already bound to that
 * file/offset if it finds one.
 */
int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, unsigned flags)
{
	char dev[LOOP_NAMESIZE];
	char *try;
	bb_loop_info loopinfo;
	struct stat statbuf;
	int i, dfd, ffd, mode, rc;

	rc = dfd = -1;

	/* Open the file.  Barf if this doesn't work.  */
	mode = (flags & BB_LO_FLAGS_READ_ONLY) ? O_RDONLY : O_RDWR;
 open_ffd:
	ffd = open(file, mode);
	if (ffd < 0) {
		if (mode != O_RDONLY) {
			mode = O_RDONLY;
			goto open_ffd;
		}
		return -errno;
	}

	try = *device;
	if (!try) {
		i = get_free_loop();
		if (i == -2) { /* no /dev/loop-control */
			i = 0;
			try = dev;
			goto old_style;
		}
		if (i == -1) {
			close(ffd);
			return -1; /* no free loop devices */
		}
		try = *device = xasprintf(LOOP_FORMAT, i);
		goto try_to_open;
	}

 old_style:
	/* Find a loop device.  */
	/* 1048575 (0xfffff) is a max possible minor number in Linux circa 2010 */
	for (i = 0; rc && i < 1048576; i++) {
		sprintf(dev, LOOP_FORMAT, i);

		IF_FEATURE_MOUNT_LOOP_CREATE(errno = 0;)
		if (stat(try, &statbuf) != 0 || !S_ISBLK(statbuf.st_mode)) {
			if (ENABLE_FEATURE_MOUNT_LOOP_CREATE
			 && errno == ENOENT
			 && try == dev
			) {
				/* Node doesn't exist, try to create it.  */
				if (mknod(dev, S_IFBLK|0644, makedev(7, i)) == 0)
					goto try_to_open;
			}
			/* Ran out of block devices, return failure.  */
			rc = -1;
			break;
		}
 try_to_open:
		/* Open the sucker and check its loopiness.  */
		dfd = open(try, mode);
		if (dfd < 0 && errno == EROFS) {
			mode = O_RDONLY;
			dfd = open(try, mode);
		}
		if (dfd < 0) {
			if (errno == ENXIO) {
				/* Happens if loop module is not loaded */
				rc = -1;
				break;
			}
			goto try_again;
		}

		rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo);

		/* If device is free, claim it.  */
		if (rc && errno == ENXIO) {
			/* Associate free loop device with file.  */
			if (ioctl(dfd, LOOP_SET_FD, ffd) == 0) {
				memset(&loopinfo, 0, sizeof(loopinfo));
				safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE);
				loopinfo.lo_offset = offset;
				/*
				 * Used by mount to set LO_FLAGS_AUTOCLEAR.
				 * LO_FLAGS_READ_ONLY is not set because RO is controlled by open type of the file.
				 * Note that closing LO_FLAGS_AUTOCLEARed dfd before mount
				 * is wrong (would free the loop device!)
				 */
				loopinfo.lo_flags = (flags & ~BB_LO_FLAGS_READ_ONLY);
				rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo);
				if (rc != 0 && (loopinfo.lo_flags & BB_LO_FLAGS_AUTOCLEAR)) {
					/* Old kernel, does not support LO_FLAGS_AUTOCLEAR? */
					/* (this code path is not tested) */
					loopinfo.lo_flags -= BB_LO_FLAGS_AUTOCLEAR;
					rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo);
				}
				if (rc != 0) {
					ioctl(dfd, LOOP_CLR_FD, 0); // actually, 0 param is unnecessary
				}
			}
		} else {
			rc = -1;
		}
		if (rc != 0) {
			close(dfd);
		}
 try_again:
		if (*device) break;
	}
	close(ffd);
	if (rc == 0) {
		if (!*device)
			*device = xstrdup(dev);
		return dfd;
	}
	return rc;
}
