Skip to content
telnet.c 26 KiB
Newer Older
          SB_ACCUM(tn,c);
          tn->telrcv_state = TS_SB;
          SB_ACCUM(tn, (unsigned char)IAC);
          SB_ACCUM(tn, (unsigned char)SE);
          tn->subpointer -= 2;
          SB_TERM(tn);
          suboption(conn);   /* handle sub-option */
          tn->telrcv_state = TS_DATA;
CURLcode Curl_telnet_done(struct connectdata *conn)
Daniel Stenberg's avatar
Daniel Stenberg committed
{
  struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
  curl_slist_free_all(tn->telnet_vars);
Daniel Stenberg's avatar
Daniel Stenberg committed

  free(conn->proto.telnet);
  conn->proto.telnet = NULL;

CURLcode Curl_telnet(struct connectdata *conn)
  struct SessionHandle *data = conn->data;
  int sockfd = conn->firstsocket;
  fd_set readfd;
  fd_set keepfd;
Daniel Stenberg's avatar
Daniel Stenberg committed

  bool keepon = TRUE;
  struct TELNET *tn;

  code = init_telnet(conn);
  if(code)
    return code;

  tn = (struct TELNET *)conn->proto.telnet;
Daniel Stenberg's avatar
Daniel Stenberg committed

  code = check_telnet_options(conn);
  if(code)
    return code;
  
  FD_ZERO (&readfd);		/* clear it */
  FD_SET (sockfd, &readfd);
  FD_SET (1, &readfd);
Daniel Stenberg's avatar
Daniel Stenberg committed

  keepfd = readfd;
Daniel Stenberg's avatar
Daniel Stenberg committed

  while (keepon) {
    readfd = keepfd;		/* set this every lap in the loop */
Daniel Stenberg's avatar
Daniel Stenberg committed

    switch (select (sockfd + 1, &readfd, NULL, NULL, NULL)) {
    case -1:			/* error, stop reading */
      keepon = FALSE;
      continue;
    case 0:			/* timeout */
      break;
    default:			/* read! */
      if(FD_ISSET(1, &readfd)) { /* read from stdin */
        unsigned char outbuf[2];
        int out_count = 0;
        size_t bytes_written;
        char *buffer = buf;
        
        nread = read(1, buf, 255);

        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);
        }
      }
Daniel Stenberg's avatar
Daniel Stenberg committed

      if(FD_ISSET(sockfd, &readfd)) {
        Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
Daniel Stenberg's avatar
Daniel Stenberg committed

        /* if we receive 0 or less here, the server closed the connection and
           we bail out from this! */
        if (nread <= 0) {
          keepon = FALSE;
          break;
        }
        telrcv(conn, (unsigned char *)buf, nread);

        /* 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) {
          tn->already_negotiated = 1;
  /* mark this as "no further transfer wanted" */
  return Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
Daniel Stenberg's avatar
Daniel Stenberg committed
}

/*
 * local variables:
 * eval: (load-file "../curl-mode.el")
 * end:
 * vim600: et sw=2 ts=2 sts=2 tw=78 fdm=marker
 * vim<600: et sw=2 ts=2 sts=2 tw=78
 */