/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */
#include "../posix.h"
#include "../fileops.h"
#include "path.h"
#include "path_w32.h"
#include "utf-conv.h"
#include "repository.h"
#include "reparse.h"
#include "global.h"
#include "buffer.h"
#include <errno.h>
#include <io.h>
#include <fcntl.h>
#include <ws2tcpip.h>

#ifndef FILE_NAME_NORMALIZED
# define FILE_NAME_NORMALIZED 0
#endif

#ifndef IO_REPARSE_TAG_SYMLINK
#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif

/* Allowable mode bits on Win32.  Using mode bits that are not supported on
 * Win32 (eg S_IRWXU) is generally ignored, but Wine warns loudly about it
 * so we simply remove them.
 */
#define WIN32_MODE_MASK (_S_IREAD | _S_IWRITE)

/* GetFinalPathNameByHandleW signature */
typedef DWORD(WINAPI *PFGetFinalPathNameByHandleW)(HANDLE, LPWSTR, DWORD, DWORD);

unsigned long git_win32__createfile_sharemode =
 FILE_SHARE_READ | FILE_SHARE_WRITE;
int git_win32__retries = 10;

GIT_INLINE(void) set_errno(void)
{
	switch (GetLastError()) {
	case ERROR_FILE_NOT_FOUND:
	case ERROR_PATH_NOT_FOUND:
	case ERROR_INVALID_DRIVE:
	case ERROR_NO_MORE_FILES:
	case ERROR_BAD_NETPATH:
	case ERROR_BAD_NET_NAME:
	case ERROR_BAD_PATHNAME:
	case ERROR_FILENAME_EXCED_RANGE:
		errno = ENOENT;
		break;
	case ERROR_BAD_ENVIRONMENT:
		errno = E2BIG;
		break;
	case ERROR_BAD_FORMAT:
	case ERROR_INVALID_STARTING_CODESEG:
	case ERROR_INVALID_STACKSEG:
	case ERROR_INVALID_MODULETYPE:
	case ERROR_INVALID_EXE_SIGNATURE:
	case ERROR_EXE_MARKED_INVALID:
	case ERROR_BAD_EXE_FORMAT:
	case ERROR_ITERATED_DATA_EXCEEDS_64k:
	case ERROR_INVALID_MINALLOCSIZE:
	case ERROR_DYNLINK_FROM_INVALID_RING:
	case ERROR_IOPL_NOT_ENABLED:
	case ERROR_INVALID_SEGDPL:
	case ERROR_AUTODATASEG_EXCEEDS_64k:
	case ERROR_RING2SEG_MUST_BE_MOVABLE:
	case ERROR_RELOC_CHAIN_XEEDS_SEGLIM:
	case ERROR_INFLOOP_IN_RELOC_CHAIN:
		errno = ENOEXEC;
		break;
	case ERROR_INVALID_HANDLE:
	case ERROR_INVALID_TARGET_HANDLE:
	case ERROR_DIRECT_ACCESS_HANDLE:
		errno = EBADF;
		break;
	case ERROR_WAIT_NO_CHILDREN:
	case ERROR_CHILD_NOT_COMPLETE:
		errno = ECHILD;
		break;
	case ERROR_NO_PROC_SLOTS:
	case ERROR_MAX_THRDS_REACHED:
	case ERROR_NESTING_NOT_ALLOWED:
		errno = EAGAIN;
		break;
	case ERROR_ARENA_TRASHED:
	case ERROR_NOT_ENOUGH_MEMORY:
	case ERROR_INVALID_BLOCK:
	case ERROR_NOT_ENOUGH_QUOTA:
		errno = ENOMEM;
		break;
	case ERROR_ACCESS_DENIED:
	case ERROR_CURRENT_DIRECTORY:
	case ERROR_WRITE_PROTECT:
	case ERROR_BAD_UNIT:
	case ERROR_NOT_READY:
	case ERROR_BAD_COMMAND:
	case ERROR_CRC:
	case ERROR_BAD_LENGTH:
	case ERROR_SEEK:
	case ERROR_NOT_DOS_DISK:
	case ERROR_SECTOR_NOT_FOUND:
	case ERROR_OUT_OF_PAPER:
	case ERROR_WRITE_FAULT:
	case ERROR_READ_FAULT:
	case ERROR_GEN_FAILURE:
	case ERROR_SHARING_VIOLATION:
	case ERROR_LOCK_VIOLATION:
	case ERROR_WRONG_DISK:
	case ERROR_SHARING_BUFFER_EXCEEDED:
	case ERROR_NETWORK_ACCESS_DENIED:
	case ERROR_CANNOT_MAKE:
	case ERROR_FAIL_I24:
	case ERROR_DRIVE_LOCKED:
	case ERROR_SEEK_ON_DEVICE:
	case ERROR_NOT_LOCKED:
	case ERROR_LOCK_FAILED:
		errno = EACCES;
		break;
	case ERROR_FILE_EXISTS:
	case ERROR_ALREADY_EXISTS:
		errno = EEXIST;
		break;
	case ERROR_NOT_SAME_DEVICE:
		errno = EXDEV;
		break;
	case ERROR_INVALID_FUNCTION:
	case ERROR_INVALID_ACCESS:
	case ERROR_INVALID_DATA:
	case ERROR_INVALID_PARAMETER:
	case ERROR_NEGATIVE_SEEK:
		errno = EINVAL;
		break;
	case ERROR_TOO_MANY_OPEN_FILES:
		errno = EMFILE;
		break;
	case ERROR_DISK_FULL:
		errno = ENOSPC;
		break;
	case ERROR_BROKEN_PIPE:
		errno = EPIPE;
		break;
	case ERROR_DIR_NOT_EMPTY:
		errno = ENOTEMPTY;
		break;
	default:
		errno = EINVAL;
	}
}

