/*
 * save.c - write the cache struct to disk
 *
 * Copyright (C) 2001 by 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%
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#include "closestream.h"

#include "blkidP.h"


static void save_quoted(const char *data, FILE *file)
{
	const char *p;

	fputc('"', file);
	for (p = data; p && *p; p++) {
		if ((unsigned char) *p == 0x22 ||		/* " */
		    (unsigned char) *p == 0x5c)			/* \ */
			fputc('\\', file);

		fputc(*p, file);
	}
	fputc('"', file);
}
static int save_dev(blkid_dev dev, FILE *file)
{
	struct list_head *p;

	if (!dev || dev->bid_name[0] != '/')
		return 0;

	DBG(SAVE, ul_debug("device %s, type %s", dev->bid_name, dev->bid_type ?
		   dev->bid_type : "(null)"));

	fprintf(file, "<device DEVNO=\"0x%04lx\" TIME=\"%ld.%ld\"",
			(unsigned long) dev->bid_devno,
			(long) dev->bid_time,
			(long) dev->bid_utime);

	if (dev->bid_pri)
		fprintf(file, " PRI=\"%d\"", dev->bid_pri);

	list_for_each(p, &dev->bid_tags) {
		blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);

		fputc(' ', file);			/* space between tags */
		fputs(tag->bit_name, file);		/* tag NAME */
		fputc('=', file);			/* separator between NAME and VALUE */
		save_quoted(tag->bit_val, file);	/* tag "VALUE" */
	}
	fprintf(file, ">%s</device>\n", dev->bid_name);

	return 0;
}

/*
 * Write out the cache struct to the cache file on disk.
 */
int blkid_flush_cache(blkid_cache cache)
{
	struct list_head *p;
	char *tmp = NULL;
	char *opened = NULL;
	char *filename;
	FILE *file = NULL;
	int fd, ret = 0;
	struct stat st;

	if (!cache)
		return -BLKID_ERR_PARAM;

	if (list_empty(&cache->bic_devs) ||
	    !(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
		DBG(SAVE, ul_debug("skipping cache file write"));
		return 0;
	}

	filename = cache->bic_filename ? cache->bic_filename :
					 blkid_get_cache_filename(NULL);
	if (!filename)
		return -BLKID_ERR_PARAM;

	if (strncmp(filename,
	    BLKID_RUNTIME_DIR "/", sizeof(BLKID_RUNTIME_DIR)) == 0) {

		/* default destination, create the directory if necessary */
		if (stat(BLKID_RUNTIME_DIR, &st)
		    && errno == ENOENT
		    && mkdir(BLKID_RUNTIME_DIR, S_IWUSR|
						S_IRUSR|S_IRGRP|S_IROTH|
						S_IXUSR|S_IXGRP|S_IXOTH) != 0
		    && errno != EEXIST) {
			DBG(SAVE, ul_debug("can't create %s directory for cache file",
					BLKID_RUNTIME_DIR));
			return 0;
		}
	}

	/* If we can't write to the cache file, then don't even try */
	if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) ||
	    (ret == 0 && access(filename, W_OK) < 0)) {
		DBG(SAVE, ul_debug("can't write to cache file %s", filename));
		return 0;
	}

	/*
	 * Try and create a temporary file in the same directory so
	 * that in case of error we don't overwrite the cache file.
	 * If the cache file doesn't yet exist, it isn't a regular
	 * file (e.g. /dev/null or a socket), or we couldn't create
	 * a temporary file then we open it directly.
	 */
	if (ret == 0 && S_ISREG(st.st_mode)) {
		tmp = malloc(strlen(filename) + 8);
		if (tmp) {
			sprintf(tmp, "%s-XXXXXX", filename);
			fd = mkstemp(tmp);
			if (fd >= 0) {
				if (fchmod(fd, 0644) != 0)
					DBG(SAVE, ul_debug("%s: fchmod failed", filename));
				else if ((file = fdopen(fd, "w" UL_CLOEXECSTR)))
					opened = tmp;
				if (!file)
					close(fd);
			}
		}
	}

	if (!file) {
		file = fopen(filename, "w" UL_CLOEXECSTR);
		opened = filename;
	}

	DBG(SAVE, ul_debug("writing cache file %s (really %s)",
		   filename, opened));

	if (!file) {
		ret = errno;
		goto errout;
	}

	list_for_each(p, &cache->bic_devs) {
		blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
		if (!dev->bid_type || (dev->bid_flags & BLKID_BID_FL_REMOVABLE))
			continue;
		if ((ret = save_dev(dev, file)) < 0)
			break;
	}

	if (ret >= 0) {
		cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
		ret = 1;
	}

	if (close_stream(file) != 0)
		DBG(SAVE, ul_debug("write failed: %s", filename));

	if (opened != filename) {
		if (ret < 0) {
			unlink(opened);
			DBG(SAVE, ul_debug("unlinked temp cache %s", opened));
		} else {
			char *backup;

			backup = malloc(strlen(filename) + 5);
			if (backup) {
				sprintf(backup, "%s.old", filename);
				unlink(backup);
				if (link(filename, backup)) {
					DBG(SAVE, ul_debug("can't link %s to %s",
							filename, backup));
				}
				free(backup);
			}
			if (rename(opened, filename)) {
				ret = errno;
				DBG(SAVE, ul_debug("can't rename %s to %s",
						opened, filename));
			} else {
				DBG(SAVE, ul_debug("moved temp cache %s", opened));
			}
		}
	}

errout:
	free(tmp);
	if (filename != cache->bic_filename)
		free(filename);
	return ret;
}

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

	blkid_init_debug(BLKID_DEBUG_ALL);
	if (argc > 2) {
		fprintf(stderr, "Usage: %s [filename]\n"
			"Test loading/saving a cache (filename)\n", argv[0]);
		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 (%d) probing devices\n", ret);
		exit(1);
	}
	cache->bic_filename = strdup(argv[1]);

	if ((ret = blkid_flush_cache(cache)) < 0) {
		fprintf(stderr, "error (%d) saving cache\n", ret);
		exit(1);
	}

	blkid_put_cache(cache);

	return ret;
}
#endif
