diff src/protocols/gg/libgg.c @ 3630:9682c0e022c6

[gaim-migrate @ 3753] Yeah this will probably break a lot of shit knowing my luck. But hey, I really don't care what people thnk. committer: Tailor Script <tailor@pidgin.im>
author Rob Flynn <gaim@robflynn.com>
date Fri, 11 Oct 2002 03:14:01 +0000
parents 4b3f17ca66bf
children 988485669631
line wrap: on
line diff
--- a/src/protocols/gg/libgg.c	Fri Oct 11 02:10:08 2002 +0000
+++ b/src/protocols/gg/libgg.c	Fri Oct 11 03:14:01 2002 +0000
@@ -1,4 +1,4 @@
-/* $Id: libgg.c 2859 2001-12-05 09:48:56Z warmenhoven $ */
+/* $Id: libgg.c 3753 2002-10-11 03:14:01Z robflynn $ */
 
 /*
  *  (C) Copyright 2001 Wojtek Kaniewski <wojtekka@irc.pl>,
@@ -18,23 +18,29 @@
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
+#ifndef _WIN32
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/ioctl.h>
 #include <sys/wait.h>
+#include <netdb.h>
+#include <pwd.h>
+#else
+#include <winsock.h>
+#include <fcntl.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
 #include <sys/time.h>
-#include <netdb.h>
 #include <errno.h>
 #ifndef _AIX
 #  include <string.h>
 #endif
 #include <stdarg.h>
-#include <pwd.h>
 #include <time.h>
 #ifdef sun
   #include <sys/filio.h>
@@ -45,19 +51,24 @@
 #endif
 #include "libgg.h"
 #include "config.h"
+#include "gaim.h"
+#include "proxy.h"
 
-int gg_debug_level = 0;
+int gg_debug_level = (GG_DEBUG_NET | GG_DEBUG_TRAFFIC | GG_DEBUG_DUMP | GG_DEBUG_FUNCTION | GG_DEBUG_MISC);
 int gg_http_use_proxy = 0;
 int gg_http_proxy_port = 0;
 char *gg_http_proxy_host = NULL;
 
+/* temp -Herman */
+static int ping_outstanding = 0;
+
 #ifndef lint 
 
 static char rcsid[]
 #ifdef __GNUC__
 __attribute__ ((unused))
 #endif
-= "$Id: libgg.c 2859 2001-12-05 09:48:56Z warmenhoven $";
+= "$Id: libgg.c 3753 2002-10-11 03:14:01Z robflynn $";
 
 #endif 
 
@@ -95,6 +106,7 @@
 #endif
 }
 
+#ifndef _WIN32
 /*
  * gg_resolve() // funkcja wewnętrzna
  *
@@ -149,6 +161,7 @@
 
 	return 0;
 }
+#endif /*!_WIN32*/
 
 /*
  * gg_recv_packet() // funkcja wewnętrzna
@@ -165,6 +178,7 @@
 	struct gg_header h;
 	char *buf = NULL;
 	int ret = 0, offset, size = 0;
+	int sizeh = sizeof(struct gg_header);
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_recv_packet(...);\n");
 	
@@ -174,21 +188,41 @@
 	}
 
 	if (sess->recv_left < 1) {
-		while (ret != sizeof(h)) {
-			ret = read(sess->fd, &h, sizeof(h));
-			gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeof(h), ret);
-			if (ret < sizeof(h)) {
+		while (ret != sizeh) {
+#ifndef _WIN32
+			ret = read(sess->fd, &h, sizeh);
+			gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeh, ret);
+			if (ret < sizeh) {
 				if (errno != EINTR) {
 					gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno));
 					return NULL;
 				}
 			}
+#else
+			ret = recv(sess->fd, (char*)&h, sizeh, 0);
+			gg_debug(GG_DEBUG_MISC, "-- header recv(..., %d) = %d\n", sizeh, ret);
+			if (ret < sizeh) {
+				/* connection has been gracefully closed */
+				if (ret == 0) {
+					gg_debug(GG_DEBUG_MISC, "Connection has been gracefully closed\n");
+					WSASetLastError(WSAEDISCON);
+					return NULL;
+				}
+				else if (ret == SOCKET_ERROR) {
+					if(WSAGetLastError() != WSAEINTR) {
+						gg_debug(GG_DEBUG_MISC, "-- socket error = %d\n", WSAGetLastError());
+						return NULL;
+					}
+				}
+				
+			}
+#endif
 		}
 
 		h.type = fix32(h.type);
 		h.length = fix32(h.length);
 	} else {
-		memcpy(&h, sess->recv_buf, sizeof(h));
+		memcpy(&h, sess->recv_buf, sizeh);
 	}
 
 	/* jakieś sensowne limity na rozmiar pakietu */
