/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 2001-2017  The R Core Team.
 *  Copyright (C) 1998-2012  Daniel Veillard.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, a copy is available at
 *  https://www.R-project.org/Licenses/
 */

/* <UTF8> the only interpretation of char is ASCII
   <MBCS> only does strchr on ASCII strings, unless user@passwd in URLs
   can be non-ASCII.
 */

/* based on libxml2-2.4.10
 * (but updated to protect against CVE-2004-0989):
 * nanoftp.c: basic FTP client support
 *
 *  Reference: RFC 959
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif


#ifdef ENABLE_NLS
#include <libintl.h>
#define _(String) gettext (String)
#else
#define _(String) (String)
#endif

extern void R_ProcessEvents(void);

#ifdef Win32
#define FD_SETSIZE 1024
#include <io.h>
#include <winsock2.h>
#define _WINSOCKAPI_
#define R_SelectEx(n,rfd,wrd,efd,tv,ih) select(n,rfd,wrd,efd,tv)
#endif

#ifdef HAVE_STRINGS_H
   /* may be needed to define bzero in FD_ZERO (eg AIX) */
  #include <strings.h>
#endif

// ../../include/R_ext/R-ftp-http.h :
#include <R_ext/R-ftp-http.h>
/* #define DEBUG_FTP */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifdef Unix
# include <netdb.h>
# include <sys/socket.h>
# include <netinet/in.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif


#if !defined(strdup) && defined(HAVE_DECL_STRDUP) && !HAVE_DECL_STRDUP
extern char *strdup(const char *s1);
#endif
#if !defined(snprintf) && defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
extern int snprintf (char *s, size_t n, const char *format, ...);
#endif


#define xmlFree free
#define xmlMalloc malloc
#define xmlMemStrdup strdup


#ifdef Unix
#include <R_ext/eventloop.h>

/* modified from src/unix/sys-std.c  */
static int
setSelectMask(InputHandler *handlers, fd_set *readMask)
{
    int maxfd = -1;
    InputHandler *tmp = handlers;
    FD_ZERO(readMask);

    while(tmp) {
	if(tmp->fileDescriptor > 0) {
	    FD_SET(tmp->fileDescriptor, readMask);
	    maxfd = maxfd < tmp->fileDescriptor ? tmp->fileDescriptor : maxfd;
	}
	tmp = tmp->next;
    }

    return(maxfd);
}
#endif

/**
 * A couple of portability macros
 */
#ifndef _WINSOCKAPI_
#define closesocket(s) close(s)
#define SOCKET int
#endif

#define FTP_COMMAND_OK		200
#define FTP_SYNTAX_ERROR	500
#define FTP_GET_PASSWD		331
#define FTP_BUF_SIZE		1024

#define XML_NANO_MAX_URLBUF	4096

typedef struct RxmlNanoFTPCtxt {
    char *protocol;	/* the protocol name */
    char *hostname;	/* the host name */
    int port;		/* the port */
    char *path;		/* the path within the URL */
    char *user;		/* user string */
    char *passwd;	/* passwd string */
    struct sockaddr_in ftpAddr; /* the socket address struct */
    int passive;	/* currently we support only passive !!! */
    SOCKET controlFd;	/* the file descriptor for the control socket */
    SOCKET dataFd;	/* the file descriptor for the data socket */
    int state;		/* WRITE / READ / CLOSED */
    int returnValue;	/* the protocol return value */
    DLsize_t contentLength;
    /* buffer for data received from the control connection */
    char controlBuf[FTP_BUF_SIZE + 1];
    int controlBufIndex;
    int controlBufUsed;
    int controlBufAnswer;
} RxmlNanoFTPCtxt, *RxmlNanoFTPCtxtPtr;

static int initialized = 0;
static char *proxy = NULL;	/* the proxy name if any */
static int proxyPort = 0;	/* the proxy port if any */
static char *proxyUser = NULL;	/* user for proxy authentication */
static char *proxyPasswd = NULL;/* passwd for proxy authentication */
static int proxyType = 0;	/* uses TYPE or a@b ? */
static unsigned int timeout = 60;/* the select() timeout in seconds */

static void RxmlNanoFTPScanProxy(const char *URL);
static int  RxmlNanoFTPCheckResponse(void *ctx);
static void RxmlNanoFTPFreeCtxt(void * ctx);

/**
 * RxmlNanoFTPInit:
 *
 * Initialize the FTP protocol layer.
 * Currently it just checks for proxy informations,
 * and get the hostname
 */

static void
RxmlNanoFTPInit(void) {
    const char *env;
#ifdef _WINSOCKAPI_
    WSADATA wsaData;
#endif

    if (initialized)
	return;

#ifdef _WINSOCKAPI_
    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
	return;
#endif

    proxyPort = 21;
    env = getenv("no_proxy");
    if (env && ((env[0] == '*' ) && (env[1] == 0)))
	return;
    env = getenv("ftp_proxy");
    if (env != NULL) {
	RxmlNanoFTPScanProxy(env);
    } else {
	env = getenv("FTP_PROXY");
	if (env != NULL) {
	    RxmlNanoFTPScanProxy(env);
	}
    }
    env = getenv("ftp_proxy_user");
    if (env != NULL) {
	proxyUser = xmlMemStrdup(env);
    }
    env = getenv("ftp_proxy_password");
    if (env != NULL) {
	proxyPasswd = xmlMemStrdup(env);
    }
    initialized = 1;
}

