/*
 * evaluate.c - very high-level API to evaluate LABELs or UUIDs
 *
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdint.h>
#include <stdarg.h>

#include "pathnames.h"
#include "canonicalize.h"
#include "closestream.h"

#include "blkidP.h"

/**
 * SECTION:evaluate
 * @title: Tags and Spec evaluation
 * @short_description: top-level API for LABEL and UUID evaluation.
 *
 * This API provides very simple and portable way how evaluate LABEL and UUID
 * tags.  The blkid_evaluate_tag() and blkid_evaluate_spec() work on 2.4 and
 * 2.6 systems and on systems with or without udev. Currently, the libblkid
 * library supports "udev" and "scan" methods. The "udev" method uses udev
 * /dev/disk/by-* symlinks and the "scan" method scans all block devices from
 * the /proc/partitions file. The evaluation could be controlled by the
 * /etc/blkid.conf config file. The default is to try "udev" and then "scan"
 * method.
 *
 * The blkid_evaluate_tag() also automatically informs udevd when an obsolete
 * /dev/disk/by-* symlink is detected.
 *
 * If you are not sure how translate LABEL or UUID to the device name use this
 * API.
 */

#ifdef CONFIG_BLKID_VERIFY_UDEV
/* returns zero when the device has NAME=value (LABEL/UUID) */
static int verify_tag(const char *devname, const char *name, const char *value)
{
	blkid_probe pr;
	int fd = -1, rc = -1;
	size_t len;
	const char *data;
	int errsv = 0;

	pr = blkid_new_probe();
	if (!pr)
		return -1;

	blkid_probe_enable_superblocks(pr, TRUE);
	blkid_probe_set_superblocks_flags(pr,
			BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID);

	blkid_probe_enable_partitions(pr, TRUE);
	blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);

	fd = open(devname, O_RDONLY|O_CLOEXEC);
	if (fd < 0) {
		errsv = errno;
		goto done;
	}
	if (blkid_probe_set_device(pr, fd, 0, 0))
		goto done;
	rc = blkid_do_safeprobe(pr);
	if (rc)
		goto done;
	rc = blkid_probe_lookup_value(pr, name, &data, &len);
	if (!rc)
		rc = memcmp(value, data, len);
done:
	DBG(EVALUATE, ul_debug("%s: %s verification %s",
			devname, name, rc == 0 ? "PASS" : "FAILED"));
	if (fd >= 0)
		close(fd);
	blkid_free_probe(pr);

	/* for non-root users we use unverified udev links */
	return errsv == EACCES ? 0 : rc;
}
#endif /* CONFIG_BLKID_VERIFY_UDEV*/

/**
 * blkid_send_uevent:
 * @devname: absolute path to the device
 * @action: event string
 *
 * Returns: -1 in case of failure, or 0 on success.
 */
int blkid_send_uevent(const char *devname, const char *action)
{
	char uevent[PATH_MAX];
	struct stat st;
	FILE *f;
	int rc = -1;

	DBG(EVALUATE, ul_debug("%s: uevent '%s' requested", devname, action));

	if (!devname || !action)
		return -1;
	if (stat(devname, &st) || !S_ISBLK(st.st_mode))
		return -1;

	snprintf(uevent, sizeof(uevent), "/sys/dev/block/%d:%d/uevent",
			major(st.st_rdev), minor(st.st_rdev));

	f = fopen(uevent, "w" UL_CLOEXECSTR);
	if (f) {
		rc = 0;
		if (fputs(action, f) >= 0)
			rc = 0;
		if (close_stream(f) != 0)
			DBG(EVALUATE, ul_debug("write failed: %s", uevent));
	}
	DBG(EVALUATE, ul_debug("%s: send uevent %s",
			uevent, rc == 0 ? "SUCCES" : "FAILED"));
	return rc;
}

