diff options
Diffstat (limited to 'libblkid/evaluate.c')
-rw-r--r-- | libblkid/evaluate.c | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/libblkid/evaluate.c b/libblkid/evaluate.c deleted file mode 100644 index 2e1ca574d..000000000 --- a/libblkid/evaluate.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - * 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 |