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