@@ -204,24 +238,29 @@
 		offset = sess->recv_done;
 		buf = sess->recv_buf;
 	} else {
-		if (!(buf = malloc(sizeof(h) + h.length + 1))) {
+		if (!(buf = malloc(sizeh + h.length + 1))) {
 			gg_debug(GG_DEBUG_MISC, "-- not enough memory\n");
 			return NULL;
 		}
 
-		memcpy(buf, &h, sizeof(h));
+		memcpy(buf, &h, sizeh);
 
 		offset = 0;
 		size = h.length;
 	}
 
 	while (size > 0) {
-		ret = read(sess->fd, buf + sizeof(h) + offset, size);
+#ifndef _WIN32
+		ret = read(sess->fd, buf + sizeh + offset, size);
+#else
+		ret = recv(sess->fd, buf + sizeh + offset, size, 0);
+#endif
 		gg_debug(GG_DEBUG_MISC, "-- body recv(..., %d) = %d\n", size, ret);
 		if (ret > -1 && ret <= size) {
 			offset += ret;
 			size -= ret;
 		} else if (ret == -1) {	
+#ifndef _WIN32
 			gg_debug(GG_DEBUG_MISC, "-- errno = %d (%s)\n", errno, strerror(errno));
 			if (errno == EAGAIN) {
 				gg_debug(GG_DEBUG_MISC, "-- %d bytes received, %d left\n", offset, size);
@@ -235,6 +274,13 @@
 				free(buf);
 				return NULL;
 			}
+#else
+			gg_debug(GG_DEBUG_MISC, "-- errno = %d\n", WSAGetLastError());
+			if (WSAGetLastError()!= WSAEINTR) {
+				free(buf);
+				return NULL;
+			}
+#endif
 		}
 	}
 
@@ -244,7 +290,7 @@
 		int i;
 
 		gg_debug(GG_DEBUG_DUMP, ">> received packet (type=%.2x):", h.type);
-		for (i = 0; i < sizeof(h) + h.length; i++) 
+		for (i = 0; i < sizeh + h.length; i++) 
 			gg_debug(GG_DEBUG_DUMP, " %.2x", (unsigned char) buf[i]);
 		gg_debug(GG_DEBUG_DUMP, "\n");
 	}
@@ -306,9 +352,14 @@
 	}
 
 	plen = sizeof(struct gg_header) + length + payload_length;
-	
+#ifndef _WIN32
 	if ((res = write(sock, tmp, plen)) < plen) {
 		gg_debug(GG_DEBUG_MISC, "-- write() failed. res = %d, errno = %d (%s)\n", res, errno, strerror(errno));
+#else
+	if ((res = send(sock, tmp, plen, 0)) < plen) {
+		gg_debug(GG_DEBUG_MISC, "-- send() failed. res = %d, errno = %d\n", 
+			 res, (res == SOCKET_ERROR) ? WSAGetLastError() : 0);
+#endif
 		free(tmp);
 		return -1;
 	}
@@ -317,7 +368,7 @@
 	return 0;
 }
 