/**
 * RxmlNanoFTPCleanup:
 *
 * Cleanup the FTP protocol layer. This cleanup proxy informations.
 */

void
RxmlNanoFTPCleanup(void) {
    if (proxy != NULL) {
	xmlFree(proxy);
	proxy = NULL;
    }
    if (proxyUser != NULL) {
	xmlFree(proxyUser);
	proxyUser = NULL;
    }
    if (proxyPasswd != NULL) {
	xmlFree(proxyPasswd);
	proxyPasswd = NULL;
    }
#ifdef _WINSOCKAPI_
    if (initialized)
	WSACleanup();
#endif
    initialized = 0;
}


/**
 * RxmlNanoFTPScanURL:
 * @ctx:  an FTP context
 * @URL:  The URL used to initialize the context
 *
 * (Re)Initialize an FTP context by parsing the URL and finding
 * the protocol host port and path it indicates.
 */

static void
RxmlNanoFTPScanURL(void *ctx, const char *URL) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    const char *cur = URL;
    char buf[XML_NANO_MAX_URLBUF];
    int indx = 0;
    int port = 0;

    /*
     * Clear any existing data from the context
     */
    if (ctxt->protocol != NULL) {
	xmlFree(ctxt->protocol);
	ctxt->protocol = NULL;
    }
    if (ctxt->hostname != NULL) {
	xmlFree(ctxt->hostname);
	ctxt->hostname = NULL;
    }
    if (ctxt->path != NULL) {
	xmlFree(ctxt->path);
	ctxt->path = NULL;
    }
    if (URL == NULL) return;
    buf[indx] = 0;
    while (*cur != 0 && (indx < XML_NANO_MAX_URLBUF-1)) {
	if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
	    buf[indx] = 0;
	    ctxt->protocol = xmlMemStrdup(buf);
	    indx = 0;
	    cur += 3;
	    break;
	}
	buf[indx++] = *cur++;
    }
    if (*cur == 0) return;

    buf[indx] = 0;
    /* allow user@ and user:pass@ forms */
    {
	const char *p = strchr(cur, '@');
	if(p) {
	    while(indx < XML_NANO_MAX_URLBUF-1) {
		if(cur[0] == ':' || cur[0] == '@') break;
		buf[indx++] = *cur++;
	    }
	    buf[indx] = 0;
	    ctxt->user = xmlMemStrdup(buf);
	    indx = 0;
	    if(cur[0] == ':') {
		cur++;
		while(indx < XML_NANO_MAX_URLBUF-1) {
		    if(cur[0] == '@') break;
		    buf[indx++] = *cur++;
		}
		buf[indx] = 0;
		ctxt->passwd = xmlMemStrdup(buf);
		indx = 0;
	    }
	    cur = p+1;
	}
    }

    while (indx < XML_NANO_MAX_URLBUF-1) {
	if (cur[0] == ':') {
	    buf[indx] = 0;
	    ctxt->hostname = xmlMemStrdup(buf);
	    indx = 0;
	    cur += 1;
	    while ((*cur >= '0') && (*cur <= '9')) {
		port *= 10;
		port += *cur - '0';
		cur++;
	    }
	    if (port != 0) ctxt->port = port;
	    while ((cur[0] != '/') && (*cur != 0))
		cur++;
	    break;
	}
	if ((*cur == '/') || (*cur == 0)) {
	    buf[indx] = 0;
	    ctxt->hostname = xmlMemStrdup(buf);
	    indx = 0;
	    break;
	}
	buf[indx++] = *cur++;
    }
    if (*cur == 0)
	ctxt->path = xmlMemStrdup("/");
    else {
	indx = 0;
	buf[indx] = 0;
	while (*cur != 0 && (indx < XML_NANO_MAX_URLBUF-1))
	    buf[indx++] = *cur++;
	buf[indx] = 0;
	ctxt->path = xmlMemStrdup(buf);
    }
}

/**
 * RxmlNanoFTPScanProxy:
 * @URL:  The proxy URL used to initialize the proxy context
 *
 * (Re)Initialize the FTP Proxy context by parsing the URL and finding
 * the protocol host port it indicates.
 * Should be like ftp://myproxy/ or ftp://myproxy:3128/
 * A NULL URL cleans up proxy informations.
 */

