/* vi: set sw=4 ts=4: */
/*
 * Support functions for mounting devices by label/uuid
 *
 * Copyright (C) 2006 by Jason Schoon <floydpink@gmail.com>
 * Some portions cribbed from e2fsprogs, util-linux, dosfstools
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

//kbuild:lib-$(CONFIG_BLKID) += get_devname.o
//kbuild:lib-$(CONFIG_FINDFS) += get_devname.o
//kbuild:lib-$(CONFIG_FEATURE_MOUNT_LABEL) += get_devname.o

#include <sys/mount.h> /* BLKGETSIZE64 */
#if !defined(BLKGETSIZE64)
# define BLKGETSIZE64 _IOR(0x12,114,size_t)
#endif
#include "volume_id_internal.h"

static struct uuidCache_s {
	struct uuidCache_s *next;
//	int major, minor;
	char *device;
	char *label;
	char *uc_uuid; /* prefix makes it easier to grep for */
	IF_FEATURE_BLKID_TYPE(const char *type;)
} *uuidCache;

#if !ENABLE_FEATURE_BLKID_TYPE
#define get_label_uuid(fd, label, uuid, type) \
	get_label_uuid(fd, label, uuid)
#define uuidcache_addentry(device, label, uuid, type) \
	uuidcache_addentry(device, label, uuid)
#endif

/* Returns !0 on error.
 * Otherwise, returns malloc'ed strings for label and uuid
 * (and they can't be NULL, although they can be "").
 * NB: closes fd. */
static int
get_label_uuid(int fd, char **label, char **uuid, const char **type)
{
	int rv = 1;
	uint64_t size;
	struct volume_id *vid;

	/* fd is owned by vid now */
	vid = volume_id_open_node(fd);

	if (ioctl(/*vid->*/fd, BLKGETSIZE64, &size) != 0)
		size = 0;

	if (volume_id_probe_all(vid, /*0,*/ size) != 0)
		goto ret;

	if (vid->label[0] != '\0' || vid->uuid[0] != '\0'
#if ENABLE_FEATURE_BLKID_TYPE
	 || vid->type != NULL
#endif
	) {
		*label = xstrndup(vid->label, sizeof(vid->label));
		*uuid  = xstrndup(vid->uuid, sizeof(vid->uuid));
#if ENABLE_FEATURE_BLKID_TYPE
		*type = vid->type;
		dbg("found label '%s', uuid '%s', type '%s'", *label, *uuid, *type);
#else
		dbg("found label '%s', uuid '%s'", *label, *uuid);
#endif
		rv = 0;
	}
 ret:
	free_volume_id(vid); /* also closes fd */
	return rv;
}

/* NB: we take ownership of (malloc'ed) label and uuid */
static void
uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *uuid, const char *type)
{
	struct uuidCache_s *last;

	if (!uuidCache) {
		last = uuidCache = xzalloc(sizeof(*uuidCache));
	} else {
		for (last = uuidCache; last->next; last = last->next)
			continue;
		last->next = xzalloc(sizeof(*uuidCache));
		last = last->next;
	}
	/*last->next = NULL; - xzalloc did it*/
//	last->major = major;
//	last->minor = minor;
	last->device = device;
	last->label = label;
	last->uc_uuid = uuid;
	IF_FEATURE_BLKID_TYPE(last->type = type;)
}

/* If get_label_uuid() on device_name returns success,
 * add a cache entry for this device.
 * If device node does not exist, it will be temporarily created. */
static int FAST_FUNC
uuidcache_check_device(const char *device,
		struct stat *statbuf,
		void *userData UNUSED_PARAM,
		int depth UNUSED_PARAM)
{
	/* note: this check rejects links to devices, among other nodes */
	if (!S_ISBLK(statbuf->st_mode)
#if ENABLE_FEATURE_VOLUMEID_UBIFS
	 && !(S_ISCHR(statbuf->st_mode) && strncmp(bb_basename(device), "ubi", 3) == 0)
#endif
	)
		return TRUE;

	/* Users report that mucking with floppies (especially non-present
	 * ones) is significant PITA. This is a horribly dirty hack,
	 * but it is very useful in real world.
	 * If this will ever need to be enabled, consider using O_NONBLOCK.
	 */
	if (major(statbuf->st_rdev) == 2)
		return TRUE;

	add_to_uuid_cache(device);

	return TRUE;
}

static struct uuidCache_s*
uuidcache_init(int scan_devices)
{
	dbg("DBG: uuidCache=%x, uuidCache");
	if (uuidCache)
		return uuidCache;

	/* We were scanning /proc/partitions
	 * and /proc/sys/dev/cdrom/info here.
	 * Missed volume managers. I see that "standard" blkid uses these:
	 * /dev/mapper/control
	 * /proc/devices
	 * /proc/evms/volumes
	 * /proc/lvm/VGs
	 * This is unacceptably complex. Let's just scan /dev.
	 * (Maybe add scanning of /sys/block/XXX/dev for devices
	 * somehow not having their /dev/XXX entries created?) */
	if (scan_devices)
		recursive_action("/dev", ACTION_RECURSE,
			uuidcache_check_device, /* file_action */
			NULL, /* dir_action */
			NULL, /* userData */
			0 /* depth */);

	return uuidCache;
}

