mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-07 21:56:44 +00:00
Merge pull request #437 from carlosmn/networking-windows
Fix networking on Windows
This commit is contained in:
commit
f77d4f7fc6
24
src/netops.c
24
src/netops.c
@ -77,7 +77,7 @@ int gitno_connect(const char *host, const char *port)
|
|||||||
struct addrinfo *info, *p;
|
struct addrinfo *info, *p;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int ret, error = GIT_SUCCESS;
|
int ret, error = GIT_SUCCESS;
|
||||||
int s;
|
GIT_SOCKET s;
|
||||||
|
|
||||||
memset(&hints, 0x0, sizeof(struct addrinfo));
|
memset(&hints, 0x0, sizeof(struct addrinfo));
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
@ -92,7 +92,11 @@ int gitno_connect(const char *host, const char *port)
|
|||||||
|
|
||||||
for (p = info; p != NULL; p = p->ai_next) {
|
for (p = info; p != NULL; p = p->ai_next) {
|
||||||
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
if (s == INVALID_SOCKET) {
|
||||||
|
#else
|
||||||
if (s < 0) {
|
if (s < 0) {
|
||||||
|
#endif
|
||||||
error = GIT_EOSERR;
|
error = GIT_EOSERR;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -109,19 +113,21 @@ int gitno_connect(const char *host, const char *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Oops, we couldn't connect to any address */
|
/* Oops, we couldn't connect to any address */
|
||||||
error = GIT_EOSERR;
|
error = git__throw(GIT_EOSERR, "Failed to connect: %s", strerror(errno));
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
freeaddrinfo(info);
|
freeaddrinfo(info);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gitno_send(int s, const char *msg, size_t len, int flags)
|
int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
|
|
||||||
while (off < len) {
|
while (off < len) {
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
ret = send(s, msg + off, len - off, flags);
|
ret = send(s, msg + off, len - off, flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return git__throw(GIT_EOSERR, "Error sending data: %s", strerror(errno));
|
return git__throw(GIT_EOSERR, "Error sending data: %s", strerror(errno));
|
||||||
@ -132,6 +138,18 @@ int gitno_send(int s, const char *msg, size_t len, int flags)
|
|||||||
return off;
|
return 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)
|
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
|
||||||
{
|
{
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef GIT_WIN32
|
#ifndef GIT_WIN32
|
||||||
typedef int GIT_SOCKET;
|
typedef int GIT_SOCKET;
|
||||||
#else
|
#else
|
||||||
typedef unsigned int GIT_SOCKET;
|
typedef SOCKET GIT_SOCKET;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct gitno_buffer {
|
typedef struct gitno_buffer {
|
||||||
@ -26,7 +26,8 @@ void gitno_consume(gitno_buffer *buf, const char *ptr);
|
|||||||
void gitno_consume_n(gitno_buffer *buf, size_t cons);
|
void gitno_consume_n(gitno_buffer *buf, size_t cons);
|
||||||
|
|
||||||
int gitno_connect(const char *host, const char *port);
|
int gitno_connect(const char *host, const char *port);
|
||||||
int gitno_send(int s, const char *msg, size_t len, int flags);
|
int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags);
|
||||||
|
int gitno_close(GIT_SOCKET s);
|
||||||
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec);
|
int gitno_select_in(gitno_buffer *buf, long int sec, long int usec);
|
||||||
|
|
||||||
int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port);
|
int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port);
|
||||||
|
@ -52,6 +52,9 @@ typedef struct {
|
|||||||
enum last_cb last_cb;
|
enum last_cb last_cb;
|
||||||
char *content_type;
|
char *content_type;
|
||||||
char *service;
|
char *service;
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
WSADATA wsd;
|
||||||
|
#endif
|
||||||
} transport_http;
|
} transport_http;
|
||||||
|
|
||||||
static int gen_request(git_buf *buf, const char *url, const char *host, const char *service)
|
static int gen_request(git_buf *buf, const char *url, const char *host, const char *service)
|
||||||
@ -76,7 +79,8 @@ static int gen_request(git_buf *buf, const char *url, const char *host, const ch
|
|||||||
static int do_connect(transport_http *t, const char *service)
|
static int do_connect(transport_http *t, const char *service)
|
||||||
{
|
{
|
||||||
git_buf request = GIT_BUF_INIT;
|
git_buf request = GIT_BUF_INIT;
|
||||||
int s = -1, error;
|
int error;
|
||||||
|
int s;
|
||||||
const char *url, *prefix;
|
const char *url, *prefix;
|
||||||
char *host = NULL, *port = NULL;
|
char *host = NULL, *port = NULL;
|
||||||
|
|
||||||
@ -358,10 +362,14 @@ static int http_close(git_transport *transport)
|
|||||||
transport_http *t = (transport_http *) transport;
|
transport_http *t = (transport_http *) transport;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = close(t->socket);
|
error = gitno_close(t->socket);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
return git__throw(GIT_EOSERR, "Failed to close the socket: %s", strerror(errno));
|
return git__throw(GIT_EOSERR, "Failed to close the socket: %s", strerror(errno));
|
||||||
|
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,6 +396,9 @@ static void http_free(git_transport *transport)
|
|||||||
int git_transport_http(git_transport **out)
|
int git_transport_http(git_transport **out)
|
||||||
{
|
{
|
||||||
transport_http *t;
|
transport_http *t;
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
int ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
t = git__malloc(sizeof(transport_http));
|
t = git__malloc(sizeof(transport_http));
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
@ -402,5 +413,13 @@ int git_transport_http(git_transport **out)
|
|||||||
|
|
||||||
*out = (git_transport *) t;
|
*out = (git_transport *) t;
|
||||||
|
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
ret = WSAStartup(MAKEWORD(2,2), &t->wsd);
|
||||||
|
if (ret != 0) {
|
||||||
|
http_free(*out);
|
||||||
|
return git__throw(GIT_EOSERR, "Winsock init failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,13 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
git_transport parent;
|
git_transport parent;
|
||||||
int socket;
|
GIT_SOCKET socket;
|
||||||
git_vector refs;
|
git_vector refs;
|
||||||
git_remote_head **heads;
|
git_remote_head **heads;
|
||||||
git_transport_caps caps;
|
git_transport_caps caps;
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
WSADATA wsd;
|
||||||
|
#endif
|
||||||
} transport_git;
|
} transport_git;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -35,10 +38,11 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
static int gen_proto(char **out, int *outlen, const char *cmd, const char *url)
|
static int gen_proto(char **out, int *outlen, const char *cmd, const char *url)
|
||||||
{
|
{
|
||||||
char *delim, *repo, *ptr;
|
char *delim, *repo;
|
||||||
char default_command[] = "git-upload-pack";
|
char default_command[] = "git-upload-pack";
|
||||||
char host[] = "host=";
|
char host[] = "host=";
|
||||||
int len;
|
int len;
|
||||||
|
git_buf buf = GIT_BUF_INIT;
|
||||||
|
|
||||||
delim = strchr(url, '/');
|
delim = strchr(url, '/');
|
||||||
if (delim == NULL)
|
if (delim == NULL)
|
||||||
@ -53,22 +57,21 @@ static int gen_proto(char **out, int *outlen, const char *cmd, const char *url)
|
|||||||
if (cmd == NULL)
|
if (cmd == NULL)
|
||||||
cmd = default_command;
|
cmd = default_command;
|
||||||
|
|
||||||
len = 4 + strlen(cmd) + 1 + strlen(repo) + 1 + strlen(host) + (delim - url) + 2;
|
len = 4 + strlen(cmd) + 1 + strlen(repo) + 1 + strlen(host) + (delim - url) + 1 + 1;
|
||||||
|
|
||||||
*out = git__malloc(len);
|
git_buf_grow(&buf, len);
|
||||||
if (*out == NULL)
|
|
||||||
return GIT_ENOMEM;
|
|
||||||
|
|
||||||
*outlen = len - 1;
|
git_buf_printf(&buf, "%04x%s %s%c%s", len, cmd, repo, 0, host);
|
||||||
ptr = *out;
|
git_buf_put(&buf, url, delim - url);
|
||||||
memset(ptr, 0x0, len);
|
git_buf_putc(&buf, '\0');
|
||||||
/* We expect the return value to be > len - 1 so don't bother checking it */
|
|
||||||
snprintf(ptr, len -1, "%04x%s %s%c%s%s", len - 1, cmd, repo, 0, host, url);
|
*outlen = len;
|
||||||
|
*out = buf.ptr;
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int send_request(int s, const char *cmd, const char *url)
|
static int send_request(GIT_SOCKET s, const char *cmd, const char *url)
|
||||||
{
|
{
|
||||||
int error, len;
|
int error, len;
|
||||||
char *msg = NULL;
|
char *msg = NULL;
|
||||||
@ -91,7 +94,7 @@ cleanup:
|
|||||||
*/
|
*/
|
||||||
static int do_connect(transport_git *t, const char *url)
|
static int do_connect(transport_git *t, const char *url)
|
||||||
{
|
{
|
||||||
int s = -1;
|
GIT_SOCKET s;
|
||||||
char *host, *port;
|
char *host, *port;
|
||||||
const char prefix[] = "git://";
|
const char prefix[] = "git://";
|
||||||
int error, connected = 0;
|
int error, connected = 0;
|
||||||
@ -502,15 +505,18 @@ static int git_download_pack(char **out, git_transport *transport, git_repositor
|
|||||||
static int git_close(git_transport *transport)
|
static int git_close(git_transport *transport)
|
||||||
{
|
{
|
||||||
transport_git *t = (transport_git*) transport;
|
transport_git *t = (transport_git*) transport;
|
||||||
int s = t->socket;
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Can't do anything if there's an error, so don't bother checking */
|
/* Can't do anything if there's an error, so don't bother checking */
|
||||||
git_pkt_send_flush(s);
|
git_pkt_send_flush(t->socket);
|
||||||
error = close(s);
|
error = gitno_close(t->socket);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
error = git__throw(GIT_EOSERR, "Failed to close socket");
|
error = git__throw(GIT_EOSERR, "Failed to close socket");
|
||||||
|
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
WSACleanup();
|
||||||
|
#endif
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,6 +540,9 @@ static void git_free(git_transport *transport)
|
|||||||
int git_transport_git(git_transport **out)
|
int git_transport_git(git_transport **out)
|
||||||
{
|
{
|
||||||
transport_git *t;
|
transport_git *t;
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
int ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
t = git__malloc(sizeof(transport_git));
|
t = git__malloc(sizeof(transport_git));
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
@ -554,5 +563,13 @@ int git_transport_git(git_transport **out)
|
|||||||
|
|
||||||
*out = (git_transport *) t;
|
*out = (git_transport *) t;
|
||||||
|
|
||||||
|
#ifdef GIT_WIN32
|
||||||
|
ret = WSAStartup(MAKEWORD(2,2), &t->wsd);
|
||||||
|
if (ret != 0) {
|
||||||
|
git_free(*out);
|
||||||
|
return git__throw(GIT_EOSERR, "Winsock init failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return GIT_SUCCESS;
|
return GIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -201,16 +201,19 @@ static void local_free(git_transport *transport)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
transport_local *t = (transport_local *) transport;
|
transport_local *t = (transport_local *) transport;
|
||||||
git_vector *vec = t->refs;
|
git_vector *vec = t->refs;
|
||||||
|
git_remote_head *h;
|
||||||
|
|
||||||
assert(transport);
|
assert(transport);
|
||||||
|
|
||||||
for (i = 0; i < vec->length; ++i) {
|
if (t->refs != NULL) {
|
||||||
git_remote_head *h = git_vector_get(vec, i);
|
git_vector_foreach (vec, i, h) {
|
||||||
free(h->name);
|
free(h->name);
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
git_vector_free(vec);
|
git_vector_free(vec);
|
||||||
free(vec);
|
free(vec);
|
||||||
|
}
|
||||||
|
|
||||||
git_repository_free(t->repo);
|
git_repository_free(t->repo);
|
||||||
free(t->parent.url);
|
free(t->parent.url);
|
||||||
free(t);
|
free(t);
|
||||||
@ -228,6 +231,8 @@ int git_transport_local(git_transport **out)
|
|||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return GIT_ENOMEM;
|
return GIT_ENOMEM;
|
||||||
|
|
||||||
|
memset(t, 0x0, sizeof(transport_local));
|
||||||
|
|
||||||
t->parent.connect = local_connect;
|
t->parent.connect = local_connect;
|
||||||
t->parent.ls = local_ls;
|
t->parent.ls = local_ls;
|
||||||
t->parent.send_wants = local_send_wants;
|
t->parent.send_wants = local_send_wants;
|
||||||
|
Loading…
Reference in New Issue
Block a user