static void
RxmlNanoFTPScanProxy(const char *URL) {
    const char *cur = URL;
    char buf[XML_NANO_MAX_URLBUF];
    int indx = 0;
    int port = 0;

    if (proxy != NULL) {
	xmlFree(proxy);
	proxy = NULL;
    }
    /*if (proxyPort != 0) {
	proxyPort = 0;
	}*/
    if (URL == NULL)
	RxmlMessage(0, _("removing FTP proxy info"));
    else
	RxmlMessage(1, _("using FTP proxy '%s'"), URL);
    if (URL == NULL) return;
    buf[indx] = 0;
    while (*cur != 0 && (indx < XML_NANO_MAX_URLBUF - 1)) {
	if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {
	    buf[indx] = 0;
	    indx = 0;
	    cur += 3;
	    break;
	}
	buf[indx++] = *cur++;
    }
    if (*cur == 0) return;

    buf[indx] = 0;
    while (indx < XML_NANO_MAX_URLBUF-1) {
	if (cur[0] == ':') {
	    buf[indx] = 0;
	    proxy = xmlMemStrdup(buf);
	    indx = 0;
	    cur += 1;
	    while ((*cur >= '0') && (*cur <= '9')) {
		port *= 10;
		port += *cur - '0';
		cur++;
	    }
	    if (port != 0) proxyPort = port;
	    while ((cur[0] != '/') && (*cur != 0))
		cur++;
	    break;
	}
	if ((*cur == '/') || (*cur == 0)) {
	    buf[indx] = 0;
	    proxy = xmlMemStrdup(buf);
	    indx = 0;
	    break;
	}
	buf[indx++] = *cur++;
    }
}

/**
 * RxmlNanoFTPNewCtxt:
 * @URL:  The URL used to initialize the context
 *
 * Allocate and initialize a new FTP context.
 *
 * Returns an FTP context or NULL in case of error.
 */

static void*
RxmlNanoFTPNewCtxt(const char *URL) {
    RxmlNanoFTPCtxtPtr ret;

    ret = (RxmlNanoFTPCtxtPtr) xmlMalloc(sizeof(RxmlNanoFTPCtxt));
    if (ret == NULL) {
	RxmlMessage(1, "error allocating FTP context");
	return(NULL);
    }

    memset(ret, 0, sizeof(RxmlNanoFTPCtxt));
    ret->port = 21;
    ret->passive = 1;
    ret->returnValue = 0;
    ret->contentLength = -1;
    ret->controlBufIndex = 0;
    ret->controlBufUsed = 0;
    ret->controlFd = -1;

    if (URL != NULL)
	RxmlNanoFTPScanURL(ret, URL);

    return(ret);
}

/**
 * RxmlNanoFTPFreeCtxt:
 * @ctx:  an FTP context
 *
 * Frees the context after closing the connection.
 */

static void
RxmlNanoFTPFreeCtxt(void * ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    if (ctxt == NULL) return;
    if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
    if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
    if (ctxt->path != NULL) xmlFree(ctxt->path);
    ctxt->passive = 1;
    if (ctxt->controlFd > 2) closesocket(ctxt->controlFd);
    ctxt->controlFd = -1;
    ctxt->controlBufIndex = -1;
    ctxt->controlBufUsed = -1;
    xmlFree(ctxt);
}

/**
 * RxmlNanoFTPParseResponse:
 * @buf:  the buffer containing the response
 * @len:  the buffer length
 *
 * Parsing of the server answer, we just extract the code.
 *
 * returns 0 for errors
 *     +XXX for last line of response
 *     -XXX for response to be continued
 */
static int
RxmlNanoFTPParseResponse(char *buf, int len) {
    int val = 0;

    if (len < 3) return(-1);
    if ((*buf >= '0') && (*buf <= '9'))
	val = val * 10 + (*buf - '0');
    else
	return(0);
    buf++;
    if ((*buf >= '0') && (*buf <= '9'))
	val = val * 10 + (*buf - '0');
    else
	return(0);
    buf++;
    if ((*buf >= '0') && (*buf <= '9'))
	val = val * 10 + (*buf - '0');
    else
	return(0);
    buf++;
    if (*buf == '-')
	return(-val);
    return(val);
}

/**
 * RxmlNanoFTPGetMore:
 * @ctx:  an FTP context
 *
 * Read more information from the FTP control connection
 * Returns the number of bytes read, < 0 indicates an error
 */
