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>
#ifdef HAVE_SYS_TYPES_H
#endif
#ifdef HAVE_SYS_STAT_H
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
73
74
75
#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();
Loading
Loading full blame…