/*
 * cache.c - allocation/initialization/free routines for cache
 *
 * Copyright (C) 2001 Andreas Dilger
 * Copyright (C) 2003 Theodore Ts'o
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 * %End-Header%
 */

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include "blkidP.h"
#include "env.h"

int blkid_debug_mask = 0;

/**
 * SECTION:cache
 * @title: Cache
 * @short_description: basic routines to work with libblkid cache
 *
 * Block device information is normally kept in a cache file blkid.tab and is
 * verified to still be valid before being returned to the user (if the user has
 * read permission on the raw block device, otherwise not).  The cache file also
 * allows unprivileged users (normally anyone other than root, or those not in the
 * "disk" group) to locate devices by label/id.  The standard location of the
 * cache file can be overridden by the environment variable BLKID_FILE.
 *
 * In situations where one is getting information about a single known device, it
 * does not impact performance whether the cache is used or not (unless you are
 * not able to read the block device directly).  If you are dealing with multiple
 * devices, use of the cache is highly recommended (even if empty) as devices will
 * be scanned at most one time and the on-disk cache will be updated if possible.
 * There is rarely a reason not to use the cache.
 *
 * In some cases (modular kernels), block devices are not even visible until after
 * they are accessed the first time, so it is critical that there is some way to
 * locate these devices without enumerating only visible devices, so the use of
 * the cache file is required in this situation.
 */

#if 0 /* ifdef CONFIG_BLKID_DEBUG */
static blkid_debug_dump_cache(int mask, blkid_cache cache)
{
	struct list_head *p;

	if (!cache) {
		printf("cache: NULL\n");
		return;
	}

	printf("cache: time = %lu\n", cache->bic_time);
	printf("cache: flags = 0x%08X\n", cache->bic_flags);

	list_for_each(p, &cache->bic_devs) {
		blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
		blkid_debug_dump_dev(dev);
	}
}
#endif

#ifdef CONFIG_BLKID_DEBUG
void blkid_init_debug(int mask)
{
	if (blkid_debug_mask & DEBUG_INIT)
		return;

	if (!mask)
	{
		char *dstr = getenv("LIBBLKID_DEBUG");

		if (!dstr)
			dstr = getenv("BLKID_DEBUG");	/* for backward compatibility */
		if (dstr)
			blkid_debug_mask = strtoul(dstr, 0, 0);
	} else
		blkid_debug_mask = mask;

	if (blkid_debug_mask)
		printf("libblkid: debug mask set to 0x%04x.\n", blkid_debug_mask);

	blkid_debug_mask |= DEBUG_INIT;
}
#endif

static const char *get_default_cache_filename(void)
{
	struct stat st;

	if (stat(BLKID_RUNTIME_TOPDIR, &st) == 0 && S_ISDIR(st.st_mode))
		return BLKID_CACHE_FILE;	/* cache in /run */

	return BLKID_CACHE_FILE_OLD;	/* cache in /etc */
}

/* returns allocated path to cache */
char *blkid_get_cache_filename(struct blkid_config *conf)
{
	char *filename;

	filename = safe_getenv("BLKID_FILE");
	if (filename)
		filename = strdup(filename);
	else if (conf)
		filename = conf->cachefile ? strdup(conf->cachefile) : NULL;
	else {
		struct blkid_config *c = blkid_read_config(NULL);
		if (!c)
			filename = strdup(get_default_cache_filename());
		else {
			filename = c->cachefile;  /* already allocated */
			c->cachefile = NULL;
			blkid_free_config(c);
		}
	}
	return filename;
}

/**
 * blkid_get_cache:
 * @cache: pointer to return cache handler
 * @filename: path to the cache file or NULL for the default path
 *
 * Allocates and initialize librray cache handler.
 *
 * Returns: 0 on success or number less than zero in case of error.
 */
int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
{
	blkid_cache cache;

	if (!ret_cache)
		return -BLKID_ERR_PARAM;

	blkid_init_debug(0);

	DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n",
				filename ? filename : "default cache"));

	if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
		return -BLKID_ERR_MEM;

	INIT_LIST_HEAD(&cache->bic_devs);
	INIT_LIST_HEAD(&cache->bic_tags);

	if (filename && !*filename)
		filename = NULL;
	if (filename)
		cache->bic_filename = strdup(filename);
	else
		cache->bic_filename = blkid_get_cache_filename(NULL);

	blkid_read_cache(cache);
	*ret_cache = cache;
	return 0;
}

/**
 * blkid_put_cache:
 * @cache: cache handler
 *
 * Saves changes to cache file.
 */
void blkid_put_cache(blkid_cache cache)
{
	if (!cache)
		return;

	(void) blkid_flush_cache(cache);

	DBG(DEBUG_CACHE, printf("freeing cache struct\n"));

	/* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */

	while (!list_empty(&cache->bic_devs)) {
		blkid_dev dev = list_entry(cache->bic_devs.next,
					   struct blkid_struct_dev,
					    bid_devs);
		blkid_free_dev(dev);
	}

	while (!list_empty(&cache->bic_tags)) {
		blkid_tag tag = list_entry(cache->bic_tags.next,
					   struct blkid_struct_tag,
					   bit_tags);

		while (!list_empty(&tag->bit_names)) {
			blkid_tag bad = list_entry(tag->bit_names.next,
						   struct blkid_struct_tag,
						   bit_names);

			DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n",
						bad->bit_name, bad->bit_val));
			blkid_free_tag(bad);
		}
		blkid_free_tag(tag);
	}

	blkid_free_probe(cache->probe);

	free(cache->bic_filename);
	free(cache);
}

/**
 * blkid_gc_cache:
 * @cache: cache handler
 *
 * Removes garbage (non-existing devices) from the cache.
 */
void blkid_gc_cache(blkid_cache cache)
{
	struct list_head *p, *pnext;
	struct stat st;

	if (!cache)
		return;

	list_for_each_safe(p, pnext, &cache->bic_devs) {
		blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
		if (stat(dev->bid_name, &st) < 0) {
			DBG(DEBUG_CACHE,
			    printf("freeing %s\n", dev->bid_name));
			blkid_free_dev(dev);
			cache->bic_flags |= BLKID_BIC_FL_CHANGED;
		} else {
			DBG(DEBUG_CACHE,
			    printf("Device %s exists\n", dev->bid_name));
		}
	}
}

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

	blkid_init_debug(DEBUG_ALL);

	if ((argc > 2)) {
		fprintf(stderr, "Usage: %s [filename] \n", argv[0]);
		exit(1);
	}

	if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
		fprintf(stderr, "error %d parsing cache file %s\n", ret,
			argv[1] ? argv[1] : blkid_get_cache_filename(NULL));
		exit(1);
	}
	if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
		fprintf(stderr, "%s: error creating cache (%d)\n",
			argv[0], ret);
		exit(1);
	}
	if ((ret = blkid_probe_all(cache)) < 0)
		fprintf(stderr, "error probing devices\n");

	blkid_put_cache(cache);

	return ret;
}
#endif