#define UUID   1
#define VOL    2

#ifdef UNUSED
static char *
get_spec_by_x(int n, const char *t, int *majorPtr, int *minorPtr)
{
	struct uuidCache_s *uc;

	uc = uuidcache_init(/*scan_devices:*/ 1);
	while (uc) {
		switch (n) {
		case UUID:
			if (strcmp(t, uc->uc_uuid) == 0) {
				*majorPtr = uc->major;
				*minorPtr = uc->minor;
				return uc->device;
			}
			break;
		case VOL:
			if (strcmp(t, uc->label) == 0) {
				*majorPtr = uc->major;
				*minorPtr = uc->minor;
				return uc->device;
			}
			break;
		}
		uc = uc->next;
	}
	return NULL;
}

static unsigned char
fromhex(char c)
{
	if (isdigit(c))
		return (c - '0');
	return ((c|0x20) - 'a' + 10);
}

static char *
get_spec_by_uuid(const char *s, int *major, int *minor)
{
	unsigned char uuid[16];
	int i;

	if (strlen(s) != 36 || s[8] != '-' || s[13] != '-'
	 || s[18] != '-' || s[23] != '-'
	) {
		goto bad_uuid;
	}
	for (i = 0; i < 16; i++) {
		if (*s == '-')
			s++;
		if (!isxdigit(s[0]) || !isxdigit(s[1]))
			goto bad_uuid;
		uuid[i] = ((fromhex(s[0]) << 4) | fromhex(s[1]));
		s += 2;
	}
	return get_spec_by_x(UUID, (char *)uuid, major, minor);

 bad_uuid:
	fprintf(stderr, _("mount: bad UUID"));
	return 0;
}

static char *
get_spec_by_volume_label(const char *s, int *major, int *minor)
{
	return get_spec_by_x(VOL, s, major, minor);
}
#endif // UNUSED

/* Used by blkid */
void display_uuid_cache(int scan_devices)
{
	struct uuidCache_s *uc;

	uc = uuidcache_init(scan_devices);
	while (uc) {
		printf("%s:", uc->device);
		if (uc->label[0])
			printf(" LABEL=\"%s\"", uc->label);
		if (uc->uc_uuid[0])
			printf(" UUID=\"%s\"", uc->uc_uuid);
#if ENABLE_FEATURE_BLKID_TYPE
	if (uc->type)
		printf(" TYPE=\"%s\"", uc->type);
#endif
		bb_putchar('\n');
		uc = uc->next;
	}
}

int add_to_uuid_cache(const char *device)
{
	char *uuid = uuid; /* for compiler */
	char *label = label;
#if ENABLE_FEATURE_BLKID_TYPE
	const char *type = type;
#endif
	int fd;

	fd = open(device, O_RDONLY);
	if (fd < 0)
		return 0;

	/* get_label_uuid() closes fd in all cases (success & failure) */
	if (get_label_uuid(fd, &label, &uuid, &type) == 0) {
		/* uuidcache_addentry() takes ownership of all four params */
		uuidcache_addentry(xstrdup(device), /*ma, mi,*/ label, uuid, type);
		return 1;
	}
	return 0;
}


/* Used by mount and findfs */

char *get_devname_from_label(const char *spec)
{
	struct uuidCache_s *uc;

	uc = uuidcache_init(/*scan_devices:*/ 1);
	while (uc) {
		if (uc->label[0] && strcmp(spec, uc->label) == 0) {
			return xstrdup(uc->device);
		}
		uc = uc->next;
	}
	return NULL;
}

char *get_devname_from_uuid(const char *spec)
{
	struct uuidCache_s *uc;

	uc = uuidcache_init(/*scan_devices:*/ 1);
	while (uc) {
		/* case of hex numbers doesn't matter */
		if (strcasecmp(spec, uc->uc_uuid) == 0) {
			return xstrdup(uc->device);
		}
		uc = uc->next;
	}
	return NULL;
}

int resolve_mount_spec(char **fsname)
{
	char *tmp = *fsname;

	if (is_prefixed_with(*fsname, "UUID="))
		tmp = get_devname_from_uuid(*fsname + 5);
	else if (is_prefixed_with(*fsname, "LABEL="))
		tmp = get_devname_from_label(*fsname + 6);

	if (tmp == *fsname)
		return 0; /* no UUID= or LABEL= prefix found */

	if (tmp)
		*fsname = tmp;
	return 1;
}
