/*
 * 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/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 ? "SUCCESS" : "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;
		}
		if (blkid_parse_tag_string(token, &t, &v) != 0 || !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
