ReactOS 0.4.15-dev-7846-g8ba6c66
nanoftp.c
Go to the documentation of this file.
1/*
2 * nanoftp.c: basic FTP client support
3 *
4 * Reference: RFC 959
5 */
6
7#ifdef TESTING
8#define STANDALONE
9#define HAVE_UNISTD_H
10#define HAVE_SYS_SOCKET_H
11#define HAVE_NETINET_IN_H
12#define HAVE_NETDB_H
13#define HAVE_SYS_TIME_H
14#endif /* TESTING */
15
16#define IN_LIBXML
17#include "libxml.h"
18
19#ifdef LIBXML_FTP_ENABLED
20#include <string.h>
21#include <stdlib.h>
22#include <errno.h>
23
24#ifdef HAVE_UNISTD_H
25#include <unistd.h>
26#endif
27#ifdef HAVE_SYS_SOCKET_H
28#include <sys/socket.h>
29#endif
30#ifdef HAVE_NETINET_IN_H
31#include <netinet/in.h>
32#endif
33#ifdef HAVE_ARPA_INET_H
34#include <arpa/inet.h>
35#endif
36#ifdef HAVE_NETDB_H
37#include <netdb.h>
38#endif
39#ifdef HAVE_FCNTL_H
40#include <fcntl.h>
41#endif
42#ifdef HAVE_SYS_TIME_H
43#include <sys/time.h>
44#endif
45#ifdef HAVE_SYS_SELECT_H
46#include <sys/select.h>
47#endif
48#ifdef HAVE_SYS_SOCKET_H
49#include <sys/socket.h>
50#endif
51#ifdef HAVE_SYS_TYPES_H
52#include <sys/types.h>
53#endif
54
55#include <libxml/xmlmemory.h>
56#include <libxml/parser.h>
57#include <libxml/xmlerror.h>
58#include <libxml/uri.h>
59#include <libxml/nanoftp.h>
60#include <libxml/globals.h>
61
62/* #define DEBUG_FTP 1 */
63#ifdef STANDALONE
64#ifndef DEBUG_FTP
65#define DEBUG_FTP 1
66#endif
67#endif
68
69
70#if defined(_WIN32)
71#include <wsockcompat.h>
72#endif
73
77#ifndef _WINSOCKAPI_
78#if !defined(__BEOS__) || defined(__HAIKU__)
79#define closesocket(s) close(s)
80#endif
81#endif
82
83#ifdef __BEOS__
84#ifndef PF_INET
85#define PF_INET AF_INET
86#endif
87#endif
88
89#ifdef _AIX
90#ifdef HAVE_BROKEN_SS_FAMILY
91#define ss_family __ss_family
92#endif
93#endif
94
95#ifndef XML_SOCKLEN_T
96#define XML_SOCKLEN_T unsigned int
97#endif
98
99#define FTP_COMMAND_OK 200
100#define FTP_SYNTAX_ERROR 500
101#define FTP_GET_PASSWD 331
102#define FTP_BUF_SIZE 1024
103
104#define XML_NANO_MAX_URLBUF 4096
105
106typedef struct xmlNanoFTPCtxt {
107 char *protocol; /* the protocol name */
108 char *hostname; /* the host name */
109 int port; /* the port */
110 char *path; /* the path within the URL */
111 char *user; /* user string */
112 char *passwd; /* passwd string */
113#ifdef SUPPORT_IP6
114 struct sockaddr_storage ftpAddr; /* this is large enough to hold IPv6 address*/
115#else
116 struct sockaddr_in ftpAddr; /* the socket address struct */
117#endif
118 int passive; /* currently we support only passive !!! */
119 SOCKET controlFd; /* the file descriptor for the control socket */
120 SOCKET dataFd; /* the file descriptor for the data socket */
121 int state; /* WRITE / READ / CLOSED */
122 int returnValue; /* the protocol return value */
123 /* buffer for data received from the control connection */
124 char controlBuf[FTP_BUF_SIZE + 1];
125 int controlBufIndex;
126 int controlBufUsed;
127 int controlBufAnswer;
128} xmlNanoFTPCtxt, *xmlNanoFTPCtxtPtr;
129
130static int initialized = 0;
131static char *proxy = NULL; /* the proxy name if any */
132static int proxyPort = 0; /* the proxy port if any */
133static char *proxyUser = NULL; /* user for proxy authentication */
134static char *proxyPasswd = NULL;/* passwd for proxy authentication */
135static int proxyType = 0; /* uses TYPE or a@b ? */
136
137#ifdef SUPPORT_IP6
138static
139int have_ipv6(void) {
140 int s;
141
143 if (s != -1) {
144 close (s);
145 return (1);
146 }
147 return (0);
148}
149#endif
150
157static void
158xmlFTPErrMemory(const char *extra)
159{
160 __xmlSimpleError(XML_FROM_FTP, XML_ERR_NO_MEMORY, NULL, NULL, extra);
161}
162
171void
172xmlNanoFTPInit(void) {
173 const char *env;
174#ifdef _WINSOCKAPI_
175 WSADATA wsaData;
176#endif
177
178 if (initialized)
179 return;
180
181#ifdef _WINSOCKAPI_
182 if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
183 return;
184#endif
185
186 proxyPort = 21;
187 env = getenv("no_proxy");
188 if (env && ((env[0] == '*' ) && (env[1] == 0)))
189 return;
190 env = getenv("ftp_proxy");
191 if (env != NULL) {
192 xmlNanoFTPScanProxy(env);
193 } else {
194 env = getenv("FTP_PROXY");
195 if (env != NULL) {
196 xmlNanoFTPScanProxy(env);
197 }
198 }
199 env = getenv("ftp_proxy_user");
200 if (env != NULL) {
201 proxyUser = xmlMemStrdup(env);
202 }
203 env = getenv("ftp_proxy_password");
204 if (env != NULL) {
205 proxyPasswd = xmlMemStrdup(env);
206 }
207 initialized = 1;
208}
209
216void
217xmlNanoFTPCleanup(void) {
218 if (proxy != NULL) {
219 xmlFree(proxy);
220 proxy = NULL;
221 }
222 if (proxyUser != NULL) {
223 xmlFree(proxyUser);
224 proxyUser = NULL;
225 }
226 if (proxyPasswd != NULL) {
227 xmlFree(proxyPasswd);
228 proxyPasswd = NULL;
229 }
230#ifdef _WINSOCKAPI_
231 if (initialized)
232 WSACleanup();
233#endif
234 initialized = 0;
235}
236
250void
251xmlNanoFTPProxy(const char *host, int port, const char *user,
252 const char *passwd, int type) {
253 if (proxy != NULL) {
254 xmlFree(proxy);
255 proxy = NULL;
256 }
257 if (proxyUser != NULL) {
258 xmlFree(proxyUser);
259 proxyUser = NULL;
260 }
261 if (proxyPasswd != NULL) {
262 xmlFree(proxyPasswd);
263 proxyPasswd = NULL;
264 }
265 if (host)
267 if (user)
268 proxyUser = xmlMemStrdup(user);
269 if (passwd)
270 proxyPasswd = xmlMemStrdup(passwd);
271 proxyPort = port;
272 proxyType = type;
273}
274
284static void
285xmlNanoFTPScanURL(void *ctx, const char *URL) {
286 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
288
289 /*
290 * Clear any existing data from the context
291 */
292 if (ctxt->protocol != NULL) {
293 xmlFree(ctxt->protocol);
294 ctxt->protocol = NULL;
295 }
296 if (ctxt->hostname != NULL) {
297 xmlFree(ctxt->hostname);
298 ctxt->hostname = NULL;
299 }
300 if (ctxt->path != NULL) {
301 xmlFree(ctxt->path);
302 ctxt->path = NULL;
303 }
304 if (URL == NULL) return;
305
306 uri = xmlParseURIRaw(URL, 1);
307 if (uri == NULL)
308 return;
309
310 if ((uri->scheme == NULL) || (uri->server == NULL)) {
312 return;
313 }
314
315 ctxt->protocol = xmlMemStrdup(uri->scheme);
316 ctxt->hostname = xmlMemStrdup(uri->server);
317 if (uri->path != NULL)
318 ctxt->path = xmlMemStrdup(uri->path);
319 else
320 ctxt->path = xmlMemStrdup("/");
321 if (uri->port != 0)
322 ctxt->port = uri->port;
323
324 if (uri->user != NULL) {
325 char *cptr;
326 if ((cptr=strchr(uri->user, ':')) == NULL)
327 ctxt->user = xmlMemStrdup(uri->user);
328 else {
329 ctxt->user = (char *)xmlStrndup((xmlChar *)uri->user,
330 (cptr - uri->user));
331 ctxt->passwd = xmlMemStrdup(cptr+1);
332 }
333 }
334
336
337}
338
353int
354xmlNanoFTPUpdateURL(void *ctx, const char *URL) {
355 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
357
358 if (URL == NULL)
359 return(-1);
360 if (ctxt == NULL)
361 return(-1);
362 if (ctxt->protocol == NULL)
363 return(-1);
364 if (ctxt->hostname == NULL)
365 return(-1);
366
367 uri = xmlParseURIRaw(URL, 1);
368 if (uri == NULL)
369 return(-1);
370
371 if ((uri->scheme == NULL) || (uri->server == NULL)) {
373 return(-1);
374 }
375 if ((strcmp(ctxt->protocol, uri->scheme)) ||
376 (strcmp(ctxt->hostname, uri->server)) ||
377 ((uri->port != 0) && (ctxt->port != uri->port))) {
379 return(-1);
380 }
381
382 if (uri->port != 0)
383 ctxt->port = uri->port;
384
385 if (ctxt->path != NULL) {
386 xmlFree(ctxt->path);
387 ctxt->path = NULL;
388 }
389
390 if (uri->path == NULL)
391 ctxt->path = xmlMemStrdup("/");
392 else
393 ctxt->path = xmlMemStrdup(uri->path);
394
396
397 return(0);
398}
399
410void
411xmlNanoFTPScanProxy(const char *URL) {
413
414 if (proxy != NULL) {
415 xmlFree(proxy);
416 proxy = NULL;
417 }
418 proxyPort = 0;
419
420#ifdef DEBUG_FTP
421 if (URL == NULL)
423 "Removing FTP proxy info\n");
424 else
426 "Using FTP proxy %s\n", URL);
427#endif
428 if (URL == NULL) return;
429
430 uri = xmlParseURIRaw(URL, 1);
431 if ((uri == NULL) || (uri->scheme == NULL) ||
432 (strcmp(uri->scheme, "ftp")) || (uri->server == NULL)) {
433 __xmlIOErr(XML_FROM_FTP, XML_FTP_URL_SYNTAX, "Syntax Error\n");
434 if (uri != NULL)
436 return;
437 }
438
439 proxy = xmlMemStrdup(uri->server);
440 if (uri->port != 0)
441 proxyPort = uri->port;
442
444}
445
455void*
456xmlNanoFTPNewCtxt(const char *URL) {
457 xmlNanoFTPCtxtPtr ret;
458 char *unescaped;
459
460 ret = (xmlNanoFTPCtxtPtr) xmlMalloc(sizeof(xmlNanoFTPCtxt));
461 if (ret == NULL) {
462 xmlFTPErrMemory("allocating FTP context");
463 return(NULL);
464 }
465
466 memset(ret, 0, sizeof(xmlNanoFTPCtxt));
467 ret->port = 21;
468 ret->passive = 1;
469 ret->returnValue = 0;
470 ret->controlBufIndex = 0;
471 ret->controlBufUsed = 0;
472 ret->controlFd = INVALID_SOCKET;
473
474 unescaped = xmlURIUnescapeString(URL, 0, NULL);
475 if (unescaped != NULL) {
476 xmlNanoFTPScanURL(ret, unescaped);
477 xmlFree(unescaped);
478 } else if (URL != NULL)
479 xmlNanoFTPScanURL(ret, URL);
480
481 return(ret);
482}
483
491void
492xmlNanoFTPFreeCtxt(void * ctx) {
493 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
494 if (ctxt == NULL) return;
495 if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);
496 if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);
497 if (ctxt->path != NULL) xmlFree(ctxt->path);
498 if (ctxt->user != NULL) xmlFree(ctxt->user);
499 if (ctxt->passwd != NULL) xmlFree(ctxt->passwd);
500 ctxt->passive = 1;
501 if (ctxt->controlFd != INVALID_SOCKET) closesocket(ctxt->controlFd);
502 ctxt->controlFd = INVALID_SOCKET;
503 ctxt->controlBufIndex = -1;
504 ctxt->controlBufUsed = -1;
505 xmlFree(ctxt);
506}
507
519static int
520xmlNanoFTPParseResponse(char *buf, int len) {
521 int val = 0;
522
523 if (len < 3) return(-1);
524 if ((*buf >= '0') && (*buf <= '9'))
525 val = val * 10 + (*buf - '0');
526 else
527 return(0);
528 buf++;
529 if ((*buf >= '0') && (*buf <= '9'))
530 val = val * 10 + (*buf - '0');
531 else
532 return(0);
533 buf++;
534 if ((*buf >= '0') && (*buf <= '9'))
535 val = val * 10 + (*buf - '0');
536 else
537 return(0);
538 buf++;
539 if (*buf == '-')
540 return(-val);
541 return(val);
542}
543
551static int
552xmlNanoFTPGetMore(void *ctx) {
553 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
554 int len;
555 int size;
556
557 if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
558
559 if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {
560#ifdef DEBUG_FTP
562 "xmlNanoFTPGetMore : controlBufIndex = %d\n",
563 ctxt->controlBufIndex);
564#endif
565 return(-1);
566 }
567
568 if ((ctxt->controlBufUsed < 0) || (ctxt->controlBufUsed > FTP_BUF_SIZE)) {
569#ifdef DEBUG_FTP
571 "xmlNanoFTPGetMore : controlBufUsed = %d\n",
572 ctxt->controlBufUsed);
573#endif
574 return(-1);
575 }
576 if (ctxt->controlBufIndex > ctxt->controlBufUsed) {
577#ifdef DEBUG_FTP
579 "xmlNanoFTPGetMore : controlBufIndex > controlBufUsed %d > %d\n",
580 ctxt->controlBufIndex, ctxt->controlBufUsed);
581#endif
582 return(-1);
583 }
584
585 /*
586 * First pack the control buffer
587 */
588 if (ctxt->controlBufIndex > 0) {
589 memmove(&ctxt->controlBuf[0], &ctxt->controlBuf[ctxt->controlBufIndex],
590 ctxt->controlBufUsed - ctxt->controlBufIndex);
591 ctxt->controlBufUsed -= ctxt->controlBufIndex;
592 ctxt->controlBufIndex = 0;
593 }
594 size = FTP_BUF_SIZE - ctxt->controlBufUsed;
595 if (size == 0) {
596#ifdef DEBUG_FTP
598 "xmlNanoFTPGetMore : buffer full %d \n", ctxt->controlBufUsed);
599#endif
600 return(0);
601 }
602
603 /*
604 * Read the amount left on the control connection
605 */
606 if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],
607 size, 0)) < 0) {
608 __xmlIOErr(XML_FROM_FTP, 0, "recv failed");
609 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
610 ctxt->controlFd = INVALID_SOCKET;
611 return(-1);
612 }
613#ifdef DEBUG_FTP
615 "xmlNanoFTPGetMore : read %d [%d - %d]\n", len,
616 ctxt->controlBufUsed, ctxt->controlBufUsed + len);
617#endif
618 ctxt->controlBufUsed += len;
619 ctxt->controlBuf[ctxt->controlBufUsed] = 0;
620
621 return(len);
622}
623
631static int
632xmlNanoFTPReadResponse(void *ctx) {
633 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
634 char *ptr, *end;
635 int len;
636 int res = -1, cur = -1;
637
638 if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
639
640get_more:
641 /*
642 * Assumes everything up to controlBuf[controlBufIndex] has been read
643 * and analyzed.
644 */
645 len = xmlNanoFTPGetMore(ctx);
646 if (len < 0) {
647 return(-1);
648 }
649 if ((ctxt->controlBufUsed == 0) && (len == 0)) {
650 return(-1);
651 }
652 ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
653 end = &ctxt->controlBuf[ctxt->controlBufUsed];
654
655#ifdef DEBUG_FTP
657 "\n<<<\n%s\n--\n", ptr);
658#endif
659 while (ptr < end) {
660 cur = xmlNanoFTPParseResponse(ptr, end - ptr);
661 if (cur > 0) {
662 /*
663 * Successfully scanned the control code, scratch
664 * till the end of the line, but keep the index to be
665 * able to analyze the result if needed.
666 */
667 res = cur;
668 ptr += 3;
669 ctxt->controlBufAnswer = ptr - ctxt->controlBuf;
670 while ((ptr < end) && (*ptr != '\n')) ptr++;
671 if (*ptr == '\n') ptr++;
672 if (*ptr == '\r') ptr++;
673 break;
674 }
675 while ((ptr < end) && (*ptr != '\n')) ptr++;
676 if (ptr >= end) {
677 ctxt->controlBufIndex = ctxt->controlBufUsed;
678 goto get_more;
679 }
680 if (*ptr != '\r') ptr++;
681 }
682
683 if (res < 0) goto get_more;
684 ctxt->controlBufIndex = ptr - ctxt->controlBuf;
685#ifdef DEBUG_FTP
686 ptr = &ctxt->controlBuf[ctxt->controlBufIndex];
687 xmlGenericError(xmlGenericErrorContext, "\n---\n%s\n--\n", ptr);
688#endif
689
690#ifdef DEBUG_FTP
692#endif
693 return(res / 100);
694}
695
704int
705xmlNanoFTPGetResponse(void *ctx) {
706 int res;
707
708 res = xmlNanoFTPReadResponse(ctx);
709
710 return(res);
711}
712
721int
722xmlNanoFTPCheckResponse(void *ctx) {
723 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
724 fd_set rfd;
725 struct timeval tv;
726
727 if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
728 tv.tv_sec = 0;
729 tv.tv_usec = 0;
730 FD_ZERO(&rfd);
731 FD_SET(ctxt->controlFd, &rfd);
732 switch(select(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv)) {
733 case 0:
734 return(0);
735 case -1:
736 __xmlIOErr(XML_FROM_FTP, 0, "select");
737 return(-1);
738
739 }
740
741 return(xmlNanoFTPReadResponse(ctx));
742}
743
748static int
749xmlNanoFTPSendUser(void *ctx) {
750 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
751 char buf[200];
752 int len;
753 int res;
754
755 if (ctxt->user == NULL)
756 snprintf(buf, sizeof(buf), "USER anonymous\r\n");
757 else
758 snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);
759 buf[sizeof(buf) - 1] = 0;
760 len = strlen(buf);
761#ifdef DEBUG_FTP
763#endif
764 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
765 if (res < 0) {
766 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
767 return(res);
768 }
769 return(0);
770}
771
776static int
777xmlNanoFTPSendPasswd(void *ctx) {
778 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
779 char buf[200];
780 int len;
781 int res;
782
783 if (ctxt->passwd == NULL)
784 snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
785 else
786 snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
787 buf[sizeof(buf) - 1] = 0;
788 len = strlen(buf);
789#ifdef DEBUG_FTP
791#endif
792 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
793 if (res < 0) {
794 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
795 return(res);
796 }
797 return(0);
798}
799
810int
811xmlNanoFTPQuit(void *ctx) {
812 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
813 char buf[200];
814 int len, res;
815
816 if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
817
818 snprintf(buf, sizeof(buf), "QUIT\r\n");
819 len = strlen(buf);
820#ifdef DEBUG_FTP
821 xmlGenericError(xmlGenericErrorContext, "%s", buf); /* Just to be consistent, even though we know it can't have a % in it */
822#endif
823 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
824 if (res < 0) {
825 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
826 return(res);
827 }
828 return(0);
829}
830
840int
841xmlNanoFTPConnect(void *ctx) {
842 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
843 struct hostent *hp;
844 int port;
845 int res;
846 int addrlen = sizeof (struct sockaddr_in);
847
848 if (ctxt == NULL)
849 return(-1);
850 if (ctxt->hostname == NULL)
851 return(-1);
852
853 /*
854 * do the blocking DNS query.
855 */
856 if (proxy) {
857 port = proxyPort;
858 } else {
859 port = ctxt->port;
860 }
861 if (port == 0)
862 port = 21;
863
864 memset (&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));
865
866#ifdef SUPPORT_IP6
867 if (have_ipv6 ()) {
868 struct addrinfo hints, *tmp, *result;
869
870 result = NULL;
871 memset (&hints, 0, sizeof(hints));
872 hints.ai_socktype = SOCK_STREAM;
873
874 if (proxy) {
875 if (getaddrinfo (proxy, NULL, &hints, &result) != 0) {
876 __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");
877 return (-1);
878 }
879 }
880 else
881 if (getaddrinfo (ctxt->hostname, NULL, &hints, &result) != 0) {
882 __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");
883 return (-1);
884 }
885
886 for (tmp = result; tmp; tmp = tmp->ai_next)
887 if (tmp->ai_family == AF_INET || tmp->ai_family == AF_INET6)
888 break;
889
890 if (!tmp) {
891 if (result)
893 __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");
894 return (-1);
895 }
896 if ((size_t)tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) {
897 if (result)
899 __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");
900 return (-1);
901 }
902 if (tmp->ai_family == AF_INET6) {
903 memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen);
904 ((struct sockaddr_in6 *) &ctxt->ftpAddr)->sin6_port = htons (port);
905 ctxt->controlFd = socket (AF_INET6, SOCK_STREAM, 0);
906 }
907 else {
908 memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen);
909 ((struct sockaddr_in *) &ctxt->ftpAddr)->sin_port = htons (port);
910 ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);
911 }
912 addrlen = tmp->ai_addrlen;
914 }
915 else
916#endif
917 {
918 if (proxy)
920 else
921 hp = gethostbyname (GETHOSTBYNAME_ARG_CAST ctxt->hostname);
922 if (hp == NULL) {
923 __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname failed");
924 return (-1);
925 }
926 if ((unsigned int) hp->h_length >
927 sizeof(((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr)) {
928 __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");
929 return (-1);
930 }
931
932 /*
933 * Prepare the socket
934 */
935 ((struct sockaddr_in *)&ctxt->ftpAddr)->sin_family = AF_INET;
936 memcpy (&((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr,
937 hp->h_addr_list[0], hp->h_length);
938 ((struct sockaddr_in *)&ctxt->ftpAddr)->sin_port =
939 (unsigned short)htons ((unsigned short)port);
940 ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);
941 addrlen = sizeof (struct sockaddr_in);
942 }
943
944 if (ctxt->controlFd == INVALID_SOCKET) {
945 __xmlIOErr(XML_FROM_FTP, 0, "socket failed");
946 return(-1);
947 }
948
949 /*
950 * Do the connect.
951 */
952 if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,
953 addrlen) < 0) {
954 __xmlIOErr(XML_FROM_FTP, 0, "Failed to create a connection");
955 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
956 ctxt->controlFd = INVALID_SOCKET;
957 return(-1);
958 }
959
960 /*
961 * Wait for the HELLO from the server.
962 */
963 res = xmlNanoFTPGetResponse(ctxt);
964 if (res != 2) {
965 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
966 ctxt->controlFd = INVALID_SOCKET;
967 return(-1);
968 }
969
970 /*
971 * State diagram for the login operation on the FTP server
972 *
973 * Reference: RFC 959
974 *
975 * 1
976 * +---+ USER +---+------------->+---+
977 * | B |---------->| W | 2 ---->| E |
978 * +---+ +---+------ | -->+---+
979 * | | | | |
980 * 3 | | 4,5 | | |
981 * -------------- ----- | | |
982 * | | | | |
983 * | | | | |
984 * | --------- |
985 * | 1| | | |
986 * V | | | |
987 * +---+ PASS +---+ 2 | ------>+---+
988 * | |---------->| W |------------->| S |
989 * +---+ +---+ ---------->+---+
990 * | | | | |
991 * 3 | |4,5| | |
992 * -------------- -------- |
993 * | | | | |
994 * | | | | |
995 * | -----------
996 * | 1,3| | | |
997 * V | 2| | |
998 * +---+ ACCT +---+-- | ----->+---+
999 * | |---------->| W | 4,5 -------->| F |
1000 * +---+ +---+------------->+---+
1001 *
1002 * Of course in case of using a proxy this get really nasty and is not
1003 * standardized at all :-(
1004 */
1005 if (proxy) {
1006 int len;
1007 char buf[400];
1008
1009 if (proxyUser != NULL) {
1010 /*
1011 * We need proxy auth
1012 */
1013 snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);
1014 buf[sizeof(buf) - 1] = 0;
1015 len = strlen(buf);
1016#ifdef DEBUG_FTP
1018#endif
1019 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1020 if (res < 0) {
1021 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1022 closesocket(ctxt->controlFd);
1023 ctxt->controlFd = INVALID_SOCKET;
1024 return(res);
1025 }
1026 res = xmlNanoFTPGetResponse(ctxt);
1027 switch (res) {
1028 case 2:
1029 if (proxyPasswd == NULL)
1030 break;
1031 /* Falls through. */
1032 case 3:
1033 if (proxyPasswd != NULL)
1034 snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);
1035 else
1036 snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
1037 buf[sizeof(buf) - 1] = 0;
1038 len = strlen(buf);
1039#ifdef DEBUG_FTP
1041#endif
1042 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1043 if (res < 0) {
1044 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1045 closesocket(ctxt->controlFd);
1046 ctxt->controlFd = INVALID_SOCKET;
1047 return(res);
1048 }
1049 res = xmlNanoFTPGetResponse(ctxt);
1050 if (res > 3) {
1051 closesocket(ctxt->controlFd);
1052 ctxt->controlFd = INVALID_SOCKET;
1053 return(-1);
1054 }
1055 break;
1056 case 1:
1057 break;
1058 case 4:
1059 case 5:
1060 case -1:
1061 default:
1062 closesocket(ctxt->controlFd);
1063 ctxt->controlFd = INVALID_SOCKET;
1064 return(-1);
1065 }
1066 }
1067
1068 /*
1069 * We assume we don't need more authentication to the proxy
1070 * and that it succeeded :-\
1071 */
1072 switch (proxyType) {
1073 case 0:
1074 /* we will try in sequence */
1075 case 1:
1076 /* Using SITE command */
1077 snprintf(buf, sizeof(buf), "SITE %s\r\n", ctxt->hostname);
1078 buf[sizeof(buf) - 1] = 0;
1079 len = strlen(buf);
1080#ifdef DEBUG_FTP
1082#endif
1083 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1084 if (res < 0) {
1085 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1086 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1087 ctxt->controlFd = INVALID_SOCKET;
1088 return(res);
1089 }
1090 res = xmlNanoFTPGetResponse(ctxt);
1091 if (res == 2) {
1092 /* we assume it worked :-\ 1 is error for SITE command */
1093 proxyType = 1;
1094 break;
1095 }
1096 if (proxyType == 1) {
1097 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1098 ctxt->controlFd = INVALID_SOCKET;
1099 return(-1);
1100 }
1101 /* Falls through. */
1102 case 2:
1103 /* USER user@host command */
1104 if (ctxt->user == NULL)
1105 snprintf(buf, sizeof(buf), "USER anonymous@%s\r\n",
1106 ctxt->hostname);
1107 else
1108 snprintf(buf, sizeof(buf), "USER %s@%s\r\n",
1109 ctxt->user, ctxt->hostname);
1110 buf[sizeof(buf) - 1] = 0;
1111 len = strlen(buf);
1112#ifdef DEBUG_FTP
1114#endif
1115 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1116 if (res < 0) {
1117 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1118 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1119 ctxt->controlFd = INVALID_SOCKET;
1120 return(res);
1121 }
1122 res = xmlNanoFTPGetResponse(ctxt);
1123 if ((res == 1) || (res == 2)) {
1124 /* we assume it worked :-\ */
1125 proxyType = 2;
1126 return(0);
1127 }
1128 if (ctxt->passwd == NULL)
1129 snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");
1130 else
1131 snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);
1132 buf[sizeof(buf) - 1] = 0;
1133 len = strlen(buf);
1134#ifdef DEBUG_FTP
1136#endif
1137 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1138 if (res < 0) {
1139 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1140 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1141 ctxt->controlFd = INVALID_SOCKET;
1142 return(res);
1143 }
1144 res = xmlNanoFTPGetResponse(ctxt);
1145 if ((res == 1) || (res == 2)) {
1146 /* we assume it worked :-\ */
1147 proxyType = 2;
1148 return(0);
1149 }
1150 if (proxyType == 2) {
1151 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1152 ctxt->controlFd = INVALID_SOCKET;
1153 return(-1);
1154 }
1155 /* Falls through. */
1156 case 3:
1157 /*
1158 * If you need support for other Proxy authentication scheme
1159 * send the code or at least the sequence in use.
1160 */
1161 default:
1162 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1163 ctxt->controlFd = INVALID_SOCKET;
1164 return(-1);
1165 }
1166 }
1167 /*
1168 * Non-proxy handling.
1169 */
1170 res = xmlNanoFTPSendUser(ctxt);
1171 if (res < 0) {
1172 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1173 ctxt->controlFd = INVALID_SOCKET;
1174 return(-1);
1175 }
1176 res = xmlNanoFTPGetResponse(ctxt);
1177 switch (res) {
1178 case 2:
1179 return(0);
1180 case 3:
1181 break;
1182 case 1:
1183 case 4:
1184 case 5:
1185 case -1:
1186 default:
1187 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1188 ctxt->controlFd = INVALID_SOCKET;
1189 return(-1);
1190 }
1191 res = xmlNanoFTPSendPasswd(ctxt);
1192 if (res < 0) {
1193 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1194 ctxt->controlFd = INVALID_SOCKET;
1195 return(-1);
1196 }
1197 res = xmlNanoFTPGetResponse(ctxt);
1198 switch (res) {
1199 case 2:
1200 break;
1201 case 3:
1203 "FTP server asking for ACCNT on anonymous\n");
1204 /* Falls through. */
1205 case 1:
1206 case 4:
1207 case 5:
1208 case -1:
1209 default:
1210 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1211 ctxt->controlFd = INVALID_SOCKET;
1212 return(-1);
1213 }
1214
1215 return(0);
1216}
1217
1228void*
1229xmlNanoFTPConnectTo(const char *server, int port) {
1230 xmlNanoFTPCtxtPtr ctxt;
1231 int res;
1232
1233 xmlNanoFTPInit();
1234 if (server == NULL)
1235 return(NULL);
1236 if (port <= 0)
1237 return(NULL);
1238 ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(NULL);
1239 if (ctxt == NULL)
1240 return(NULL);
1241 ctxt->hostname = xmlMemStrdup(server);
1242 if (ctxt->hostname == NULL) {
1243 xmlNanoFTPFreeCtxt(ctxt);
1244 return(NULL);
1245 }
1246 ctxt->port = port;
1247 res = xmlNanoFTPConnect(ctxt);
1248 if (res < 0) {
1249 xmlNanoFTPFreeCtxt(ctxt);
1250 return(NULL);
1251 }
1252 return(ctxt);
1253}
1254
1265int
1266xmlNanoFTPCwd(void *ctx, const char *directory) {
1267 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1268 char buf[400];
1269 int len;
1270 int res;
1271
1272 if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
1273 if (directory == NULL) return 0;
1274
1275 /*
1276 * Expected response code for CWD:
1277 *
1278 * CWD
1279 * 250
1280 * 500, 501, 502, 421, 530, 550
1281 */
1282 snprintf(buf, sizeof(buf), "CWD %s\r\n", directory);
1283 buf[sizeof(buf) - 1] = 0;
1284 len = strlen(buf);
1285#ifdef DEBUG_FTP
1287#endif
1288 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1289 if (res < 0) {
1290 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1291 return(res);
1292 }
1293 res = xmlNanoFTPGetResponse(ctxt);
1294 if (res == 4) {
1295 return(-1);
1296 }
1297 if (res == 2) return(1);
1298 if (res == 5) {
1299 return(0);
1300 }
1301 return(0);
1302}
1303
1314int
1315xmlNanoFTPDele(void *ctx, const char *file) {
1316 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1317 char buf[400];
1318 int len;
1319 int res;
1320
1321 if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET) ||
1322 (file == NULL)) return(-1);
1323
1324 /*
1325 * Expected response code for DELE:
1326 *
1327 * DELE
1328 * 250
1329 * 450, 550
1330 * 500, 501, 502, 421, 530
1331 */
1332
1333 snprintf(buf, sizeof(buf), "DELE %s\r\n", file);
1334 buf[sizeof(buf) - 1] = 0;
1335 len = strlen(buf);
1336#ifdef DEBUG_FTP
1338#endif
1339 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1340 if (res < 0) {
1341 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1342 return(res);
1343 }
1344 res = xmlNanoFTPGetResponse(ctxt);
1345 if (res == 4) {
1346 return(-1);
1347 }
1348 if (res == 2) return(1);
1349 if (res == 5) {
1350 return(0);
1351 }
1352 return(0);
1353}
1364SOCKET
1365xmlNanoFTPGetConnection(void *ctx) {
1366 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1367 char buf[200], *cur;
1368 int len, i;
1369 int res;
1370 unsigned char ad[6], *adp, *portp;
1371 unsigned int temp[6];
1372#ifdef SUPPORT_IP6
1373 struct sockaddr_storage dataAddr;
1374#else
1375 struct sockaddr_in dataAddr;
1376#endif
1377 XML_SOCKLEN_T dataAddrLen;
1378
1379 if (ctxt == NULL) return INVALID_SOCKET;
1380
1381 memset (&dataAddr, 0, sizeof(dataAddr));
1382#ifdef SUPPORT_IP6
1383 if ((ctxt->ftpAddr).ss_family == AF_INET6) {
1384 ctxt->dataFd = socket (AF_INET6, SOCK_STREAM, IPPROTO_TCP);
1385 ((struct sockaddr_in6 *)&dataAddr)->sin6_family = AF_INET6;
1386 dataAddrLen = sizeof(struct sockaddr_in6);
1387 } else
1388#endif
1389 {
1390 ctxt->dataFd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
1391 ((struct sockaddr_in *)&dataAddr)->sin_family = AF_INET;
1392 dataAddrLen = sizeof (struct sockaddr_in);
1393 }
1394
1395 if (ctxt->dataFd == INVALID_SOCKET) {
1396 __xmlIOErr(XML_FROM_FTP, 0, "socket failed");
1397 return INVALID_SOCKET;
1398 }
1399
1400 if (ctxt->passive) {
1401#ifdef SUPPORT_IP6
1402 if ((ctxt->ftpAddr).ss_family == AF_INET6)
1403 snprintf (buf, sizeof(buf), "EPSV\r\n");
1404 else
1405#endif
1406 snprintf (buf, sizeof(buf), "PASV\r\n");
1407 len = strlen (buf);
1408#ifdef DEBUG_FTP
1410#endif
1411 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1412 if (res < 0) {
1413 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1414 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1415 return INVALID_SOCKET;
1416 }
1417 res = xmlNanoFTPReadResponse(ctx);
1418 if (res != 2) {
1419 if (res == 5) {
1420 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1421 return INVALID_SOCKET;
1422 } else {
1423 /*
1424 * retry with an active connection
1425 */
1426 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1427 ctxt->passive = 0;
1428 }
1429 }
1430 cur = &ctxt->controlBuf[ctxt->controlBufAnswer];
1431 while (((*cur < '0') || (*cur > '9')) && *cur != '\0') cur++;
1432#ifdef SUPPORT_IP6
1433 if ((ctxt->ftpAddr).ss_family == AF_INET6) {
1434 if (sscanf (cur, "%u", &temp[0]) != 1) {
1436 "Invalid answer to EPSV\n");
1437 if (ctxt->dataFd != INVALID_SOCKET) {
1438 closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1439 }
1440 return INVALID_SOCKET;
1441 }
1442 memcpy (&((struct sockaddr_in6 *)&dataAddr)->sin6_addr, &((struct sockaddr_in6 *)&ctxt->ftpAddr)->sin6_addr, sizeof(struct in6_addr));
1443 ((struct sockaddr_in6 *)&dataAddr)->sin6_port = htons (temp[0]);
1444 }
1445 else
1446#endif
1447 {
1448 if (sscanf (cur, "%u,%u,%u,%u,%u,%u", &temp[0], &temp[1], &temp[2],
1449 &temp[3], &temp[4], &temp[5]) != 6) {
1451 "Invalid answer to PASV\n");
1452 if (ctxt->dataFd != INVALID_SOCKET) {
1453 closesocket (ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1454 }
1455 return INVALID_SOCKET;
1456 }
1457 for (i=0; i<6; i++) ad[i] = (unsigned char) (temp[i] & 0xff);
1458 memcpy (&((struct sockaddr_in *)&dataAddr)->sin_addr, &ad[0], 4);
1459 memcpy (&((struct sockaddr_in *)&dataAddr)->sin_port, &ad[4], 2);
1460 }
1461
1462 if (connect(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
1463 __xmlIOErr(XML_FROM_FTP, 0, "Failed to create a data connection");
1464 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1465 return INVALID_SOCKET;
1466 }
1467 } else {
1468 getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
1469#ifdef SUPPORT_IP6
1470 if ((ctxt->ftpAddr).ss_family == AF_INET6)
1471 ((struct sockaddr_in6 *)&dataAddr)->sin6_port = 0;
1472 else
1473#endif
1474 ((struct sockaddr_in *)&dataAddr)->sin_port = 0;
1475
1476 if (bind(ctxt->dataFd, (struct sockaddr *) &dataAddr, dataAddrLen) < 0) {
1477 __xmlIOErr(XML_FROM_FTP, 0, "bind failed");
1478 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1479 return INVALID_SOCKET;
1480 }
1481 getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);
1482
1483 if (listen(ctxt->dataFd, 1) < 0) {
1484 __xmlIOErr(XML_FROM_FTP, 0, "listen failed");
1485 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1486 return INVALID_SOCKET;
1487 }
1488#ifdef SUPPORT_IP6
1489 if ((ctxt->ftpAddr).ss_family == AF_INET6) {
1490 char buf6[INET6_ADDRSTRLEN];
1491 inet_ntop (AF_INET6, &((struct sockaddr_in6 *)&dataAddr)->sin6_addr,
1492 buf6, INET6_ADDRSTRLEN);
1493 adp = (unsigned char *) buf6;
1494 portp = (unsigned char *) &((struct sockaddr_in6 *)&dataAddr)->sin6_port;
1495 snprintf (buf, sizeof(buf), "EPRT |2|%s|%s|\r\n", adp, portp);
1496 } else
1497#endif
1498 {
1499 adp = (unsigned char *) &((struct sockaddr_in *)&dataAddr)->sin_addr;
1500 portp = (unsigned char *) &((struct sockaddr_in *)&dataAddr)->sin_port;
1501 snprintf (buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",
1502 adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,
1503 portp[0] & 0xff, portp[1] & 0xff);
1504 }
1505
1506 buf[sizeof(buf) - 1] = 0;
1507 len = strlen(buf);
1508#ifdef DEBUG_FTP
1510#endif
1511
1512 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1513 if (res < 0) {
1514 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1515 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1516 return INVALID_SOCKET;
1517 }
1518 res = xmlNanoFTPGetResponse(ctxt);
1519 if (res != 2) {
1520 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1521 return INVALID_SOCKET;
1522 }
1523 }
1524 return(ctxt->dataFd);
1525
1526}
1527
1537int
1538xmlNanoFTPCloseConnection(void *ctx) {
1539 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1540 int res;
1541 fd_set rfd, efd;
1542 struct timeval tv;
1543
1544 if ((ctxt == NULL) || (ctxt->controlFd == INVALID_SOCKET)) return(-1);
1545
1546 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1547 tv.tv_sec = 15;
1548 tv.tv_usec = 0;
1549 FD_ZERO(&rfd);
1550 FD_SET(ctxt->controlFd, &rfd);
1551 FD_ZERO(&efd);
1552 FD_SET(ctxt->controlFd, &efd);
1553 res = select(ctxt->controlFd + 1, &rfd, NULL, &efd, &tv);
1554 if (res < 0) {
1555#ifdef DEBUG_FTP
1556 perror("select");
1557#endif
1558 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1559 return(-1);
1560 }
1561 if (res == 0) {
1562#ifdef DEBUG_FTP
1564 "xmlNanoFTPCloseConnection: timeout\n");
1565#endif
1566 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1567 } else {
1568 res = xmlNanoFTPGetResponse(ctxt);
1569 if (res != 2) {
1570 closesocket(ctxt->controlFd); ctxt->controlFd = INVALID_SOCKET;
1571 return(-1);
1572 }
1573 }
1574 return(0);
1575}
1576
1588static int
1589xmlNanoFTPParseList(const char *list, ftpListCallback callback, void *userData) {
1590 const char *cur = list;
1591 char filename[151];
1592 char attrib[11];
1593 char owner[11];
1594 char group[11];
1595 char month[4];
1596 int year = 0;
1597 int minute = 0;
1598 int hour = 0;
1599 int day = 0;
1600 unsigned long size = 0;
1601 int links = 0;
1602 int i;
1603
1604 if (!strncmp(cur, "total", 5)) {
1605 cur += 5;
1606 while (*cur == ' ') cur++;
1607 while ((*cur >= '0') && (*cur <= '9'))
1608 links = (links * 10) + (*cur++ - '0');
1609 while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
1610 cur++;
1611 return(cur - list);
1612 } else if (*list == '+') {
1613 return(0);
1614 } else {
1615 while ((*cur == ' ') || (*cur == '\n') || (*cur == '\r'))
1616 cur++;
1617 if (*cur == 0) return(0);
1618 i = 0;
1619 while (*cur != ' ') {
1620 if (i < 10)
1621 attrib[i++] = *cur;
1622 cur++;
1623 if (*cur == 0) return(0);
1624 }
1625 attrib[10] = 0;
1626 while (*cur == ' ') cur++;
1627 if (*cur == 0) return(0);
1628 while ((*cur >= '0') && (*cur <= '9'))
1629 links = (links * 10) + (*cur++ - '0');
1630 while (*cur == ' ') cur++;
1631 if (*cur == 0) return(0);
1632 i = 0;
1633 while (*cur != ' ') {
1634 if (i < 10)
1635 owner[i++] = *cur;
1636 cur++;
1637 if (*cur == 0) return(0);
1638 }
1639 owner[i] = 0;
1640 while (*cur == ' ') cur++;
1641 if (*cur == 0) return(0);
1642 i = 0;
1643 while (*cur != ' ') {
1644 if (i < 10)
1645 group[i++] = *cur;
1646 cur++;
1647 if (*cur == 0) return(0);
1648 }
1649 group[i] = 0;
1650 while (*cur == ' ') cur++;
1651 if (*cur == 0) return(0);
1652 while ((*cur >= '0') && (*cur <= '9'))
1653 size = (size * 10) + (*cur++ - '0');
1654 while (*cur == ' ') cur++;
1655 if (*cur == 0) return(0);
1656 i = 0;
1657 while (*cur != ' ') {
1658 if (i < 3)
1659 month[i++] = *cur;
1660 cur++;
1661 if (*cur == 0) return(0);
1662 }
1663 month[i] = 0;
1664 while (*cur == ' ') cur++;
1665 if (*cur == 0) return(0);
1666 while ((*cur >= '0') && (*cur <= '9'))
1667 day = (day * 10) + (*cur++ - '0');
1668 while (*cur == ' ') cur++;
1669 if (*cur == 0) return(0);
1670 if ((cur[1] == 0) || (cur[2] == 0)) return(0);
1671 if ((cur[1] == ':') || (cur[2] == ':')) {
1672 while ((*cur >= '0') && (*cur <= '9'))
1673 hour = (hour * 10) + (*cur++ - '0');
1674 if (*cur == ':') cur++;
1675 while ((*cur >= '0') && (*cur <= '9'))
1676 minute = (minute * 10) + (*cur++ - '0');
1677 } else {
1678 while ((*cur >= '0') && (*cur <= '9'))
1679 year = (year * 10) + (*cur++ - '0');
1680 }
1681 while (*cur == ' ') cur++;
1682 if (*cur == 0) return(0);
1683 i = 0;
1684 while ((*cur != '\n') && (*cur != '\r')) {
1685 if (i < 150)
1686 filename[i++] = *cur;
1687 cur++;
1688 if (*cur == 0) return(0);
1689 }
1690 filename[i] = 0;
1691 if ((*cur != '\n') && (*cur != '\r'))
1692 return(0);
1693 while ((*cur == '\n') || (*cur == '\r'))
1694 cur++;
1695 }
1696 if (callback != NULL) {
1697 callback(userData, filename, attrib, owner, group, size, links,
1698 year, month, day, hour, minute);
1699 }
1700 return(cur - list);
1701}
1702
1716int
1717xmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,
1718 const char *filename) {
1719 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1720 char buf[4096 + 1];
1721 int len, res;
1722 int indx = 0, base;
1723 fd_set rfd, efd;
1724 struct timeval tv;
1725
1726 if (ctxt == NULL) return (-1);
1727 if (filename == NULL) {
1728 if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
1729 return(-1);
1730 ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
1731 if (ctxt->dataFd == INVALID_SOCKET)
1732 return(-1);
1733 snprintf(buf, sizeof(buf), "LIST -L\r\n");
1734 } else {
1735 if (filename[0] != '/') {
1736 if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)
1737 return(-1);
1738 }
1739 ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
1740 if (ctxt->dataFd == INVALID_SOCKET)
1741 return(-1);
1742 snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);
1743 }
1744 buf[sizeof(buf) - 1] = 0;
1745 len = strlen(buf);
1746#ifdef DEBUG_FTP
1748#endif
1749 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1750 if (res < 0) {
1751 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1752 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1753 return(res);
1754 }
1755 res = xmlNanoFTPReadResponse(ctxt);
1756 if (res != 1) {
1757 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1758 return(-res);
1759 }
1760
1761 do {
1762 tv.tv_sec = 1;
1763 tv.tv_usec = 0;
1764 FD_ZERO(&rfd);
1765 FD_SET(ctxt->dataFd, &rfd);
1766 FD_ZERO(&efd);
1767 FD_SET(ctxt->dataFd, &efd);
1768 res = select(ctxt->dataFd + 1, &rfd, NULL, &efd, &tv);
1769 if (res < 0) {
1770#ifdef DEBUG_FTP
1771 perror("select");
1772#endif
1773 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1774 return(-1);
1775 }
1776 if (res == 0) {
1777 res = xmlNanoFTPCheckResponse(ctxt);
1778 if (res < 0) {
1779 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1780 ctxt->dataFd = INVALID_SOCKET;
1781 return(-1);
1782 }
1783 if (res == 2) {
1784 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1785 return(0);
1786 }
1787
1788 continue;
1789 }
1790
1791 if ((len = recv(ctxt->dataFd, &buf[indx], sizeof(buf) - (indx + 1), 0)) < 0) {
1792 __xmlIOErr(XML_FROM_FTP, 0, "recv");
1793 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1794 ctxt->dataFd = INVALID_SOCKET;
1795 return(-1);
1796 }
1797#ifdef DEBUG_FTP
1798 write(1, &buf[indx], len);
1799#endif
1800 indx += len;
1801 buf[indx] = 0;
1802 base = 0;
1803 do {
1804 res = xmlNanoFTPParseList(&buf[base], callback, userData);
1805 base += res;
1806 } while (res > 0);
1807
1808 memmove(&buf[0], &buf[base], indx - base);
1809 indx -= base;
1810 } while (len != 0);
1811 xmlNanoFTPCloseConnection(ctxt);
1812 return(0);
1813}
1814
1826SOCKET
1827xmlNanoFTPGetSocket(void *ctx, const char *filename) {
1828 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1829 char buf[300];
1830 int res, len;
1831 if (ctx == NULL)
1832 return INVALID_SOCKET;
1833 if ((filename == NULL) && (ctxt->path == NULL))
1834 return INVALID_SOCKET;
1835 ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);
1836 if (ctxt->dataFd == INVALID_SOCKET)
1837 return INVALID_SOCKET;
1838
1839 snprintf(buf, sizeof(buf), "TYPE I\r\n");
1840 len = strlen(buf);
1841#ifdef DEBUG_FTP
1843#endif
1844 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1845 if (res < 0) {
1846 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1847 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1848 return INVALID_SOCKET;
1849 }
1850 res = xmlNanoFTPReadResponse(ctxt);
1851 if (res != 2) {
1852 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1853 return INVALID_SOCKET;
1854 }
1855 if (filename == NULL)
1856 snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);
1857 else
1858 snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);
1859 buf[sizeof(buf) - 1] = 0;
1860 len = strlen(buf);
1861#ifdef DEBUG_FTP
1863#endif
1864 res = send(ctxt->controlFd, SEND_ARG2_CAST buf, len, 0);
1865 if (res < 0) {
1866 __xmlIOErr(XML_FROM_FTP, 0, "send failed");
1867 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1868 return INVALID_SOCKET;
1869 }
1870 res = xmlNanoFTPReadResponse(ctxt);
1871 if (res != 1) {
1872 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1873 return INVALID_SOCKET;
1874 }
1875 return(ctxt->dataFd);
1876}
1877
1891int
1892xmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,
1893 const char *filename) {
1894 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1895 char buf[4096];
1896 int len = 0, res;
1897 fd_set rfd;
1898 struct timeval tv;
1899
1900 if (ctxt == NULL) return(-1);
1901 if ((filename == NULL) && (ctxt->path == NULL))
1902 return(-1);
1903 if (callback == NULL)
1904 return(-1);
1905 if (xmlNanoFTPGetSocket(ctxt, filename) == INVALID_SOCKET)
1906 return(-1);
1907
1908 do {
1909 tv.tv_sec = 1;
1910 tv.tv_usec = 0;
1911 FD_ZERO(&rfd);
1912 FD_SET(ctxt->dataFd, &rfd);
1913 res = select(ctxt->dataFd + 1, &rfd, NULL, NULL, &tv);
1914 if (res < 0) {
1915#ifdef DEBUG_FTP
1916 perror("select");
1917#endif
1918 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1919 return(-1);
1920 }
1921 if (res == 0) {
1922 res = xmlNanoFTPCheckResponse(ctxt);
1923 if (res < 0) {
1924 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1925 ctxt->dataFd = INVALID_SOCKET;
1926 return(-1);
1927 }
1928 if (res == 2) {
1929 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1930 return(0);
1931 }
1932
1933 continue;
1934 }
1935 if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {
1936 __xmlIOErr(XML_FROM_FTP, 0, "recv failed");
1937 callback(userData, buf, len);
1938 closesocket(ctxt->dataFd); ctxt->dataFd = INVALID_SOCKET;
1939 return(-1);
1940 }
1941 callback(userData, buf, len);
1942 } while (len != 0);
1943
1944 return(xmlNanoFTPCloseConnection(ctxt));
1945}
1946
1959int
1960xmlNanoFTPRead(void *ctx, void *dest, int len) {
1961 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
1962
1963 if (ctx == NULL) return(-1);
1964 if (ctxt->dataFd == INVALID_SOCKET) return(0);
1965 if (dest == NULL) return(-1);
1966 if (len <= 0) return(0);
1967
1968 len = recv(ctxt->dataFd, dest, len, 0);
1969 if (len <= 0) {
1970 if (len < 0)
1971 __xmlIOErr(XML_FROM_FTP, 0, "recv failed");
1972 xmlNanoFTPCloseConnection(ctxt);
1973 }
1974#ifdef DEBUG_FTP
1975 xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);
1976#endif
1977 return(len);
1978}
1979
1989void*
1990xmlNanoFTPOpen(const char *URL) {
1991 xmlNanoFTPCtxtPtr ctxt;
1992 SOCKET sock;
1993
1994 xmlNanoFTPInit();
1995 if (URL == NULL) return(NULL);
1996 if (strncmp("ftp://", URL, 6)) return(NULL);
1997
1998 ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(URL);
1999 if (ctxt == NULL) return(NULL);
2000 if (xmlNanoFTPConnect(ctxt) < 0) {
2001 xmlNanoFTPFreeCtxt(ctxt);
2002 return(NULL);
2003 }
2004 sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);
2005 if (sock == INVALID_SOCKET) {
2006 xmlNanoFTPFreeCtxt(ctxt);
2007 return(NULL);
2008 }
2009 return(ctxt);
2010}
2011
2021int
2022xmlNanoFTPClose(void *ctx) {
2023 xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;
2024
2025 if (ctxt == NULL)
2026 return(-1);
2027
2028 if (ctxt->dataFd != INVALID_SOCKET) {
2029 closesocket(ctxt->dataFd);
2030 ctxt->dataFd = INVALID_SOCKET;
2031 }
2032 if (ctxt->controlFd != INVALID_SOCKET) {
2033 xmlNanoFTPQuit(ctxt);
2034 closesocket(ctxt->controlFd);
2035 ctxt->controlFd = INVALID_SOCKET;
2036 }
2037 xmlNanoFTPFreeCtxt(ctxt);
2038 return(0);
2039}
2040
2041#ifdef STANDALONE
2042/************************************************************************
2043 * *
2044 * Basic test in Standalone mode *
2045 * *
2046 ************************************************************************/
2047static
2048void ftpList(void *userData, const char *filename, const char* attrib,
2049 const char *owner, const char *group, unsigned long size, int links,
2050 int year, const char *month, int day, int hour, int minute) {
2052 "%s %s %s %ld %s\n", attrib, owner, group, size, filename);
2053}
2054static
2055void ftpData(void *userData, const char *data, int len) {
2056 if (userData == NULL) return;
2057 if (len <= 0) {
2058 fclose((FILE*)userData);
2059 return;
2060 }
2061 fwrite(data, len, 1, (FILE*)userData);
2062}
2063
2064int main(int argc, char **argv) {
2065 void *ctxt;
2066 FILE *output;
2067 char *tstfile = NULL;
2068
2069 xmlNanoFTPInit();
2070 if (argc > 1) {
2071 ctxt = xmlNanoFTPNewCtxt(argv[1]);
2072 if (xmlNanoFTPConnect(ctxt) < 0) {
2074 "Couldn't connect to %s\n", argv[1]);
2075 exit(1);
2076 }
2077 if (argc > 2)
2078 tstfile = argv[2];
2079 } else
2080 ctxt = xmlNanoFTPConnectTo("localhost", 0);
2081 if (ctxt == NULL) {
2083 "Couldn't connect to localhost\n");
2084 exit(1);
2085 }
2086 xmlNanoFTPList(ctxt, ftpList, NULL, tstfile);
2087 output = fopen("/tmp/tstdata", "w");
2088 if (output != NULL) {
2089 if (xmlNanoFTPGet(ctxt, ftpData, (void *) output, tstfile) < 0)
2091 "Failed to get file\n");
2092
2093 }
2094 xmlNanoFTPClose(ctxt);
2095 xmlMemoryDump();
2096 exit(0);
2097}
2098#endif /* STANDALONE */
2099#else /* !LIBXML_FTP_ENABLED */
2100#ifdef STANDALONE
2101#include <stdio.h>
2102int main(int argc, char **argv) {
2104 "%s : FTP support not compiled in\n", argv[0]);
2105 return(0);
2106}
2107#endif /* STANDALONE */
2108#endif /* LIBXML_FTP_ENABLED */
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define close
Definition: acwin.h:98
#define write
Definition: acwin.h:97
static int state
Definition: maze.c:121
void user(int argc, const char *argv[])
Definition: cmds.c:1350
char * hostname
Definition: ftp.c:88
Definition: list.h:37
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define NULL
Definition: types.h:112
static DOUBLE day(DOUBLE time)
Definition: date.c:117
USHORT port
Definition: uri.c:228
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
static const WCHAR month[12][4]
Definition: session.c:2150
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
int main()
Definition: test.c:6
#define IPPROTO_TCP
Definition: ip.h:196
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
int proxy
Definition: main.c:67
FxCollectionEntry * cur
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLboolean GLuint group
Definition: glext.h:11120
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ extra
Definition: id3.c:95
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
const char * filename
Definition: ioapi.h:137
void __xmlIOErr(int domain, int code, const char *extra)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define htons(x)
Definition: module.h:215
static PVOID ptr
Definition: dispmode.c:27
static IPrintDialogCallback callback
Definition: printdlg.c:326
static char * dest
Definition: rtl.c:135
const char * uri
Definition: sec_mgr.c:1588
#define argv
Definition: mplay32.c:18
#define closesocket
Definition: ncftp.h:477
#define list
Definition: rosglue.h:35
static calc_node_t temp
Definition: rpn_ieee.c:38
XMLPUBVAR xmlStrdupFunc xmlMemStrdup
Definition: globals.h:252
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBVAR void * xmlGenericErrorContext
Definition: globals.h:353
XMLPUBVAR xmlGenericErrorFunc xmlGenericError
Definition: globals.h:337
#define exit(n)
Definition: config.h:202
#define SEND_ARG2_CAST
Definition: config.h:175
#define GETHOSTBYNAME_ARG_CAST
Definition: config.h:8
#define XML_SOCKLEN_T
Definition: config.h:192
#define memset(x, y, z)
Definition: compat.h:39
namespace GUID const ADDRINFOEXW * hints
Definition: sock.c:80
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
Definition: uri.h:33
size_t ai_addrlen
Definition: ws2def.h:669
struct sockaddr * ai_addr
Definition: ws2def.h:671
struct addrinfo * ai_next
Definition: ws2def.h:672
int ai_family
Definition: ws2def.h:666
Definition: winsock.h:66
Definition: fci.c:127
short h_length
Definition: winsock.h:137
char ** h_addr_list
Definition: winsock.h:138
Definition: tcpcore.h:1455
struct in_addr sin_addr
Definition: winsock.h:512
u_short sin_port
Definition: winsock.h:511
unsigned long tv_sec
Definition: linux.h:1738
static BOOL initialized
Definition: syslog.c:39
#define MAKEWORD(a, b)
Definition: typedefs.h:248
const char *WSAAPI inet_ntop(int af, const void *src, char *dst, size_t cnt)
Definition: unix_func.c:8
XMLPUBFUN xmlURIPtr XMLCALL xmlParseURIRaw(const char *str, int raw)
Definition: uri.c:986
XMLPUBFUN char *XMLCALL xmlURIUnescapeString(const char *str, int len, char *target)
Definition: uri.c:1620
XMLPUBFUN void XMLCALL xmlFreeURI(xmlURIPtr uri)
Definition: uri.c:1387
static rfbScreenInfoPtr server
Definition: vnc.c:74
int ret
char * host
Definition: whois.c:55
#define FD_ZERO(set)
Definition: winsock.h:96
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define INVALID_SOCKET
Definition: winsock.h:332
UINT_PTR SOCKET
Definition: winsock.h:47
#define AF_INET6
Definition: winsock.h:369
#define FD_SET(fd, set)
Definition: winsock.h:89
#define snprintf
Definition: wintirpc.h:48
#define INET6_ADDRSTRLEN
Definition: ws2ipdef.h:132
#define getaddrinfo
Definition: wspiapi.h:44
#define freeaddrinfo
Definition: wspiapi.h:46
@ XML_FROM_FTP
Definition: xmlerror.h:46
@ XML_FTP_ACCNT
Definition: xmlerror.h:691
@ XML_FTP_URL_SYNTAX
Definition: xmlerror.h:692
@ XML_FTP_EPSV_ANSWER
Definition: xmlerror.h:690
@ XML_FTP_PASV_ANSWER
Definition: xmlerror.h:689
@ XML_ERR_NO_MEMORY
Definition: xmlerror.h:102
XMLPUBFUN void XMLCALL xmlMemoryDump(void)
Definition: xmlmemory.c:910
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
unsigned char xmlChar
Definition: xmlstring.h:28