static int
RxmlNanoFTPGetMore(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    int len;
    int size;

    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);

    if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
	RxmlMessage(0, "RxmlNanoFTPGetMore : controlBufIndex = %d",
		    ctxt->controlBufIndex);
	return(-1);
    }

    if ((ctxt->controlBufUsed < 0) || (ctxt->controlBufUsed > FTP_BUF_SIZE)) {
	RxmlMessage(0, "RxmlNanoFTPGetMore : controlBufUsed = %d",
	    ctxt->controlBufUsed);
	return(-1);
    }
    if (ctxt->controlBufIndex > ctxt->controlBufUsed) {
	RxmlMessage(0, "RxmlNanoFTPGetMore : controlBufIndex > controlBufUsed %d > %d\n",
	    ctxt->controlBufIndex, ctxt->controlBufUsed);
	return(-1);
    }

    /*
     * First pack the control buffer
     */
    if (ctxt->controlBufIndex > 0) {
	memmove(&ctxt->controlBuf[0], &ctxt->controlBuf[ctxt->controlBufIndex],
		ctxt->controlBufUsed - ctxt->controlBufIndex);
	ctxt->controlBufUsed -= ctxt->controlBufIndex;
	ctxt->controlBufIndex = 0;
    }
    size = FTP_BUF_SIZE - ctxt->controlBufUsed;
    if (size == 0) {
	RxmlMessage(0, "RxmlNanoFTPGetMore : buffer full %d", ctxt->controlBufUsed);
	return(0);
    }

    /*
     * Read the amount left on the control connection
     */
    if ((len = (int) recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
			  size, 0)) < 0) {
	RxmlMessage(1, "recv failed");
	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	ctxt->controlFd = -1;
	return(-1);
    }
    RxmlMessage(0, "RxmlNanoFTPGetMore : read %d [%d - %d]", len,
		ctxt->controlBufUsed, ctxt->controlBufUsed + len);
    ctxt->controlBufUsed += len;
    ctxt->controlBuf[ctxt->controlBufUsed] = 0;

    return(len);
}

static void RxmlFindLength(void *ctxt, char *ptr)
{
    char *p, *q;

    p = strrchr(ptr, '(');
    if(p) {
	p++;
	q = strchr(p, 'b');
	if(!q || strncmp(q, "bytes)", 6) != 0) return;
	// was atoi, but DLsize_t may be > long, let alone int.
	char *endp;
	double len = strtod(p, &endp);
	if(len >= 0)
	    ((RxmlNanoFTPCtxtPtr) ctxt)->contentLength = (DLsize_t) len;
    }
}

/**
 * RxmlNanoFTPReadResponse:
 * @ctx:  an FTP context
 *
 * Read the response from the FTP server after a command.
 * Returns the code number
 */
static int
RxmlNanoFTPReadResponse(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    char *ptr, *end;
    int len;
    int res = -1, cur = -1;

    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);

get_more:
    /*
     * Assumes everything up to controlBuf[controlBufIndex] has been read
     * and analyzed.
     */
    len = RxmlNanoFTPGetMore(ctx);
    if (len < 0) {
	return(-1);
    }
    if ((ctxt->controlBufUsed == 0) && (len == 0)) {
	return(-1);
    }
    ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
    end = &ctxt->controlBuf[ctxt->controlBufUsed];

    RxmlMessage(0, "\n<<<\n%s\n--\n", ptr);
    while (ptr < end) {
	cur = RxmlNanoFTPParseResponse(ptr, (int)(end - ptr));
	if (cur > 0) {
	    /*
	     * Successfully scanned the control code, scratch
	     * till the end of the line, but keep the index to be
	     * able to analyze the result if needed.
	     */
	    res = cur;
	    if(res == 150) RxmlFindLength(ctxt, ptr);
	    ptr += 3;
	    ctxt->controlBufAnswer = (int)(ptr - ctxt->controlBuf);
	    while ((ptr < end) && (*ptr != '\n')) ptr++;
	    if (*ptr == '\n') ptr++;
	    if (*ptr == '\r') ptr++;
	    break;
	}
	while ((ptr < end) && (*ptr != '\n')) ptr++;
	if (ptr >= end) {
	    ctxt->controlBufIndex = ctxt->controlBufUsed;
	    goto get_more;
	}
	if (*ptr != '\r') ptr++;
    }

    if (res < 0) goto get_more;
    ctxt->controlBufIndex = (int)(ptr - ctxt->controlBuf);
    ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
    RxmlMessage(1, "\n---\n%s\n--\n", ptr);
    RxmlMessage(1, "Got %d", res);
    return(res / 100);
}

/**
 * RxmlNanoFTPGetResponse:
 * @ctx:  an FTP context
 *
 * Get the response from the FTP server after a command.
 * Returns the code number
 */

static int
RxmlNanoFTPGetResponse(void *ctx) {
    int res;

    res = RxmlNanoFTPReadResponse(ctx);

    return(res);
}

/**
 * RxmlNanoFTPCheckResponse:
 * @ctx:  an FTP context
 *
 * Check if there is a response from the FTP server after a command.
 * Returns the code number, or 0
 */

static int
RxmlNanoFTPCheckResponse(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    fd_set rfd;
    struct timeval tv;

    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&rfd);
    FD_SET(ctxt->controlFd, &rfd);
    /* no-block select call */
    switch(R_SelectEx(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv, NULL)) {
	case 0:
	    return(0);
	case -1:
#ifdef DEBUG_FTP
	    perror("select");
#endif
	    return(-1);

    }

    return(RxmlNanoFTPReadResponse(ctx));
}

/**
 * Send the user authentication
 */

