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