GIT_INLINE(bool) last_error_retryable(void)
{
	int os_error = GetLastError();

	return (os_error == ERROR_SHARING_VIOLATION ||
		os_error == ERROR_ACCESS_DENIED);
}

#define do_with_retries(fn, remediation) \
	do {                                                             \
		int __tries, __ret;                                          \
		for (__tries = 0; __tries < git_win32__retries; __tries++) { \
			if (__tries && (__ret = (remediation)) != 0)             \
				return __ret;                                        \
			if ((__ret = (fn)) != GIT_RETRY)                         \
				return __ret;                                        \
			Sleep(5);                                                \
		}                                                            \
		return -1;                                                   \
	} while (0)                                                      \

static int ensure_writable(wchar_t *path)
{
	DWORD attrs;

	if ((attrs = GetFileAttributesW(path)) == INVALID_FILE_ATTRIBUTES)
		goto on_error;

	if ((attrs & FILE_ATTRIBUTE_READONLY) == 0)
		return 0;

	if (!SetFileAttributesW(path, (attrs & ~FILE_ATTRIBUTE_READONLY)))
		goto on_error;

	return 0;

on_error:
	set_errno();
	return -1;
}

/**
 * Truncate or extend file.
 *
 * We now take a "git_off_t" rather than "long" because
 * files may be longer than 2Gb.
 */
int p_ftruncate(int fd, git_off_t size)
{
	if (size < 0) {
		errno = EINVAL;
		return -1;
	}

#if !defined(__MINGW32__) || defined(MINGW_HAS_SECURE_API)
	return ((_chsize_s(fd, size) == 0) ? 0 : -1);
#else
	/* TODO MINGW32 Find a replacement for _chsize() that handles big files. */
	if (size > INT32_MAX) {
		errno = EFBIG;
		return -1;
	}
	return _chsize(fd, (long)size);
#endif
}

int p_mkdir(const char *path, mode_t mode)
{
	git_win32_path buf;

	GIT_UNUSED(mode);

	if (git_win32_path_from_utf8(buf, path) < 0)
		return -1;

	return _wmkdir(buf);
}

int p_link(const char *old, const char *new)
{
	GIT_UNUSED(old);
	GIT_UNUSED(new);
	errno = ENOSYS;
	return -1;
}

GIT_INLINE(int) unlink_once(const wchar_t *path)
{
	if (DeleteFileW(path))
		return 0;

	if (last_error_retryable())
		return GIT_RETRY;

	set_errno();
	return -1;
}

int p_unlink(const char *path)
{
	git_win32_path wpath;

	if (git_win32_path_from_utf8(wpath, path) < 0)
		return -1;

	do_with_retries(unlink_once(wpath), ensure_writable(wpath));
}

int p_fsync(int fd)
{
	HANDLE fh = (HANDLE)_get_osfhandle(fd);

	p_fsync__cnt++;

	if (fh == INVALID_HANDLE_VALUE) {
		errno = EBADF;
		return -1;
	}

	if (!FlushFileBuffers(fh)) {
		DWORD code = GetLastError();

		if (code == ERROR_INVALID_HANDLE)
			errno = EINVAL;
		else
			errno = EIO;

		return -1;
	}

	return 0;
}