static int
RxmlNanoFTPSendUser(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    char buf[200];
    int len;
    int res;

    if (ctxt->user == NULL)
	snprintf(buf, sizeof(buf), "USER anonymous\r\n");
    else
	snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
    buf[sizeof(buf) - 1] = 0;
    len = (int) strlen(buf);
    RxmlMessage(0, "%s", buf);
    res = (int) send(ctxt->controlFd, buf, len, 0);
    if (res < 0) {
	RxmlMessage(1, "send failed");
	return(res);
    }
    return(0);
}

/**
 * Send the password authentication
 */

static int
RxmlNanoFTPSendPasswd(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    char buf[200];
    int len;
    int res;

    if (ctxt->passwd == NULL)
	snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
    else
	snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
    buf[sizeof(buf) - 1] = 0;
    len = (int) strlen(buf);
    RxmlMessage(0, "%s", buf);
    res = (int) send(ctxt->controlFd, buf, len, 0);
    if (res < 0) {
	RxmlMessage(1, "send failed");
	return(res);
    }
    return(0);
}

/**
 * RxmlNanoFTPQuit:
 * @ctx:  an FTP context
 *
 * Send a QUIT command to the server
 *
 * Returns -1 in case of error, 0 otherwise
 */


static int
RxmlNanoFTPQuit(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    char buf[200];
    int len;

    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);

    snprintf(buf, sizeof(buf), "QUIT\r\n");
    len = (int) strlen(buf);
    RxmlMessage(0, "%s", buf);
    send(ctxt->controlFd, buf, len, 0);
    return(0);
}

/**
 * RxmlNanoFTPConnect:
 * @ctx:  an FTP context
 *
 * Tries to open a control connection
 *
 * Returns -1 in case of error, 0 otherwise
 */

