mirror of
				https://git.proxmox.com/git/libgit2
				synced 2025-11-04 07:09:14 +00:00 
			
		
		
		
	This fixes all the warnings on win64 except those in deps, which come from the regex code.
		
			
				
	
	
		
			208 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2009-2012 the libgit2 contributors
 | 
						|
 *
 | 
						|
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 | 
						|
 * a Linking Exception. For full terms see the included COPYING file.
 | 
						|
 */
 | 
						|
#ifndef _WIN32
 | 
						|
#	include <sys/types.h>
 | 
						|
#	include <sys/socket.h>
 | 
						|
#	include <sys/select.h>
 | 
						|
#	include <sys/time.h>
 | 
						|
#	include <netdb.h>
 | 
						|
#else
 | 
						|
#	define _WIN32_WINNT 0x0501
 | 
						|
#	include <winsock2.h>
 | 
						|
#	include <Ws2tcpip.h>
 | 
						|
#	ifdef _MSC_VER
 | 
						|
#		pragma comment(lib, "Ws2_32.lib")
 | 
						|
#	endif
 | 
						|
#endif
 | 
						|
 | 
						|
 | 
						|
#include "git2/errors.h"
 | 
						|
 | 
						|
#include "common.h"
 | 
						|
#include "netops.h"
 | 
						|
#include "posix.h"
 | 
						|
#include "buffer.h"
 | 
						|
 | 
						|
#ifdef GIT_WIN32
 | 
						|
static void net_set_error(const char *str)
 | 
						|
{
 | 
						|
	int size, error = WSAGetLastError();
 | 
						|
	LPSTR err_str = NULL;
 | 
						|
 | 
						|
	size = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
 | 
						|
			     0, error, 0, (LPSTR)&err_str, 0, 0);
 | 
						|
 | 
						|
	giterr_set(GITERR_NET, "%s: $s", str, err_str);
 | 
						|
	LocalFree(err_str);
 | 
						|
}
 | 
						|
#else
 | 
						|
