mirror of
https://github.com/moparisthebest/curl
synced 2024-12-24 00:58:48 -05:00
telnet.c: depend on static requirement of WinSock version 2
Drop dynamic loading of ws2_32.dll and instead rely on the imported version which is now required to be at least 2.2. Reviewed-by: Marcel Raad Reviewed-by: Jay Satiro Reviewed-by: Daniel Stenberg Reviewed-by: Viktor Szakats Closes #5854
This commit is contained in:
parent
3e4b32a3e1
commit
8bdc4f8aee
129
lib/telnet.c
129
lib/telnet.c
@ -87,12 +87,6 @@
|
|||||||
#define printoption(a,b,c,d) Curl_nop_stmt
|
#define printoption(a,b,c,d) Curl_nop_stmt
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
typedef WSAEVENT (WINAPI *WSOCK2_EVENT)(void);
|
|
||||||
typedef FARPROC WSOCK2_FUNC;
|
|
||||||
static CURLcode check_wsock2(struct Curl_easy *data);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static
|
static
|
||||||
CURLcode telrcv(struct connectdata *,
|
CURLcode telrcv(struct connectdata *,
|
||||||
const unsigned char *inbuf, /* Data received from socket */
|
const unsigned char *inbuf, /* Data received from socket */
|
||||||
@ -198,46 +192,6 @@ const struct Curl_handler Curl_handler_telnet = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
static CURLcode
|
|
||||||
check_wsock2(struct Curl_easy *data)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
WORD wVersionRequested;
|
|
||||||
WSADATA wsaData;
|
|
||||||
|
|
||||||
DEBUGASSERT(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
|
static
|
||||||
CURLcode init_telnet(struct connectdata *conn)
|
CURLcode init_telnet(struct connectdata *conn)
|
||||||
{
|
{
|
||||||
@ -1301,11 +1255,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
|||||||
struct Curl_easy *data = conn->data;
|
struct Curl_easy *data = conn->data;
|
||||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
HMODULE wsock2;
|
|
||||||
WSOCK2_FUNC close_event_func;
|
|
||||||
WSOCK2_EVENT create_event_func;
|
|
||||||
WSOCK2_FUNC event_select_func;
|
|
||||||
WSOCK2_FUNC enum_netevents_func;
|
|
||||||
WSAEVENT event_handle;
|
WSAEVENT event_handle;
|
||||||
WSANETWORKEVENTS events;
|
WSANETWORKEVENTS events;
|
||||||
HANDLE stdin_handle;
|
HANDLE stdin_handle;
|
||||||
@ -1340,75 +1289,21 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
/*
|
|
||||||
** This functionality only works with WinSock >= 2.0. So,
|
|
||||||
** make sure we have it.
|
|
||||||
*/
|
|
||||||
result = check_wsock2(data);
|
|
||||||
if(result)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
/* OK, so we have WinSock 2.0. We need to dynamically */
|
|
||||||
/* load ws2_32.dll and get the function pointers we need. */
|
|
||||||
wsock2 = Curl_load_library(TEXT("WS2_32.DLL"));
|
|
||||||
if(wsock2 == NULL) {
|
|
||||||
failf(data, "failed to load WS2_32.DLL (%u)", GetLastError());
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Grab a pointer to WSACreateEvent */
|
|
||||||
create_event_func =
|
|
||||||
CURLX_FUNCTION_CAST(WSOCK2_EVENT,
|
|
||||||
(GetProcAddress(wsock2, "WSACreateEvent")));
|
|
||||||
if(create_event_func == NULL) {
|
|
||||||
failf(data, "failed to find WSACreateEvent function (%u)", GetLastError());
|
|
||||||
FreeLibrary(wsock2);
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* And WSACloseEvent */
|
|
||||||
close_event_func = GetProcAddress(wsock2, "WSACloseEvent");
|
|
||||||
if(close_event_func == NULL) {
|
|
||||||
failf(data, "failed to find WSACloseEvent function (%u)", 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 (%u)", 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 (%u)",
|
|
||||||
GetLastError());
|
|
||||||
FreeLibrary(wsock2);
|
|
||||||
return CURLE_FAILED_INIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We want to wait for both stdin and the socket. Since
|
/* We want to wait for both stdin and the socket. Since
|
||||||
** the select() function in winsock only works on sockets
|
** the select() function in winsock only works on sockets
|
||||||
** we have to use the WaitForMultipleObjects() call.
|
** we have to use the WaitForMultipleObjects() call.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* First, create a sockets event object */
|
/* First, create a sockets event object */
|
||||||
event_handle = (WSAEVENT)create_event_func();
|
event_handle = WSACreateEvent();
|
||||||
if(event_handle == WSA_INVALID_EVENT) {
|
if(event_handle == WSA_INVALID_EVENT) {
|
||||||
failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
|
failf(data, "WSACreateEvent failed (%d)", SOCKERRNO);
|
||||||
FreeLibrary(wsock2);
|
|
||||||
return CURLE_FAILED_INIT;
|
return CURLE_FAILED_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tell winsock what events we want to listen to */
|
/* Tell winsock what events we want to listen to */
|
||||||
if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
|
if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) {
|
||||||
SOCKET_ERROR) {
|
WSACloseEvent(event_handle);
|
||||||
close_event_func(event_handle);
|
|
||||||
FreeLibrary(wsock2);
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1439,6 +1334,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
|||||||
DWORD waitret = WaitForMultipleObjects(obj_count, objs,
|
DWORD waitret = WaitForMultipleObjects(obj_count, objs,
|
||||||
FALSE, wait_timeout);
|
FALSE, wait_timeout);
|
||||||
switch(waitret) {
|
switch(waitret) {
|
||||||
|
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
{
|
{
|
||||||
for(;;) {
|
for(;;) {
|
||||||
@ -1508,9 +1404,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
|
{
|
||||||
events.lNetworkEvents = 0;
|
events.lNetworkEvents = 0;
|
||||||
if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
|
if(WSAEnumNetworkEvents(sockfd, event_handle, &events) == SOCKET_ERROR) {
|
||||||
err = SOCKERRNO;
|
err = SOCKERRNO;
|
||||||
if(err != EINPROGRESS) {
|
if(err != EINPROGRESS) {
|
||||||
infof(data, "WSAEnumNetworkEvents failed (%d)", err);
|
infof(data, "WSAEnumNetworkEvents failed (%d)", err);
|
||||||
@ -1554,6 +1450,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
|||||||
if(events.lNetworkEvents & FD_CLOSE) {
|
if(events.lNetworkEvents & FD_CLOSE) {
|
||||||
keepon = FALSE;
|
keepon = FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1569,19 +1466,9 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We called WSACreateEvent, so call WSACloseEvent */
|
/* We called WSACreateEvent, so call WSACloseEvent */
|
||||||
if(!close_event_func(event_handle)) {
|
if(!WSACloseEvent(event_handle)) {
|
||||||
infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
|
infof(data, "WSACloseEvent failed (%d)", SOCKERRNO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "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 (%u)", GetLastError());
|
|
||||||
#else
|
#else
|
||||||
pfd[0].fd = sockfd;
|
pfd[0].fd = sockfd;
|
||||||
pfd[0].events = POLLIN;
|
pfd[0].events = POLLIN;
|
||||||
|
Loading…
Reference in New Issue
Block a user