static int
RxmlNanoFTPConnect(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    struct hostent *hp;
    int port;
    int res;

    if (ctxt == NULL)
	return(-1);
    if (ctxt->hostname == NULL)
	return(-1);

    /*
     * do the blocking DNS query.
     */
    if (proxy)
	hp = gethostbyname(proxy);
    else
	hp = gethostbyname(ctxt->hostname);
    if (hp == NULL) {
	RxmlMessage(1, _("cannot resolve host"));
	return(-1);
    }


    /*
     * Prepare the socket
     */
    memset(&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
    ctxt->ftpAddr.sin_family = AF_INET;
    if ((unsigned int)hp->h_length > sizeof(struct in_addr)) {
	RxmlMessage(1, _("Malformed address resolved"));
	return(-1);
    }
    memcpy(&ctxt->ftpAddr.sin_addr, hp->h_addr_list[0], hp->h_length);
    if (proxy) {
	port = proxyPort;
    } else {
	port = ctxt->port;
    }
    if (port == 0)
	port = 21;
    ctxt->ftpAddr.sin_port = htons(port);
    ctxt->controlFd = socket(AF_INET, SOCK_STREAM, 0);
    if (ctxt->controlFd < 0)
	return(-1);

    /*
     * Do the connect.
     */
    if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
		sizeof(struct sockaddr_in)) < 0) {
	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	ctxt->controlFd = -1;
	RxmlMessage(1, _("failed to connect to server"));
	return(-1);
    }

    /*
     * Wait for the HELLO from the server.
     */
    res = RxmlNanoFTPGetResponse(ctxt);
    if (res != 2) {
	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	ctxt->controlFd = -1;
	RxmlMessage(1, _("failed to get response from server"));
	return(-1);
    }

    /*
     * State diagram for the login operation on the FTP server
     *
     * Reference: RFC 959
     *
     *                       1
     * +---+   USER    +---+------------->+---+
     * | B |---------->| W | 2       ---->| E |
     * +---+           +---+------  |  -->+---+
     *                  | |       | | |
     *                3 | | 4,5   | | |
     *    --------------   -----  | | |
     *   |                      | | | |
     *   |                      | | | |
     *   |                 ---------  |
     *   |               1|     | |   |
     *   V                |     | |   |
     * +---+   PASS    +---+ 2  |  ------>+---+
     * |   |---------->| W |------------->| S |
     * +---+           +---+   ---------->+---+
     *                  | |   | |     |
     *                3 | |4,5| |     |
     *    --------------   --------   |
     *   |                    | |  |  |
     *   |                    | |  |  |
     *   |                 -----------
     *   |             1,3|   | |  |
     *   V                |  2| |  |
     * +---+   ACCT    +---+--  |   ----->+---+
     * |   |---------->| W | 4,5 -------->| F |
     * +---+           +---+------------->+---+
     *
     * Of course in case of using a proxy this get really nasty and is not
     * standardized at all :-(
     */
    if (proxy) {
	int len;
	char buf[400];

	if (proxyUser != NULL) {
	    /*
	     * We need proxy auth
	     */
	    snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
	    buf[sizeof(buf) - 1] = 0;
	    len = (int) strlen(buf);
	    RxmlMessage(0, "%s", buf);
	    res = (int) send(ctxt->controlFd, buf, len, 0);
	    if (res < 0) {
		RxmlMessage(1, "send failed");
		closesocket(ctxt->controlFd);
		ctxt->controlFd = -1;
		return(res);
	    }
	    res = RxmlNanoFTPGetResponse(ctxt);
	    switch (res) {
		case 2:
		    if (proxyPasswd == NULL)
			break;
		case 3:
		    if (proxyPasswd != NULL)
			snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
		    else
			snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
		    buf[sizeof(buf) - 1] = 0;
		    len = (int) strlen(buf);
		    RxmlMessage(0, "%s", buf);
		    res = (int) send(ctxt->controlFd, buf, len, 0);
		    if (res < 0) {
			RxmlMessage(1, "send failed");
			closesocket(ctxt->controlFd);
			ctxt->controlFd = -1;
			return(res);
		    }
		    res = RxmlNanoFTPGetResponse(ctxt);
		    if (res > 3) {
			closesocket(ctxt->controlFd);
			ctxt->controlFd = -1;
			return(-1);
		    }
		    break;
		case 1:
		    break;
		case 4:
		case 5:
		case -1:
		default:
		    closesocket(ctxt->controlFd);
		    ctxt->controlFd = -1;
		    return(-1);
	    }
	}

	/*
	 * We assume we don't need more authentication to the proxy
	 * and that it succeeded :-\
	 */
	switch (proxyType) {
	    case 0:
		/* we will try in sequence */
	    case 1:
		/* Using SITE command */
		snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
		buf[sizeof(buf) - 1] = 0;
		len = (int) strlen(buf);
		RxmlMessage(0, "%s", buf);
		res = (int) send(ctxt->controlFd, buf, len, 0);
		if (res < 0) {
		    RxmlMessage(1, "send failed");
		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
		    ctxt->controlFd = -1;
		    return(res);
		}
		res = RxmlNanoFTPGetResponse(ctxt);
		if (res == 2) {
		    /* we assume it worked :-\ 1 is error for SITE command */
		    proxyType = 1;
		    break;
		}
		if (proxyType == 1) {
		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
		    ctxt->controlFd = -1;
		    return(-1);
		}
	    case 2:
		/* USER user@host command */
		if (ctxt->user == NULL)
		    snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
				   ctxt->hostname);
		else
		    snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
				   ctxt->user, ctxt->hostname);
		buf[sizeof(buf) - 1] = 0;
		len = (int) strlen(buf);
		RxmlMessage(0, "%s", buf);
		res = (int) send(ctxt->controlFd, buf, len, 0);
		if (res < 0) {
		    RxmlMessage(1, "send failed");
		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
		    ctxt->controlFd = -1;
		    return(res);
		}
		res = RxmlNanoFTPGetResponse(ctxt);
		if ((res == 1) || (res == 2)) {
		    /* we assume it worked :-\ */
		    proxyType = 2;
		    return(0);
		}
		if (ctxt->passwd == NULL)
		    snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
		else

		    snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
		buf[sizeof(buf) - 1] = 0;
		len = (int) strlen(buf);
		RxmlMessage(0, "%s", buf);
		res = (int) send(ctxt->controlFd, buf, len, 0);
		if (res < 0) {
		    RxmlMessage(1, "send failed");
		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
		    ctxt->controlFd = -1;
		    return(res);
		}
		res = RxmlNanoFTPGetResponse(ctxt);
		if ((res == 1) || (res == 2)) {
		    /* we assume it worked :-\ */
		    proxyType = 2;
		    return(0);
		}
		if (proxyType == 2) {
		    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
		    ctxt->controlFd = -1;
		    return(-1);
		}
	    case 3:
		/*
		 * If you need support for other Proxy authentication scheme
		 * send the code or at least the sequence in use.
		 */
	    default:
		closesocket(ctxt->controlFd); ctxt->controlFd = -1;
		ctxt->controlFd = -1;
		return(-1);
	}
    }
    /*
     * Non-proxy handling.
     */
    res = RxmlNanoFTPSendUser(ctxt);
    if (res < 0) {
	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	ctxt->controlFd = -1;
	return(-1);
    }
    res = RxmlNanoFTPGetResponse(ctxt);
    switch (res) {
	case 2:
	    return(0);
	case 3:
	    break;
	case 1:
	case 4:
	case 5:
	case -1:
	default:
	    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	    ctxt->controlFd = -1;
	    return(-1);
    }
    res = RxmlNanoFTPSendPasswd(ctxt);
    if (res < 0) {
	closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	ctxt->controlFd = -1;
	return(-1);
    }
    res = RxmlNanoFTPGetResponse(ctxt);
    switch (res) {
	case 2:
	    break;
	case 3:
	    RxmlMessage(1, "FTP server asking for ACCNT on anonymous");
	case 1:
	case 4:
	case 5:
	case -1:
	default:
	    closesocket(ctxt->controlFd); ctxt->controlFd = -1;
	    ctxt->controlFd = -1;
	    return(-1);
    }

    return(0);
}



