/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "lib.h"
#include "lvm-file.h"

#include <unistd.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <dirent.h>

/*
 * Creates a temporary filename, and opens a descriptor to the
 * file.  Both the filename and descriptor are needed so we can
 * rename the file after successfully writing it.  Grab
 * NFS-supported exclusive fcntl discretionary lock.
 */
int create_temp_name(const char *dir, char *buffer, size_t len, int *fd,
		     unsigned *seed)
{
	const struct flock lock = { .l_type = F_WRLCK };
	int i, num;
	pid_t pid;
	char hostname[255];
	char *p;

	num = rand_r(seed);
	pid = getpid();
	if (gethostname(hostname, sizeof(hostname)) < 0) {
		log_sys_error("gethostname", "");
		strcpy(hostname, "nohostname");
	} else {
		/* Replace any '/' with '?' found in the hostname. */
		p = hostname;
		while ((p = strchr(p, '/')))
			*p = '?';
	}

	for (i = 0; i < 20; i++, num++) {

		if (dm_snprintf(buffer, len, "%s/.lvm_%s_%d_%d",
				 dir, hostname, pid, num) == -1) {
			log_error("Not enough space to build temporary file "
				  "string.");
			return 0;
		}

		*fd = open(buffer, O_CREAT | O_EXCL | O_WRONLY | O_APPEND,
			   S_IRUSR | S_IRGRP | S_IROTH |
			   S_IWUSR | S_IWGRP | S_IWOTH);
		if (*fd < 0)
			continue;

		if (!fcntl(*fd, F_SETLK, &lock))
			return 1;

		if (close(*fd))
			log_sys_error("close", buffer);
	}

	return 0;
}

/*
 * NFS-safe rename of a temporary file to a common name, designed
 * to avoid race conditions and not overwrite the destination if
 * it exists.
 *
 * Try to create the new filename as a hard link to the original.
 * Check the link count of the original file to see if it worked.
 * (Assumes nothing else touches our temporary file!)  If it
 * worked, unlink the old filename.
 */
int lvm_rename(const char *old, const char *new)
{
	struct stat buf;

	if (link(old, new)) {
		log_error("%s: rename to %s failed: %s", old, new,
			  strerror(errno));
		return 0;
	}

	if (stat(old, &buf)) {
		log_sys_error("stat", old);
		return 0;
	}

	if (buf.st_nlink != 2) {
		log_error("%s: rename to %s failed", old, new);
		return 0;
	}

	if (unlink(old)) {
		log_sys_error("unlink", old);
		return 0;
	}

	return 1;
}

int path_exists(const char *path)
{
	struct stat info;

	if (!*path)
		return 0;

	if (stat(path, &info) < 0)
		return 0;

	return 1;
}

int dir_exists(const char *path)
{
	struct stat info;

	if (!*path)
		return 0;

	if (stat(path, &info) < 0)
		return 0;

	if (!S_ISDIR(info.st_mode))
		return 0;

	return 1;
}

int is_empty_dir(const char *dir)
{
	struct dirent *dirent;
	DIR *d;

	if (!(d = opendir(dir))) {
		log_sys_error("opendir", dir);
		return 0;
	}

	while ((dirent = readdir(d)))
		if (strcmp(dirent->d_name, ".") && strcmp(dirent->d_name, ".."))
			break;

	if (closedir(d))
		log_sys_error("closedir", dir);

	return dirent ? 0 : 1;
}

void sync_dir(const char *file)
{
	int fd;
	char *dir, *c;

	if (!(dir = dm_strdup(file))) {
		log_error("sync_dir failed in strdup");
		return;
	}

	if (!dir_exists(dir)) {
		c = dir + strlen(dir);
		while (*c != '/' && c > dir)
			c--;

		if (c == dir)
			*c++ = '.';

		*c = '\0';
	}

	if ((fd = open(dir, O_RDONLY)) == -1) {
		log_sys_error("open", dir);
		goto out;
	}

	if (fsync(fd) && (errno != EROFS) && (errno != EINVAL))
		log_sys_error("fsync", dir);

	if (close(fd))
		log_sys_error("close", dir);

      out:
	dm_free(dir);
}

/*
 * Attempt to obtain fcntl lock on a file, if necessary creating file first
 * or waiting.
 * Returns file descriptor on success, else -1.
 * mode is F_WRLCK or F_RDLCK
 */
int fcntl_lock_file(const char *file, short lock_type, int warn_if_read_only)
{
	const struct flock lock = { .l_type = lock_type };
	int lockfd;
	char *dir;
	char *c;

	if (!(dir = dm_strdup(file))) {
		log_error("fcntl_lock_file failed in strdup.");
		return -1;
	}

	if ((c = strrchr(dir, '/')))
		*c = '\0';

	if (!dm_create_dir(dir)) {
		dm_free(dir);
		return -1;
	}

	dm_free(dir);

	log_very_verbose("Locking %s (%s, %hd)", file,
			 (lock_type == F_WRLCK) ? "F_WRLCK" : "F_RDLCK",
			 lock_type);
	if ((lockfd = open(file, O_RDWR | O_CREAT, 0777)) < 0) {
		/* EACCES has been reported on NFS */
		if (warn_if_read_only || (errno != EROFS && errno != EACCES))
			log_sys_error("open", file);
		else
			stack;

		return -1;
	}

	if (fcntl(lockfd, F_SETLKW, &lock)) {
		log_sys_error("fcntl", file);
		if (close(lockfd))
			log_sys_error("close", file);
		return -1;
	}

	return lockfd;
}

void fcntl_unlock_file(int lockfd)
{
	const struct flock lock = { .l_type = F_UNLCK };

	log_very_verbose("Unlocking fd %d", lockfd);

	if (fcntl(lockfd, F_SETLK, &lock) == -1)
		log_sys_error("fcntl", "");

	if (close(lockfd))
		log_sys_error("close","");
}

int lvm_fclose(FILE *fp, const char *filename)
{
	if (!dm_fclose(fp))
		return 0;

	if (errno == 0)
		log_error("%s: write error", filename);
	else
		log_sys_error("write error", filename);

	return EOF;
}

void lvm_stat_ctim(struct timespec *ctim, const struct stat *buf)
{
#ifdef HAVE_STAT_ST_CTIM
	*ctim = buf->st_ctim;
#else
	ctim->tv_sec = buf->st_ctime;
	ctim->tv_nsec = 0;
#endif
}