#define WIN32_IS_WSEP(CH) ((CH) == L'/' || (CH) == L'\\')

static int lstat_w(
	wchar_t *path,
	struct stat *buf,
	bool posix_enotdir)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (GetFileAttributesExW(path, GetFileExInfoStandard, &fdata)) {
		if (!buf)
			return 0;

		return git_win32__file_attribute_to_stat(buf, &fdata, path);
	}

	switch (GetLastError()) {
	case ERROR_ACCESS_DENIED:
		errno = EACCES;
		break;
	default:
		errno = ENOENT;
		break;
	}

	/* To match POSIX behavior, set ENOTDIR when any of the folders in the
	 * file path is a regular file, otherwise set ENOENT.
	 */
	if (errno == ENOENT && posix_enotdir) {
		size_t path_len = wcslen(path);

		/* scan up path until we find an existing item */
		while (1) {
			DWORD attrs;

			/* remove last directory component */
			for (path_len--; path_len > 0 && !WIN32_IS_WSEP(path[path_len]); path_len--);

			if (path_len <= 0)
				break;

			path[path_len] = L'\0';
			attrs = GetFileAttributesW(path);

			if (attrs != INVALID_FILE_ATTRIBUTES) {
				if (!(attrs & FILE_ATTRIBUTE_DIRECTORY))
					errno = ENOTDIR;
				break;
			}
		}
	}

	return -1;
}

static int do_lstat(const char *path, struct stat *buf, bool posixly_correct)
{
	git_win32_path path_w;
	int len;

	if ((len = git_win32_path_from_utf8(path_w, path)) < 0)
		return -1;

	git_win32__path_trim_end(path_w, len);

	return lstat_w(path_w, buf, posixly_correct);
}

int p_lstat(const char *filename, struct stat *buf)
{
	return do_lstat(filename, buf, false);
}

int p_lstat_posixly(const char *filename, struct stat *buf)
{
	return do_lstat(filename, buf, true);
}

int p_readlink(const char *path, char *buf, size_t bufsiz)
{
	git_win32_path path_w, target_w;
	git_win32_utf8_path target;
	int len;

	/* readlink(2) does not NULL-terminate the string written
	 * to the target buffer. Furthermore, the target buffer need
	 * not be large enough to hold the entire result. A truncated
	 * result should be written in this case. Since this truncation
	 * could occur in the middle of the encoding of a code point,
	 * we need to buffer the result on the stack. */

	if (git_win32_path_from_utf8(path_w, path) < 0 ||
		git_win32_path_readlink_w(target_w, path_w) < 0 ||
		(len = git_win32_path_to_utf8(target, target_w)) < 0)
		return -1;

	bufsiz = min((size_t)len, bufsiz);
	memcpy(buf, target, bufsiz);

	return (int)bufsiz;
}

int p_symlink(const char *old, const char *new)
{
	/* Real symlinks on NTFS require admin privileges. Until this changes,
	 * libgit2 just creates a text file with the link target in the contents.
	 */
	return git_futils_fake_symlink(old, new);
}

struct open_opts {
	DWORD access;
	DWORD sharing;
	SECURITY_ATTRIBUTES security;
	DWORD creation_disposition;
	DWORD attributes;
	int osf_flags;
};

GIT_INLINE(void) open_opts_from_posix(struct open_opts *opts, int flags, mode_t mode)
{
	memset(opts, 0, sizeof(struct open_opts));

	switch (flags & (O_WRONLY | O_RDWR)) {
	case O_WRONLY:
		opts->access = GENERIC_WRITE;
		break;
	case O_RDWR:
		opts->access = GENERIC_READ | GENERIC_WRITE;
		break;
	default:
		opts->access = GENERIC_READ;
		break;
	}

	opts->sharing = (DWORD)git_win32__createfile_sharemode;

	switch (flags & (O_CREAT | O_TRUNC | O_EXCL)) {
	case O_CREAT | O_EXCL:
	case O_CREAT | O_TRUNC | O_EXCL:
		opts->creation_disposition = CREATE_NEW;
		break;
	case O_CREAT | O_TRUNC:
		opts->creation_disposition = CREATE_ALWAYS;
		break;
	case O_TRUNC:
		opts->creation_disposition = TRUNCATE_EXISTING;
		break;
	case O_CREAT:
		opts->creation_disposition = OPEN_ALWAYS;
		break;
	default:
		opts->creation_disposition = OPEN_EXISTING;
		break;
	}

	opts->attributes = ((flags & O_CREAT) && !(mode & S_IWRITE)) ?
		FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL;
	opts->osf_flags = flags & (O_RDONLY | O_APPEND);

	opts->security.nLength = sizeof(SECURITY_ATTRIBUTES);
	opts->security.lpSecurityDescriptor = NULL;
	opts->security.bInheritHandle = 0;
}

