Commit e30dcd05 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

Linus Nielsen Feltzing's telnet-for-win32 fixes

parent 24dc7cff
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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 {
+6 −6
Original line number Diff line number Diff line
@@ -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. */ 
+97 −7
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@
#include <errno.h>

#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#include <winsock2.h>
#include <time.h>
#include <io.h>
#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;
@@ -1051,6 +1060,86 @@ CURLcode Curl_telnet(struct connectdata *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);
}
+1 −1
Original line number Diff line number Diff line
@@ -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

+1 −1
Original line number Diff line number Diff line
#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 ") "