From e30dcd05017726859fb185090741b700996f26aa Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 17 Sep 2001 14:10:38 +0000 Subject: [PATCH] Linus Nielsen Feltzing's telnet-for-win32 fixes --- include/curl/curl.h | 4 +- lib/easy.c | 12 ++--- lib/telnet.c | 104 +++++++++++++++++++++++++++++++++++++++++--- src/setup.h | 2 +- src/version.h | 2 +- 5 files changed, 107 insertions(+), 17 deletions(-) diff --git a/include/curl/curl.h b/include/curl/curl.h index 698d84625..036dc04aa 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -548,8 +548,8 @@ CURLcode curl_global_init(long flags); void curl_global_cleanup(void); /* This is the version number */ -#define LIBCURL_VERSION "7.8.2-pre1" -#define LIBCURL_VERSION_NUM 0x070802 +#define LIBCURL_VERSION "7.9-pre6" +#define LIBCURL_VERSION_NUM 0x070900 /* linked-list structure for the CURLOPT_QUOTE option (and other) */ struct curl_slist { diff --git a/lib/easy.c b/lib/easy.c index a0def11e6..d79dbacef 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -94,7 +94,7 @@ static CURLcode win32_init(void) WORD wVersionRequested; WSADATA wsaData; int err; - wVersionRequested = MAKEWORD(1, 1); + wVersionRequested = MAKEWORD(2, 0); err = WSAStartup(wVersionRequested, &wsaData); @@ -103,14 +103,14 @@ static CURLcode win32_init(void) /* winsock.dll. */ return CURLE_FAILED_INIT; - /* Confirm that the Windows Sockets DLL supports 1.1.*/ + /* Confirm that the Windows Sockets DLL supports 2.0.*/ /* Note that if the DLL supports versions greater */ - /* than 1.1 in addition to 1.1, it will still return */ - /* 1.1 in wVersion since that is the version we */ + /* 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 ) != 1 || - HIBYTE( wsaData.wVersion ) != 1 ) { + if ( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 0 ) { /* Tell the user that we couldn't find a useable */ /* winsock.dll. */ diff --git a/lib/telnet.c b/lib/telnet.c index f190b7cf0..ac40e18e6 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -35,7 +35,7 @@ #include #if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__) -#include +#include #include #include #else @@ -152,8 +152,8 @@ struct TELNET { int him[256]; int himq[256]; int him_preferred[256]; - char *subopt_ttype; /* Set with suboption TTYPE */ - char *subopt_xdisploc; /* Set with suboption XDISPLOC */ + char subopt_ttype[32]; /* Set with suboption TTYPE */ + char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */ struct curl_slist *telnet_vars; /* Environment variables */ /* suboptions */ @@ -765,14 +765,16 @@ static int check_telnet_options(struct connectdata *conn) /* Terminal type */ if(strequal(option_keyword, "TTYPE")) { - tn->subopt_ttype = option_arg; + strncpy(tn->subopt_ttype, option_arg, 31); + tn->subopt_ttype[31] = 0; /* String termination */ tn->us_preferred[TELOPT_TTYPE] = YES; continue; } /* Display variable */ if(strequal(option_keyword, "XDISPLOC")) { - tn->subopt_xdisploc = option_arg; + strncpy(tn->subopt_xdisploc, option_arg, 127); + tn->subopt_xdisploc[127] = 0; /* String termination */ tn->us_preferred[TELOPT_XDISPLOC] = YES; continue; } @@ -1033,9 +1035,16 @@ CURLcode Curl_telnet(struct connectdata *conn) CURLcode code; struct SessionHandle *data = conn->data; int sockfd = conn->firstsocket; +#ifdef WIN32 + WSAEVENT event_handle; + WSANETWORKEVENTS events; + HANDLE stdin_handle; + HANDLE objs[2]; + DWORD waitret; +#else fd_set readfd; fd_set keepfd; - +#endif bool keepon = TRUE; char *buf = data->state.buffer; ssize_t nread; @@ -1050,7 +1059,87 @@ CURLcode Curl_telnet(struct connectdata *conn) code = check_telnet_options(conn); if(code) return code; - + +#ifdef WIN32 + /* 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(); + + /* The get the Windows file handle for stdin */ + stdin_handle = GetStdHandle(STD_INPUT_HANDLE); + + /* Create the list of objects to wait for */ + objs[0] = stdin_handle; + objs[1] = event_handle; + + /* Tell winsock what events we want to listen to */ + if(WSAEventSelect(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { + return 0; + } + + /* Keep on listening and act on events */ + while(keepon) { + waitret = WaitForMultipleObjects(2, objs, FALSE, INFINITE); + switch(waitret - WAIT_OBJECT_0) + { + case 0: + { + unsigned char outbuf[2]; + int out_count = 0; + size_t bytes_written; + char *buffer = buf; + + if(!ReadFile(stdin_handle, buf, 255, &nread, NULL)) { + keepon = FALSE; + break; + } + + while(nread--) { + outbuf[0] = *buffer++; + out_count = 1; + if(outbuf[0] == IAC) + outbuf[out_count++] = IAC; + + Curl_write(conn, conn->firstsocket, outbuf, + out_count, &bytes_written); + } + } + break; + + case 1: + if(WSAEnumNetworkEvents(sockfd, event_handle, &events) + != SOCKET_ERROR) + { + if(events.lNetworkEvents & FD_READ) + { + Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); + + telrcv(conn, (unsigned char *)buf, nread); + + fflush(stdout); + + /* Negotiate if the peer has started negotiating, + otherwise don't. We don't want to speak telnet with + non-telnet servers, like POP or SMTP. */ + if(tn->please_negotiate && !tn->already_negotiated) { + negotiate(conn); + tn->already_negotiated = 1; + } + } + + if(events.lNetworkEvents & FD_CLOSE) + { + keepon = FALSE; + } + } + break; + } + } +#else FD_ZERO (&readfd); /* clear it */ FD_SET (sockfd, &readfd); FD_SET (1, &readfd); @@ -1108,6 +1197,7 @@ CURLcode Curl_telnet(struct connectdata *conn) } } } +#endif /* mark this as "no further transfer wanted" */ return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); } diff --git a/src/setup.h b/src/setup.h index cf47843c5..74c4e8490 100644 --- a/src/setup.h +++ b/src/setup.h @@ -44,7 +44,7 @@ #define OS "unknown" #endif -#ifndef fileno /* sunos 4 have this as a macro! */ +#if !defined(fileno) && !defined(WIN32) /* sunos 4 have this as a macro! */ int fileno( FILE *stream); #endif diff --git a/src/version.h b/src/version.h index 6e8594a98..f0c5e8808 100644 --- a/src/version.h +++ b/src/version.h @@ -1,3 +1,3 @@ #define CURL_NAME "curl" -#define CURL_VERSION "7.8.2-pre1" +#define CURL_VERSION "7.9-pre6" #define CURL_ID CURL_NAME " " CURL_VERSION " (" OS ") "