static char *evaluate_by_udev(const char *token, const char *value, int uevent)
{
	char dev[PATH_MAX];
	char *path = NULL;
	size_t len;
	struct stat st;

	DBG(EVALUATE, ul_debug("evaluating by udev %s=%s", token, value));

	if (!strcmp(token, "UUID"))
		strcpy(dev, _PATH_DEV_BYUUID "/");
	else if (!strcmp(token, "LABEL"))
		strcpy(dev, _PATH_DEV_BYLABEL "/");
	else if (!strcmp(token, "PARTLABEL"))
		strcpy(dev, _PATH_DEV_BYPARTLABEL "/");
	else if (!strcmp(token, "PARTUUID"))
		strcpy(dev, _PATH_DEV_BYPARTUUID "/");
	else {
		DBG(EVALUATE, ul_debug("unsupported token %s", token));
		return NULL;	/* unsupported tag */
	}

	len = strlen(dev);
	if (blkid_encode_string(value, &dev[len], sizeof(dev) - len) != 0)
		return NULL;

	DBG(EVALUATE, ul_debug("expected udev link: %s", dev));

	if (stat(dev, &st))
		goto failed;	/* link or device does not exist */

	if (!S_ISBLK(st.st_mode))
		return NULL;

	path = canonicalize_path(dev);
	if (!path)
		return NULL;

#ifdef CONFIG_BLKID_VERIFY_UDEV
	if (verify_tag(path, token, value))
		goto failed;
#endif
	return path;

failed:
	DBG(EVALUATE, ul_debug("failed to evaluate by udev"));

	if (uevent && path)
		blkid_send_uevent(path, "change");
	free(path);
	return NULL;
}

static char *evaluate_by_scan(const char *token, const char *value,
		blkid_cache *cache, struct blkid_config *conf)
{
	blkid_cache c = cache ? *cache : NULL;
	char *res;

	DBG(EVALUATE, ul_debug("evaluating by blkid scan %s=%s", token, value));

	if (!c) {
		char *cachefile = blkid_get_cache_filename(conf);
		blkid_get_cache(&c, cachefile);
		free(cachefile);
	}
	if (!c)
		return NULL;

	res = blkid_get_devname(c, token, value);

	if (cache)
		*cache = c;
	else
		blkid_put_cache(c);

	return res;
}

/**
 * blkid_evaluate_tag:
 * @token: token name (e.g "LABEL" or "UUID") or unparsed tag (e.g. "LABEL=foo")
 * @value: token data (e.g. "foo")
 * @cache: pointer to cache (or NULL when you don't want to re-use the cache)
 *
 * Returns: allocated string with a device name.
 */
char *blkid_evaluate_tag(const char *token, const char *value, blkid_cache *cache)
{
	struct blkid_config *conf = NULL;
	char *t = NULL, *v = NULL;
	char *ret = NULL;
	int i;

	if (!token)
		return NULL;

	if (!cache || !*cache)
		blkid_init_debug(0);

	DBG(EVALUATE, ul_debug("evaluating  %s%s%s", token, value ? "=" : "",
		   value ? value : ""));

	if (!value) {
		if (!strchr(token, '=')) {
			ret = strdup(token);
			goto out;
		}
		blkid_parse_tag_string(token, &t, &v);
		if (!t || !v)
			goto out;
		token = t;
		value = v;
	}

	conf = blkid_read_config(NULL);
	if (!conf)
		goto out;

	for (i = 0; i < conf->nevals; i++) {
		if (conf->eval[i] == BLKID_EVAL_UDEV)
			ret = evaluate_by_udev(token, value, conf->uevent);
		else if (conf->eval[i] == BLKID_EVAL_SCAN)
			ret = evaluate_by_scan(token, value, cache, conf);
		if (ret)
			break;
	}

	DBG(EVALUATE, ul_debug("%s=%s evaluated as %s", token, value, ret));
out:
	blkid_free_config(conf);
	free(t);
	free(v);
	return ret;
}

/**
 * blkid_evaluate_spec:
 * @spec: unparsed tag (e.g. "LABEL=foo") or path (e.g. /dev/dm-0)
 * @cache: pointer to cache (or NULL when you don't want to re-use the cache)
 *
 * All returned paths are canonicalized, device-mapper paths are converted
 * to the /dev/mapper/name format.
 *
 * Returns: allocated string with a device name.
 */
char *blkid_evaluate_spec(const char *spec, blkid_cache *cache)
{
	char *t = NULL, *v = NULL, *res;

	if (!spec)
		return NULL;

	if (strchr(spec, '=') &&
	    blkid_parse_tag_string(spec, &t, &v) != 0)	/* parse error */
		return NULL;

	if (v)
		res = blkid_evaluate_tag(t, v, cache);
	else
		res = canonicalize_path(spec);

	free(t);
	free(v);
	return res;
}


#ifdef TEST_PROGRAM
int main(int argc, char *argv[])
{
	blkid_cache cache = NULL;
	char *res;

	if (argc < 2) {
		fprintf(stderr, "usage: %s <tag> | <spec>\n", argv[0]);
		return EXIT_FAILURE;
	}

	blkid_init_debug(0);

	res = blkid_evaluate_spec(argv[1], &cache);
	if (res)
		printf("%s\n", res);
	if (cache)
		blkid_put_cache(cache);

	return res ? EXIT_SUCCESS : EXIT_FAILURE;
}
#endif
