⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nanoftp.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
/* * nanoftp.c: basic FTP client support * *  Reference: RFC 959 */#ifdef TESTING#define STANDALONE#define HAVE_STDLIB_H#define HAVE_UNISTD_H#define HAVE_SYS_SOCKET_H#define HAVE_NETINET_IN_H#define HAVE_NETDB_H#define HAVE_SYS_TIME_H#else /* TESTING */#define NEED_SOCKETS#endif /* TESTING */#define IN_LIBXML#include "libxml.h"#ifdef LIBXML_FTP_ENABLED#include <string.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#ifdef HAVE_NETDB_H#include <netdb.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h> #endif#ifdef HAVE_ERRNO_H#include <errno.h>#endif#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_STRINGS_H#include <strings.h>#endif#include <libxml/xmlmemory.h>#include <libxml/parser.h>#include <libxml/xmlerror.h>#include <libxml/uri.h>#include <libxml/nanoftp.h>#include <libxml/globals.h>/* #define DEBUG_FTP 1  */#ifdef STANDALONE#ifndef DEBUG_FTP#define DEBUG_FTP 1#endif#endif#ifdef __MINGW32__#define _WINSOCKAPI_#include <wsockcompat.h>#include <winsock2.h>#undef SOCKLEN_T#define SOCKLEN_T unsigned int#endif/** * A couple portability macros */#ifndef _WINSOCKAPI_#ifndef __BEOS__#define closesocket(s) close(s)#endif#define SOCKET int#endif#if defined(VMS) || defined(__VMS)#define SOCKLEN_T unsigned int#endif#ifdef __BEOS__#ifndef PF_INET#define PF_INET AF_INET#endif#endif#define FTP_COMMAND_OK		200#define FTP_SYNTAX_ERROR	500#define FTP_GET_PASSWD		331#define FTP_BUF_SIZE		512#define XML_NANO_MAX_URLBUF	4096typedef struct xmlNanoFTPCtxt {    char *protocol;	/* the protocol name */    char *hostname;	/* the host name */    int port;		/* the port */    char *path;		/* the path within the URL */    char *user;		/* user string */    char *passwd;	/* passwd string */#ifdef SUPPORT_IP6    struct sockaddr_storage ftpAddr; /* this is large enough to hold IPv6 address*/#else    struct sockaddr_in ftpAddr; /* the socket address struct */#endif    int passive;	/* currently we support only passive !!! */    SOCKET controlFd;	/* the file descriptor for the control socket */    SOCKET dataFd;	/* the file descriptor for the data socket */    int state;		/* WRITE / READ / CLOSED */    int returnValue;	/* the protocol return value */    /* buffer for data received from the control connection */    char controlBuf[FTP_BUF_SIZE + 1];    int controlBufIndex;    int controlBufUsed;    int controlBufAnswer;} xmlNanoFTPCtxt, *xmlNanoFTPCtxtPtr;static int initialized = 0;static char *proxy = NULL;	/* the proxy name if any */static int proxyPort = 0;	/* the proxy port if any */static char *proxyUser = NULL;	/* user for proxy authentication */static char *proxyPasswd = NULL;/* passwd for proxy authentication */static int proxyType = 0;	/* uses TYPE or a@b ? */#ifdef SUPPORT_IP6staticint have_ipv6(void) {    int s;    s = socket (AF_INET6, SOCK_STREAM, 0);    if (s != -1) {	close (s);	return (1);    }    return (0);}#endif/** * xmlFTPErrMemory: * @extra:  extra informations * * Handle an out of memory condition */static voidxmlFTPErrMemory(const char *extra){    __xmlSimpleError(XML_FROM_FTP, XML_ERR_NO_MEMORY, NULL, NULL, extra);}/** * xmlNanoFTPInit: * * Initialize the FTP protocol layer. * Currently it just checks for proxy informations, * and get the hostname */voidxmlNanoFTPInit(void) {    const char *env;#ifdef _WINSOCKAPI_    WSADATA wsaData;    #endif    if (initialized)	return;#ifdef _WINSOCKAPI_    if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)	return;#endif    proxyPort = 21;    env = getenv("no_proxy");    if (env != NULL)	return;    env = getenv("ftp_proxy");    if (env != NULL) {	xmlNanoFTPScanProxy(env);    } else {	env = getenv("FTP_PROXY");	if (env != NULL) {	    xmlNanoFTPScanProxy(env);	}    }    env = getenv("ftp_proxy_user");    if (env != NULL) {	proxyUser = xmlMemStrdup(env);    }    env = getenv("ftp_proxy_password");    if (env != NULL) {	proxyPasswd = xmlMemStrdup(env);    }    initialized = 1;}/** * xmlNanoFTPCleanup: * * Cleanup the FTP protocol layer. This cleanup proxy informations. */voidxmlNanoFTPCleanup(void) {    if (proxy != NULL) {	xmlFree(proxy);	proxy = NULL;    }    if (proxyUser != NULL) {	xmlFree(proxyUser);	proxyUser = NULL;    }    if (proxyPasswd != NULL) {	xmlFree(proxyPasswd);	proxyPasswd = NULL;    }#ifdef _WINSOCKAPI_    if (initialized)	WSACleanup();#endif    initialized = 0;}/** * xmlNanoFTPProxy: * @host:  the proxy host name * @port:  the proxy port * @user:  the proxy user name * @passwd:  the proxy password * @type:  the type of proxy 1 for using SITE, 2 for USER a@b * * Setup the FTP proxy informations. * This can also be done by using ftp_proxy ftp_proxy_user and * ftp_proxy_password environment variables. */voidxmlNanoFTPProxy(const char *host, int port, const char *user,	        const char *passwd, int type) {    if (proxy != NULL)	xmlFree(proxy);    if (proxyUser != NULL)	xmlFree(proxyUser);    if (proxyPasswd != NULL)	xmlFree(proxyPasswd);    if (host)	proxy = xmlMemStrdup(host);    if (user)	proxyUser = xmlMemStrdup(user);    if (passwd)	proxyPasswd = xmlMemStrdup(passwd);    proxyPort = port;    proxyType = type;}/** * xmlNanoFTPScanURL: * @ctx:  an FTP context * @URL:  The URL used to initialize the context * * (Re)Initialize an FTP context by parsing the URL and finding * the protocol host port and path it indicates. */static voidxmlNanoFTPScanURL(void *ctx, const char *URL) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    const char *cur = URL;    char buf[XML_NANO_MAX_URLBUF];    int indx = 0;    int port = 0;    if (ctxt->protocol != NULL) {         xmlFree(ctxt->protocol);	ctxt->protocol = NULL;    }    if (ctxt->hostname != NULL) {         xmlFree(ctxt->hostname);	ctxt->hostname = NULL;    }    if (ctxt->path != NULL) {         xmlFree(ctxt->path);	ctxt->path = NULL;    }    if (URL == NULL) return;    buf[indx] = 0;    while ((*cur != 0) && (indx < XML_NANO_MAX_URLBUF - 1)) {        if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {	    buf[indx] = 0;	    ctxt->protocol = xmlMemStrdup(buf);	    indx = 0;            cur += 3;	    break;	}	buf[indx++] = *cur++;    }    if (*cur == 0) return;    buf[indx] = 0;    /* allow user@ and user:pass@ forms */    {	const char *p = strchr(cur, '@');	if(p) {	    while(indx < XML_NANO_MAX_URLBUF-1) {		if(cur[0] == ':' || cur[0] == '@') break;		buf[indx++] = *cur++;	    }	    buf[indx] = 0;	    ctxt->user = xmlMemStrdup(buf);	    indx = 0;	    if(cur[0] == ':') {		cur++;		while(indx < XML_NANO_MAX_URLBUF-1) {		    if(cur[0] == '@') break;		    buf[indx++] = *cur++;		}		buf[indx] = 0;		ctxt->passwd = xmlMemStrdup(buf);		indx = 0;	    }	    cur = p+1;	}    }    while (indx < XML_NANO_MAX_URLBUF - 1) {	if ((strchr (cur, '[') && !strchr (cur, ']')) ||		(!strchr (cur, '[') && strchr (cur, ']'))) {	    xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPScanURL: %s",		    "Syntax Error\n");	    return;	}	if (cur[0] == '[') {	    cur++;	    while (cur[0] != ']')		buf[indx++] = *cur++;	    if (!strchr (buf, ':')) {		xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPScanURL: %s",			"Use [IPv6]/IPv4 format\n");		return;	    }	    buf[indx] = 0;	    ctxt->hostname = xmlMemStrdup (buf);	    indx = 0;	    cur += 1;	    if (cur[0] == ':') {		cur++;		while (*cur >= '0' && *cur <= '9') {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != 0) ctxt->port = port;		while ((cur[0] != '/') && (*cur != 0))		    cur++;	    }	    break;	}	else {     /* address is an IPv4 one*/	    if (cur[0] == ':') {		buf[indx] = 0;		ctxt->hostname = xmlMemStrdup (buf);		indx = 0;		cur += 1;		while ((*cur >= '0') && (*cur <= '9')) {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != 0) ctxt->port = port;		while ((cur[0] != '/') && (*cur != 0)) 		    cur++;		break;	    }	    if ((*cur == '/') || (*cur == 0)) {		buf[indx] = 0;		ctxt->hostname = xmlMemStrdup (buf);		indx = 0;		break;	    }	}	buf[indx++] = *cur++;    }    if (*cur == 0)         ctxt->path = xmlMemStrdup("/");    else {        indx = 0;        buf[indx] = 0;	while ((*cur != 0) && (indx < XML_NANO_MAX_URLBUF-1))	    buf[indx++] = *cur++;	buf[indx] = 0;	ctxt->path = xmlMemStrdup(buf);    }	}/** * xmlNanoFTPUpdateURL: * @ctx:  an FTP context * @URL:  The URL used to update the context * * Update an FTP context by parsing the URL and finding * new path it indicates. If there is an error in the  * protocol, hostname, port or other information, the * error is raised. It indicates a new connection has to * be established. * * Returns 0 if Ok, -1 in case of error (other host). */intxmlNanoFTPUpdateURL(void *ctx, const char *URL) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    const char *cur = URL;    char buf[XML_NANO_MAX_URLBUF];    int indx = 0;    int port = 0;    if (URL == NULL)	return(-1);    if (ctxt == NULL)	return(-1);    if (ctxt->protocol == NULL)	return(-1);    if (ctxt->hostname == NULL)	return(-1);    buf[indx] = 0;    while ((*cur != 0) && (indx < XML_NANO_MAX_URLBUF-1)) {        if ((cur[0] == ':') && (cur[1] == '/') && (cur[2] == '/')) {	    buf[indx] = 0;	    if (strcmp(ctxt->protocol, buf))		return(-1);	    indx = 0;            cur += 3;	    break;	}	buf[indx++] = *cur++;    }    if (*cur == 0)	return(-1);    buf[indx] = 0;    while (indx < XML_NANO_MAX_URLBUF-1) {	if ((strchr (cur, '[') && !strchr (cur, ']')) ||		(!strchr (cur, '[') && strchr (cur, ']'))) {	    xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPUpdateURL: %s",		    "Syntax Error\n");	    return (-1);	}	if (cur[0] == '[') {	    cur++;	    while ((cur[0] != ']') && (indx < XML_NANO_MAX_URLBUF-1))		buf[indx++] = *cur++;	    if (!strchr (buf, ':')) {		xmlGenericError (xmlGenericErrorContext, "\nxmlNanoFTPUpdateURL: %s",			"Use [IPv6]/IPv4 format\n");		return (-1);	    }	    buf[indx] = 0;	    if (strcmp (ctxt->hostname, buf))		return (-1);	    indx = 0;	    cur += 1;	    if (cur[0] == ':') {		cur++;		while (*cur >= '0' && *cur <= '9') {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != ctxt->port)		    return (-1);		while ((cur[0] != '/') && (*cur != 0))		    cur++;	    }	    break;	}	else {	    if (cur[0] == ':') {		buf[indx] = 0;		if (strcmp (ctxt->hostname, buf))		    return (-1);		indx = 0;		cur += 1;		while ((*cur >= '0') && (*cur <= '9')) {		    port *= 10;		    port += *cur - '0';		    cur++;		}		if (port != ctxt->port)		    return (-1);		while ((cur[0] != '/') && (*cur != 0)) 		    cur++;		break;	    }	    if ((*cur == '/') || (*cur == 0)) {		buf[indx] = 0;		if (strcmp (ctxt->hostname, buf))		    return (-1);		indx = 0;		break;	    }	}	buf[indx++] = *cur++;    }    if (ctxt->path != NULL) {	xmlFree(ctxt->path);	ctxt->path = NULL;    }    if (*cur == 0)         ctxt->path = xmlMemStrdup("/");    else {        indx = 0;        buf[indx] = 0;	while ((*cur != 0) && (indx < XML_NANO_MAX_URLBUF-1))	    buf[indx++] = *cur++;	buf[indx] = 0;	ctxt->path = xmlMemStrdup(buf);    }	    return(0);}/** * xmlNanoFTPScanProxy: * @URL:  The proxy URL used to initialize the proxy context * * (Re)Initialize the FTP Proxy context by parsing the URL and finding * the protocol host port it indicates. * Should be like ftp://myproxy/ or ftp://myproxy:3128/ * A NULL URL cleans up proxy informations. */voidxmlNanoFTPScanProxy(const char *URL) {    const char *cur = URL;    char buf[XML_NANO_MAX_URLBUF];    int indx = 0;    int port = 0;    if (proxy != NULL) { 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -