mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
Improved telnet support by drastically reducing the number of write
callbacks needed to pass a buffer to the user. Instead one per byte it is now as little as one per segment.
This commit is contained in:
parent
70f10f1ac9
commit
33f7ac06c3
5
CHANGES
5
CHANGES
@ -6,6 +6,11 @@
|
||||
|
||||
Changelog
|
||||
|
||||
Dan F (6 Nov 2007)
|
||||
- Improved telnet support by drastically reducing the number of write
|
||||
callbacks needed to pass a buffer to the user. Instead one per byte it
|
||||
is now as little as one per segment.
|
||||
|
||||
Yang Tse (6 Nov 2007)
|
||||
- Bug report #1824894 (http://curl.haxx.se/bug/view.cgi?id=1824894) pointed
|
||||
out a problem in curl.h when building C++ apps with MSVC. To fix it, the
|
||||
|
63
lib/telnet.c
63
lib/telnet.c
@ -106,7 +106,7 @@ static CURLcode check_wsock2 ( struct SessionHandle *data );
|
||||
|
||||
static
|
||||
void telrcv(struct connectdata *,
|
||||
unsigned char *inbuf, /* Data received from socket */
|
||||
const unsigned char *inbuf, /* Data received from socket */
|
||||
ssize_t count); /* Number of bytes received */
|
||||
|
||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||
@ -949,104 +949,119 @@ static void suboption(struct connectdata *conn)
|
||||
|
||||
static
|
||||
void telrcv(struct connectdata *conn,
|
||||
unsigned char *inbuf, /* Data received from socket */
|
||||
const unsigned char *inbuf, /* Data received from socket */
|
||||
ssize_t count) /* Number of bytes received */
|
||||
{
|
||||
unsigned char c;
|
||||
int in = 0;
|
||||
int startwrite=-1;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct TELNET *tn = (struct TELNET *)data->reqdata.proto.telnet;
|
||||
|
||||
#define startskipping() \
|
||||
if (startwrite >= 0) \
|
||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&inbuf[startwrite], in-startwrite); \
|
||||
startwrite = -1
|
||||
|
||||
#define writebyte() \
|
||||
if (startwrite < 0) \
|
||||
startwrite = in
|
||||
|
||||
#define bufferflush() startskipping()
|
||||
|
||||
while(count--)
|
||||
{
|
||||
c = inbuf[in++];
|
||||
c = inbuf[in];
|
||||
|
||||
/*infof(data,"In rcv state %d char %d\n", tn->telrcv_state, c);*/
|
||||
switch (tn->telrcv_state)
|
||||
{
|
||||
case CURL_TS_CR:
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
if(c == '\0')
|
||||
{
|
||||
startskipping();
|
||||
break; /* Ignore \0 after CR */
|
||||
}
|
||||
|
||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
|
||||
continue;
|
||||
writebyte();
|
||||
break;
|
||||
|
||||
case CURL_TS_DATA:
|
||||
if(c == CURL_IAC)
|
||||
{
|
||||
tn->telrcv_state = CURL_TS_IAC;
|
||||
startskipping();
|
||||
break;
|
||||
}
|
||||
else if(c == '\r')
|
||||
{
|
||||
tn->telrcv_state = CURL_TS_CR;
|
||||
}
|
||||
|
||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
|
||||
continue;
|
||||
writebyte();
|
||||
break;
|
||||
|
||||
case CURL_TS_IAC:
|
||||
process_iac:
|
||||
DEBUGASSERT(startwrite < 0);
|
||||
switch (c)
|
||||
{
|
||||
case CURL_WILL:
|
||||
tn->telrcv_state = CURL_TS_WILL;
|
||||
continue;
|
||||
break;
|
||||
case CURL_WONT:
|
||||
tn->telrcv_state = CURL_TS_WONT;
|
||||
continue;
|
||||
break;
|
||||
case CURL_DO:
|
||||
tn->telrcv_state = CURL_TS_DO;
|
||||
continue;
|
||||
break;
|
||||
case CURL_DONT:
|
||||
tn->telrcv_state = CURL_TS_DONT;
|
||||
continue;
|
||||
break;
|
||||
case CURL_SB:
|
||||
CURL_SB_CLEAR(tn);
|
||||
tn->telrcv_state = CURL_TS_SB;
|
||||
continue;
|
||||
break;
|
||||
case CURL_IAC:
|
||||
Curl_client_write(conn, CLIENTWRITE_BODY, (char *)&c, 1);
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
writebyte();
|
||||
break;
|
||||
case CURL_DM:
|
||||
case CURL_NOP:
|
||||
case CURL_GA:
|
||||
default:
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
printoption(data, "RCVD", CURL_IAC, c);
|
||||
break;
|
||||
}
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case CURL_TS_WILL:
|
||||
printoption(data, "RCVD", CURL_WILL, c);
|
||||
tn->please_negotiate = 1;
|
||||
rec_will(conn, c);
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case CURL_TS_WONT:
|
||||
printoption(data, "RCVD", CURL_WONT, c);
|
||||
tn->please_negotiate = 1;
|
||||
rec_wont(conn, c);
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case CURL_TS_DO:
|
||||
printoption(data, "RCVD", CURL_DO, c);
|
||||
tn->please_negotiate = 1;
|
||||
rec_do(conn, c);
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case CURL_TS_DONT:
|
||||
printoption(data, "RCVD", CURL_DONT, c);
|
||||
tn->please_negotiate = 1;
|
||||
rec_dont(conn, c);
|
||||
tn->telrcv_state = CURL_TS_DATA;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case CURL_TS_SB:
|
||||
if(c == CURL_IAC)
|
||||
@ -1057,7 +1072,7 @@ void telrcv(struct connectdata *conn,
|
||||
{
|
||||
CURL_SB_ACCUM(tn,c);
|
||||
}
|
||||
continue;
|
||||
break;
|
||||
|
||||
case CURL_TS_SE:
|
||||
if(c != CURL_SE)
|
||||
@ -1097,7 +1112,9 @@ void telrcv(struct connectdata *conn,
|
||||
}
|
||||
break;
|
||||
}
|
||||
++in;
|
||||
}
|
||||
bufferflush();
|
||||
}
|
||||
|
||||
static CURLcode Curl_telnet_done(struct connectdata *conn,
|
||||
@ -1143,7 +1160,7 @@ static CURLcode Curl_telnet(struct connectdata *conn, bool *done)
|
||||
char *buf = data->state.buffer;
|
||||
struct TELNET *tn;
|
||||
|
||||
*done = TRUE; /* uncontionally */
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
code = init_telnet(conn);
|
||||
if(code)
|
||||
|
Loading…
Reference in New Issue
Block a user