/**
 * RxmlNanoFTPGetConnection:
 * @ctx:  an FTP context
 *
 * Try to open a data connection to the server. Currently only
 * passive mode is supported.
 *
 * Returns -1 in case of error, 0 otherwise
 */

static int
RxmlNanoFTPGetConnection(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    char buf[200], *cur;
    int len, i;
    int res;
    unsigned char ad[6], *adp, *portp;
    unsigned int temp[6];
    struct sockaddr_in dataAddr;
    R_SOCKLEN_T dataAddrLen;

    ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ctxt->dataFd < 0) {
	RxmlMessage(2, _("RxmlNanoFTPGetConnection: failed to create socket"));
	return(-1);
    }
    dataAddrLen = sizeof(dataAddr);
    memset(&dataAddr, 0, dataAddrLen);
    dataAddr.sin_family = AF_INET;

    if (ctxt->passive) {
	snprintf (buf, sizeof(buf), "PASV\r\n");
	len = (int) strlen(buf);
#ifdef DEBUG_FTP
	RxmlMessage(0, "%s", buf);
#endif
	res = (int) send(ctxt->controlFd, buf, len, 0);
	if (res < 0) {
	    RxmlMessage(1, "send failed");
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return(res);
	}
	res = RxmlNanoFTPReadResponse(ctx);
	if (res != 2) {
	    if (res == 5) {
		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
		return(-1);
	    } else {
		/*
		 * retry with an active connection
		 */
		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
		ctxt->passive = 0;
	    }
	}
	cur = &ctxt->controlBuf[ctxt->controlBufAnswer];
	while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++;
	if (sscanf(cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
		    &temp[3], &temp[4], &temp[5]) != 6) {
	    RxmlMessage(1, "Invalid answer to PASV");
	    if (ctxt->dataFd != -1) {
		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    }
	    return(-1);
	}
	for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
	memcpy(&dataAddr.sin_addr, &ad[0], 4);
	memcpy(&dataAddr.sin_port, &ad[4], 2);
	if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
	    RxmlMessage(2, _("failed to create a data connection"));
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return (-1);
	}
    } else {
	getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
	dataAddr.sin_port = 0;
	if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
	    RxmlMessage(2, _("failed to bind a port"));
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return (-1);
	}
	getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);

	if (listen(ctxt->dataFd, 1) < 0) {
	    RxmlMessage(2, _("could not listen on port %d"),
			ntohs(dataAddr.sin_port));
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return (-1);
	}
	adp = (unsigned char *) &dataAddr.sin_addr;
	portp = (unsigned char *) &dataAddr.sin_port;
	snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
	       adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
	       portp[0] & 0xff, portp[1] & 0xff);
	buf[sizeof(buf) - 1] = 0;
	len = (int) strlen(buf);
#ifdef DEBUG_FTP
	RxmlMessage(1, "%s", buf);
#endif

	res = (int) send(ctxt->controlFd, buf, len, 0);
	if (res < 0) {
	    RxmlMessage(1, "send failed");
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return(res);
	}
	res = RxmlNanoFTPGetResponse(ctxt);
	if (res != 2) {
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return(-1);
	}
    }
    return(ctxt->dataFd);

}



/**
 * RxmlNanoFTPGetSocket:
 * @ctx:  an FTP context
 * @filename:  the file to retrieve (or NULL if path is in context).
 *
 * Initiate fetch of the given file from the server.
 *
 * Returns the socket for the data connection, or <0 in case of error
 */


static int
RxmlNanoFTPGetSocket(void *ctx, const char *filename) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    char buf[300];
    int res, len;
    if (ctx == NULL)
	return(-1);
    if ((filename == NULL) && (ctxt->path == NULL))
	return(-1);
    ctxt->dataFd = RxmlNanoFTPGetConnection(ctxt);
    if (ctxt->dataFd == -1)
	return(-1);

    snprintf(buf, sizeof(buf), "TYPE I\r\n");
    len = (int) strlen(buf);
#ifdef DEBUG_FTP
    RxmlMessage(0, "%s", buf);
#endif
    res = (int) send(ctxt->controlFd, buf, len, 0);
    if (res < 0) {
	RxmlMessage(1, "send failed");
	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	return(res);
    }
    res = RxmlNanoFTPReadResponse(ctxt);
    if (res != 2) {
	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	return(-res);
    }
    if (filename == NULL)
	snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
    else
	snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
    buf[sizeof(buf) - 1] = 0;
    len = (int) strlen(buf);
#ifdef DEBUG_FTP
    RxmlMessage(0, "%s", buf);
#endif
    res = (int) send(ctxt->controlFd, buf, len, 0);
    if (res < 0) {
	RxmlMessage(1, "send failed");
	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	return(res);
    }
    res = RxmlNanoFTPReadResponse(ctxt);
    if (res != 1) {
	closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	return(-res);
    }
    return(ctxt->dataFd);
}

