Commit 1b4f814025ca0c48477fb074929cd15f41f4f68f

Carlos Martín Nieto 2011-06-16T00:39:35

Create netops and start moving git:// to it Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>

diff --git a/src/netops.c b/src/netops.c
new file mode 100644
index 0000000..04f758f
--- /dev/null
+++ b/src/netops.c
@@ -0,0 +1,76 @@
+/*
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2,
+ * as published by the Free Software Foundation.
+ *
+ * In addition to the permissions in the GNU General Public License,
+ * the authors give you unlimited permission to link the compiled
+ * version of this file into combinations with other programs,
+ * and to distribute those combinations without any restriction
+ * coming from the use of this file.  (The General Public License
+ * restrictions do apply in other respects; for example, they cover
+ * modification of the file, and distribution when not linked into
+ * a combined executable.)
+ *
+ * This file 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; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+#include "git2/errors.h"
+
+#include "common.h"
+#include "netops.h"
+
+int gitno_connect(const char *host, const char *port)
+{
+	struct addrinfo *info, *p;
+	struct addrinfo hints;
+	int ret, error = GIT_SUCCESS;
+	int s;
+
+	memset(&hints, 0x0, sizeof(struct addrinfo));
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+
+	ret = getaddrinfo(host, port, &hints, &info);
+	if (ret != 0) {
+		error = GIT_EOSERR;
+		goto cleanup;
+	}
+
+	for (p = info; p != NULL; p = p->ai_next) {
+		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+		if (s < 0) {
+			error = GIT_EOSERR;
+			goto cleanup;
+		}
+
+		ret = connect(s, p->ai_addr, p->ai_addrlen);
+		/* If we can't connect, try the next one */
+		if (ret < 0) {
+			continue;
+		}
+
+		/* Return the socket */
+		error = s;
+		goto cleanup;
+	}
+
+	/* Oops, we couldn't connect to any address */
+	error = GIT_EOSERR;
+
+cleanup:
+	freeaddrinfo(info);
+	return error;
+}
diff --git a/src/netops.h b/src/netops.h
new file mode 100644
index 0000000..10627d4
--- /dev/null
+++ b/src/netops.h
@@ -0,0 +1,9 @@
+/*
+ * netops.h - convencience functions for networking
+ */
+#ifndef INCLUDE_netops_h__
+#define INCLUDE_netops_h__
+
+int gitno_connect(const char *host, const char *port);
+
+#endif
diff --git a/src/transport_git.c b/src/transport_git.c
index e5c7b1d..12af21b 100644
--- a/src/transport_git.c
+++ b/src/transport_git.c
@@ -42,6 +42,7 @@
 #include "vector.h"
 #include "transport.h"
 #include "common.h"
+#include "netops.h"
 
 typedef struct {
 	int socket;
@@ -91,53 +92,29 @@ static int do_connect(git_priv *priv, const char *url)
 	char *host, *port, *msg;
 	const char prefix[] = "git://";
 	int error, ret, msg_len, connected = 0;
-	struct addrinfo *info, *p;
-	struct addrinfo hints;
-
-	memset(&hints, 0x0, sizeof(struct addrinfo));
-	hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */
-	hints.ai_socktype = SOCK_STREAM; /* TCP */
 
 	if (!git__prefixcmp(url, prefix))
 		url += STRLEN(prefix);
 
 	error = extract_host_and_port(&host, &port, url);
+	s = gitno_connect(host, port);
+	connected = 1;
 
-	ret = getaddrinfo(host, port, &hints, &info);
-	if (ret != 0) {
-		info = NULL;
-		error = git__throw(GIT_EOSERR, "Failed to get address info: %s", gai_strerror(ret));
+	error = git_pkt_gen_proto(&msg, &msg_len, url);
+	if (error < GIT_SUCCESS)
 		goto cleanup;
-	}
 
-	for (p = info; p != NULL; p = p->ai_next) {
-		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
-		if (s < 0) {
-			error = git__throw(GIT_EOSERR, "Failed to create socket");
-			goto cleanup;
-		}
-
-		ret = connect(s, p->ai_addr, p->ai_addrlen);
-		if (ret < 0) { /* Try the next one */
-			continue;
-		}
-		connected = 1;
-
-		error = git_pkt_gen_proto(&msg, &msg_len, url);
-		if (error < GIT_SUCCESS)
-			break;
-
-		/* FIXME: Do this in a loop */
-		ret = send(s, msg, msg_len, 0);
-		free(msg);
-		if (ret < 0)
-			error = git__throw(GIT_EOSERR, "Failed to send request");
+	/* FIXME: Do this in a loop */
+	ret = send(s, msg, msg_len, 0);
+	free(msg);
+	if (ret < 0) {
+		error = git__throw(GIT_EOSERR, "Failed to send request");
+		goto cleanup;
 	}
 
 	priv->socket = s;
 
 cleanup:
-	freeaddrinfo(info);
 	free(host);
 	free(port);