aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2004-03-03 13:32:56 +0000
committerDaniel Stenberg <daniel@haxx.se>2004-03-03 13:32:56 +0000
commit2479e06848a7625b1b55511b43f86abc3a76c93d (patch)
tree5f229a8dad5a33c0d0698e2474b943203b38a5c1 /lib
parentf2abe03fcf09acc3727e995c3304dc80caea39f5 (diff)
David Byron's work on making libcurl only require winsock 1.1 on Windows
machines.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.vc68
-rw-r--r--lib/easy.c21
-rw-r--r--lib/strtoofft.h2
-rw-r--r--lib/telnet.c129
4 files changed, 141 insertions, 19 deletions
diff --git a/lib/Makefile.vc6 b/lib/Makefile.vc6
index d84f17f3b..e9ddd366e 100644
--- a/lib/Makefile.vc6
+++ b/lib/Makefile.vc6
@@ -48,7 +48,6 @@ CFLAGS = /I "." /I "../include" /nologo /W3 /GX /D "WIN32" /D "VC6" /D "_MBCS" /
LNKDLL = link.exe /DLL /def:libcurl.def
LNKLIB = link.exe /lib
LFLAGS = /nologo
-LINKLIBS = ws2_32.lib winmm.lib
SSLLIBS = libeay32.lib ssleay32.lib
# RSAglue.lib was formerly needed in the SSLLIBS
CFGSET = FALSE
@@ -84,7 +83,6 @@ TARGET =$(LIB_NAME).lib
DIROBJ =.\$(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32"
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET)
-LINKLIBS = $(LINKLIBS)
CC = $(CCNODBG) $(CFLAGSSSL)
CFGSET = TRUE
!ENDIF
@@ -97,7 +95,6 @@ TARGET =$(LIB_NAME).dll
DIROBJ =.\$(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32dll"
LNK = $(LNKDLL) $(LFLAGSSSL) /out:$(TARGET) /IMPLIB:"$(LIB_NAME).lib"
-LINKLIBS = $(LINKLIBS) $(SSLLIBS)
CC = $(CCNODBG) $(CFLAGSSSL)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
@@ -110,7 +107,6 @@ TARGET =$(LIB_NAME).lib
DIROBJ =.\$(CFG)
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)/out32dll"
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET)
-LINKLIBS = $(LINKLIBS) $(SSLLIBS)
CC = $(CCNODBG) $(CFLAGSSSL)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
@@ -147,7 +143,6 @@ RESOURCE = $(DIROBJ)\libcurl.res
TARGET = $(LIB_NAME_DEBUG).lib
DIROBJ =.\$(CFG)
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(TARGET)
-LINKLIBS = $(LINKLIBS)
CC = $(CCDEBUG) $(CFLAGSSSL)
CFGSET = TRUE
!ENDIF
@@ -160,7 +155,6 @@ TARGET =$(LIB_NAME_DEBUG).dll
DIROBJ =.\$(CFG)
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)/out32dll
LNK = $(LNKDLL) $(LFLAGSSSL) /DEBUG /out:$(TARGET) /IMPLIB:"$(LIB_NAME_DEBUG).lib" /PDB:"$(LIB_NAME_DEBUG).pdb"
-LINKLIBS = $(LINKLIBS) $(SSLLIBS)
CC = $(CCDEBUG) $(CFLAGSSSL)
CFGSET = TRUE
RESOURCE = $(DIROBJ)\libcurl.res
@@ -234,7 +228,7 @@ all : $(TARGET)
$(TARGET): $(X_OBJS)
- $(LNK) $(LFLAGS) $(LINKLIBS) $(X_OBJS)
+ $(LNK) $(LFLAGS) $(X_OBJS)
$(X_OBJS): $(DIROBJ)
diff --git a/lib/easy.c b/lib/easy.c
index 5ecd10575..4c4e271f6 100644
--- a/lib/easy.c
+++ b/lib/easy.c
@@ -98,7 +98,12 @@ static CURLcode win32_init(void)
WORD wVersionRequested;
WSADATA wsaData;
int err;
- wVersionRequested = MAKEWORD(2, 0);
+
+#ifdef ENABLE_IPV6
+ wVersionRequested = MAKEWORD(2, 0);
+#else
+ wVersionRequested = MAKEWORD(1, 1);
+#endif
err = WSAStartup(wVersionRequested, &wsaData);
@@ -107,14 +112,14 @@ static CURLcode win32_init(void)
/* winsock.dll. */
return CURLE_FAILED_INIT;
- /* Confirm that the Windows Sockets DLL supports 2.0.*/
+ /* Confirm that the Windows Sockets DLL supports what we need.*/
/* Note that if the DLL supports versions greater */
- /* than 2.0 in addition to 2.0, it will still return */
- /* 2.0 in wVersion since that is the version we */
- /* requested. */
-
- if ( LOBYTE( wsaData.wVersion ) != 2 ||
- HIBYTE( wsaData.wVersion ) != 0 ) {
+ /* than wVersionRequested, it will still return */
+ /* wVersionRequested in wVersion. wHighVersion contains the */
+ /* highest supported version. */
+
+ if ( LOBYTE( wsaData.wVersion ) != LOBYTE(wVersionRequested) ||
+ HIBYTE( wsaData.wVersion ) != HIBYTE(wVersionRequested) ) {
/* Tell the user that we couldn't find a useable */
/* winsock.dll. */
diff --git a/lib/strtoofft.h b/lib/strtoofft.h
index 9944ba1d9..27c3668e3 100644
--- a/lib/strtoofft.h
+++ b/lib/strtoofft.h
@@ -45,7 +45,7 @@
/* For MSVC7 we can use _strtoi64() which seems to be a strtoll() clone */
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
-#define strtoll _strtoi64
+#define strtoofft _strtoi64
#else /* MSVC7 or later */
curl_off_t curlx_strtoll(const char *nptr, char **endptr, int base);
#define strtoofft curlx_strtoll
diff --git a/lib/telnet.c b/lib/telnet.c
index 2faffb225..c925ad52e 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -101,6 +101,11 @@
#define CURL_SB_EOF(x) (x->subpointer >= x->subend)
#define CURL_SB_LEN(x) (x->subend - x->subpointer)
+#ifdef WIN32
+typedef FARPROC WSOCK2_FUNC;
+static CURLcode check_wsock2 ( struct SessionHandle *data );
+#endif
+
static
void telrcv(struct connectdata *,
unsigned char *inbuf, /* Data received from socket */
@@ -164,6 +169,45 @@ struct TELNET {
TelnetReceive telrcv_state;
};
+#ifdef WIN32
+static CURLcode
+check_wsock2 ( struct SessionHandle *data )
+{
+ int err;
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ curlassert(data);
+
+ /* telnet requires at least WinSock 2.0 so ask for it. */
+ wVersionRequested = MAKEWORD(2, 0);
+
+ err = WSAStartup(wVersionRequested, &wsaData);
+
+ /* We must've called this once already, so this call */
+ /* should always succeed. But, just in case... */
+ if (err != 0) {
+ failf(data,"WSAStartup failed (%d)",err);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* We have to have a WSACleanup call for every successful */
+ /* WSAStartup call. */
+ WSACleanup();
+
+ /* Check that our version is supported */
+ if (LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
+ HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
+ /* Our version isn't supported */
+ failf(data,"insufficient winsock version to support "
+ "telnet");
+ return CURLE_FAILED_INIT;
+ }
+
+ /* Our version is supported */
+ return CURLE_OK;
+}
+#endif
static
CURLcode init_telnet(struct connectdata *conn)
{
@@ -1037,6 +1081,11 @@ CURLcode Curl_telnet(struct connectdata *conn)
struct SessionHandle *data = conn->data;
int sockfd = conn->sock[FIRSTSOCKET];
#ifdef WIN32
+ HMODULE wsock2;
+ WSOCK2_FUNC close_event_func;
+ WSOCK2_FUNC create_event_func;
+ WSOCK2_FUNC event_select_func;
+ WSOCK2_FUNC enum_netevents_func;
WSAEVENT event_handle;
WSANETWORKEVENTS events;
HANDLE stdin_handle;
@@ -1063,13 +1112,70 @@ CURLcode Curl_telnet(struct connectdata *conn)
return code;
#ifdef WIN32
+ /*
+ ** This functionality only works with WinSock >= 2.0. So,
+ ** make sure have it.
+ */
+ code = check_wsock2(data);
+ if (code)
+ return code;
+
+ /* OK, so we have WinSock 2.0. We need to dynamically */
+ /* load ws2_32.dll and get the function pointers we need. */
+ wsock2 = LoadLibrary("WS2_32.DLL");
+ if (wsock2 == NULL) {
+ failf(data,"failed to load WS2_32.DLL (%d)",GetLastError());
+ return CURLE_FAILED_INIT;
+ }
+
+ /* Grab a pointer to WSACreateEvent */
+ create_event_func = GetProcAddress(wsock2,"WSACreateEvent");
+ if (create_event_func == NULL) {
+ failf(data,"failed to find WSACreateEvent function (%d)",
+ GetLastError());
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* And WSACloseEvent */
+ close_event_func = GetProcAddress(wsock2,"WSACloseEvent");
+ if (create_event_func == NULL) {
+ failf(data,"failed to find WSACloseEvent function (%d)",
+ GetLastError());
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* And WSAEventSelect */
+ event_select_func = GetProcAddress(wsock2,"WSAEventSelect");
+ if (event_select_func == NULL) {
+ failf(data,"failed to find WSAEventSelect function (%d)",
+ GetLastError());
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
+ /* And WSAEnumNetworkEvents */
+ enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents");
+ if (enum_netevents_func == NULL) {
+ failf(data,"failed to find WSAEnumNetworkEvents function (%d)",
+ GetLastError());
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
+
/* We want to wait for both stdin and the socket. Since
** the select() function in winsock only works on sockets
** we have to use the WaitForMultipleObjects() call.
*/
/* First, create a sockets event object */
- event_handle = WSACreateEvent();
+ event_handle = (WSAEVENT)create_event_func();
+ if (event_handle == WSA_INVALID_EVENT) {
+ failf(data,"WSACreateEvent failed (%d)",WSAGetLastError());
+ FreeLibrary(wsock2);
+ return CURLE_FAILED_INIT;
+ }
/* The get the Windows file handle for stdin */
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
@@ -1079,7 +1185,9 @@ CURLcode Curl_telnet(struct connectdata *conn)
objs[1] = event_handle;
/* Tell winsock what events we want to listen to */
- if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
+ if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
+ close_event_func(event_handle);
+ FreeLibrary(wsock2);
return 0;
}
@@ -1113,7 +1221,7 @@ CURLcode Curl_telnet(struct connectdata *conn)
break;
case 1:
- if(WSAEnumNetworkEvents(sockfd, event_handle, &events)
+ if(enum_netevents_func(sockfd, event_handle, &events)
!= SOCKET_ERROR) {
if(events.lNetworkEvents & FD_READ) {
/* This reallu OUGHT to check its return code. */
@@ -1139,6 +1247,21 @@ CURLcode Curl_telnet(struct connectdata *conn)
break;
}
}
+
+ /* We called WSACreateEvent, so call WSACloseEvent */
+ if (close_event_func(event_handle) == FALSE) {
+ infof(data,"WSACloseEvent failed (%d)",WSAGetLastError());
+ }
+
+ /* "Forget" pointers into the library we're about to free */
+ create_event_func = NULL;
+ close_event_func = NULL;
+ event_select_func = NULL;
+ enum_netevents_func = NULL;
+
+ /* We called LoadLibrary, so call FreeLibrary */
+ if (!FreeLibrary(wsock2))
+ infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError());
#else
FD_ZERO (&readfd); /* clear it */
FD_SET (sockfd, &readfd);