static void net_set_error(const char *str)
 | 
						|
{
 | 
						|
	giterr_set(GITERR_NET, "%s: %s", str, strerror(errno));
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void gitno_buffer_setup(gitno_buffer *buf, char *data, unsigned int len, GIT_SOCKET fd)
 | 
						|
{
 | 
						|
	memset(buf, 0x0, sizeof(gitno_buffer));
 | 
						|
	memset(data, 0x0, len);
 | 
						|
	buf->data = data;
 | 
						|
	buf->len = len;
 | 
						|
	buf->offset = 0;
 | 
						|
	buf->fd = fd;
 | 
						|
}
 | 
						|
 | 
						|
int gitno_recv(gitno_buffer *buf)
 | 
						|
{
 | 
						|
	int ret;
 | 
						|
 | 
						|
	ret = p_recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0);
 | 
						|
	if (ret < 0) {
 | 
						|
		net_set_error("Error receiving socket data");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	buf->offset += ret;
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
/* Consume up to ptr and move the rest of the buffer to the beginning */
 | 
						|
void gitno_consume(gitno_buffer *buf, const char *ptr)
 | 
						|
{
 | 
						|
	size_t consumed;
 | 
						|
 | 
						|
	assert(ptr - buf->data >= 0);
 | 
						|
	assert(ptr - buf->data <= (int) buf->len);
 | 
						|
 | 
						|
	consumed = ptr - buf->data;
 | 
						|
 | 
						|
	memmove(buf->data, ptr, buf->offset - consumed);
 | 
						|
	memset(buf->data + buf->offset, 0x0, buf->len - buf->offset);
 | 
						|
	buf->offset -= consumed;
 | 
						|
}
 | 
						|
 | 
						|
/* Consume const bytes and move the rest of the buffer to the beginning */
 | 
						|
void gitno_consume_n(gitno_buffer *buf, size_t cons)
 | 
						|
{
 | 
						|
	memmove(buf->data, buf->data + cons, buf->len - buf->offset);
 | 
						|
	memset(buf->data + cons, 0x0, buf->len - buf->offset);
 | 
						|
	buf->offset -= cons;
 | 
						|
}
 | 
						|
 | 
						|
GIT_SOCKET gitno_connect(const char *host, const char *port)
 | 
						|
{
 | 
						|
	struct addrinfo *info = NULL, *p;
 | 
						|
	struct addrinfo hints;
 | 
						|
	int ret;
 | 
						|
	GIT_SOCKET s = INVALID_SOCKET;
 | 
						|
 | 
						|
	memset(&hints, 0x0, sizeof(struct addrinfo));
 | 
						|
	hints.ai_family = AF_UNSPEC;
 | 
						|
	hints.ai_socktype = SOCK_STREAM;
 | 
						|
 | 
						|
	if ((ret = getaddrinfo(host, port, &hints, &info)) < 0) {
 | 
						|
		giterr_set(GITERR_NET, "Failed to resolve address for %s: %s", host, gai_strerror(ret));
 | 
						|
		return INVALID_SOCKET;
 | 
						|
	}
 | 
						|
 | 
						|
	for (p = info; p != NULL; p = p->ai_next) {
 | 
						|
		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
 | 
						|
		if (s == INVALID_SOCKET) {
 | 
						|
			net_set_error("error creating socket");
 | 
						|
			break;
 | 
						|
		}
 | 
						|
 | 
						|
		if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
 | 
						|
			break;
 | 
						|
 | 
						|
		/* If we can't connect, try the next one */
 | 
						|
		gitno_close(s);
 | 
						|
		s = INVALID_SOCKET;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Oops, we couldn't connect to any address */
 | 
						|
	if (s == INVALID_SOCKET && p == NULL)
 | 
						|
		giterr_set(GITERR_OS, "Failed to connect to %s", host);
 | 
						|
 | 
						|
	freeaddrinfo(info);
 | 
						|
	return s;
 | 
						|
}
 | 
						|
 | 
						|
int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags)
 | 
						|
{
 | 
						|
	int ret;
 | 
						|
	size_t off = 0;
 | 
						|
 | 
						|
	while (off < len) {
 | 
						|
		errno = 0;
 | 
						|
 | 
						|
		ret = p_send(s, msg + off, len - off, flags);
 | 
						|
		if (ret < 0) {
 | 
						|
			net_set_error("Error sending data");
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
 | 
						|
		off += ret;
 | 
						|
	}
 | 
						|
 | 
						|
	return (int)off;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#ifdef GIT_WIN32
 | 
						|
int gitno_close(GIT_SOCKET s)
 | 
						|
{
 | 
						|
	return closesocket(s) == SOCKET_ERROR ? -1 : 0;
 | 
						|
}
 | 
						|
#else
 | 
						|
int gitno_close(GIT_SOCKET s)
 | 
						|
{
 | 
						|
	return close(s);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
 | 
						|
{
 | 
						|
	fd_set fds;
 | 
						|
	struct timeval tv;
 | 
						|
 | 
						|
	tv.tv_sec = sec;
 | 
						|
	tv.tv_usec = usec;
 | 
						|
 | 
						|
	FD_ZERO(&fds);
 | 
						|
	FD_SET(buf->fd, &fds);
 | 
						|
 | 
						|
	/* The select(2) interface is silly */
 | 
						|
	return select((int)buf->fd + 1, &fds, NULL, NULL, &tv);
 | 
						|
}
 | 
						|
 | 
						|
int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port)
 | 
						|
{
 | 
						|
	char *colon, *slash, *delim;
 | 
						|
 | 
						|
	colon = strchr(url, ':');
 | 
						|
	slash = strchr(url, '/');
 | 
						|
 | 
						|
	if (slash == NULL) {
 | 
						|
		giterr_set(GITERR_NET, "Malformed URL: missing /");
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	if (colon == NULL) {
 | 
						|
		*port = git__strdup(default_port);
 | 
						|
	} else {
 | 
						|
		*port = git__strndup(colon + 1, slash - colon - 1);
 | 
						|
	}
 | 
						|
	GITERR_CHECK_ALLOC(*port);
 | 
						|
 | 
						|
	delim = colon == NULL ? slash : colon;
 | 
						|
	*host = git__strndup(url, delim - url);
 | 
						|
	GITERR_CHECK_ALLOC(*host);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 |