online
  "   li~e8_6ژoh      online
  +   	lY>eJ}@?q1heǚs_I|+ ?     	/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2016 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.01 of the PHP license,      |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_01.txt                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Authors: Andrew Skalski <askalski@chek.com>                          |
   |          Stefan Esser <sesser@php.net> (resume functions)            |
   +----------------------------------------------------------------------+
 */

/* $Id$ */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"

#if HAVE_FTP

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <string.h>
#include <time.h>
#ifdef PHP_WIN32
#include <winsock2.h>
#elif defined(NETWARE)
#ifdef USE_WINSOCK    /* Modified to use Winsock (NOVSOCK2.H), at least for now */
#include <novsock2.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif
#else
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <errno.h>

#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#if HAVE_OPENSSL_EXT
#include <openssl/ssl.h>
#endif

#include "ftp.h"
#include "ext/standard/fsock.h"

/* Additional headers for NetWare */
#if defined(NETWARE) && !defined(USE_WINSOCK)
#include <sys/select.h>
#endif

/* sends an ftp command, returns true on success, false on error.
 * it sends the string "cmd args\r\n" if args is non-null, or
 * "cmd\r\n" if args is null
 */
static int		ftp_putcmd(	ftpbuf_t *ftp,
					const char *cmd,
					const char *args);

/* wrapper around send/recv to handle timeouts */
static int		my_send(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len);
static int		my_recv(ftpbuf_t *ftp, php_socket_t s, void *buf, size_t len);
static int		my_accept(ftpbuf_t *ftp, php_socket_t s, struct sockaddr *addr, socklen_t *addrlen);

/* reads a line the socket , returns true on success, false on error */
static int		ftp_readline(ftpbuf_t *ftp);

/* reads an ftp response, returns true on success, false on error */
static int		ftp_getresp(ftpbuf_t *ftp);

/* sets the ftp transfer type */
static int		ftp_type(ftpbuf_t *ftp, ftptype_t type);

/* opens up a data stream */
static databuf_t*	ftp_getdata(ftpbuf_t *ftp TSRMLS_DC);

/* accepts the data connection, returns updated data buffer */
static databuf_t*	data_accept(databuf_t *data, ftpbuf_t *ftp TSRMLS_DC);

/* closes the data connection, returns NULL */
static databuf_t*	data_close(ftpbuf_t *ftp, databuf_t *data);

/* generic file lister */
static char**		ftp_genlist(ftpbuf_t *ftp, const char *cmd, const char *path TSRMLS_DC);

/* IP and port conversion box */
union ipbox {
	struct in_addr	ia[2];
	unsigned short	s[4];
	unsigned char	c[8];
};

/* {{{ ftp_open
 */
ftpbuf_t*
ftp_open(const char *host, short port, long timeout_sec TSRMLS_DC)
{
	ftpbuf_t		*ftp;
	socklen_t		 size;
	struct timeval tv;


	/* alloc the ftp structure */
	ftp = ecalloc(1, sizeof(*ftp));

	tv.tv_sec = timeout_sec;
	tv.tv_usec = 0;

	ftp->fd = php_network_connect_socket_to_host(host,
