Newer
Older
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* Copyright (C) 1998 - 2013, 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.
* 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.
***************************************************************************/
#include "curl_setup.h"
#ifndef CURL_DISABLE_FTP
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <inet.h>
#endif
#if (defined(NETWARE) && defined(__NOVELL_LIBC__))
#undef in_addr_t
#define in_addr_t unsigned long
#endif
#include "urldata.h"
#include "sendf.h"
#include "if2ip.h"
#include "hostip.h"
#include "progress.h"
#include "transfer.h"
#include "escape.h"
#include "http.h" /* for HTTP proxy tunnel stuff */
#include "socks.h"
#include "ftp.h"
#include "fileinfo.h"
#include "ftplistparser.h"
#include "curl_sec.h"
#include "strtoofft.h"
#include "strequal.h"
#include "sslgen.h"
#include "connect.h"
#include "strerror.h"
#include "inet_ntop.h"
#include "inet_pton.h"
#include "select.h"
#include "parsedate.h" /* for the week day and month names */
#include "sockaddr.h" /* required for Curl_sockaddr_storage */
#include "multiif.h"
#include "url.h"
#include "rawstr.h"
#include "speedcheck.h"
#include "warnless.h"
#include "http_proxy.h"
#include "non-ascii.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
/* The last #include file should be: */
Guenter Knauf
committed
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
Daniel Stenberg
committed
#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
Daniel Stenberg
committed
#define ftp_pasv_verbose(a,b,c,d) Curl_nop_stmt
#ifndef DEBUGBUILD
static void _state(struct connectdata *conn,
ftpstate newstate);
#define state(x,y) _state(x,y)
#else
static void _state(struct connectdata *conn,
ftpstate newstate,
int lineno);
#define state(x,y) _state(x,y,__LINE__)
#endif
static CURLcode ftp_sendquote(struct connectdata *conn,
struct curl_slist *quote);
Daniel Stenberg
committed
static CURLcode ftp_quit(struct connectdata *conn);
Daniel Stenberg
committed
static CURLcode ftp_parse_url_path(struct connectdata *conn);
static CURLcode ftp_regular_transfer(struct connectdata *conn, bool *done);
static void ftp_pasv_verbose(struct connectdata *conn,
Curl_addrinfo *ai,
char *newhost, /* ascii version */
int port);
static CURLcode ftp_state_prepare_transfer(struct connectdata *conn);
static CURLcode ftp_state_mdtm(struct connectdata *conn);
static CURLcode ftp_state_quote(struct connectdata *conn,
bool init, ftpstate instate);
Daniel Stenberg
committed
static CURLcode ftp_nb_type(struct connectdata *conn,
bool ascii, ftpstate newstate);
Daniel Stenberg
committed
static int ftp_need_type(struct connectdata *conn,
bool ascii);
static CURLcode ftp_do(struct connectdata *conn, bool *done);
static CURLcode ftp_done(struct connectdata *conn,
CURLcode, bool premature);
static CURLcode ftp_connect(struct connectdata *conn, bool *done);
static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection);
static CURLcode ftp_do_more(struct connectdata *conn, int *completed);
static CURLcode ftp_multi_statemach(struct connectdata *conn, bool *done);
static int ftp_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
static int ftp_domore_getsock(struct connectdata *conn, curl_socket_t *socks,
int numsocks);
static CURLcode ftp_doing(struct connectdata *conn,
bool *dophase_done);
static CURLcode ftp_setup_connection(struct connectdata * conn);
static CURLcode init_wc_data(struct connectdata *conn);
static CURLcode wc_statemach(struct connectdata *conn);
static void wc_data_dtor(void *ptr);
static CURLcode ftp_state_retr(struct connectdata *conn, curl_off_t filesize);
static CURLcode ftp_readresp(curl_socket_t sockfd,
struct pingpong *pp,
int *ftpcode,
size_t *size);
static CURLcode ftp_dophase_done(struct connectdata *conn,
bool connected);
/* easy-to-use macro: */
#define PPSENDF(x,y,z) if((result = Curl_pp_sendf(x,y,z)) != CURLE_OK) \
Gisle Vanem
committed
return result
Patrick Monnerat
committed
/*
* FTP protocol handler.
*/
const struct Curl_handler Curl_handler_ftp = {
"FTP", /* scheme */
ftp_setup_connection, /* setup_connection */
ftp_do, /* do_it */
ftp_done, /* done */
ftp_do_more, /* do_more */
ftp_connect, /* connect_it */
ftp_multi_statemach, /* connecting */
ftp_doing, /* doing */
ftp_getsock, /* proto_getsock */
ftp_getsock, /* doing_getsock */
ftp_domore_getsock, /* domore_getsock */
Daniel Stenberg
committed
ZERO_NULL, /* perform_getsock */
ftp_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
Daniel Stenberg
committed
PORT_FTP, /* defport */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD
| PROTOPT_NOURLQUERY /* flags */
Patrick Monnerat
committed
};
#ifdef USE_SSL
/*
* FTPS protocol handler.
*/
const struct Curl_handler Curl_handler_ftps = {
"FTPS", /* scheme */
ftp_setup_connection, /* setup_connection */
ftp_do, /* do_it */
ftp_done, /* done */
ftp_do_more, /* do_more */
Loading
Loading full blame…