/* 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.
 */
#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') {
		*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))
		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 (strncmp(*fsname, "UUID=", 5) == 0)
		tmp = get_devname_from_uuid(*fsname + 5);
	else if (strncmp(*fsname, "LABEL=", 6) == 0)
		tmp = get_devname_from_label(*fsname + 6);

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

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