GIT_INLINE(int) open_once(
	const wchar_t *path,
	struct open_opts *opts)
{
	int fd;

	HANDLE handle = CreateFileW(path, opts->access, opts->sharing,
		&opts->security, opts->creation_disposition, opts->attributes, 0);

	if (handle == INVALID_HANDLE_VALUE) {
		if (last_error_retryable())
			return GIT_RETRY;

		set_errno();
		return -1;
	}

	if ((fd = _open_osfhandle((intptr_t)handle, opts->osf_flags)) < 0)
		CloseHandle(handle);

	return fd;
}

int p_open(const char *path, int flags, ...)
{
	git_win32_path wpath;
	mode_t mode = 0;
	struct open_opts opts = {0};

	if (git_win32_path_from_utf8(wpath, path) < 0)
		return -1;

	if (flags & O_CREAT) {
		va_list arg_list;

		va_start(arg_list, flags);
		mode = (mode_t)va_arg(arg_list, int);
		va_end(arg_list);
	}

	open_opts_from_posix(&opts, flags, mode);

	do_with_retries(
		open_once(wpath, &opts),
		0);
}

int p_creat(const char *path, mode_t mode)
{
	return p_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
}

int p_utimes(const char *path, const struct p_timeval times[2])
{
	git_win32_path wpath;
	int fd, error;
	DWORD attrs_orig, attrs_new = 0;
	struct open_opts opts = { 0 };

	if (git_win32_path_from_utf8(wpath, path) < 0)
		return -1;

	attrs_orig = GetFileAttributesW(wpath);

	if (attrs_orig & FILE_ATTRIBUTE_READONLY) {
		attrs_new = attrs_orig & ~FILE_ATTRIBUTE_READONLY;

		if (!SetFileAttributesW(wpath, attrs_new)) {
			giterr_set(GITERR_OS, "failed to set attributes");
			return -1;
		}
	}

	open_opts_from_posix(&opts, O_RDWR, 0);

	if ((fd = open_once(wpath, &opts)) < 0) {
		error = -1;
		goto done;
	}

	error = p_futimes(fd, times);
	close(fd);

done:
	if (attrs_orig != attrs_new) {
		DWORD os_error = GetLastError();
		SetFileAttributesW(wpath, attrs_orig);
		SetLastError(os_error);
	}

	return error;
}

int p_futimes(int fd, const struct p_timeval times[2])
{
	HANDLE handle;
	FILETIME atime = { 0 }, mtime = { 0 };

	if (times == NULL) {
		SYSTEMTIME st;

		GetSystemTime(&st);
		SystemTimeToFileTime(&st, &atime);
		SystemTimeToFileTime(&st, &mtime);
	}
	else {
		git_win32__timeval_to_filetime(&atime, times[0]);
		git_win32__timeval_to_filetime(&mtime, times[1]);
	}

	if ((handle = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE)
		return -1;

	if (SetFileTime(handle, NULL, &atime, &mtime) == 0)
		return -1;

	return 0;
}

int p_getcwd(char *buffer_out, size_t size)
{
	git_win32_path buf;
	wchar_t *cwd = _wgetcwd(buf, GIT_WIN_PATH_UTF16);

	if (!cwd)
		return -1;

	/* Convert the working directory back to UTF-8 */
	if (git__utf16_to_8(buffer_out, size, cwd) < 0) {
		DWORD code = GetLastError();

		if (code == ERROR_INSUFFICIENT_BUFFER)
			errno = ERANGE;
		else
			errno = EINVAL;

		return -1;
	}

	return 0;
}

/*
 * Returns the address of the GetFinalPathNameByHandleW function.
 * This function is available on Windows Vista and higher.
 */
static PFGetFinalPathNameByHandleW get_fpnbyhandle(void)
{
	static PFGetFinalPathNameByHandleW pFunc = NULL;
	PFGetFinalPathNameByHandleW toReturn = pFunc;

	if (!toReturn) {
		HMODULE hModule = GetModuleHandleW(L"kernel32");

		if (hModule)
			toReturn = (PFGetFinalPathNameByHandleW)GetProcAddress(hModule, "GetFinalPathNameByHandleW");

		pFunc = toReturn;
	}

	assert(toReturn);

	return toReturn;
}

static int getfinalpath_w(
	git_win32_path dest,
	const wchar_t *path)
{
	PFGetFinalPathNameByHandleW pgfp = get_fpnbyhandle();
	HANDLE hFile;
	DWORD dwChars;

	if (!pgfp)
		return -1;

	/* Use FILE_FLAG_BACKUP_SEMANTICS so we can open a directory. Do not
	* specify FILE_FLAG_OPEN_REPARSE_POINT; we want to open a handle to the
	* target of the link. */
	hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
		NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);

	if (INVALID_HANDLE_VALUE == hFile)
		return -1;

	/* Call GetFinalPathNameByHandle */
	dwChars = pgfp(hFile, dest, GIT_WIN_PATH_UTF16, FILE_NAME_NORMALIZED);
	CloseHandle(hFile);

	if (!dwChars || dwChars >= GIT_WIN_PATH_UTF16)
		return -1;

	/* The path may be delivered to us with a prefix; canonicalize */
	return (int)git_win32__canonicalize_path(dest, dwChars);
}