/**
 * RxmlNanoFTPRead:
 * @ctx:  the FTP context
 * @dest:  a buffer
 * @len:  the buffer length
 *
 * This function tries to read @len bytes from the existing FTP connection
 * and saves them in @dest. This is a non-blocking version of the original.
 *
 * Returns the number of byte read. 0 is an indication of an end of connection.
 *         -1 indicates a parameter error.
 */

int
RxmlNanoFTPRead(void *ctx, void *dest, int len)
{
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;
    int got = 0, res;
    fd_set rfd;
    struct timeval tv;
    double used = 0.0;

    if (ctx == NULL) return(-1);
    if (ctxt->dataFd < 0) return(0);
    if (dest == NULL) return(-1);
    if (len <= 0) return(0);
    while(1) {
	int maxfd = 0;
	R_ProcessEvents();
#ifdef Unix
	if(R_wait_usec > 0) {
	    tv.tv_sec = 0;
	    tv.tv_usec = R_wait_usec;
	} else {
	    tv.tv_sec = 1;
	    tv.tv_usec = 0;
	}
#elif defined(Win32)
	tv.tv_sec = 0;
	tv.tv_usec = 2e5;
#else
	tv.tv_sec = 1;
	tv.tv_usec = 0;
#endif

#ifdef Unix
	maxfd = setSelectMask(R_InputHandlers, &rfd);
#else
	FD_ZERO(&rfd);
#endif
	FD_SET(ctxt->dataFd, &rfd);
	if(maxfd < ctxt->dataFd) maxfd = ctxt->dataFd;

	res = R_SelectEx(maxfd + 1, &rfd, NULL, NULL, &tv, NULL);

	if (res < 0) { /* socket error */
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return(-1);
	}
	if (res == 0) { /* timeout, no data available yet */
	    used += tv.tv_sec + 1e-6 * tv.tv_usec;
	    if (used > timeout) return(0);
	    res = RxmlNanoFTPCheckResponse(ctxt);
	    if (res < 0) {
		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
		ctxt->dataFd = -1;
		return(-1);
	    }
	    if (res == 2) {
		closesocket(ctxt->dataFd); ctxt->dataFd = -1;
		return(0);
	    }
	    continue;
	}
	/* one or more fd is ready */
#ifdef Unix
	if(!FD_ISSET(ctxt->dataFd, &rfd) || res > 1) {
	    /* was one of the extras */
	    InputHandler *what;
	    what = getSelectedHandler(R_InputHandlers, &rfd);
	    if(what != NULL) what->handler((void*) NULL);
	    continue;
	}
#endif

	/* was the socket */
	got = (int) recv(ctxt->dataFd, dest, len, 0);
	if (got < 0) {
	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;
	    return(-1);
	} else  break;
    }
    return got;
}


/**
 * RxmlNanoFTPOpen:
 * @URL: the URL to the resource
 *
 * Start to fetch the given ftp:// resource
 *
 * Returns an FTP context, or NULL
 */

void*
RxmlNanoFTPOpen(const char *URL) {
    RxmlNanoFTPCtxtPtr ctxt;
    int sock;

    RxmlNanoFTPInit();
    if (URL == NULL) return(NULL);
    if (strncmp("ftp://", URL, 6)) return(NULL);

    ctxt = (RxmlNanoFTPCtxtPtr) RxmlNanoFTPNewCtxt(URL);
    if (ctxt == NULL) return(NULL);
    if (RxmlNanoFTPConnect(ctxt) < 0) {
	RxmlNanoFTPFreeCtxt(ctxt);
	return(NULL);
    }
    sock = RxmlNanoFTPGetSocket(ctxt, ctxt->path);
    if (sock < 0) {
	RxmlNanoFTPFreeCtxt(ctxt);
	return(NULL);
    }
    return(ctxt);
}

/**
 * RxmlNanoFTPClose:
 * @ctx: an FTP context
 *
 * Close the connection and both control and transport
 *
 * Returns -1 incase of error, 0 otherwise
 */

int
RxmlNanoFTPClose(void *ctx) {
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;

    if (ctxt == NULL)
	return(-1);

    if (ctxt->dataFd >= 0) {
	closesocket(ctxt->dataFd);
	ctxt->dataFd = -1;
    }
    if (ctxt->controlFd >= 0) {
	RxmlNanoFTPQuit(ctxt);
	closesocket(ctxt->controlFd);
	ctxt->controlFd = -1;
    }
    RxmlNanoFTPFreeCtxt(ctxt);
    return(0);
}

/**
 * RxmlNanoFTPTimeout:
 * @delay:  the delay in seconds
 *
 * Set the FTP timeout, (default is 60secs).  0 means immediate
 * return, while -1 infinite.
 */

void
RxmlNanoFTPTimeout(int delay) {
    timeout = (unsigned int) delay;
}

DLsize_t
RxmlNanoFTPContentLength(void *ctx)
{
    RxmlNanoFTPCtxtPtr ctxt = (RxmlNanoFTPCtxtPtr) ctx;

    if (ctxt == NULL) return(-1);
    return(ctxt->contentLength);
}
