25 #ifndef CURL_DISABLE_TELNET 27 #ifdef HAVE_NETINET_IN_H 28 #include <netinet/in.h> 33 #ifdef HAVE_ARPA_INET_H 34 #include <arpa/inet.h> 39 #ifdef HAVE_SYS_IOCTL_H 40 #include <sys/ioctl.h> 43 #ifdef HAVE_SYS_PARAM_H 44 #include <sys/param.h> 69 #define SUBBUFSIZE 512 71 #define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer 72 #define CURL_SB_TERM(x) \ 74 x->subend = x->subpointer; \ 77 #define CURL_SB_ACCUM(x,c) \ 79 if(x->subpointer < (x->subbuffer + sizeof x->subbuffer)) \ 80 *x->subpointer++ = (c); \ 83 #define CURL_SB_GET(x) ((*x->subpointer++)&0xff) 84 #define CURL_SB_LEN(x) (x->subend - x->subpointer) 90 #ifdef CURL_DISABLE_VERBOSE_STRINGS 91 #define printoption(a,b,c,d) Curl_nop_stmt 95 typedef FARPROC WSOCK2_FUNC;
101 const unsigned char *inbuf,
104 #ifndef CURL_DISABLE_VERBOSE_STRINGS 106 const char *direction,
107 int cmd,
int option);
116 int direction,
unsigned char *pointer,
130 #define CURL_WANTYES 2 131 #define CURL_WANTNO 3 134 #define CURL_OPPOSITE 1 207 WORD wVersionRequested;
213 wVersionRequested = MAKEWORD(2, 0);
215 err = WSAStartup(wVersionRequested, &wsaData);
220 failf(data,
"WSAStartup failed (%d)",err);
229 if(LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
230 HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
232 failf(data,
"insufficient winsock version to support " 310 #ifndef CURL_DISABLE_VERBOSE_STRINGS 312 const char *direction,
int cmd,
int option)
322 infof(data,
"%s IAC %d\n", direction, option);
336 infof(data,
"%s %s %s\n", direction, fmt, opt);
338 infof(data,
"%s %s %d\n", direction, fmt, option);
341 infof(data,
"%s %d %d\n", direction, cmd, option);
349 unsigned char buf[3];
355 buf[1] = (
unsigned char)cmd;
356 buf[2] = (
unsigned char)option;
359 if(bytes_written < 0) {
361 failf(data,
"Sending data failed (%d)",err);
372 switch(tn->
him[option]) {
383 switch(tn->
himq[option]) {
395 switch(tn->
himq[option]) {
407 switch(tn->
him[option]) {
418 switch(tn->
himq[option]) {
429 switch(tn->
himq[option]) {
445 switch(tn->
him[option]) {
461 switch(tn->
himq[option]) {
475 switch(tn->
himq[option]) {
493 switch(tn->
him[option]) {
504 switch(tn->
himq[option]) {
518 switch(tn->
himq[option]) {
536 switch(tn->
us[option]) {
547 switch(tn->
usq[option]) {
559 switch(tn->
usq[option]) {
571 switch(tn->
us[option]) {
582 switch(tn->
usq[option]) {
593 switch(tn->
usq[option]) {
609 switch(tn->
us[option]) {
633 switch(tn->
usq[option]) {
647 switch(tn->
usq[option]) {
669 switch(tn->
us[option]) {
680 switch(tn->
usq[option]) {
694 switch(tn->
usq[option]) {
710 unsigned char *pointer,
717 infof(data,
"%s IAC SB ", (direction ==
'<')?
"RCVD":
"SENT");
721 i = pointer[length-2];
722 j = pointer[length-1];
725 infof(data,
"(terminated by ");
731 infof(data,
"%u ", i);
737 infof(data,
"%d", j);
738 infof(data,
", not IAC SE!) ");
744 infof(data,
"(Empty suboption?)");
762 infof(data,
"%d (unknown)", pointer[i]);
767 infof(data,
"Width: %hu ; Height: %hu", (pointer[1]<<8) | pointer[2],
768 (pointer[3]<<8) | pointer[4]);
776 infof(data,
" SEND");
779 infof(data,
" INFO/REPLY");
782 infof(data,
" NAME");
790 infof(data,
" \"%s\"", &pointer[2]);
795 for(i = 3; i < length; i++) {
804 infof(data,
"%c", pointer[i]);
811 for(i = 2; i < length; i++)
812 infof(data,
" %.2x", pointer[i]);
825 char option_keyword[128] =
"";
826 char option_arg[256] =
"";
835 snprintf(option_arg,
sizeof(option_arg),
"USER,%s", conn->
user);
847 if(sscanf(head->
data,
"%127[^= ]%*[ =]%255s",
848 option_keyword, option_arg) == 2) {
880 if(sscanf(option_arg,
"%hu%*[xX]%hu",
884 failf(data,
"Syntax error in telnet option: %s", head->
data);
893 binary_option = atoi(option_arg);
894 if(binary_option != 1) {
901 failf(data,
"Unknown telnet option %s", head->
data);
905 failf(data,
"Syntax error in telnet option: %s", head->
data);
928 unsigned char temp[2048];
933 char varname[128] =
"";
934 char varval[128] =
"";
942 snprintf((
char *)temp,
sizeof(temp),
946 if(bytes_written < 0) {
948 failf(data,
"Sending data failed (%d)",err);
950 printsub(data,
'>', &temp[2], len-2);
954 snprintf((
char *)temp,
sizeof(temp),
958 if(bytes_written < 0) {
960 failf(data,
"Sending data failed (%d)",err);
962 printsub(data,
'>', &temp[2], len-2);
965 snprintf((
char *)temp,
sizeof(temp),
971 tmplen = (strlen(v->
data) + 1);
973 if(len + tmplen < (
int)
sizeof(temp)-6) {
974 if(sscanf(v->
data,
"%127[^,],%127s", varname, varval)) {
975 snprintf((
char *)&temp[len],
sizeof(temp) - len,
982 snprintf((
char *)&temp[len],
sizeof(temp) - len,
986 if(bytes_written < 0) {
988 failf(data,
"Sending data failed (%d)",err);
990 printsub(data,
'>', &temp[2], len-2);
1007 unsigned short x,
y;
1008 unsigned char *uc1, *uc2;
1024 uc1 = (
unsigned char *)&x;
1025 uc2 = (
unsigned char *)&y;
1041 if(bytes_written < 0) {
1043 failf(data,
"Sending data failed (%d)", err);
1050 if(bytes_written < 0) {
1052 failf(data,
"Sending data failed (%d)", err);
1061 const unsigned char *inbuf,
1067 int startwrite = -1;
1072 if(startwrite >= 0) {
\ 1075 (
char *)&inbuf[startwrite], \
1082 #define writebyte() \ 1083 if(startwrite < 0) \ 1086 #define bufferflush() startskipping() 1228 unsigned char *outbuf = NULL;
1230 ssize_t bytes_written, total_written;
1234 for(i = 0; i < nread; i++)
1235 if((
unsigned char)buffer[i] ==
CURL_IAC)
1237 outlen = nread + escapes;
1240 outbuf = (
unsigned char *)buffer;
1242 outbuf =
malloc(nread + escapes + 1);
1247 for(i = 0; i < nread; i++) {
1248 outbuf[j++] = buffer[
i];
1249 if((
unsigned char)buffer[i] ==
CURL_IAC)
1256 while(!result && total_written < outlen) {
1269 outbuf + total_written,
1270 outlen - total_written,
1272 total_written += bytes_written;
1278 if(outbuf != (
unsigned char *)buffer)
1309 WSOCK2_FUNC close_event_func;
1310 WSOCK2_FUNC create_event_func;
1311 WSOCK2_FUNC event_select_func;
1312 WSOCK2_FUNC enum_netevents_func;
1313 WSAEVENT event_handle;
1314 WSANETWORKEVENTS events;
1315 HANDLE stdin_handle;
1320 DWORD readfile_read;
1352 result = check_wsock2(data);
1358 wsock2 = Curl_load_library(TEXT(
"WS2_32.DLL"));
1359 if(wsock2 == NULL) {
1360 failf(data,
"failed to load WS2_32.DLL (%u)", GetLastError());
1365 create_event_func = GetProcAddress(wsock2,
"WSACreateEvent");
1366 if(create_event_func == NULL) {
1367 failf(data,
"failed to find WSACreateEvent function (%u)", GetLastError());
1368 FreeLibrary(wsock2);
1373 close_event_func = GetProcAddress(wsock2,
"WSACloseEvent");
1374 if(close_event_func == NULL) {
1375 failf(data,
"failed to find WSACloseEvent function (%u)", GetLastError());
1376 FreeLibrary(wsock2);
1381 event_select_func = GetProcAddress(wsock2,
"WSAEventSelect");
1382 if(event_select_func == NULL) {
1383 failf(data,
"failed to find WSAEventSelect function (%u)", GetLastError());
1384 FreeLibrary(wsock2);
1389 enum_netevents_func = GetProcAddress(wsock2,
"WSAEnumNetworkEvents");
1390 if(enum_netevents_func == NULL) {
1391 failf(data,
"failed to find WSAEnumNetworkEvents function (%u)",
1393 FreeLibrary(wsock2);
1403 event_handle = (WSAEVENT)create_event_func();
1404 if(event_handle == WSA_INVALID_EVENT) {
1406 FreeLibrary(wsock2);
1411 if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) ==
1413 close_event_func(event_handle);
1414 FreeLibrary(wsock2);
1419 stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
1422 objs[0] = event_handle;
1423 objs[1] = stdin_handle;
1427 if(GetFileType(stdin_handle) == FILE_TYPE_PIPE ||
1436 wait_timeout = 1000;
1442 waitret = WaitForMultipleObjects(obj_count, objs,
FALSE, wait_timeout);
1463 readfile_read = (DWORD)n;
1467 if(!PeekNamedPipe(stdin_handle, NULL, 0, NULL,
1468 &readfile_read, NULL)) {
1477 if(!ReadFile(stdin_handle, buf, buf_size,
1478 &readfile_read, NULL)) {
1494 case WAIT_OBJECT_0 + 1:
1496 if(!ReadFile(stdin_handle, buf, buf_size,
1497 &readfile_read, NULL)) {
1513 events.lNetworkEvents = 0;
1514 if(SOCKET_ERROR == enum_netevents_func(sockfd, event_handle, &events)) {
1516 if(err != EINPROGRESS) {
1517 infof(data,
"WSAEnumNetworkEvents failed (%d)", err);
1523 if(events.lNetworkEvents & FD_READ) {
1536 else if(nread <= 0) {
1541 result =
telrcv(conn, (
unsigned char *) buf, nread);
1555 if(events.lNetworkEvents & FD_CLOSE) {
1565 failf(data,
"Time-out");
1573 if(!close_event_func(event_handle)) {
1578 create_event_func = NULL;
1579 close_event_func = NULL;
1580 event_select_func = NULL;
1581 enum_netevents_func = NULL;
1584 if(!FreeLibrary(wsock2))
1585 infof(data,
"FreeLibrary(wsock2) failed (%u)", GetLastError());
1599 interval_ms = 1 * 1000;
1603 switch(
Curl_poll(pfd, poll_cnt, interval_ms)) {
1612 if(pfd[0].revents &
POLLIN) {
1625 else if(nread <= 0) {
1632 result =
telrcv(conn, (
unsigned char *)buf, nread);
1649 if(pfd[1].revents & POLLIN) {
1683 failf(data,
"Time-out");
#define CURL_TELCMD_OK(x)
static CURLcode telnet_do(struct connectdata *conn, bool *done)
void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size)
static void printsub(struct Curl_easy *data, int direction, unsigned char *pointer, size_t length)
#define PROTOPT_NOURLQUERY
unsigned short subopt_wsx
#define CURL_TELOPT_EXOPL
static void suboption(struct connectdata *)
const struct Curl_handler Curl_handler_telnet
static CURLcode telrcv(struct connectdata *, const unsigned char *inbuf, ssize_t count)
static CURLcode init_telnet(struct connectdata *conn)
static void rec_dont(struct connectdata *conn, int option)
unsigned short subopt_wsy
#define CURL_TELOPT_BINARY
if(strcmp(arg,"1305")!=0)
struct curl_slist * telnet_options
#define strcasecompare(a, b)
TFSIMD_FORCE_INLINE const tfScalar & y() const
static void rec_do(struct connectdata *conn, int option)
UNITTEST_START int result
int Curl_pgrsUpdate(struct connectdata *conn)
static void set_local_option(struct connectdata *, int cmd, int option)
void Curl_setup_transfer(struct connectdata *conn, int sockindex, curl_off_t size, bool getheader, curl_off_t *bytecountp, int writesockindex, curl_off_t *writecountp)
static void rec_wont(struct connectdata *conn, int option)
static CURLcode check_telnet_options(struct connectdata *conn)
CURL_EXTERN struct curl_slist * curl_slist_append(struct curl_slist *, const char *)
static void negotiate(struct connectdata *)
#define CURL_NEW_ENV_VALUE
static void send_negotiation(struct connectdata *, int cmd, int option)
static void sendsuboption(struct connectdata *conn, int option)
TFSIMD_FORCE_INLINE const tfScalar & x() const
CURL_TYPEOF_CURL_OFF_T curl_off_t
CURLcode Curl_write(struct connectdata *conn, curl_socket_t sockfd, const void *mem, size_t len, ssize_t *written)
static CURLcode telnet_done(struct connectdata *conn, CURLcode, bool premature)
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len)
static void set_remote_option(struct connectdata *, int cmd, int option)
#define CURL_SB_ACCUM(x, c)
#define Curl_safefree(ptr)
char subopt_xdisploc[128]
#define CURL_READFUNC_ABORT
#define CURL_TELQUAL_INFO
#define CURL_TELOPT_OK(x)
unsigned char subbuffer[SUBBUFSIZE]
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
#define CURL_READFUNC_PAUSE
static CURLcode send_telnet_data(struct connectdata *conn, char *buffer, ssize_t nread)
#define Curl_tvdiff(x, y)
curl_read_callback fread_func
int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
#define CURL_TELOPT_NEW_ENVIRON
static void printoption(struct Curl_easy *data, const char *direction, int cmd, int option)
#define CURL_TELQUAL_NAME
unsigned char * subpointer
struct curl_slist * telnet_vars
CURL_EXTERN void curl_slist_free_all(struct curl_slist *)
static void rec_will(struct connectdata *conn, int option)
#define CURL_TELOPT_TTYPE
#define CURL_TELQUAL_SEND
#define calloc(nbelem, size)
CURLcode Curl_read(struct connectdata *conn, curl_socket_t sockfd, char *buf, size_t sizerequested, ssize_t *n)
TelnetReceive telrcv_state
#define CURL_TELOPT_XDISPLOC
struct curl_llist_element * head
case 1: list has >1 element, removing head : 1: list size will be decremented by one 2: head will be ...