static int follow_and_lstat_link(git_win32_path path, struct stat* buf)
{
	git_win32_path target_w;

	if (getfinalpath_w(target_w, path) < 0)
		return -1;

	return lstat_w(target_w, buf, false);
}

int p_fstat(int fd, struct stat *buf)
{
	BY_HANDLE_FILE_INFORMATION fhInfo;

	HANDLE fh = (HANDLE)_get_osfhandle(fd);

	if (fh == INVALID_HANDLE_VALUE ||
		!GetFileInformationByHandle(fh, &fhInfo)) {
		errno = EBADF;
		return -1;
	}

	git_win32__file_information_to_stat(buf, &fhInfo);
	return 0;
}

int p_stat(const char* path, struct stat* buf)
{
	git_win32_path path_w;
	int len;

	if ((len = git_win32_path_from_utf8(path_w, path)) < 0 ||
		lstat_w(path_w, buf, false) < 0)
		return -1;

	/* The item is a symbolic link or mount point. No need to iterate
	 * to follow multiple links; use GetFinalPathNameFromHandle. */
	if (S_ISLNK(buf->st_mode))
		return follow_and_lstat_link(path_w, buf);

	return 0;
}

int p_chdir(const char* path)
{
	git_win32_path buf;

	if (git_win32_path_from_utf8(buf, path) < 0)
		return -1;

	return _wchdir(buf);
}

int p_chmod(const char* path, mode_t mode)
{
	git_win32_path buf;

	if (git_win32_path_from_utf8(buf, path) < 0)
		return -1;

	return _wchmod(buf, mode);
}

int p_rmdir(const char* path)
{
	git_win32_path buf;
	int error;

	if (git_win32_path_from_utf8(buf, path) < 0)
		return -1;

	error = _wrmdir(buf);

	if (error == -1) {
		switch (GetLastError()) {
			/* _wrmdir() is documented to return EACCES if "A program has an open
			 * handle to the directory."  This sounds like what everybody else calls
			 * EBUSY.  Let's convert appropriate error codes.
			 */
			case ERROR_SHARING_VIOLATION:
				errno = EBUSY;
				break;

			/* This error can be returned when trying to rmdir an extant file. */
			case ERROR_DIRECTORY:
				errno = ENOTDIR;
				break;
		}
	}

	return error;
}

char *p_realpath(const char *orig_path, char *buffer)
{
	git_win32_path orig_path_w, buffer_w;

	if (git_win32_path_from_utf8(orig_path_w, orig_path) < 0)
		return NULL;

	/* Note that if the path provided is a relative path, then the current directory
	 * is used to resolve the path -- which is a concurrency issue because the current
	 * directory is a process-wide variable. */
	if (!GetFullPathNameW(orig_path_w, GIT_WIN_PATH_UTF16, buffer_w, NULL)) {
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
			errno = ENAMETOOLONG;
		else
			errno = EINVAL;

		return NULL;
	}

	/* The path must exist. */
	if (GetFileAttributesW(buffer_w) == INVALID_FILE_ATTRIBUTES) {
		errno = ENOENT;
		return NULL;
	}

	if (!buffer && !(buffer = git__malloc(GIT_WIN_PATH_UTF8))) {
		errno = ENOMEM;
		return NULL;
	}

	/* Convert the path to UTF-8. If the caller provided a buffer, then it
	 * is assumed to be GIT_WIN_PATH_UTF8 characters in size. If it isn't,
	 * then we may overflow. */
	if (git_win32_path_to_utf8(buffer, buffer_w) < 0)
		return NULL;

	git_path_mkposix(buffer);

	return buffer;
}