-
+#ifndef _WIN32
 /*
  * gg_login()
  *
@@ -419,6 +470,7 @@
 
 	return sess;
 }
+#endif /*!_WIN32*/
 
 /* 
  * gg_free_session()
@@ -458,7 +510,11 @@
 	}
 
 	if (sess->state != GG_STATE_CONNECTED) {
+#ifndef _WIN32
 		errno = ENOTCONN;
+#else
+		WSASetLastError( WSAENOTCONN );
+#endif
 		return -1;
 	}
 
@@ -517,7 +573,11 @@
 	}
 	
 	if (sess->state != GG_STATE_CONNECTED) {
+#ifndef _WIN32
 		errno = ENOTCONN;
+#else
+		WSASetLastError( WSAENOTCONN );
+#endif
 		return -1;
 	}
 
@@ -553,13 +613,24 @@
 	}
 
 	if (sess->state != GG_STATE_CONNECTED) {
+#ifndef _WIN32
 		errno = ENOTCONN;
+#else
+		WSASetLastError( WSAENOTCONN );
+#endif
 		return -1;
 	}
 
 	gg_debug(GG_DEBUG_FUNCTION, "** gg_ping(...);\n");
-
-	return gg_send_packet(sess->fd, GG_PING, NULL, 0, NULL, 0);
+	
+	if(ping_outstanding) {
+		debug_printf("Trying to send ping, when we havn't been ponged on last ping\n");
+		return 1;
+	}
+	else {
+		ping_outstanding = 1;
+		return gg_send_packet(sess->fd, GG_PING, NULL, 0, NULL, 0);
+	}
 }
 
 /*
@@ -605,7 +676,11 @@
 	}
 	
 	if (sess->state != GG_STATE_CONNECTED) {
+#ifndef _WIN32
 		errno = ENOTCONN;
+#else
+		WSASetLastError( WSAENOTCONN );
+#endif
 		return -1;
 	}
 
@@ -650,7 +725,11 @@
 	}
 
 	if (sess->state != GG_STATE_CONNECTED) {
+#ifndef _WIN32
 		errno = ENOTCONN;
+#else
+		WSASetLastError( WSAENOTCONN );
+#endif
 		return -1;
 	}
 	
@@ -682,7 +761,11 @@
 	}
 
 	if (sess->state != GG_STATE_CONNECTED) {
+#ifndef _WIN32
 		errno = ENOTCONN;
+#else
+		WSASetLastError( WSAENOTCONN );
+#endif
 		return -1;
 	}
 
@@ -785,7 +868,7 @@
 
 	if (h->type == GG_PONG) {
 		gg_debug(GG_DEBUG_MISC, "-- received a pong\n");
-
+		ping_outstanding = 0;
 		sess->last_pong = time(NULL);
 	}
 
@@ -812,7 +895,9 @@
 {
 	struct gg_event *e;
 	int res = 0;
+#ifndef _WIN32
 	int port;
+#endif
 
 	if (!sess) {
 		errno = EFAULT;
@@ -829,6 +914,9 @@
 	e->type = GG_EVENT_NONE;
 
 	switch (sess->state) {
+#ifndef _WIN32
+		/* Apparantly we will never be in this state as long as we are
+		   using proxy_connect instead of gg_login - Herman */
 		case GG_STATE_RESOLVING:
 		{
 			struct in_addr a;
@@ -887,7 +975,7 @@
 				
 			break;
 		}
