/*
 * libdpkg - Debian packaging suite library routines
 * file.c - file handling functions
 *
 * Copyright © 1994, 1995 Ian Jackson <ian@chiark.greenend.org.uk>
 * Copyright © 2008 Guillem Jover <guillem@debian.org>
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <config.h>
#include <compat.h>

#include <sys/types.h>
#include <sys/stat.h>

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <dpkg/dpkg.h>
#include <dpkg/i18n.h>
#include <dpkg/file.h>

/**
 * Copy file ownership and permissions from one file to another.
 *
 * @param src The source filename.
 * @param dst The destination filename.
 */
void
file_copy_perms(const char *src, const char *dst)
{
	struct stat stab;

	if (stat(src, &stab) == -1) {
		if (errno == ENOENT)
			return;
		ohshite(_("unable to stat source file '%.250s'"), src);
	}

	if (chown(dst, stab.st_uid, stab.st_gid) == -1)
		ohshite(_("unable to change ownership of target file '%.250s'"),
		        dst);

	if (chmod(dst, (stab.st_mode & 07777)) == -1)
		ohshite(_("unable to set mode of target file '%.250s'"), dst);
}

static void
file_lock_setup(struct flock *fl, short type)
{
	fl->l_type = type;
	fl->l_whence = SEEK_SET;
	fl->l_start = 0;
	fl->l_len = 0;
	fl->l_pid = 0;
}

/**
 * Unlock a previously locked file.
 */
void
file_unlock(int lockfd, const char *lock_desc)
{
	struct flock fl;

	assert(lockfd >= 0);

	file_lock_setup(&fl, F_UNLCK);

	if (fcntl(lockfd, F_SETLK, &fl) == -1)
		ohshite(_("unable to unlock %s"), lock_desc);
}

static void
file_unlock_cleanup(int argc, void **argv)
{
	int lockfd = *(int *)argv[0];
	const char *lock_desc = argv[1];

	file_unlock(lockfd, lock_desc);
}

/**
 * Check if a file has a lock acquired.
 *
 * @param lockfd The file descriptor for the lock.
 * @param filename The file name associated to the file descriptor.
 */
bool
file_is_locked(int lockfd, const char *filename)
{
	struct flock fl;

	file_lock_setup(&fl, F_WRLCK);

	if (fcntl(lockfd, F_GETLK, &fl) == -1)
		ohshit(_("unable to check file '%s' lock status"), filename);

	if (fl.l_type == F_WRLCK && fl.l_pid != getpid())
		return true;
	else
		return false;
}

/**
 * Lock a file.
 *
 * @param lockfd The pointer to the lock file descriptor. It must be allocated
 *        statically as its addresses is passed to a cleanup handler.
 * @param flags The lock flags specifying what type of locking to perform.
 * @param filename The name of the file to lock.
 * @param desc The description of the file to lock.
 */
void
file_lock(int *lockfd, enum file_lock_flags flags, const char *filename,
          const char *desc)
{
	struct flock fl;
	int lock_cmd;

	setcloexec(*lockfd, filename);

	file_lock_setup(&fl, F_WRLCK);

	if (flags == FILE_LOCK_WAIT)
		lock_cmd = F_SETLKW;
	else
		lock_cmd = F_SETLK;

	if (fcntl(*lockfd, lock_cmd, &fl) == -1) {
		if (errno == EACCES || errno == EAGAIN)
			ohshit(_("%s is locked by another process"), desc);
		else
			ohshite(_("unable to lock %s"), desc);
	}

	push_cleanup(file_unlock_cleanup, ~0, NULL, 0, 2, lockfd, desc);
}
