diff -r d166c9f8c50f -r caa952062dc2 src/proxy.c --- a/src/proxy.c Fri Oct 11 02:10:08 2002 +0000 +++ b/src/proxy.c Fri Oct 11 03:14:01 2002 +0000 @@ -30,16 +30,26 @@ #include #include #include + +#ifndef _WIN32 #include #include #include #include #include +#else +#include +#endif + #include #include #include "gaim.h" #include "proxy.h" +#ifdef _WIN32 +#include "win32dep.h" +#endif + #define GAIM_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR) #define GAIM_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL) @@ -123,11 +133,20 @@ { static struct sockaddr_in sin; +#ifndef _WIN32 if (!inet_aton(host, &sin.sin_addr)) { +#else + if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) { +#endif struct hostent *hp; - if (!(hp = gethostbyname(host))) { + if(!(hp = gethostbyname(host))) { +#ifndef _WIN32 debug_printf("gaim_gethostbyname(\"%s\", %d) failed: %s", host, port, hstrerror(h_errno)); +#else + debug_printf("gaim_gethostbyname(\"%s\", %d) failed: Error %d", + host, port, WSAGetLastError()); +#endif return NULL; } memset(&sin, 0, sizeof(struct sockaddr_in)); @@ -144,8 +163,26 @@ { struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(source); + gaim_input_remove(phb->inpa); + phb->func(phb->data, -1, GAIM_INPUT_READ); + g_free(phb); + return; + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(source, FIONBIO, &imode); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); @@ -155,6 +192,7 @@ return; } fcntl(source, F_SETFL, 0); +#endif gaim_input_remove(phb->inpa); phb->func(phb->data, source, GAIM_INPUT_READ); g_free(phb); @@ -175,7 +213,10 @@ { struct sockaddr_in *sin; int fd = -1; - +#ifdef _WIN32 + u_long imode; + int w_errno; +#endif debug_printf("connecting to %s:%d with no proxy\n", host, port); if (!(sin = gaim_gethostbyname(host, port))) { @@ -189,19 +230,50 @@ g_free(phb); return -1; } - +#ifdef _WIN32 + imode=1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + w_errno = WSAGetLastError(); + if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR) || (w_errno == WSAEWOULDBLOCK)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, no_one_calls, phb); } else { +#ifdef _WIN32 + debug_printf("connect failed (errno %d)\n", w_errno); + closesocket(fd); +#else debug_printf("connect failed (errno %d)\n", errno); close(fd); +#endif g_free(phb); return -1; } } else { +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + unsigned int len; + u_long imode; + + debug_printf("Connect didn't block\n"); + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + debug_printf("getsockopt failed\n"); + closesocket(fd); + g_free(phb); + return -1; + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else unsigned int len; int error = ETIMEDOUT; debug_printf("Connect didn't block\n"); @@ -213,6 +285,7 @@ return -1; } fcntl(fd, F_SETFL, 0); +#endif phb->port = fd; /* bleh */ g_timeout_add(50, clean_connect, phb); /* we do this because we never want to call our callback @@ -234,7 +307,11 @@ gaim_input_remove(phb->inpa); +#ifdef _WIN32 + while ((nlc != 2) && (recv(source, &inputline[pos++], 1, 0) == 1)) { +#else while ((nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) { +#endif if (inputline[pos - 1] == '\n') nlc++; else if (inputline[pos - 1] != '\r') @@ -252,7 +329,11 @@ return; } +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -264,24 +345,44 @@ char cmd[384]; struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int w_error = WSAETIMEDOUT; + u_long imode = 0; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); if (phb->inpa > 0) gaim_input_remove(phb->inpa); +#ifdef _WIN32 + len = sizeof(w_error); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&w_error, &len) < 0) { + closesocket(source); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; +#ifdef _WIN32 + } else + WSASetLastError( w_error ); + ioctlsocket(source, FIONBIO, &imode); +#else } fcntl(source, F_SETFL, 0); - +#endif g_snprintf(cmd, sizeof(cmd), "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", phb->host, phb->port, phb->host, phb->port); if (send(source, cmd, strlen(cmd), 0) < 0) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -296,7 +397,11 @@ g_snprintf(cmd, sizeof(cmd), "Proxy-Authorization: Basic %s\r\n", t2); g_free(t2); if (send(source, cmd, strlen(cmd), 0) < 0) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -306,7 +411,11 @@ g_snprintf(cmd, sizeof(cmd), "\r\n"); if (send(source, cmd, strlen(cmd), 0) < 0) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -320,6 +429,9 @@ { struct sockaddr_in *sin; int fd = -1; +#ifdef _WIN32 + u_long imode; +#endif debug_printf("connecting to %s:%d via %s:%d using HTTP\n", host, port, proxyhost, proxyport); @@ -336,29 +448,61 @@ phb->host = g_strdup(host); phb->port = port; +#ifdef _WIN32 + imode = 1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + int w_errno = WSAGetLastError(); + if ((w_errno == WSAEINPROGRESS) || (w_errno == WSAEINTR)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, http_canwrite, phb); } else { +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif g_free(phb->host); g_free(phb); return -1; } } else { unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connect didn't block\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(fd); +#else len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); +#endif g_free(phb->host); g_free(phb); return -1; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else } fcntl(fd, F_SETFL, 0); +#endif http_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -373,14 +517,22 @@ gaim_input_remove(phb->inpa); memset(packet, 0, sizeof(packet)); +#ifdef _WIN32 + if (recv(source, packet, 9, 0) >= 4 && packet[1] == 90) { +#else if (read(source, packet, 9) >= 4 && packet[1] == 90) { +#endif phb->func(phb->data, source, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; } +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -392,23 +544,44 @@ struct hostent *hp; struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); if (phb->inpa > 0) gaim_input_remove(phb->inpa); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(source); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(source, FIONBIO, &imode); +#else } fcntl(source, F_SETFL, 0); - +#endif /* XXX does socks4 not support host name lookups by the proxy? */ if (!(hp = gethostbyname(phb->host))) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -424,8 +597,13 @@ packet[6] = (unsigned char)(hp->h_addr_list[0])[2]; packet[7] = (unsigned char)(hp->h_addr_list[0])[3]; packet[8] = 0; +#ifdef _WIN32 + if (send(source, packet, 9, 0) != 9) { + closesocket(source); +#else if (write(source, packet, 9) != 9) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -439,6 +617,10 @@ { struct sockaddr_in *sin; int fd = -1; +#ifdef _WIN32 + int werrno; + u_long imode; +#endif debug_printf("connecting to %s:%d via %s:%d using SOCKS4\n", host, port, proxyhost, proxyport); @@ -455,29 +637,61 @@ phb->host = g_strdup(host); phb->port = port; +#ifdef _WIN32 + imode=1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + werrno = WSAGetLastError(); + if ((werrno == WSAEINPROGRESS) || (werrno == WSAEINTR)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s4_canwrite, phb); } else { +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif g_free(phb->host); g_free(phb); return -1; } } else { unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connect didn't block\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(fd); +#else len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); +#endif g_free(phb->host); g_free(phb); return -1; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else } fcntl(fd, F_SETFL, 0); +#endif s4_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -492,9 +706,17 @@ gaim_input_remove(phb->inpa); debug_printf("able to read again\n"); +#ifdef _WIN32 + if (recv(source, buf, 10, 0) < 10) { +#else if (read(source, buf, 10) < 10) { +#endif debug_printf("or not...\n"); +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -502,7 +724,11 @@ } if ((buf[0] != 0x05) || (buf[1] != 0x00)) { debug_printf("bad data\n"); +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -530,8 +756,13 @@ buf[5 + strlen(phb->host)] = phb->port >> 8; buf[5 + strlen(phb->host) + 1] = phb->port & 0xff; +#ifdef _WIN32 + if (send(source, buf, (5 + strlen(phb->host) + 2), 0) < (5 + strlen(phb->host) + 2)) { + closesocket(source); +#else if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -549,8 +780,13 @@ gaim_input_remove(phb->inpa); debug_printf("got auth response\n"); +#ifdef _WIN32 + if (recv(source, buf, 2, 0) < 2) { + closesocket(source); +#else if (read(source, buf, 2) < 2) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -558,7 +794,11 @@ } if ((buf[0] != 0x01) || (buf[1] != 0x00)) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -576,8 +816,13 @@ gaim_input_remove(phb->inpa); debug_printf("able to read\n"); +#ifdef _WIN32 + if (recv(source, buf, 2, 0) < 2) { + closesocket(source); +#else if (read(source, buf, 2) < 2) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -585,7 +830,11 @@ } if ((buf[0] != 0x05) || (buf[1] == 0xff)) { +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -599,8 +848,13 @@ memcpy(buf + 2, proxyuser, i); buf[2 + i] = j; memcpy(buf + 2 + i + 1, proxypass, j); +#ifdef _WIN32 + if (send(source, buf, 3 + i + j, 0) < 3 + i + j) { + closesocket(source); +#else if (write(source, buf, 3 + i + j) < 3 + i + j) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -619,19 +873,37 @@ int i; struct PHB *phb = data; unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; + u_long imode; +#else int error = ETIMEDOUT; +#endif debug_printf("Connected\n"); if (phb->inpa > 0) gaim_input_remove(phb->inpa); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(source, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(source); +#else len = sizeof(error); if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); return; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(source, FIONBIO, &imode); +#else } fcntl(source, F_SETFL, 0); +#endif i = 0; buf[0] = 0x05; /* SOCKS version 5 */ @@ -645,10 +917,17 @@ buf[2] = 0x00; i = 3; } - +#ifdef _WIN32 + if (send(source, buf, i, 0) < i) { +#else if (write(source, buf, i) < i) { +#endif debug_printf("unable to write\n"); +#ifdef _WIN32 + closesocket(source); +#else close(source); +#endif phb->func(phb->data, -1, GAIM_INPUT_READ); g_free(phb->host); g_free(phb); @@ -662,6 +941,10 @@ { struct sockaddr_in *sin; int fd = -1; +#ifdef _WIN32 + u_long imode; + int werrno; +#endif debug_printf("connecting to %s:%d via %s:%d using SOCKS5\n", host, port, proxyhost, proxyport); @@ -678,29 +961,60 @@ phb->host = g_strdup(host); phb->port = port; +#ifdef _WIN32 + imode=1; + ioctlsocket(fd, FIONBIO, &imode); +#else fcntl(fd, F_SETFL, O_NONBLOCK); +#endif if (connect(fd, (struct sockaddr *)sin, sizeof(*sin)) < 0) { +#ifdef _WIN32 + werrno = WSAGetLastError(); + if ((werrno == WSAEINPROGRESS) || (werrno == WSAEINTR)) { +#else if ((errno == EINPROGRESS) || (errno == EINTR)) { +#endif debug_printf("Connect would have blocked\n"); phb->inpa = gaim_input_add(fd, GAIM_INPUT_WRITE, s5_canwrite, phb); } else { +#ifdef _WIN32 + closesocket(fd); +#else close(fd); +#endif g_free(phb->host); g_free(phb); return -1; } } else { unsigned int len; +#ifdef _WIN32 + int werror = WSAETIMEDOUT; +#else int error = ETIMEDOUT; +#endif debug_printf("Connect didn't block\n"); +#ifdef _WIN32 + len = sizeof(werror); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&werror, &len) < 0) { + closesocket(fd); +#else len = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { close(fd); +#endif g_free(phb->host); g_free(phb); return -1; +#ifdef _WIN32 + } else + WSASetLastError(werror); + imode=0; + ioctlsocket(fd, FIONBIO, &imode); +#else } fcntl(fd, F_SETFL, 0); +#endif s5_canwrite(phb, fd, GAIM_INPUT_WRITE); } @@ -717,9 +1031,9 @@ g_free(phb); return -1; } - +#ifndef _WIN32 sethostent(1); - +#endif if ((proxytype == PROXY_NONE) || !proxyhost || !proxyhost[0] || !proxyport || (proxyport == -1)) return proxy_connect_none(host, port, phb); else if (proxytype == PROXY_HTTP) @@ -732,3 +1046,4 @@ g_free(phb); return -1; } +