/*
 * 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 the device-mapper userspace tools.
 *
 * 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 "dmlib.h"

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

static int _is_dir(const char *path)
{
	struct stat st;

	if (stat(path, &st) < 0) {
		log_sys_error("stat", path);
		return 0;
	}

	if (!S_ISDIR(st.st_mode)) {
		log_error("Existing path %s is not "
			  "a directory.", path);
		return 0;
	}

	return 1;
}

static int _create_dir_recursive(const char *dir)
{
	char *orig, *s;
	int rc, r = 0;

	log_verbose("Creating directory \"%s\"", dir);
	/* Create parent directories */
	orig = s = dm_strdup(dir);
	if (!s) {
		log_error("Failed to duplicate directory name.");
		return 0;
	}

	while ((s = strchr(s, '/')) != NULL) {
		*s = '\0';
		if (*orig) {
			rc = mkdir(orig, 0777);
			if (rc < 0) {
				if (errno == EEXIST) {
					if (!_is_dir(orig))
						goto_out;
				} else {
					if (errno != EROFS)
						log_sys_error("mkdir", orig);
					goto out;
				}
			}
		}
		*s++ = '/';
	}

	/* Create final directory */
	rc = mkdir(dir, 0777);
	if (rc < 0) {
		if (errno == EEXIST) {
			if (!_is_dir(dir))
				goto_out;
		} else {
			if (errno != EROFS)
				log_sys_error("mkdir", orig);
			goto out;
		}
	}

	r = 1;
out:
	dm_free(orig);
	return r;
}

int dm_create_dir(const char *dir)
{
	struct stat info;

	if (!*dir)
		return 1;

	if (stat(dir, &info) == 0 && S_ISDIR(info.st_mode))
		return 1;

	if (!_create_dir_recursive(dir))
		return_0;

	return 1;
}

int dm_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;
}

int dm_fclose(FILE *stream)
{
	int prev_fail = ferror(stream);
	int fclose_fail = fclose(stream);

	/* If there was a previous failure, but fclose succeeded,
	   clear errno, since ferror does not set it, and its value
	   may be unrelated to the ferror-reported failure.  */
	if (prev_fail && !fclose_fail)
		errno = 0;

	return prev_fail || fclose_fail ? EOF : 0;
}

int dm_create_lockfile(const char *lockfile)
{
	int fd, value;
	size_t bufferlen;
	ssize_t write_out;
	struct flock lock;
	char buffer[50];
	int retries = 0;

	if ((fd = open(lockfile, O_CREAT | O_WRONLY,
		       (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
		log_error("Cannot open lockfile [%s], error was [%s]",
			  lockfile, strerror(errno));
		return 0;
	}

	lock.l_type = F_WRLCK;
	lock.l_start = 0;
	lock.l_whence = SEEK_SET;
	lock.l_len = 0;
retry_fcntl:
	if (fcntl(fd, F_SETLK, &lock) < 0) {
		switch (errno) {
		case EINTR:
			goto retry_fcntl;
		case EACCES:
		case EAGAIN:
			if (retries == 20) {
				log_error("Cannot lock lockfile [%s], error was [%s]",
					  lockfile, strerror(errno));
				break;
			} else {
				++ retries;
				usleep(1000);
				goto retry_fcntl;
			}
		default:
			log_error("process is already running");
		}

		goto fail_close;
	}

	if (ftruncate(fd, 0) < 0) {
		log_error("Cannot truncate pidfile [%s], error was [%s]",
			  lockfile, strerror(errno));

		goto fail_close_unlink;
	}

	memset(buffer, 0, sizeof(buffer));
	snprintf(buffer, sizeof(buffer)-1, "%u\n", getpid());

	bufferlen = strlen(buffer);
	write_out = write(fd, buffer, bufferlen);

	if ((write_out < 0) || (write_out == 0 && errno)) {
		log_error("Cannot write pid to pidfile [%s], error was [%s]",
			  lockfile, strerror(errno));

		goto fail_close_unlink;
	}

	if ((write_out == 0) || ((size_t)write_out < bufferlen)) {
		log_error("Cannot write pid to pidfile [%s], shortwrite of"
			  "[%" PRIsize_t "] bytes, expected [%" PRIsize_t "]\n",
			  lockfile, write_out, bufferlen);

		goto fail_close_unlink;
	}

	if ((value = fcntl(fd, F_GETFD, 0)) < 0) {
		log_error("Cannot get close-on-exec flag from pidfile [%s], "
			  "error was [%s]", lockfile, strerror(errno));

		goto fail_close_unlink;
	}
	value |= FD_CLOEXEC;
	if (fcntl(fd, F_SETFD, value) < 0) {
		log_error("Cannot set close-on-exec flag from pidfile [%s], "
			  "error was [%s]", lockfile, strerror(errno));

		goto fail_close_unlink;
	}

	return 1;

fail_close_unlink:
	if (unlink(lockfile))
		log_sys_debug("unlink", lockfile);
fail_close:
	if (close(fd))
		log_sys_debug("close", lockfile);

	return 0;
}

int dm_daemon_is_running(const char* lockfile)
{
       int fd;
       struct flock lock;

       if((fd = open(lockfile, O_RDONLY)) < 0)
               return 0;

       lock.l_type = F_WRLCK;
       lock.l_start = 0;
       lock.l_whence = SEEK_SET;
       lock.l_len = 0;
       if (fcntl(fd, F_GETLK, &lock) < 0) {
               log_error("Cannot check lock status of lockfile [%s], error was [%s]",
                         lockfile, strerror(errno));
               if (close(fd))
                       stack;
               return 0;
       }

       if (close(fd))
               stack;

       return (lock.l_type == F_UNLCK) ? 0 : 1;
}
