Newer
Older
Daniel Stenberg
committed
printoption(data, "In SUBOPTION processing, RCVD", CURL_IAC, c);
suboption(conn); /* handle sub-option */
Daniel Stenberg
committed
tn->telrcv_state = CURL_TS_IAC;
Daniel Stenberg
committed
CURL_SB_ACCUM(tn,c);
tn->telrcv_state = CURL_TS_SB;
Daniel Stenberg
committed
CURL_SB_ACCUM(tn, (unsigned char)CURL_IAC);
CURL_SB_ACCUM(tn, (unsigned char)CURL_SE);
Daniel Stenberg
committed
CURL_SB_TERM(tn);
suboption(conn); /* handle sub-option */
Daniel Stenberg
committed
tn->telrcv_state = CURL_TS_DATA;
}
break;
}
}
CURLcode Curl_telnet_done(struct connectdata *conn)
struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
curl_slist_free_all(tn->telnet_vars);
free(conn->proto.telnet);
conn->proto.telnet = NULL;
CURLcode Curl_telnet(struct connectdata *conn)
Daniel Stenberg
committed
struct SessionHandle *data = conn->data;
Daniel Stenberg
committed
int sockfd = conn->sock[FIRSTSOCKET];
#ifdef WIN32
WSAEVENT event_handle;
WSANETWORKEVENTS events;
HANDLE stdin_handle;
HANDLE objs[2];
DWORD waitret;
Daniel Stenberg
committed
char *buf = data->state.buffer;
struct TELNET *tn;
code = init_telnet(conn);
if(code)
return code;
tn = (struct TELNET *)conn->proto.telnet;
code = check_telnet_options(conn);
if(code)
return code;
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
#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;
ssize_t bytes_written;
char *buffer = buf;
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
(LPDWORD)&nread, NULL)) {
keepon = FALSE;
break;
}
while(nread--) {
outbuf[0] = *buffer++;
out_count = 1;
if(outbuf[0] == CURL_IAC)
outbuf[out_count++] = CURL_IAC;
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
out_count, &bytes_written);
case 1:
if(WSAEnumNetworkEvents(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) {
keepon = FALSE;
FD_ZERO (&readfd); /* clear it */
FD_SET (sockfd, &readfd);
struct timeval interval;
readfd = keepfd; /* set this every lap in the loop */
interval.tv_sec = 1;
interval.tv_usec = 0;
switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) {
case -1: /* error, stop reading */
keepon = FALSE;
continue;
case 0: /* timeout */
break;
default: /* read! */
if(FD_ISSET(0, &readfd)) { /* read from stdin */
unsigned char outbuf[2];
int out_count = 0;
ssize_t bytes_written;
while(nread--) {
outbuf[0] = *buffer++;
out_count = 1;
Daniel Stenberg
committed
if(outbuf[0] == CURL_IAC)
outbuf[out_count++] = CURL_IAC;
Daniel Stenberg
committed
Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf,
out_count, &bytes_written);
}
}
if(FD_ISSET(sockfd, &readfd)) {
/* This OUGHT to check the return code... */
(void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread);
/* 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) {
if(data->set.timeout) {
struct timeval now; /* current time */
now = Curl_tvnow();
if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) {
failf(data, "Time-out");
code = CURLE_OPERATION_TIMEOUTED;
keepon = FALSE;
}
}
/* mark this as "no further transfer wanted" */
Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
return code;