/*
 * 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 "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(DEBUG_EVALUATE, printf("%s: %s verification %s\n",
			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(DEBUG_EVALUATE, printf("%s: uevent '%s' requested\n", 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");
	if (f) {
		rc = 0;
		if (fputs(action, f) >= 0)
			rc = 0;
		fclose(f);
	}
	DBG(DEBUG_EVALUATE, printf("%s: send uevent %s\n",
			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(DEBUG_EVALUATE,
	    printf("evaluating by udev %s=%s\n", 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(DEBUG_EVALUATE,
		    printf("unsupported token %s\n", token));
		return NULL;	/* unsupported tag */
	}

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

	DBG(DEBUG_EVALUATE,
	    printf("expected udev link: %s\n", 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(DEBUG_EVALUATE, printf("failed to evaluate by udev\n"));

	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(DEBUG_EVALUATE,
	    printf("evaluating by blkid scan %s=%s\n", 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(DEBUG_EVALUATE,
	    printf("evaluating  %s%s%s\n", 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(DEBUG_EVALUATE,
	    printf("%s=%s evaluated as %s\n", 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