int p_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
{
#if defined(_MSC_VER)
	int len;

	if (count == 0)
		return _vscprintf(format, argptr);

	#if _MSC_VER >= 1500
	len = _vsnprintf_s(buffer, count, _TRUNCATE, format, argptr);
	#else
	len = _vsnprintf(buffer, count, format, argptr);
	#endif

	if (len < 0)
		return _vscprintf(format, argptr);

	return len;
#else /* MinGW */
	return vsnprintf(buffer, count, format, argptr);
#endif
}

int p_snprintf(char *buffer, size_t count, const char *format, ...)
{
	va_list va;
	int r;

	va_start(va, format);
	r = p_vsnprintf(buffer, count, format, va);
	va_end(va);

	return r;
}

/* TODO: wut? */
int p_mkstemp(char *tmp_path)
{
#if defined(_MSC_VER) && _MSC_VER >= 1500
	if (_mktemp_s(tmp_path, strlen(tmp_path) + 1) != 0)
		return -1;
#else
	if (_mktemp(tmp_path) == NULL)
		return -1;
#endif

	return p_open(tmp_path, O_RDWR | O_CREAT | O_EXCL, 0744); //-V536
}

int p_access(const char* path, mode_t mode)
{
	git_win32_path buf;

	if (git_win32_path_from_utf8(buf, path) < 0)
		return -1;

	return _waccess(buf, mode & WIN32_MODE_MASK);
}

GIT_INLINE(int) rename_once(const wchar_t *from, const wchar_t *to)
{
	if (MoveFileExW(from, to, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
		return 0;

	if (last_error_retryable())
		return GIT_RETRY;

	set_errno();
	return -1;
}

int p_rename(const char *from, const char *to)
{
	git_win32_path wfrom, wto;

	if (git_win32_path_from_utf8(wfrom, from) < 0 ||
		git_win32_path_from_utf8(wto, to) < 0)
		return -1;

	do_with_retries(rename_once(wfrom, wto), ensure_writable(wto));
}

int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags)
{
	if ((size_t)((int)length) != length)
		return -1; /* giterr_set will be done by caller */

	return recv(socket, buffer, (int)length, flags);
}

int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags)
{
	if ((size_t)((int)length) != length)
		return -1; /* giterr_set will be done by caller */

	return send(socket, buffer, (int)length, flags);
}

/**
 * Borrowed from http://old.nabble.com/Porting-localtime_r-and-gmtime_r-td15282276.html
 * On Win32, `gmtime_r` doesn't exist but `gmtime` is threadsafe, so we can use that
 */
struct tm *
p_localtime_r (const time_t *timer, struct tm *result)
{
	struct tm *local_result;
	local_result = localtime (timer);

	if (local_result == NULL || result == NULL)
		return NULL;

	memcpy (result, local_result, sizeof (struct tm));
	return result;
}
struct tm *
p_gmtime_r (const time_t *timer, struct tm *result)
{
	struct tm *local_result;
	local_result = gmtime (timer);

	if (local_result == NULL || result == NULL)
		return NULL;

	memcpy (result, local_result, sizeof (struct tm));
	return result;
}

int p_inet_pton(int af, const char *src, void *dst)
{
	struct sockaddr_storage sin;
	void *addr;
	int sin_len = sizeof(struct sockaddr_storage), addr_len;
	int error = 0;

	if (af == AF_INET) {
		addr = &((struct sockaddr_in *)&sin)->sin_addr;
		addr_len = sizeof(struct in_addr);
	} else if (af == AF_INET6) {
		addr = &((struct sockaddr_in6 *)&sin)->sin6_addr;
		addr_len = sizeof(struct in6_addr);
	} else {
		errno = EAFNOSUPPORT;
		return -1;
	}

	if ((error = WSAStringToAddressA((LPSTR)src, af, NULL, (LPSOCKADDR)&sin, &sin_len)) == 0) {
		memcpy(dst, addr, addr_len);
		return 1;
	}

	switch(WSAGetLastError()) {
	case WSAEINVAL:
		return 0;
	case WSAEFAULT:
		errno = ENOSPC;
		return -1;
	case WSA_NOT_ENOUGH_MEMORY:
		errno = ENOMEM;
		return -1;
	}

	errno = EINVAL;
	return -1;
}
