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;
int sockfd = conn->firstsocket;
#ifdef WIN32
WSAEVENT event_handle;
WSANETWORKEVENTS events;
HANDLE stdin_handle;
HANDLE objs[2];
DWORD waitret;
#else
Daniel Stenberg
committed
char *buf = data->state.buffer;
ssize_t nread;
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;
1063
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
1089
1090
1091
1092
1093
#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, 255, (LPDWORD)&nread, NULL)) {
keepon = FALSE;
break;
}
while(nread--) {
outbuf[0] = *buffer++;
out_count = 1;
Daniel Stenberg
committed
if(outbuf[0] == CURL_IAC)
outbuf[out_count++] = CURL_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)
{
/* This reallu OUGHT to check its return code. */
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
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);
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;
Curl_write(conn, conn->firstsocket, outbuf,
out_count, &bytes_written);
}
}
if(FD_ISSET(sockfd, &readfd)) {
/* This OUGHT to check the return code... */
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;