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

📄 nanoftp.c

📁 libxml,在UNIX/LINUX下非常重要的一个库,为XML相关应用提供方便.目前上载的是最新版本,若要取得最新版本,请参考里面的readme.
💻 C
📖 第 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 XML_SOCKLEN_T#define XML_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 XML_SOCKLEN_T unsigned int#endif#ifdef __BEOS__#ifndef PF_INET#define PF_INET AF_INET#endif#endif#ifdef _AIX#define ss_family __ss_family#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 && ((env[0] == '*' ) && (env[1] == 0)))	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);	proxy = NULL;    }    if (proxyUser != NULL) {	xmlFree(proxyUser);	proxyUser = NULL;    }    if (proxyPasswd != NULL) {	xmlFree(proxyPasswd);	proxyPasswd = NULL;    }    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;    xmlURIPtr uri;    /*     * Clear any existing data from the context     */    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;    uri = xmlParseURI(URL);    if (uri == NULL)	return;    if ((uri->scheme == NULL) || (uri->server == NULL)) {	xmlFreeURI(uri);	return;    }        ctxt->protocol = xmlMemStrdup(uri->scheme);    ctxt->hostname = xmlMemStrdup(uri->server);    if (uri->path != NULL)	ctxt->path = xmlMemStrdup(uri->path);    else	ctxt->path = xmlMemStrdup("/");    if (uri->port != 0)	ctxt->port = uri->port;    if (uri->user != NULL) {	char *cptr;	if ((cptr=strchr(uri->user, ':')) == NULL)	    ctxt->user = xmlMemStrdup(uri->user);	else {	    ctxt->user = (char *)xmlStrndup((xmlChar *)uri->user,			    (cptr - uri->user));	    ctxt->passwd = xmlMemStrdup(cptr+1);	}    }    xmlFreeURI(uri);}/** * 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;    xmlURIPtr uri;    if (URL == NULL)	return(-1);    if (ctxt == NULL)	return(-1);    if (ctxt->protocol == NULL)	return(-1);    if (ctxt->hostname == NULL)	return(-1);    uri = xmlParseURI(URL);    if (uri == NULL)	return(-1);    if ((uri->scheme == NULL) || (uri->server == NULL)) {	xmlFreeURI(uri);	return(-1);    }    if ((strcmp(ctxt->protocol, uri->scheme)) ||	(strcmp(ctxt->hostname, uri->server)) ||	((uri->port != 0) && (ctxt->port != uri->port))) {	xmlFreeURI(uri);	return(-1);    }    if (uri->port != 0)	ctxt->port = uri->port;    if (ctxt->path != NULL) {	xmlFree(ctxt->path);	ctxt->path = NULL;    }    if (uri->path == NULL)         ctxt->path = xmlMemStrdup("/");    else	ctxt->path = xmlMemStrdup(uri->path);    xmlFreeURI(uri);    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) {    xmlURIPtr uri;    if (proxy != NULL) {         xmlFree(proxy);	proxy = NULL;    }    proxyPort = 0;#ifdef DEBUG_FTP    if (URL == NULL)	xmlGenericError(xmlGenericErrorContext,		"Removing FTP proxy info\n");    else	xmlGenericError(xmlGenericErrorContext,		"Using FTP proxy %s\n", URL);#endif    if (URL == NULL) return;    uri = xmlParseURI(URL);    if ((uri == NULL) || (uri->scheme == NULL) ||	(strcmp(uri->scheme, "ftp")) || (uri->server == NULL)) {	__xmlIOErr(XML_FROM_FTP, XML_FTP_URL_SYNTAX, "Syntax Error\n");	if (uri != NULL)	    xmlFreeURI(uri);	return;    }        proxy = xmlMemStrdup(uri->server);    if (uri->port != 0)	proxyPort = uri->port;    xmlFreeURI(uri);}/** * xmlNanoFTPNewCtxt: * @URL:  The URL used to initialize the context * * Allocate and initialize a new FTP context. * * Returns an FTP context or NULL in case of error. */void*xmlNanoFTPNewCtxt(const char *URL) {    xmlNanoFTPCtxtPtr ret;    char *unescaped;    ret = (xmlNanoFTPCtxtPtr) xmlMalloc(sizeof(xmlNanoFTPCtxt));    if (ret == NULL) {        xmlFTPErrMemory("allocating FTP context");        return(NULL);    }    memset(ret, 0, sizeof(xmlNanoFTPCtxt));    ret->port = 21;    ret->passive = 1;    ret->returnValue = 0;    ret->controlBufIndex = 0;    ret->controlBufUsed = 0;    ret->controlFd = -1;    unescaped = xmlURIUnescapeString(URL, 0, NULL);    if (unescaped != NULL) {	xmlNanoFTPScanURL(ret, unescaped);	xmlFree(unescaped);    } else if (URL != NULL)	xmlNanoFTPScanURL(ret, URL);    return(ret);}/** * xmlNanoFTPFreeCtxt: * @ctx:  an FTP context * * Frees the context after closing the connection. */voidxmlNanoFTPFreeCtxt(void * ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    if (ctxt == NULL) return;    if (ctxt->hostname != NULL) xmlFree(ctxt->hostname);    if (ctxt->protocol != NULL) xmlFree(ctxt->protocol);    if (ctxt->path != NULL) xmlFree(ctxt->path);    ctxt->passive = 1;    if (ctxt->controlFd >= 0) closesocket(ctxt->controlFd);    ctxt->controlFd = -1;    ctxt->controlBufIndex = -1;    ctxt->controlBufUsed = -1;    xmlFree(ctxt);}/** * xmlNanoFTPParseResponse: * @buf:  the buffer containing the response * @len:  the buffer length *  * Parsing of the server answer, we just extract the code. * * returns 0 for errors *     +XXX for last line of response *     -XXX for response to be continued */

⌨️ 快捷键说明

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