Newer
Older
/***************************************************************************
Daniel Stenberg
committed
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
Daniel Stenberg
committed
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
***************************************************************************/
#ifndef CURL_DISABLE_TELNET
/* -- WIN32 approved -- */
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <time.h>
#include <io.h>
#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#include <sys/time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <netdb.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
#endif
#include <sys/ioctl.h>
#include <signal.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#endif
#include "urldata.h"
#include <curl/curl.h>
Daniel Stenberg
committed
#include "transfer.h"
#include "telnet.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
#define TELOPTS
#define TELCMDS
#include "arpa_telnet.h"
#include "memory.h"
/* The last #include file should be: */
#include "memdebug.h"
Daniel Stenberg
committed
#define CURL_SB_CLEAR(x) x->subpointer = x->subbuffer;
#define CURL_SB_TERM(x) { x->subend = x->subpointer; CURL_SB_CLEAR(x); }
#define CURL_SB_ACCUM(x,c) \
if (x->subpointer < (x->subbuffer+sizeof x->subbuffer)) { \
*x->subpointer++ = (c); \
}
Daniel Stenberg
committed
#define CURL_SB_GET(x) ((*x->subpointer++)&0xff)
#define CURL_SB_PEEK(x) ((*x->subpointer)&0xff)
#define CURL_SB_EOF(x) (x->subpointer >= x->subend)
#define CURL_SB_LEN(x) (x->subend - x->subpointer)
#ifdef WIN32
typedef FARPROC WSOCK2_FUNC;
static CURLcode check_wsock2 ( struct SessionHandle *data );
#endif
static
void telrcv(struct connectdata *,
unsigned char *inbuf, /* Data received from socket */
ssize_t count); /* Number of bytes received */
Daniel Stenberg
committed
static void printoption(struct SessionHandle *data,
const char *direction,
int cmd, int option);
static void negotiate(struct connectdata *);
static void send_negotiation(struct connectdata *, int cmd, int option);
static void set_local_option(struct connectdata *, int cmd, int option);
static void set_remote_option(struct connectdata *, int cmd, int option);
Daniel Stenberg
committed
static void printsub(struct SessionHandle *data,
int direction, unsigned char *pointer,
size_t length);
static void suboption(struct connectdata *);
/* For negotiation compliant to RFC 1143 */
#define CURL_NO 0
#define CURL_YES 1
#define CURL_WANTYES 2
#define CURL_WANTNO 3
Daniel Stenberg
committed
#define CURL_OPPOSITE 1
Daniel Stenberg
committed
CURL_TS_DATA = 0,
CURL_TS_IAC,
CURL_TS_WILL,
CURL_TS_WONT,
CURL_TS_DO,
CURL_TS_DONT,
CURL_TS_CR,
CURL_TS_SB, /* sub-option collection */
CURL_TS_SE /* looking for sub-option end */
} TelnetReceive;
struct TELNET {
int please_negotiate;
int already_negotiated;
Daniel Stenberg
committed
int us[256];
int usq[256];
int us_preferred[256];
int him[256];
int himq[256];
int him_preferred[256];
char subopt_ttype[32]; /* Set with suboption TTYPE */
char subopt_xdisploc[128]; /* Set with suboption XDISPLOC */
struct curl_slist *telnet_vars; /* Environment variables */
/* suboptions */
char subbuffer[SUBBUFSIZE];
char *subpointer, *subend; /* buffer for sub-options */
Daniel Stenberg
committed
TelnetReceive telrcv_state;
};
#ifdef WIN32
static CURLcode
check_wsock2 ( struct SessionHandle *data )
{
Daniel Stenberg
committed
int err;
WORD wVersionRequested;
WSADATA wsaData;
curlassert(data);
/* telnet requires at least WinSock 2.0 so ask for it. */
wVersionRequested = MAKEWORD(2, 0);
Daniel Stenberg
committed
err = WSAStartup(wVersionRequested, &wsaData);
/* We must've called this once already, so this call */
/* should always succeed. But, just in case... */
if (err != 0) {
failf(data,"WSAStartup failed (%d)",err);
Daniel Stenberg
committed
return CURLE_FAILED_INIT;
}
/* We have to have a WSACleanup call for every successful */
/* WSAStartup call. */
WSACleanup();
/* Check that our version is supported */
if (LOBYTE(wsaData.wVersion) != LOBYTE(wVersionRequested) ||
HIBYTE(wsaData.wVersion) != HIBYTE(wVersionRequested)) {
Loading
Loading full blame…