1ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/*
2ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * nanoftp.c: basic FTP client support
3ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
4ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *  Reference: RFC 959
5ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
6ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
7ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef TESTING
8ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define STANDALONE
9ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define HAVE_STDLIB_H
10ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define HAVE_UNISTD_H
11ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define HAVE_SYS_SOCKET_H
12ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define HAVE_NETINET_IN_H
13ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define HAVE_NETDB_H
14ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define HAVE_SYS_TIME_H
15ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#else /* TESTING */
16ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define NEED_SOCKETS
17ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif /* TESTING */
18ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
19ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define IN_LIBXML
20ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "libxml.h"
21ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
22ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef LIBXML_FTP_ENABLED
23ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <string.h>
24ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
25ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_STDLIB_H
26ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <stdlib.h>
27ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
28ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_UNISTD_H
29ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <unistd.h>
30ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
31ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_SYS_SOCKET_H
32ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <sys/socket.h>
33ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
34ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_NETINET_IN_H
35ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <netinet/in.h>
36ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
37ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_ARPA_INET_H
38ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <arpa/inet.h>
39ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
40ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_NETDB_H
41ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <netdb.h>
42ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
43ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_FCNTL_H
4494442ad4107000e6d49f9b85a46a591495a57632Selim Gurun#include <fcntl.h>
45ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
46ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_ERRNO_H
47ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <errno.h>
48ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
49ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_SYS_TIME_H
50ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <sys/time.h>
51ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
52ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_SYS_SELECT_H
53ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <sys/select.h>
54ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
55ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_SYS_SOCKET_H
56ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <sys/socket.h>
57ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
58ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_SYS_TYPES_H
59ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <sys/types.h>
60ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
61ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_STRINGS_H
62ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <strings.h>
63ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
64ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
65ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/xmlmemory.h>
66ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/parser.h>
67ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/xmlerror.h>
68ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/uri.h>
69ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/nanoftp.h>
70ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <libxml/globals.h>
71ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
72ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/* #define DEBUG_FTP 1  */
73ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef STANDALONE
74ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifndef DEBUG_FTP
75ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define DEBUG_FTP 1
76ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
77ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
78ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
79ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
80ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#if defined(__MINGW32__) || defined(_WIN32_WCE)
81df143a5041f03a22808b59c76698770b74692815Selim Gurun#ifndef _WINSOCKAPI_
82ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define _WINSOCKAPI_
83df143a5041f03a22808b59c76698770b74692815Selim Gurun#endif
84ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <wsockcompat.h>
85ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <winsock2.h>
86ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#undef XML_SOCKLEN_T
87ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define XML_SOCKLEN_T unsigned int
88ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
89ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
90ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
91ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * A couple portability macros
92ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
93ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifndef _WINSOCKAPI_
9460a4c356ee9ce5e9ccb23347c0381f0436192691Patrick Scott#if !defined(__BEOS__) || defined(__HAIKU__)
95ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define closesocket(s) close(s)
96ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
97ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
98ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
99ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef __BEOS__
100ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifndef PF_INET
101ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define PF_INET AF_INET
102ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
103ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
104ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
105ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef _AIX
106ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef HAVE_BROKEN_SS_FAMILY
107ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define ss_family __ss_family
108ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
109ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
110ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
111ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifndef XML_SOCKLEN_T
112ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define XML_SOCKLEN_T unsigned int
113ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
114ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
115ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define FTP_COMMAND_OK		200
116ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define FTP_SYNTAX_ERROR	500
117ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define FTP_GET_PASSWD		331
118ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define FTP_BUF_SIZE		1024
119ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
120ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define XML_NANO_MAX_URLBUF	4096
121ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
122ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projecttypedef struct xmlNanoFTPCtxt {
123ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *protocol;	/* the protocol name */
124ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *hostname;	/* the host name */
125ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int port;		/* the port */
126ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *path;		/* the path within the URL */
127ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *user;		/* user string */
128ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *passwd;	/* passwd string */
129ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
130ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct sockaddr_storage ftpAddr; /* this is large enough to hold IPv6 address*/
131ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#else
132ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct sockaddr_in ftpAddr; /* the socket address struct */
133ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
134ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int passive;	/* currently we support only passive !!! */
135ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    SOCKET controlFd;	/* the file descriptor for the control socket */
136ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    SOCKET dataFd;	/* the file descriptor for the data socket */
137ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int state;		/* WRITE / READ / CLOSED */
138ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int returnValue;	/* the protocol return value */
139ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /* buffer for data received from the control connection */
140ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char controlBuf[FTP_BUF_SIZE + 1];
141ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int controlBufIndex;
142ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int controlBufUsed;
143ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int controlBufAnswer;
144ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project} xmlNanoFTPCtxt, *xmlNanoFTPCtxtPtr;
145ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
146ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int initialized = 0;
147ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic char *proxy = NULL;	/* the proxy name if any */
148ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int proxyPort = 0;	/* the proxy port if any */
149ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic char *proxyUser = NULL;	/* user for proxy authentication */
150ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic char *proxyPasswd = NULL;/* passwd for proxy authentication */
151ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int proxyType = 0;	/* uses TYPE or a@b ? */
152ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
153ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
154ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic
155ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint have_ipv6(void) {
156ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int s;
157ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
158ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    s = socket (AF_INET6, SOCK_STREAM, 0);
159ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (s != -1) {
160ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	close (s);
161ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return (1);
162ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
163ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return (0);
164ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
165ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
166ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
167ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
168ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlFTPErrMemory:
169ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @extra:  extra informations
170ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
171ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Handle an out of memory condition
172ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
173ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic void
174ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlFTPErrMemory(const char *extra)
175ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project{
176ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    __xmlSimpleError(XML_FROM_FTP, XML_ERR_NO_MEMORY, NULL, NULL, extra);
177ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
178ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
179ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
180ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPInit:
181ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
182ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Initialize the FTP protocol layer.
183ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Currently it just checks for proxy informations,
184ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * and get the hostname
185ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
186ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
187ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid
188ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPInit(void) {
189ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    const char *env;
190ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef _WINSOCKAPI_
19194442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    WSADATA wsaData;
192ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
193ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
194ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (initialized)
195ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return;
196ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
197ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef _WINSOCKAPI_
198ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
199ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return;
200ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
201ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
202ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    proxyPort = 21;
203ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    env = getenv("no_proxy");
204ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (env && ((env[0] == '*' ) && (env[1] == 0)))
205ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return;
206ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    env = getenv("ftp_proxy");
207ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (env != NULL) {
208ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPScanProxy(env);
209ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else {
210ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	env = getenv("FTP_PROXY");
211ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (env != NULL) {
212ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    xmlNanoFTPScanProxy(env);
213ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
214ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
215ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    env = getenv("ftp_proxy_user");
216ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (env != NULL) {
217ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyUser = xmlMemStrdup(env);
218ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
219ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    env = getenv("ftp_proxy_password");
220ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (env != NULL) {
221ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyPasswd = xmlMemStrdup(env);
222ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
223ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    initialized = 1;
224ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
225ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
226ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
227ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPCleanup:
228ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
229ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Cleanup the FTP protocol layer. This cleanup proxy informations.
230ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
231ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
232ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid
233ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPCleanup(void) {
234ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxy != NULL) {
235ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(proxy);
236ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxy = NULL;
237ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
238ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxyUser != NULL) {
239ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(proxyUser);
240ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyUser = NULL;
241ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
242ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxyPasswd != NULL) {
243ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(proxyPasswd);
244ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyPasswd = NULL;
245ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
246ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef _WINSOCKAPI_
247ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (initialized)
248ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	WSACleanup();
249ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
250ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    initialized = 0;
251ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
252ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
253ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
254ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPProxy:
255ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @host:  the proxy host name
256ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @port:  the proxy port
257ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @user:  the proxy user name
258ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @passwd:  the proxy password
259ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @type:  the type of proxy 1 for using SITE, 2 for USER a@b
260ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
261ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Setup the FTP proxy informations.
262ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * This can also be done by using ftp_proxy ftp_proxy_user and
263ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * ftp_proxy_password environment variables.
264ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
265ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
266ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid
267ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPProxy(const char *host, int port, const char *user,
268ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	        const char *passwd, int type) {
269ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxy != NULL) {
270ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(proxy);
271ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxy = NULL;
272ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
273ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxyUser != NULL) {
274ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(proxyUser);
275ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyUser = NULL;
276ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
277ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxyPasswd != NULL) {
278ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(proxyPasswd);
279ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyPasswd = NULL;
280ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
281ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (host)
282ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxy = xmlMemStrdup(host);
283ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (user)
284ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyUser = xmlMemStrdup(user);
285ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (passwd)
286ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyPasswd = xmlMemStrdup(passwd);
287ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    proxyPort = port;
288ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    proxyType = type;
289ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
290ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
291ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
292ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPScanURL:
293ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
294ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @URL:  The URL used to initialize the context
295ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
296ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * (Re)Initialize an FTP context by parsing the URL and finding
297ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * the protocol host port and path it indicates.
298ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
299ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
300ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic void
301ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPScanURL(void *ctx, const char *URL) {
302ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
303ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlURIPtr uri;
304ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
305ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
306ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Clear any existing data from the context
307ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
30894442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if (ctxt->protocol != NULL) {
309ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlFree(ctxt->protocol);
310ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->protocol = NULL;
311ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
31294442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if (ctxt->hostname != NULL) {
313ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlFree(ctxt->hostname);
314ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->hostname = NULL;
315ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
31694442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if (ctxt->path != NULL) {
317ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlFree(ctxt->path);
318ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->path = NULL;
319ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
320ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (URL == NULL) return;
321ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
322ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    uri = xmlParseURIRaw(URL, 1);
323ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (uri == NULL)
324ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return;
325ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
326ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((uri->scheme == NULL) || (uri->server == NULL)) {
327ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFreeURI(uri);
328ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return;
329ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
33094442ad4107000e6d49f9b85a46a591495a57632Selim Gurun
331ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->protocol = xmlMemStrdup(uri->scheme);
332ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->hostname = xmlMemStrdup(uri->server);
333ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (uri->path != NULL)
334ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->path = xmlMemStrdup(uri->path);
335ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
336ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->path = xmlMemStrdup("/");
337ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (uri->port != 0)
338ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->port = uri->port;
339ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
340ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (uri->user != NULL) {
341ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	char *cptr;
342ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((cptr=strchr(uri->user, ':')) == NULL)
343ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ctxt->user = xmlMemStrdup(uri->user);
344ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	else {
345ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ctxt->user = (char *)xmlStrndup((xmlChar *)uri->user,
346ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			    (cptr - uri->user));
347ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ctxt->passwd = xmlMemStrdup(cptr+1);
348ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
349ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
350ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
351ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlFreeURI(uri);
352ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
353ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
354ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
355ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
356ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPUpdateURL:
357ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
358ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @URL:  The URL used to update the context
359ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
360ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Update an FTP context by parsing the URL and finding
36194442ad4107000e6d49f9b85a46a591495a57632Selim Gurun * new path it indicates. If there is an error in the
362ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * protocol, hostname, port or other information, the
363ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * error is raised. It indicates a new connection has to
364ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * be established.
365ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
366ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns 0 if Ok, -1 in case of error (other host).
367ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
368ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
369ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
370ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPUpdateURL(void *ctx, const char *URL) {
371ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
372ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlURIPtr uri;
373ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
374ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (URL == NULL)
375ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
376ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL)
377ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
378ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->protocol == NULL)
379ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
380ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->hostname == NULL)
381ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
382ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
383ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    uri = xmlParseURIRaw(URL, 1);
384ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (uri == NULL)
385ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
386ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
387ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((uri->scheme == NULL) || (uri->server == NULL)) {
388ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFreeURI(uri);
389ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
390ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
391ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((strcmp(ctxt->protocol, uri->scheme)) ||
392ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	(strcmp(ctxt->hostname, uri->server)) ||
393ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	((uri->port != 0) && (ctxt->port != uri->port))) {
394ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFreeURI(uri);
395ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
396ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
397ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
398ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (uri->port != 0)
399ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->port = uri->port;
400ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
401ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->path != NULL) {
402ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(ctxt->path);
403ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->path = NULL;
404ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
405ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
40694442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if (uri->path == NULL)
407ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        ctxt->path = xmlMemStrdup("/");
408ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
409ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->path = xmlMemStrdup(uri->path);
410ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
411ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlFreeURI(uri);
412ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
413ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
414ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
415ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
416ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
417ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPScanProxy:
418ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @URL:  The proxy URL used to initialize the proxy context
419ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
420ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * (Re)Initialize the FTP Proxy context by parsing the URL and finding
421ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * the protocol host port it indicates.
422ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Should be like ftp://myproxy/ or ftp://myproxy:3128/
423ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * A NULL URL cleans up proxy informations.
424ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
425ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
426ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid
427ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPScanProxy(const char *URL) {
428ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlURIPtr uri;
429ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
43094442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if (proxy != NULL) {
431ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlFree(proxy);
432ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxy = NULL;
433ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
434ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    proxyPort = 0;
435ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
436ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
437ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (URL == NULL)
438ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlGenericError(xmlGenericErrorContext,
439ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"Removing FTP proxy info\n");
440ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
441ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlGenericError(xmlGenericErrorContext,
442ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"Using FTP proxy %s\n", URL);
443ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
444ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (URL == NULL) return;
445ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
446ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    uri = xmlParseURIRaw(URL, 1);
447ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((uri == NULL) || (uri->scheme == NULL) ||
448ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	(strcmp(uri->scheme, "ftp")) || (uri->server == NULL)) {
449ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, XML_FTP_URL_SYNTAX, "Syntax Error\n");
450ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (uri != NULL)
451ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    xmlFreeURI(uri);
452ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return;
453ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
45494442ad4107000e6d49f9b85a46a591495a57632Selim Gurun
455ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    proxy = xmlMemStrdup(uri->server);
456ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (uri->port != 0)
457ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	proxyPort = uri->port;
458ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
459ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlFreeURI(uri);
460ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
461ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
462ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
463ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPNewCtxt:
464ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @URL:  The URL used to initialize the context
465ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
466ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Allocate and initialize a new FTP context.
467ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
468ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns an FTP context or NULL in case of error.
469ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
470ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
471ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid*
472ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPNewCtxt(const char *URL) {
473ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ret;
474ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *unescaped;
475ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
476ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ret = (xmlNanoFTPCtxtPtr) xmlMalloc(sizeof(xmlNanoFTPCtxt));
477ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ret == NULL) {
478ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlFTPErrMemory("allocating FTP context");
479ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(NULL);
480ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
481ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
482ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    memset(ret, 0, sizeof(xmlNanoFTPCtxt));
483ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ret->port = 21;
484ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ret->passive = 1;
485ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ret->returnValue = 0;
486ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ret->controlBufIndex = 0;
487ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ret->controlBufUsed = 0;
488df143a5041f03a22808b59c76698770b74692815Selim Gurun    ret->controlFd = INVALID_SOCKET;
489ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
490ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    unescaped = xmlURIUnescapeString(URL, 0, NULL);
491ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (unescaped != NULL) {
492ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPScanURL(ret, unescaped);
493ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlFree(unescaped);
494ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else if (URL != NULL)
495ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPScanURL(ret, URL);
496ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
497ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(ret);
498ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
499ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
500ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
501ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPFreeCtxt:
502ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
503ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
504ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Frees the context after closing the connection.
505ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
506ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
507ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid
508ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPFreeCtxt(void * ctx) {
509ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
510ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL) return;
511ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
512ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
513ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->path != NULL) xmlFree(ctxt->path);
514ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->passive = 1;
515df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt->controlFd != INVALID_SOCKET) closesocket(ctxt->controlFd);
516df143a5041f03a22808b59c76698770b74692815Selim Gurun    ctxt->controlFd = INVALID_SOCKET;
517ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->controlBufIndex = -1;
518ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->controlBufUsed = -1;
519ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlFree(ctxt);
520ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
521ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
522ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
523ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPParseResponse:
524ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @buf:  the buffer containing the response
525ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @len:  the buffer length
52694442ad4107000e6d49f9b85a46a591495a57632Selim Gurun *
527ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Parsing of the server answer, we just extract the code.
528ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
529ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * returns 0 for errors
530ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *     +XXX for last line of response
531ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *     -XXX for response to be continued
532ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
533ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int
534ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPParseResponse(char *buf, int len) {
535ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int val = 0;
536ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
537ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (len < 3) return(-1);
53894442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if ((*buf >= '0') && (*buf <= '9'))
539ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        val = val * 10 + (*buf - '0');
540ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
541ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(0);
542ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf++;
54394442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if ((*buf >= '0') && (*buf <= '9'))
544ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        val = val * 10 + (*buf - '0');
545ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
546ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(0);
547ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf++;
54894442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if ((*buf >= '0') && (*buf <= '9'))
549ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        val = val * 10 + (*buf - '0');
550ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
551ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(0);
552ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf++;
55394442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if (*buf == '-')
554ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(-val);
555ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(val);
556ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
557ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
558ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
559ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPGetMore:
560ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
561ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
562ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Read more information from the FTP control connection
563ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the number of bytes read, < 0 indicates an error
564ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
565ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int
566ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPGetMore(void *ctx) {
567ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
568ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len;
569ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int size;
570ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
571df143a5041f03a22808b59c76698770b74692815Selim Gurun    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
572ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
573ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
574ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
575ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlGenericError(xmlGenericErrorContext,
576ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"xmlNanoFTPGetMore : controlBufIndex = %d\n",
577ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		ctxt->controlBufIndex);
578ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
579ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
580ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
581ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
582ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((ctxt->controlBufUsed < 0) || (ctxt->controlBufUsed > FTP_BUF_SIZE)) {
583ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
584ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlGenericError(xmlGenericErrorContext,
585ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"xmlNanoFTPGetMore : controlBufUsed = %d\n",
586ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		ctxt->controlBufUsed);
587ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
588ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
589ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
590ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->controlBufIndex > ctxt->controlBufUsed) {
591ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
592ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlGenericError(xmlGenericErrorContext,
593ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"xmlNanoFTPGetMore : controlBufIndex > controlBufUsed %d > %d\n",
594ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	       ctxt->controlBufIndex, ctxt->controlBufUsed);
595ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
596ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
597ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
598ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
599ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
600ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * First pack the control buffer
601ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
602ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->controlBufIndex > 0) {
603ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	memmove(&ctxt->controlBuf[0], &ctxt->controlBuf[ctxt->controlBufIndex],
604ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		ctxt->controlBufUsed - ctxt->controlBufIndex);
605ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->controlBufUsed -= ctxt->controlBufIndex;
606ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->controlBufIndex = 0;
607ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
608ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    size = FTP_BUF_SIZE - ctxt->controlBufUsed;
609ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (size == 0) {
610ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
611ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlGenericError(xmlGenericErrorContext,
612ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"xmlNanoFTPGetMore : buffer full %d \n", ctxt->controlBufUsed);
613ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
614ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(0);
615ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
616ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
617ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
618ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Read the amount left on the control connection
619ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
620ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
621ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    size, 0)) < 0) {
622ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "recv failed");
623df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
624df143a5041f03a22808b59c76698770b74692815Selim Gurun        ctxt->controlFd = INVALID_SOCKET;
625ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(-1);
626ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
627ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
628ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext,
629ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    "xmlNanoFTPGetMore : read %d [%d - %d]\n", len,
630ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	   ctxt->controlBufUsed, ctxt->controlBufUsed + len);
631ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
632ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->controlBufUsed += len;
633ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->controlBuf[ctxt->controlBufUsed] = 0;
634ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
635ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(len);
636ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
637ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
638ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
639ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPReadResponse:
640ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
641ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
642ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Read the response from the FTP server after a command.
643ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the code number
644ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
645ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int
646ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPReadResponse(void *ctx) {
647ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
648ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *ptr, *end;
649ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len;
650ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res = -1, cur = -1;
651ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
652df143a5041f03a22808b59c76698770b74692815Selim Gurun    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
653ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
654ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectget_more:
655ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
656ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Assumes everything up to controlBuf[controlBufIndex] has been read
657ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * and analyzed.
658ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
659ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = xmlNanoFTPGetMore(ctx);
660ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (len < 0) {
661ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(-1);
662ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
663ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((ctxt->controlBufUsed == 0) && (len == 0)) {
664ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(-1);
665ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
666ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
667ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    end = &ctxt->controlBuf[ctxt->controlBufUsed];
668ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
669ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
670ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext,
671ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    "\n<<<\n%s\n--\n", ptr);
672ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
673ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    while (ptr < end) {
674ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        cur = xmlNanoFTPParseResponse(ptr, end - ptr);
675ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (cur > 0) {
676ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    /*
677ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     * Successfully scanned the control code, scratch
678ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     * till the end of the line, but keep the index to be
679ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     * able to analyze the result if needed.
680ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     */
681ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    res = cur;
682ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ptr += 3;
683ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ctxt->controlBufAnswer = ptr - ctxt->controlBuf;
684ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    while ((ptr < end) && (*ptr != '\n')) ptr++;
685ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*ptr == '\n') ptr++;
686ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*ptr == '\r') ptr++;
687ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    break;
688ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
689ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((ptr < end) && (*ptr != '\n')) ptr++;
690ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (ptr >= end) {
691ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ctxt->controlBufIndex = ctxt->controlBufUsed;
692ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    goto get_more;
693ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
694ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*ptr != '\r') ptr++;
695ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
696ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
697ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) goto get_more;
698ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->controlBufIndex = ptr - ctxt->controlBuf;
699ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
700ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
701ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "\n---\n%s\n--\n", ptr);
702ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
703ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
704ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
705ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "Got %d\n", res);
706ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
707ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(res / 100);
708ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
709ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
710ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
711ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPGetResponse:
712ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
713ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
714ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Get the response from the FTP server after a command.
715ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the code number
716ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
717ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
718ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
719ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPGetResponse(void *ctx) {
720ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
721ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
722ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPReadResponse(ctx);
723ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
724ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(res);
725ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
726ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
727ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
728ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPCheckResponse:
729ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
730ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
731ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Check if there is a response from the FTP server after a command.
732ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the code number, or 0
733ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
734ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
735ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
736ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPCheckResponse(void *ctx) {
737ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
738ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    fd_set rfd;
739ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct timeval tv;
740ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
741df143a5041f03a22808b59c76698770b74692815Selim Gurun    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
742ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    tv.tv_sec = 0;
743ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    tv.tv_usec = 0;
744ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    FD_ZERO(&rfd);
745ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    FD_SET(ctxt->controlFd, &rfd);
746ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    switch(select(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv)) {
747ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 0:
748ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(0);
749ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case -1:
750ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "select");
751ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
75294442ad4107000e6d49f9b85a46a591495a57632Selim Gurun
753ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
754ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
755ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(xmlNanoFTPReadResponse(ctx));
756ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
757ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
758ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
759ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Send the user authentication
760ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
761ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
762ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int
763ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPSendUser(void *ctx) {
764ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
765ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[200];
766ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len;
767ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
768ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
769ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->user == NULL)
770ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "USER anonymous\r\n");
771ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
772ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
773ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf[sizeof(buf) - 1] = 0;
774ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
775ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
776ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf);
777ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
778ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
779ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
780ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
781ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(res);
782ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
783ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
784ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
785ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
786ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
787ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Send the password authentication
788ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
789ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
790ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int
791ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPSendPasswd(void *ctx) {
792ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
793ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[200];
794ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len;
795ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
796ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
797ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->passwd == NULL)
798ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
799ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
800ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
801ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf[sizeof(buf) - 1] = 0;
802ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
803ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
804ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf);
805ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
806ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
807ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
808ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
809ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(res);
810ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
811ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
812ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
813ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
814ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
815ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPQuit:
816ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
817ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
818ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Send a QUIT command to the server
819ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
820ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 in case of error, 0 otherwise
821ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
822ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
823ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
824ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
825ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPQuit(void *ctx) {
826ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
827ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[200];
828ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len, res;
829ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
830df143a5041f03a22808b59c76698770b74692815Selim Gurun    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
831ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
832ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    snprintf(buf, sizeof(buf), "QUIT\r\n");
833ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
834ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
835ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf); /* Just to be consistent, even though we know it can't have a % in it */
836ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
837ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
838ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
839ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
840ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(res);
841ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
842ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
843ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
844ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
845ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
846ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPConnect:
847ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
848ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
849ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Tries to open a control connection
850ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
851ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 in case of error, 0 otherwise
852ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
853ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
854ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
855ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPConnect(void *ctx) {
856ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
857ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct hostent *hp;
858ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int port;
859ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
860ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int addrlen = sizeof (struct sockaddr_in);
861ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
862ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL)
863ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
864ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->hostname == NULL)
865ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
866ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
867ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
868ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * do the blocking DNS query.
869ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
870ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxy) {
871ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        port = proxyPort;
872ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else {
873ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	port = ctxt->port;
874ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
875ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (port == 0)
876ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	port = 21;
877ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
878ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    memset (&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
879ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
880ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
881ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (have_ipv6 ()) {
882ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	struct addrinfo hints, *tmp, *result;
883ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
884ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	result = NULL;
885ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	memset (&hints, 0, sizeof(hints));
886ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	hints.ai_socktype = SOCK_STREAM;
887ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
888ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (proxy) {
889ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (getaddrinfo (proxy, NULL, &hints, &result) != 0) {
890ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		__xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");
891ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return (-1);
892ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
893ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
894ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	else
895ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (getaddrinfo (ctxt->hostname, NULL, &hints, &result) != 0) {
896ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		__xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");
897ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return (-1);
898ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
899ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
900ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	for (tmp = result; tmp; tmp = tmp->ai_next)
901ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (tmp->ai_family == AF_INET || tmp->ai_family == AF_INET6)
902ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		break;
903ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
904ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (!tmp) {
905ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (result)
906ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		freeaddrinfo (result);
907ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");
908ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return (-1);
909ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
910ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) {
911ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");
912ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return (-1);
913ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
914ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (tmp->ai_family == AF_INET6) {
915ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen);
916ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ((struct sockaddr_in6 *) &ctxt->ftpAddr)->sin6_port = htons (port);
917ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ctxt->controlFd = socket (AF_INET6, SOCK_STREAM, 0);
918ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
919ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	else {
920ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen);
921ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ((struct sockaddr_in *) &ctxt->ftpAddr)->sin_port = htons (port);
922ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);
923ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
924ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	addrlen = tmp->ai_addrlen;
925ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	freeaddrinfo (result);
926ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
927ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
928ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
929ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    {
930ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (proxy)
931ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    hp = gethostbyname (proxy);
932ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	else
933ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    hp = gethostbyname (ctxt->hostname);
934ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (hp == NULL) {
935ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname failed");
936ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return (-1);
937ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
938ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((unsigned int) hp->h_length >
939ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    sizeof(((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr)) {
940ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");
941ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return (-1);
942ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
943ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
944ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	/*
945ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * Prepare the socket
946ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 */
947ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	((struct sockaddr_in *)&ctxt->ftpAddr)->sin_family = AF_INET;
948ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	memcpy (&((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr,
949ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		hp->h_addr_list[0], hp->h_length);
95094442ad4107000e6d49f9b85a46a591495a57632Selim Gurun	((struct sockaddr_in *)&ctxt->ftpAddr)->sin_port =
95194442ad4107000e6d49f9b85a46a591495a57632Selim Gurun             (unsigned short)htons ((unsigned short)port);
952ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);
953ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	addrlen = sizeof (struct sockaddr_in);
954ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
955ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
956df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt->controlFd == INVALID_SOCKET) {
957ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "socket failed");
958ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        return(-1);
959ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
960ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
961ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
962ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Do the connect.
963ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
964ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
965ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    addrlen) < 0) {
966ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "Failed to create a connection");
967df143a5041f03a22808b59c76698770b74692815Selim Gurun        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
968df143a5041f03a22808b59c76698770b74692815Selim Gurun        ctxt->controlFd = INVALID_SOCKET;
969ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
970ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
971ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
972ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
973ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Wait for the HELLO from the server.
974ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
975ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPGetResponse(ctxt);
976ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res != 2) {
977df143a5041f03a22808b59c76698770b74692815Selim Gurun        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
978df143a5041f03a22808b59c76698770b74692815Selim Gurun        ctxt->controlFd = INVALID_SOCKET;
979ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
980ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
981ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
982ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
983ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * State diagram for the login operation on the FTP server
984ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *
985ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Reference: RFC 959
986ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *
987ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *                       1
988ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * +---+   USER    +---+------------->+---+
989ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * | B |---------->| W | 2       ---->| E |
990ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * +---+           +---+------  |  -->+---+
991ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *                  | |       | | |
992ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *                3 | | 4,5   | | |
993ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *    --------------   -----  | | |
994ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |                      | | | |
995ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |                      | | | |
996ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |                 ---------  |
997ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |               1|     | |   |
998ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   V                |     | |   |
999ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * +---+   PASS    +---+ 2  |  ------>+---+
1000ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * |   |---------->| W |------------->| S |
1001ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * +---+           +---+   ---------->+---+
1002ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *                  | |   | |     |
1003ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *                3 | |4,5| |     |
1004ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *    --------------   --------   |
1005ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |                    | |  |  |
1006ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |                    | |  |  |
1007ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |                 -----------
1008ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   |             1,3|   | |  |
1009ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *   V                |  2| |  |
1010ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * +---+   ACCT    +---+--  |   ----->+---+
1011ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * |   |---------->| W | 4,5 -------->| F |
1012ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * +---+           +---+------------->+---+
1013ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *
1014ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Of course in case of using a proxy this get really nasty and is not
1015ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * standardized at all :-(
1016ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
1017ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (proxy) {
1018ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        int len;
1019ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	char buf[400];
1020ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1021ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        if (proxyUser != NULL) {
1022ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    /*
1023ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     * We need proxy auth
1024ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     */
1025ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
1026ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project            buf[sizeof(buf) - 1] = 0;
1027ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project            len = strlen(buf);
1028ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1029ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    xmlGenericError(xmlGenericErrorContext, "%s", buf);
1030ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1031ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    res = send(ctxt->controlFd, buf, len, 0);
1032ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (res < 0) {
1033ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		__xmlIOErr(XML_FROM_FTP, 0, "send failed");
1034ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		closesocket(ctxt->controlFd);
1035df143a5041f03a22808b59c76698770b74692815Selim Gurun		ctxt->controlFd = INVALID_SOCKET;
1036ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	        return(res);
1037ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1038ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    res = xmlNanoFTPGetResponse(ctxt);
1039ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    switch (res) {
1040ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		case 2:
1041ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    if (proxyPasswd == NULL)
1042ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			break;
1043ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		case 3:
1044ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    if (proxyPasswd != NULL)
1045ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
1046ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    else
1047ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
1048ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                    buf[sizeof(buf) - 1] = 0;
1049ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                    len = strlen(buf);
1050ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1051ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    xmlGenericError(xmlGenericErrorContext, "%s", buf);
1052ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1053ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    res = send(ctxt->controlFd, buf, len, 0);
1054ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    if (res < 0) {
1055ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			__xmlIOErr(XML_FROM_FTP, 0, "send failed");
1056ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			closesocket(ctxt->controlFd);
1057df143a5041f03a22808b59c76698770b74692815Selim Gurun			ctxt->controlFd = INVALID_SOCKET;
1058ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			return(res);
1059ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    }
1060ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    res = xmlNanoFTPGetResponse(ctxt);
1061ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    if (res > 3) {
1062ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			closesocket(ctxt->controlFd);
1063df143a5041f03a22808b59c76698770b74692815Selim Gurun			ctxt->controlFd = INVALID_SOCKET;
1064ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			return(-1);
1065ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    }
1066ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    break;
1067ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		case 1:
1068ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    break;
1069ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		case 4:
1070ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		case 5:
1071ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		case -1:
1072ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		default:
1073ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    closesocket(ctxt->controlFd);
1074df143a5041f03a22808b59c76698770b74692815Selim Gurun		    ctxt->controlFd = INVALID_SOCKET;
1075ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(-1);
1076ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1077ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1078ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1079ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	/*
1080ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * We assume we don't need more authentication to the proxy
1081ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 * and that it succeeded :-\
1082ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	 */
1083ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	switch (proxyType) {
1084ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    case 0:
1085ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		/* we will try in sequence */
1086ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    case 1:
1087ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		/* Using SITE command */
1088ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
1089ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                buf[sizeof(buf) - 1] = 0;
1090ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                len = strlen(buf);
1091ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1092ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		xmlGenericError(xmlGenericErrorContext, "%s", buf);
1093ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1094ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		res = send(ctxt->controlFd, buf, len, 0);
1095ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (res < 0) {
1096ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1097df143a5041f03a22808b59c76698770b74692815Selim Gurun		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1098df143a5041f03a22808b59c76698770b74692815Selim Gurun		    ctxt->controlFd = INVALID_SOCKET;
1099ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(res);
1100ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1101ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		res = xmlNanoFTPGetResponse(ctxt);
1102ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (res == 2) {
1103ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    /* we assume it worked :-\ 1 is error for SITE command */
1104ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    proxyType = 1;
1105ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    break;
110694442ad4107000e6d49f9b85a46a591495a57632Selim Gurun		}
1107ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (proxyType == 1) {
1108df143a5041f03a22808b59c76698770b74692815Selim Gurun		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1109df143a5041f03a22808b59c76698770b74692815Selim Gurun		    ctxt->controlFd = INVALID_SOCKET;
1110ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(-1);
1111ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1112ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    case 2:
1113ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		/* USER user@host command */
1114ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (ctxt->user == NULL)
1115ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
1116ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			           ctxt->hostname);
1117ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		else
1118ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
1119ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			           ctxt->user, ctxt->hostname);
1120ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                buf[sizeof(buf) - 1] = 0;
1121ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                len = strlen(buf);
1122ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1123ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		xmlGenericError(xmlGenericErrorContext, "%s", buf);
1124ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1125ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		res = send(ctxt->controlFd, buf, len, 0);
1126ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (res < 0) {
1127ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1128df143a5041f03a22808b59c76698770b74692815Selim Gurun		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1129df143a5041f03a22808b59c76698770b74692815Selim Gurun		    ctxt->controlFd = INVALID_SOCKET;
1130ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(res);
1131ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1132ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		res = xmlNanoFTPGetResponse(ctxt);
1133ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if ((res == 1) || (res == 2)) {
1134ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    /* we assume it worked :-\ */
1135ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    proxyType = 2;
1136ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(0);
113794442ad4107000e6d49f9b85a46a591495a57632Selim Gurun		}
1138ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (ctxt->passwd == NULL)
1139ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
1140ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		else
1141ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
1142ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                buf[sizeof(buf) - 1] = 0;
1143ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project                len = strlen(buf);
1144ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1145ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		xmlGenericError(xmlGenericErrorContext, "%s", buf);
1146ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1147ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		res = send(ctxt->controlFd, buf, len, 0);
1148ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (res < 0) {
1149ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1150df143a5041f03a22808b59c76698770b74692815Selim Gurun		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1151df143a5041f03a22808b59c76698770b74692815Selim Gurun		    ctxt->controlFd = INVALID_SOCKET;
1152ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(res);
1153ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1154ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		res = xmlNanoFTPGetResponse(ctxt);
1155ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if ((res == 1) || (res == 2)) {
1156ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    /* we assume it worked :-\ */
1157ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    proxyType = 2;
1158ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(0);
1159ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1160ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		if (proxyType == 2) {
1161df143a5041f03a22808b59c76698770b74692815Selim Gurun		    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1162df143a5041f03a22808b59c76698770b74692815Selim Gurun		    ctxt->controlFd = INVALID_SOCKET;
1163ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    return(-1);
1164ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1165ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    case 3:
1166ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		/*
1167ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		 * If you need support for other Proxy authentication scheme
1168ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		 * send the code or at least the sequence in use.
1169ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		 */
1170ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    default:
1171df143a5041f03a22808b59c76698770b74692815Selim Gurun		closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1172df143a5041f03a22808b59c76698770b74692815Selim Gurun		ctxt->controlFd = INVALID_SOCKET;
1173ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return(-1);
1174ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1175ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1176ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
1177ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Non-proxy handling.
1178ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
1179ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPSendUser(ctxt);
1180ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1181df143a5041f03a22808b59c76698770b74692815Selim Gurun        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1182df143a5041f03a22808b59c76698770b74692815Selim Gurun        ctxt->controlFd = INVALID_SOCKET;
1183ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1184ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1185ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPGetResponse(ctxt);
1186ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    switch (res) {
1187ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 2:
1188ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(0);
1189ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 3:
1190ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    break;
1191ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 1:
1192ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 4:
1193ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 5:
1194ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        case -1:
1195ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	default:
1196df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1197df143a5041f03a22808b59c76698770b74692815Selim Gurun	    ctxt->controlFd = INVALID_SOCKET;
1198ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1199ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1200ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPSendPasswd(ctxt);
1201ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1202df143a5041f03a22808b59c76698770b74692815Selim Gurun        closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1203df143a5041f03a22808b59c76698770b74692815Selim Gurun        ctxt->controlFd = INVALID_SOCKET;
1204ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1205ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1206ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPGetResponse(ctxt);
1207ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    switch (res) {
1208ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 2:
1209ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    break;
1210ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 3:
1211ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, XML_FTP_ACCNT,
1212ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		       "FTP server asking for ACCNT on anonymous\n");
1213ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 1:
1214ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 4:
1215ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	case 5:
1216ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        case -1:
1217ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	default:
1218df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1219df143a5041f03a22808b59c76698770b74692815Selim Gurun	    ctxt->controlFd = INVALID_SOCKET;
1220ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1221ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1222ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1223ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
1224ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1225ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1226ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1227ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPConnectTo:
1228ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @server:  an FTP server name
1229ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @port:  the port (use 21 if 0)
1230ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1231ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Tries to open a control connection to the given server/port
1232ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1233ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns an fTP context or NULL if it failed
1234ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1235ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1236ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid*
1237ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPConnectTo(const char *server, int port) {
1238ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt;
1239ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
1240ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1241ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPInit();
124294442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    if (server == NULL)
1243ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(NULL);
1244ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (port <= 0)
1245ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(NULL);
1246ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(NULL);
1247ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->hostname = xmlMemStrdup(server);
1248ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (port != 0)
1249ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->port = port;
1250ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPConnect(ctxt);
1251ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1252ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPFreeCtxt(ctxt);
1253ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(NULL);
1254ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1255ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(ctxt);
1256ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1257ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1258ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1259ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPCwd:
1260ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
1261ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @directory:  a directory on the server
1262ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1263ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Tries to change the remote directory
1264ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1265ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, 1 if CWD worked, 0 if it failed
1266ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1267ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1268ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
1269ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPCwd(void *ctx, const char *directory) {
1270ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1271ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[400];
1272ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len;
1273ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
1274ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1275df143a5041f03a22808b59c76698770b74692815Selim Gurun    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
1276ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (directory == NULL) return 0;
1277ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1278ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
1279ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Expected response code for CWD:
1280ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *
1281ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * CWD
1282ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *     250
1283ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *     500, 501, 502, 421, 530, 550
1284ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
1285ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
1286ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf[sizeof(buf) - 1] = 0;
1287ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
1288ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1289ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf);
1290ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1291ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
1292ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1293ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
1294ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(res);
1295ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1296ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPGetResponse(ctxt);
1297ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res == 4) {
1298ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1299ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1300ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res == 2) return(1);
1301ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res == 5) {
1302ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(0);
1303ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1304ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
1305ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1306ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1307ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1308ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPDele:
1309ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
1310ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @file:  a file or directory on the server
1311ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1312ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Tries to delete an item (file or directory) from server
1313ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1314ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, 1 if DELE worked, 0 if it failed
1315ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1316ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1317ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
1318ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPDele(void *ctx, const char *file) {
1319ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1320ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[400];
1321ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len;
1322ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
1323ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1324df143a5041f03a22808b59c76698770b74692815Selim Gurun    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) || (file == NULL)) return(-1);
1325ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (file == NULL) return (0);
1326ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1327ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    /*
1328ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * Expected response code for DELE:
1329ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *
1330ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     * DELE
1331ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *       250
1332ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *       450, 550
1333ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     *       500, 501, 502, 421, 530
1334ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project     */
133594442ad4107000e6d49f9b85a46a591495a57632Selim Gurun
1336ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    snprintf(buf, sizeof(buf), "DELE %s\r\n", file);
1337ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf[sizeof(buf) - 1] = 0;
1338ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
1339ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1340ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf);
1341ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1342ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
1343ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1344ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
1345ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(res);
1346ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1347ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPGetResponse(ctxt);
1348ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res == 4) {
1349ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1350ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1351ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res == 2) return(1);
1352ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res == 5) {
1353ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(0);
1354ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1355ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
1356ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1357ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1358ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPGetConnection:
1359ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
1360ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1361ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Try to open a data connection to the server. Currently only
1362ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * passive mode is supported.
1363ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1364ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, 0 otherwise
1365ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1366ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1367df143a5041f03a22808b59c76698770b74692815Selim GurunSOCKET
1368ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPGetConnection(void *ctx) {
1369ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1370ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[200], *cur;
1371ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len, i;
1372ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
1373ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    unsigned char ad[6], *adp, *portp;
1374ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    unsigned int temp[6];
1375ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
1376ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct sockaddr_storage dataAddr;
1377ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#else
1378ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct sockaddr_in dataAddr;
1379ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1380ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    XML_SOCKLEN_T dataAddrLen;
1381ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1382df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt == NULL) return INVALID_SOCKET;
1383ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1384ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    memset (&dataAddr, 0, sizeof(dataAddr));
1385ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
1386ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((ctxt->ftpAddr).ss_family == AF_INET6) {
1387ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->dataFd = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1388ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	((struct sockaddr_in6 *)&dataAddr)->sin6_family = AF_INET6;
1389ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	dataAddrLen = sizeof(struct sockaddr_in6);
1390ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else
1391ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1392ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    {
1393ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1394ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	((struct sockaddr_in *)&dataAddr)->sin_family = AF_INET;
1395ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	dataAddrLen = sizeof (struct sockaddr_in);
1396ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1397ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1398df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt->dataFd == INVALID_SOCKET) {
1399ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "socket failed");
1400df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1401ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1402ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1403ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt->passive) {
1404ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
1405ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((ctxt->ftpAddr).ss_family == AF_INET6)
1406ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    snprintf (buf, sizeof(buf), "EPSV\r\n");
1407ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	else
1408ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1409ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    snprintf (buf, sizeof(buf), "PASV\r\n");
1410ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        len = strlen (buf);
1411ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1412ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlGenericError(xmlGenericErrorContext, "%s", buf);
1413ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1414ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	res = send(ctxt->controlFd, buf, len, 0);
1415ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res < 0) {
1416ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1417df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1418df143a5041f03a22808b59c76698770b74692815Selim Gurun	    return INVALID_SOCKET;
1419ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1420ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        res = xmlNanoFTPReadResponse(ctx);
1421ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res != 2) {
1422ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (res == 5) {
1423df143a5041f03a22808b59c76698770b74692815Selim Gurun	        closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1424df143a5041f03a22808b59c76698770b74692815Selim Gurun		return INVALID_SOCKET;
1425ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    } else {
1426ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		/*
1427ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		 * retry with an active connection
1428ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		 */
1429df143a5041f03a22808b59c76698770b74692815Selim Gurun	        closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1430ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	        ctxt->passive = 0;
1431ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1432ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
143394442ad4107000e6d49f9b85a46a591495a57632Selim Gurun	cur = &ctxt->controlBuf[ctxt->controlBufAnswer];
1434ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++;
1435ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
1436ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((ctxt->ftpAddr).ss_family == AF_INET6) {
1437ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (sscanf (cur, "%u", &temp[0]) != 1) {
1438ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		__xmlIOErr(XML_FROM_FTP, XML_FTP_EPSV_ANSWER,
1439ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			"Invalid answer to EPSV\n");
1440df143a5041f03a22808b59c76698770b74692815Selim Gurun		if (ctxt->dataFd != INVALID_SOCKET) {
1441df143a5041f03a22808b59c76698770b74692815Selim Gurun		    closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1442ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1443df143a5041f03a22808b59c76698770b74692815Selim Gurun		return INVALID_SOCKET;
1444ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1445ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    memcpy (&((struct sockaddr_in6 *)&dataAddr)->sin6_addr, &((struct sockaddr_in6 *)&ctxt->ftpAddr)->sin6_addr, sizeof(struct in6_addr));
1446ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ((struct sockaddr_in6 *)&dataAddr)->sin6_port = htons (temp[0]);
1447ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1448ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	else
1449ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1450ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	{
1451ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (sscanf (cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
1452ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		&temp[3], &temp[4], &temp[5]) != 6) {
1453ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		__xmlIOErr(XML_FROM_FTP, XML_FTP_PASV_ANSWER,
1454ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project			"Invalid answer to PASV\n");
1455df143a5041f03a22808b59c76698770b74692815Selim Gurun		if (ctxt->dataFd != INVALID_SOCKET) {
1456df143a5041f03a22808b59c76698770b74692815Selim Gurun		    closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1457ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		}
1458df143a5041f03a22808b59c76698770b74692815Selim Gurun		return INVALID_SOCKET;
1459ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1460ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
1461ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    memcpy (&((struct sockaddr_in *)&dataAddr)->sin_addr, &ad[0], 4);
1462ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    memcpy (&((struct sockaddr_in *)&dataAddr)->sin_port, &ad[4], 2);
1463ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1464ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1465ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
1466ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "Failed to create a data connection");
1467df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1468df143a5041f03a22808b59c76698770b74692815Selim Gurun	    return INVALID_SOCKET;
1469ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1470ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else {
1471ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
1472ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
1473ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((ctxt->ftpAddr).ss_family == AF_INET6)
1474ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ((struct sockaddr_in6 *)&dataAddr)->sin6_port = 0;
1475ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	else
1476ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1477ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    ((struct sockaddr_in *)&dataAddr)->sin_port = 0;
1478ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1479ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
1480ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "bind failed");
1481df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1482df143a5041f03a22808b59c76698770b74692815Selim Gurun	    return INVALID_SOCKET;
1483ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1484ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
1485ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1486ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (listen(ctxt->dataFd, 1) < 0) {
1487ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "listen failed");
1488df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1489df143a5041f03a22808b59c76698770b74692815Selim Gurun	    return INVALID_SOCKET;
1490ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1491ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef SUPPORT_IP6
1492ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((ctxt->ftpAddr).ss_family == AF_INET6) {
1493ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    char buf6[INET6_ADDRSTRLEN];
1494ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    inet_ntop (AF_INET6, &((struct sockaddr_in6 *)&dataAddr)->sin6_addr,
1495ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    buf6, INET6_ADDRSTRLEN);
1496ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    adp = (unsigned char *) buf6;
1497ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    portp = (unsigned char *) &((struct sockaddr_in6 *)&dataAddr)->sin6_port;
1498ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    snprintf (buf, sizeof(buf), "EPRT |2|%s|%s|\r\n", adp, portp);
1499ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        } else
1500ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1501ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	{
1502ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    adp = (unsigned char *) &((struct sockaddr_in *)&dataAddr)->sin_addr;
1503ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    portp = (unsigned char *) &((struct sockaddr_in *)&dataAddr)->sin_port;
1504ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    snprintf (buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
1505ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
1506ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    portp[0] & 0xff, portp[1] & 0xff);
1507ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1508ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1509ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        buf[sizeof(buf) - 1] = 0;
1510ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        len = strlen(buf);
1511ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1512ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlGenericError(xmlGenericErrorContext, "%s", buf);
1513ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1514ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1515ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	res = send(ctxt->controlFd, buf, len, 0);
1516ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res < 0) {
1517ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1518df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1519df143a5041f03a22808b59c76698770b74692815Selim Gurun	    return INVALID_SOCKET;
1520ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1521ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        res = xmlNanoFTPGetResponse(ctxt);
1522ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res != 2) {
1523df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1524df143a5041f03a22808b59c76698770b74692815Selim Gurun	    return INVALID_SOCKET;
1525ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        }
1526ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1527ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(ctxt->dataFd);
152894442ad4107000e6d49f9b85a46a591495a57632Selim Gurun
1529ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1530ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1531ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1532ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPCloseConnection:
1533ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
1534ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1535ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Close the data connection from the server
1536ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1537ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, 0 otherwise
1538ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1539ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1540ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
1541ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPCloseConnection(void *ctx) {
1542ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1543ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res;
1544ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    fd_set rfd, efd;
1545ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct timeval tv;
1546ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1547df143a5041f03a22808b59c76698770b74692815Selim Gurun    if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
1548ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1549df143a5041f03a22808b59c76698770b74692815Selim Gurun    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1550ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    tv.tv_sec = 15;
1551ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    tv.tv_usec = 0;
1552ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    FD_ZERO(&rfd);
1553ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    FD_SET(ctxt->controlFd, &rfd);
1554ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    FD_ZERO(&efd);
1555ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    FD_SET(ctxt->controlFd, &efd);
1556ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = select(ctxt->controlFd + 1, &rfd, NULL, &efd, &tv);
1557ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1558ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1559ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	perror("select");
1560ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1561df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1562ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1563ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1564ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res == 0) {
1565ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1566ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlGenericError(xmlGenericErrorContext,
1567ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"xmlNanoFTPCloseConnection: timeout\n");
1568ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1569df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1570ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else {
1571ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	res = xmlNanoFTPGetResponse(ctxt);
1572ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res != 2) {
1573df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1574ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1575ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1576ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1577ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
1578ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1579ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1580ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1581ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPParseList:
1582ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @list:  some data listing received from the server
1583ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @callback:  the user callback
1584ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @userData:  the user callback data
1585ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
158694442ad4107000e6d49f9b85a46a591495a57632Selim Gurun * Parse at most one entry from the listing.
1587ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1588ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, the length of data parsed otherwise
1589ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1590ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1591ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic int
1592ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPParseList(const char *list, ftpListCallback callback, void *userData) {
1593ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    const char *cur = list;
1594ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char filename[151];
1595ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char attrib[11];
1596ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char owner[11];
1597ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char group[11];
1598ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char month[4];
1599ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int year = 0;
1600ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int minute = 0;
1601ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int hour = 0;
1602ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int day = 0;
1603ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    unsigned long size = 0;
1604ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int links = 0;
1605ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int i;
1606ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1607ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (!strncmp(cur, "total", 5)) {
1608ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        cur += 5;
1609ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1610ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((*cur >= '0') && (*cur <= '9'))
1611ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    links = (links * 10) + (*cur++ - '0');
1612ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((*cur == ' ') || (*cur == '\n')  || (*cur == '\r'))
1613ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1614ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(cur - list);
1615ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else if (*list == '+') {
1616ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(0);
1617ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else {
1618ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((*cur == ' ') || (*cur == '\n')  || (*cur == '\r'))
1619ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1620ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1621ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	i = 0;
1622ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur != ' ') {
162394442ad4107000e6d49f9b85a46a591495a57632Selim Gurun	    if (i < 10)
1624ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		attrib[i++] = *cur;
1625ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1626ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*cur == 0) return(0);
1627ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1628ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	attrib[10] = 0;
1629ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1630ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1631ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((*cur >= '0') && (*cur <= '9'))
1632ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    links = (links * 10) + (*cur++ - '0');
1633ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1634ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1635ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	i = 0;
1636ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur != ' ') {
163794442ad4107000e6d49f9b85a46a591495a57632Selim Gurun	    if (i < 10)
1638ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		owner[i++] = *cur;
1639ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1640ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*cur == 0) return(0);
1641ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1642ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	owner[i] = 0;
1643ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1644ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1645ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	i = 0;
1646ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur != ' ') {
164794442ad4107000e6d49f9b85a46a591495a57632Selim Gurun	    if (i < 10)
1648ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		group[i++] = *cur;
1649ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1650ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*cur == 0) return(0);
1651ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1652ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	group[i] = 0;
1653ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1654ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1655ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((*cur >= '0') && (*cur <= '9'))
1656ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    size = (size * 10) + (*cur++ - '0');
1657ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1658ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1659ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	i = 0;
1660ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur != ' ') {
1661ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (i < 3)
1662ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		month[i++] = *cur;
1663ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1664ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*cur == 0) return(0);
1665ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1666ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	month[i] = 0;
1667ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1668ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1669ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        while ((*cur >= '0') && (*cur <= '9'))
1670ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    day = (day * 10) + (*cur++ - '0');
1671ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1672ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1673ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((cur[1] == 0) || (cur[2] == 0)) return(0);
1674ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((cur[1] == ':') || (cur[2] == ':')) {
1675ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    while ((*cur >= '0') && (*cur <= '9'))
1676ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		hour = (hour * 10) + (*cur++ - '0');
1677ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*cur == ':') cur++;
1678ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    while ((*cur >= '0') && (*cur <= '9'))
1679ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		minute = (minute * 10) + (*cur++ - '0');
1680ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	} else {
1681ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    while ((*cur >= '0') && (*cur <= '9'))
1682ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		year = (year * 10) + (*cur++ - '0');
1683ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1684ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while (*cur == ' ') cur++;
1685ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (*cur == 0) return(0);
1686ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	i = 0;
1687ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((*cur != '\n')  && (*cur != '\r')) {
1688ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (i < 150)
1689ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		filename[i++] = *cur;
1690ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1691ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (*cur == 0) return(0);
1692ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1693ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	filename[i] = 0;
1694ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((*cur != '\n') && (*cur != '\r'))
1695ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(0);
1696ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	while ((*cur == '\n')  || (*cur == '\r'))
1697ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    cur++;
1698ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1699ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (callback != NULL) {
1700ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        callback(userData, filename, attrib, owner, group, size, links,
1701ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		 year, month, day, hour, minute);
1702ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1703ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(cur - list);
1704ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1705ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1706ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1707ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPList:
1708ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
1709ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @callback:  the user callback
1710ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @userData:  the user callback data
1711ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @filename:  optional files to list
1712ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1713ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Do a listing on the server. All files info are passed back
1714ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * in the callbacks.
1715ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1716ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, 0 otherwise
1717ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1718ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1719ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
1720ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
1721ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	       const char *filename) {
1722ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1723ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[4096 + 1];
1724ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len, res;
1725ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int indx = 0, base;
1726ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    fd_set rfd, efd;
1727ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct timeval tv;
1728ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1729ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL) return (-1);
1730ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (filename == NULL) {
1731ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
1732ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1733ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
1734df143a5041f03a22808b59c76698770b74692815Selim Gurun	if (ctxt->dataFd == INVALID_SOCKET)
1735ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1736ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "LIST -L\r\n");
1737ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else {
1738ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (filename[0] != '/') {
1739ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
1740ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return(-1);
1741ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1742ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
1743df143a5041f03a22808b59c76698770b74692815Selim Gurun	if (ctxt->dataFd == INVALID_SOCKET)
1744ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1745ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
1746ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1747ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf[sizeof(buf) - 1] = 0;
1748ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
1749ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1750ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf);
1751ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1752ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
1753ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1754ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
1755df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1756ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(res);
1757ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1758ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPReadResponse(ctxt);
1759ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res != 1) {
1760df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1761ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-res);
1762ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1763ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1764ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    do {
1765ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	tv.tv_sec = 1;
1766ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	tv.tv_usec = 0;
1767ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	FD_ZERO(&rfd);
1768ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	FD_SET(ctxt->dataFd, &rfd);
1769ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	FD_ZERO(&efd);
1770ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	FD_SET(ctxt->dataFd, &efd);
1771ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	res = select(ctxt->dataFd + 1, &rfd, NULL, &efd, &tv);
1772ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res < 0) {
1773ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1774ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    perror("select");
1775ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1776df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1777ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1778ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1779ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res == 0) {
1780ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    res = xmlNanoFTPCheckResponse(ctxt);
1781ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (res < 0) {
1782df143a5041f03a22808b59c76698770b74692815Selim Gurun		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1783df143a5041f03a22808b59c76698770b74692815Selim Gurun		ctxt->dataFd = INVALID_SOCKET;
1784ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return(-1);
1785ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1786ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (res == 2) {
1787df143a5041f03a22808b59c76698770b74692815Selim Gurun		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1788ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return(0);
1789ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1790ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1791ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    continue;
1792ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1793ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1794ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((len = recv(ctxt->dataFd, &buf[indx], sizeof(buf) - (indx + 1), 0)) < 0) {
1795ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "recv");
1796df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1797df143a5041f03a22808b59c76698770b74692815Selim Gurun	    ctxt->dataFd = INVALID_SOCKET;
1798ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1799ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1800ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1801ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        write(1, &buf[indx], len);
1802ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1803ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	indx += len;
1804ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	buf[indx] = 0;
1805ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	base = 0;
1806ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	do {
1807ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    res = xmlNanoFTPParseList(&buf[base], callback, userData);
1808ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    base += res;
1809ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	} while (res > 0);
1810ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1811ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	memmove(&buf[0], &buf[base], indx - base);
1812ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	indx -= base;
1813ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } while (len != 0);
1814ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCloseConnection(ctxt);
1815ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
1816ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1817ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1818ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1819ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPGetSocket:
1820ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
1821ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @filename:  the file to retrieve (or NULL if path is in context).
1822ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1823ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Initiate fetch of the given file from the server.
1824ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1825ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the socket for the data connection, or <0 in case of error
1826ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1827ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1828ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1829df143a5041f03a22808b59c76698770b74692815Selim GurunSOCKET
1830ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPGetSocket(void *ctx, const char *filename) {
1831ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1832ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[300];
1833ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int res, len;
1834ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctx == NULL)
1835df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1836ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((filename == NULL) && (ctxt->path == NULL))
1837df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1838ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
1839df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt->dataFd == INVALID_SOCKET)
1840df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1841ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1842ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    snprintf(buf, sizeof(buf), "TYPE I\r\n");
1843ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
1844ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1845ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf);
1846ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1847ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
1848ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1849ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
1850df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1851df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1852ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1853ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPReadResponse(ctxt);
1854ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res != 2) {
1855df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1856df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1857ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1858ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (filename == NULL)
1859ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
1860ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    else
1861ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
1862ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    buf[sizeof(buf) - 1] = 0;
1863ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = strlen(buf);
1864ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1865ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "%s", buf);
1866ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1867ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = send(ctxt->controlFd, buf, len, 0);
1868ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res < 0) {
1869ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	__xmlIOErr(XML_FROM_FTP, 0, "send failed");
1870df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1871df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1872ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1873ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    res = xmlNanoFTPReadResponse(ctxt);
1874ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (res != 1) {
1875df143a5041f03a22808b59c76698770b74692815Selim Gurun	closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1876df143a5041f03a22808b59c76698770b74692815Selim Gurun	return INVALID_SOCKET;
1877ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1878ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(ctxt->dataFd);
1879ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1880ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1881ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1882ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPGet:
1883ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  an FTP context
1884ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @callback:  the user callback
1885ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @userData:  the user callback data
1886ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @filename:  the file to retrieve
1887ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1888ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Fetch the given file from the server. All data are passed back
1889ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * in the callbacks. The last callback has a size of 0 block.
1890ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1891ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, 0 otherwise
1892ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1893ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1894ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
1895ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,
1896ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	      const char *filename) {
1897ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1898ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char buf[4096];
1899ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    int len = 0, res;
1900ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    fd_set rfd;
1901ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    struct timeval tv;
1902ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1903ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL) return(-1);
1904ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if ((filename == NULL) && (ctxt->path == NULL))
1905ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1906ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (callback == NULL)
1907ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1908df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (xmlNanoFTPGetSocket(ctxt, filename) == INVALID_SOCKET)
1909ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
1910ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1911ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    do {
1912ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	tv.tv_sec = 1;
1913ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	tv.tv_usec = 0;
1914ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	FD_ZERO(&rfd);
1915ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	FD_SET(ctxt->dataFd, &rfd);
1916ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	res = select(ctxt->dataFd + 1, &rfd, NULL, NULL, &tv);
1917ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res < 0) {
1918ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1919ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    perror("select");
1920ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1921df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1922ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1923ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1924ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (res == 0) {
1925ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    res = xmlNanoFTPCheckResponse(ctxt);
1926ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (res < 0) {
1927df143a5041f03a22808b59c76698770b74692815Selim Gurun		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1928df143a5041f03a22808b59c76698770b74692815Selim Gurun		ctxt->dataFd = INVALID_SOCKET;
1929ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return(-1);
1930ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1931ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    if (res == 2) {
1932df143a5041f03a22808b59c76698770b74692815Selim Gurun		closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1933ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		return(0);
1934ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    }
1935ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1936ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    continue;
1937ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1938ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {
1939ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "recv failed");
1940ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    callback(userData, buf, len);
1941df143a5041f03a22808b59c76698770b74692815Selim Gurun	    closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1942ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    return(-1);
1943ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
1944ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	callback(userData, buf, len);
1945ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } while (len != 0);
1946ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1947ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(xmlNanoFTPCloseConnection(ctxt));
1948ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1949ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1950ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1951ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPRead:
1952ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx:  the FTP context
1953ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @dest:  a buffer
1954ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @len:  the buffer length
1955ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1956ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * This function tries to read @len bytes from the existing FTP connection
1957ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * and saves them in @dest. This is a blocking call.
1958ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1959ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns the number of byte read. 0 is an indication of an end of connection.
1960ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *         -1 indicates a parameter error.
1961ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1962ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
1963ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPRead(void *ctx, void *dest, int len) {
1964ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1965ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1966ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctx == NULL) return(-1);
1967df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt->dataFd == INVALID_SOCKET) return(0);
1968ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (dest == NULL) return(-1);
1969ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (len <= 0) return(0);
1970ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1971ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    len = recv(ctxt->dataFd, dest, len, 0);
1972ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (len <= 0) {
1973ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (len < 0)
1974ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    __xmlIOErr(XML_FROM_FTP, 0, "recv failed");
1975ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPCloseConnection(ctxt);
1976ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
1977ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef DEBUG_FTP
1978ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);
1979ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif
1980ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(len);
1981ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
1982ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1983ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
1984ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPOpen:
1985ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @URL: the URL to the resource
1986ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
1987ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Start to fetch the given ftp:// resource
1988ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
198994442ad4107000e6d49f9b85a46a591495a57632Selim Gurun * Returns an FTP context, or NULL
1990ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
1991ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1992ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid*
1993ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPOpen(const char *URL) {
1994ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt;
1995df143a5041f03a22808b59c76698770b74692815Selim Gurun    SOCKET sock;
1996ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
1997ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPInit();
1998ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (URL == NULL) return(NULL);
1999ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (strncmp("ftp://", URL, 6)) return(NULL);
2000ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2001ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(URL);
2002ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL) return(NULL);
2003ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (xmlNanoFTPConnect(ctxt) < 0) {
2004ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPFreeCtxt(ctxt);
2005ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(NULL);
2006ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
2007ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);
2008df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (sock == INVALID_SOCKET) {
2009ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPFreeCtxt(ctxt);
2010ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(NULL);
2011ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
2012ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(ctxt);
2013ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
2014ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2015ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/**
2016ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * xmlNanoFTPClose:
2017ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * @ctx: an FTP context
2018ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
2019ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Close the connection and both control and transport
2020ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project *
2021ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project * Returns -1 incase of error, 0 otherwise
2022ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project */
2023ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2024ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint
2025ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source ProjectxmlNanoFTPClose(void *ctx) {
2026ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
2027ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2028ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL)
2029ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return(-1);
2030ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2031df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt->dataFd != INVALID_SOCKET) {
2032ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	closesocket(ctxt->dataFd);
2033df143a5041f03a22808b59c76698770b74692815Selim Gurun	ctxt->dataFd = INVALID_SOCKET;
2034ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
2035df143a5041f03a22808b59c76698770b74692815Selim Gurun    if (ctxt->controlFd != INVALID_SOCKET) {
2036ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	xmlNanoFTPQuit(ctxt);
2037ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	closesocket(ctxt->controlFd);
2038df143a5041f03a22808b59c76698770b74692815Selim Gurun	ctxt->controlFd = INVALID_SOCKET;
2039ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
2040ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPFreeCtxt(ctxt);
2041ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
2042ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
2043ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2044ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef STANDALONE
2045ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project/************************************************************************
204694442ad4107000e6d49f9b85a46a591495a57632Selim Gurun *									*
204794442ad4107000e6d49f9b85a46a591495a57632Selim Gurun *			Basic test in Standalone mode			*
204894442ad4107000e6d49f9b85a46a591495a57632Selim Gurun *									*
2049ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project ************************************************************************/
2050ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic
2051ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid ftpList(void *userData, const char *filename, const char* attrib,
2052ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     const char *owner, const char *group, unsigned long size, int links,
2053ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	     int year, const char *month, int day, int hour, int minute) {
2054ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext,
2055ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    "%s %s %s %ld %s\n", attrib, owner, group, size, filename);
2056ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
2057ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectstatic
2058ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectvoid ftpData(void *userData, const char *data, int len) {
2059ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (userData == NULL) return;
2060ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (len <= 0) {
2061ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	fclose((FILE*)userData);
2062ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	return;
206394442ad4107000e6d49f9b85a46a591495a57632Selim Gurun    }
2064ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    fwrite(data, len, 1, (FILE*)userData);
2065ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
2066ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2067ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint main(int argc, char **argv) {
2068ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    void *ctxt;
2069ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    FILE *output;
2070ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    char *tstfile = NULL;
2071ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project
2072ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPInit();
2073ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (argc > 1) {
2074ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt = xmlNanoFTPNewCtxt(argv[1]);
2075ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (xmlNanoFTPConnect(ctxt) < 0) {
2076ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    xmlGenericError(xmlGenericErrorContext,
2077ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    "Couldn't connect to %s\n", argv[1]);
2078ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    exit(1);
2079ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	}
2080ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (argc > 2)
2081ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    tstfile = argv[2];
2082ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    } else
2083ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	ctxt = xmlNanoFTPConnectTo("localhost", 0);
2084ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (ctxt == NULL) {
2085ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        xmlGenericError(xmlGenericErrorContext,
2086ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		"Couldn't connect to localhost\n");
2087ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project        exit(1);
2088ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
2089ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPList(ctxt, ftpList, NULL, tstfile);
2090ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    output = fopen("/tmp/tstdata", "w");
2091ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    if (output != NULL) {
2092ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	if (xmlNanoFTPGet(ctxt, ftpData, (void *) output, tstfile) < 0)
2093ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    xmlGenericError(xmlGenericErrorContext,
2094ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project		    "Failed to get file\n");
209594442ad4107000e6d49f9b85a46a591495a57632Selim Gurun
2096ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    }
2097ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlNanoFTPClose(ctxt);
2098ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlMemoryDump();
2099ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    exit(0);
2100ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
2101ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif /* STANDALONE */
2102ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#else /* !LIBXML_FTP_ENABLED */
2103ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#ifdef STANDALONE
2104ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include <stdio.h>
2105ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Projectint main(int argc, char **argv) {
2106ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    xmlGenericError(xmlGenericErrorContext,
2107ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project	    "%s : FTP support not compiled in\n", argv[0]);
2108ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project    return(0);
2109ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project}
2110ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif /* STANDALONE */
2111ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#endif /* LIBXML_FTP_ENABLED */
2112ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#define bottom_nanoftp
2113ab4e2e90f63db6b1cd8bb2e453cac899ef43d42bThe Android Open Source Project#include "elfgcchack.h"
2114