From f1db505778f2cea0ec7a631d5ce3b99d841f8a2c Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Wed, 11 Mar 2009 04:15:33 +0000 Subject: [PATCH] Added TELNET timeout support for Windows builds --- CHANGES | 4 ++++ RELEASE-NOTES | 3 ++- lib/telnet.c | 60 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index 19794b3eb..d68072cac 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,10 @@ Changelog +Yang Tse (11 Mar 2009) +- Added missing TELNET timeout support for Windows builds. This issue was + reported by Pierre Brico. + Daniel Stenberg (9 Mar 2009) - Frank Hempel found out a bug and provided the fix: diff --git a/RELEASE-NOTES b/RELEASE-NOTES index c28844f9e..7709d97f8 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -18,6 +18,7 @@ This release includes the following bugfixes: o fixed the GnuTLS-using code to do correct return code checks o an alloc-related call in the OpenSSL-using code didn't check the return value o curl_easy_duphandle() failed to duplicate cookies at times + o missing TELNET timeout support in Windows builds This release includes the following known bugs: @@ -27,6 +28,6 @@ This release would not have looked like this without help, code, reports and advice from friends like these: Daniel Fandrich, Yang Tse, David James, Chris Deidun, Bill Egert, - Andre Guibert de Bruet, Andreas Farber, Frank Hempel + Andre Guibert de Bruet, Andreas Farber, Frank Hempel, Pierre Brico Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/telnet.c b/lib/telnet.c index 750fa234f..7c0b20283 100644 --- a/lib/telnet.c +++ b/lib/telnet.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2009, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1195,11 +1195,13 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) DWORD wait_timeout; DWORD waitret; DWORD readfile_read; + int err; #else int interval_ms; struct pollfd pfd[2]; #endif ssize_t nread; + struct timeval now; bool keepon = TRUE; char *buf = data->state.buffer; struct TELNET *tn; @@ -1305,7 +1307,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) wait_timeout = 100; } else { obj_count = 2; - wait_timeout = INFINITE; + wait_timeout = 1000; } /* Keep on listening and act on events */ @@ -1358,30 +1360,45 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) break; case WAIT_OBJECT_0: - if(enum_netevents_func(sockfd, event_handle, &events) - != SOCKET_ERROR) { - if(events.lNetworkEvents & FD_READ) { - /* This reallu OUGHT to check its return code. */ - (void)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) { + if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) { + if((err = SOCKERRNO) != EINPROGRESS) { + infof(data,"WSAEnumNetworkEvents failed (%d)", err); keepon = FALSE; + code = CURLE_READ_ERROR; + break; } } + if(events.lNetworkEvents & FD_READ) { + /* This reallu OUGHT to check its return code. */ + (void)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; + + } + + if(data->set.timeout) { + now = Curl_tvnow(); + if(Curl_tvdiff(now, conn->created) >= data->set.timeout) { + failf(data, "Time-out"); + code = CURLE_OPERATION_TIMEDOUT; + keepon = FALSE; + } } } @@ -1446,7 +1463,6 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) } } if(data->set.timeout) { - struct timeval now; /* current time */ now = Curl_tvnow(); if(Curl_tvdiff(now, conn->created) >= data->set.timeout) { failf(data, "Time-out");