-
+#endif /* !_WIN32 */
 		case GG_STATE_CONNECTING:
 		{
 			char buf[1024];
@@ -895,10 +983,16 @@
 
 			gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING\n");
 
-			if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
+			if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, 
+#ifndef _WIN32
+						       &res, 
+#else
+						       (char*)&res,
+#endif
+						       &res_size) || res)) {
+#if 0
 				struct in_addr *addr = (struct in_addr*) &sess->server_ip;
 				gg_debug(GG_DEBUG_MISC, "-- http connection failed, errno = %d (%s), trying direct connection\n", res, strerror(res));
-
 				if ((sess->fd = gg_connect(addr, GG_DEFAULT_PORT, sess->async)) == -1) {
 				    gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n");
 				    if ((sess->fd = gg_connect(addr, GG_HTTPS_PORT, sess->async)) == -1) {
@@ -913,20 +1007,26 @@
 
 				sess->state = GG_STATE_CONNECTING_GG;
 				sess->check = GG_CHECK_WRITE;
+#else
+				gg_debug(GG_DEBUG_MISC, "-- http connection failed, errno = %d\n", res);
+				e->type = GG_EVENT_CONN_FAILED;
+				e->event.failure = GG_FAILURE_CONNECTING;
+				sess->state = GG_STATE_IDLE;
+#endif
 				break;
 			}
 			
 			gg_debug(GG_DEBUG_MISC, "-- http connection succeded, sending query\n");
 
 			if (gg_http_use_proxy) {
-				snprintf(buf, sizeof(buf) - 1,
+				g_snprintf(buf, sizeof(buf) - 1,
 					"GET http://" GG_APPMSG_HOST "/appsvc/appmsg.asp?fmnumber=%lu HTTP/1.0\r\n"
 					"Host: " GG_APPMSG_HOST "\r\n"
 					"User-Agent: " GG_HTTP_USERAGENT "\r\n"
 					"Pragma: no-cache\r\n"
 					"\r\n", sess->uin);
 			} else {
-				snprintf(buf, sizeof(buf) - 1,
+				g_snprintf(buf, sizeof(buf) - 1,
 					"GET /appsvc/appmsg.asp?fmnumber=%lu HTTP/1.0\r\n"
 					"Host: " GG_APPMSG_HOST "\r\n"
 					"User-Agent: " GG_HTTP_USERAGENT "\r\n"
@@ -935,10 +1035,12 @@
 			};
 
     			gg_debug(GG_DEBUG_MISC, "=> -----BEGIN-HTTP-QUERY-----\n%s\n=> -----END-HTTP-QUERY-----\n", buf);
-	 
+#ifndef _WIN32
 			if (write(sess->fd, buf, strlen(buf)) < strlen(buf)) {
+#else
+			if (send(sess->fd, buf, strlen(buf), 0) < strlen(buf)) {
+#endif
 				gg_debug(GG_DEBUG_MISC, "-- sending query failed\n");
-
 				errno = EIO;
 				e->type = GG_EVENT_CONN_FAILED;
 				e->event.failure = GG_FAILURE_WRITING;
@@ -1010,8 +1112,10 @@
 
 			a.s_addr = inet_addr(host);
 			sess->server_ip = a.s_addr;
-
-			if ((sess->fd = gg_connect(&a, port, sess->async)) == -1) {
+#if 0
+			/* We need to watch this non-blocking socket so lets use proxy_connect 
+			   in gg.c - Herman */
+			if((sess->fd = gg_connect(&a, port, sess->assync)) == -1) {
 				gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n");
 				if ((sess->fd = gg_connect(&a, GG_HTTPS_PORT, sess->async)) == -1) {
 				    gg_debug(GG_DEBUG_MISC, "-- connection failed, errno = %d (%s)\n", errno, strerror(errno));
@@ -1022,7 +1126,9 @@
 				    break;
 				}
 			}
-
+#else
+			sess->port = port;
+#endif
 			sess->state = GG_STATE_CONNECTING_GG;
 			sess->check = GG_CHECK_WRITE;
 		
@@ -1035,7 +1141,13 @@
 
 			gg_debug(GG_DEBUG_MISC, "== GG_STATE_CONNECTING_GG\n");
 
-			if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, &res, &res_size) || res)) {
+			if (sess->async && (getsockopt(sess->fd, SOL_SOCKET, SO_ERROR, 
+#ifndef _WIN32
+						       &res, 
+#else
+						       (char*)&res,
+#endif
+						       &res_size) || res)) {
 				struct in_addr *addr = (struct in_addr*) &sess->server_ip;
 
 				gg_debug(GG_DEBUG_MISC, "-- connection failed, trying https connection\n");
@@ -1068,8 +1180,11 @@
 			gg_debug(GG_DEBUG_MISC, "== GG_STATE_READING_KEY\n");
 
 			if (!(h = gg_recv_packet(sess))) {
+#ifndef _WIN32
 				gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet() failed. errno = %d (%s)\n", errno, strerror(errno));
-
+#else
+				gg_debug(GG_DEBUG_MISC, "-- gg_recv_packet() failed. errno = %d\n", WSAGetLastError());
+#endif
 				e->type = GG_EVENT_CONN_FAILED;
 				e->event.failure = GG_FAILURE_READING;
 				sess->state = GG_STATE_IDLE;