aboutsummaryrefslogtreecommitdiff
path: root/lib/telnet.c
diff options
context:
space:
mode:
authorDan Fandrich <dan@coneharvesters.com>2008-06-03 18:03:11 +0000
committerDan Fandrich <dan@coneharvesters.com>2008-06-03 18:03:11 +0000
commit6f0a2608b45f83064759b3585a282de5be584966 (patch)
tree39c8ad73cc6b03b0b1bafa9279f5e719c4005c7c /lib/telnet.c
parentea86edbd821fc448a4188598d18aa8ce12bb435a (diff)
Fixed a problem where telnet data would be lost if an EWOULDBLOCK
condition were encountered.
Diffstat (limited to 'lib/telnet.c')
-rw-r--r--lib/telnet.c104
1 files changed, 58 insertions, 46 deletions
diff --git a/lib/telnet.c b/lib/telnet.c
index a531e6743..c44658914 100644
--- a/lib/telnet.c
+++ b/lib/telnet.c
@@ -1117,6 +1117,46 @@ void telrcv(struct connectdata *conn,
bufferflush();
}
+/* Escape and send a telnet data block */
+/* TODO: write large chunks of data instead of one byte at a time */
+static CURLcode send_telnet_data(struct connectdata *conn,
+ char *buffer, ssize_t nread)
+{
+ unsigned char outbuf[2];
+ ssize_t bytes_written, total_written;
+ int out_count;
+ CURLcode rc = CURLE_OK;
+
+ while(rc == CURLE_OK && nread--) {
+ outbuf[0] = *buffer++;
+ out_count = 1;
+ if(outbuf[0] == CURL_IAC)
+ outbuf[out_count++] = CURL_IAC;
+
+ total_written = 0;
+ do {
+ /* Make sure socket is writable to avoid EWOULDBLOCK condition */
+ struct pollfd pfd[1];
+ pfd[0].fd = conn->sock[FIRSTSOCKET];
+ pfd[0].events = POLLOUT;
+ switch (Curl_poll(pfd, 1, -1)) {
+ case -1: /* error, abort writing */
+ case 0: /* timeout (will never happen) */
+ rc = CURLE_SEND_ERROR;
+ break;
+ default: /* write! */
+ bytes_written = 0;
+ rc = Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf+total_written,
+ out_count-total_written, &bytes_written);
+ total_written += bytes_written;
+ break;
+ }
+ /* handle partial write */
+ } while (rc == CURLE_OK && total_written < out_count);
+ }
+ return rc;
+}
+
static CURLcode telnet_done(struct connectdata *conn,
CURLcode status, bool premature)
{
@@ -1270,63 +1310,45 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
switch(waitret) {
case WAIT_TIMEOUT:
{
- unsigned char outbuf[2];
- int out_count = 0;
- ssize_t bytes_written;
- char *buffer = buf;
-
while(1) {
if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL, &readfile_read, NULL)) {
keepon = FALSE;
+ code = CURLE_READ_ERROR;
break;
}
- nread = readfile_read;
- if(!nread)
+ if(!readfile_read)
break;
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
&readfile_read, NULL)) {
keepon = FALSE;
+ code = CURLE_READ_ERROR;
break;
}
- nread = readfile_read;
- 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);
- }
+ code = send_telnet_data(conn, buf, readfile_read);
+ if(code) {
+ keepon = FALSE;
+ break;
+ }
}
}
break;
case WAIT_OBJECT_0 + 1:
{
- unsigned char outbuf[2];
- int out_count = 0;
- ssize_t bytes_written;
- char *buffer = buf;
-
if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
&readfile_read, NULL)) {
keepon = FALSE;
+ code = CURLE_READ_ERROR;
break;
}
- nread = readfile_read;
- 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);
+ code = send_telnet_data(conn, buf, readfile_read);
+ if(code) {
+ keepon = FALSE;
+ break;
}
}
break;
@@ -1389,22 +1411,12 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
break;
default: /* read! */
if(pfd[1].revents & POLLIN) { /* read from stdin */
- unsigned char outbuf[2];
- int out_count = 0;
- ssize_t bytes_written;
- char *buffer = buf;
-
nread = read(0, buf, 255);
-
- 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);
- }
+ code = send_telnet_data(conn, buf, nread);
+ if(code) {
+ keepon = FALSE;
+ break;
+ }
}
if(pfd[0].revents & POLLIN) {