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

📄 nanoftp.c

📁 libxml,在UNIX/LINUX下非常重要的一个库,为XML相关应用提供方便.目前上载的是最新版本,若要取得最新版本,请参考里面的readme.
💻 C
📖 第 1 页 / 共 4 页
字号:
static intxmlNanoFTPParseResponse(char *buf, int len) {    int val = 0;    if (len < 3) return(-1);    if ((*buf >= '0') && (*buf <= '9'))         val = val * 10 + (*buf - '0');    else        return(0);    buf++;    if ((*buf >= '0') && (*buf <= '9'))         val = val * 10 + (*buf - '0');    else        return(0);    buf++;    if ((*buf >= '0') && (*buf <= '9'))         val = val * 10 + (*buf - '0');    else        return(0);    buf++;    if (*buf == '-')         return(-val);    return(val);}/** * xmlNanoFTPGetMore: * @ctx:  an FTP context * * Read more information from the FTP control connection * Returns the number of bytes read, < 0 indicates an error */static intxmlNanoFTPGetMore(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    int len;    int size;    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);    if ((ctxt->controlBufIndex < 0) || (ctxt->controlBufIndex > FTP_BUF_SIZE)) {#ifdef DEBUG_FTP        xmlGenericError(xmlGenericErrorContext,		"xmlNanoFTPGetMore : controlBufIndex = %d\n",		ctxt->controlBufIndex);#endif	return(-1);    }    if ((ctxt->controlBufUsed < 0) || (ctxt->controlBufUsed > FTP_BUF_SIZE)) {#ifdef DEBUG_FTP        xmlGenericError(xmlGenericErrorContext,		"xmlNanoFTPGetMore : controlBufUsed = %d\n",		ctxt->controlBufUsed);#endif	return(-1);    }    if (ctxt->controlBufIndex > ctxt->controlBufUsed) {#ifdef DEBUG_FTP        xmlGenericError(xmlGenericErrorContext,		"xmlNanoFTPGetMore : controlBufIndex > controlBufUsed %d > %d\n",	       ctxt->controlBufIndex, ctxt->controlBufUsed);#endif	return(-1);    }    /*     * First pack the control buffer     */    if (ctxt->controlBufIndex > 0) {	memmove(&ctxt->controlBuf[0], &ctxt->controlBuf[ctxt->controlBufIndex],		ctxt->controlBufUsed - ctxt->controlBufIndex);	ctxt->controlBufUsed -= ctxt->controlBufIndex;	ctxt->controlBufIndex = 0;    }    size = FTP_BUF_SIZE - ctxt->controlBufUsed;    if (size == 0) {#ifdef DEBUG_FTP        xmlGenericError(xmlGenericErrorContext,		"xmlNanoFTPGetMore : buffer full %d \n", ctxt->controlBufUsed);#endif	return(0);    }    /*     * Read the amount left on the control connection     */    if ((len = recv(ctxt->controlFd, &ctxt->controlBuf[ctxt->controlBufIndex],		    size, 0)) < 0) {	__xmlIOErr(XML_FROM_FTP, 0, "recv failed");	closesocket(ctxt->controlFd); ctxt->controlFd = -1;        ctxt->controlFd = -1;        return(-1);    }#ifdef DEBUG_FTP    xmlGenericError(xmlGenericErrorContext,	    "xmlNanoFTPGetMore : read %d [%d - %d]\n", len,	   ctxt->controlBufUsed, ctxt->controlBufUsed + len);#endif    ctxt->controlBufUsed += len;    ctxt->controlBuf[ctxt->controlBufUsed] = 0;    return(len);}/** * xmlNanoFTPReadResponse: * @ctx:  an FTP context * * Read the response from the FTP server after a command. * Returns the code number */static intxmlNanoFTPReadResponse(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    char *ptr, *end;    int len;    int res = -1, cur = -1;    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);get_more:    /*     * Assumes everything up to controlBuf[controlBufIndex] has been read     * and analyzed.     */    len = xmlNanoFTPGetMore(ctx);    if (len < 0) {        return(-1);    }    if ((ctxt->controlBufUsed == 0) && (len == 0)) {        return(-1);    }    ptr = &ctxt->controlBuf[ctxt->controlBufIndex];    end = &ctxt->controlBuf[ctxt->controlBufUsed];#ifdef DEBUG_FTP    xmlGenericError(xmlGenericErrorContext,	    "\n<<<\n%s\n--\n", ptr);#endif    while (ptr < end) {        cur = xmlNanoFTPParseResponse(ptr, end - ptr);	if (cur > 0) {	    /*	     * Successfully scanned the control code, scratch	     * till the end of the line, but keep the index to be	     * able to analyze the result if needed.	     */	    res = cur;	    ptr += 3;	    ctxt->controlBufAnswer = ptr - ctxt->controlBuf;	    while ((ptr < end) && (*ptr != '\n')) ptr++;	    if (*ptr == '\n') ptr++;	    if (*ptr == '\r') ptr++;	    break;	}	while ((ptr < end) && (*ptr != '\n')) ptr++;	if (ptr >= end) {	    ctxt->controlBufIndex = ctxt->controlBufUsed;	    goto get_more;	}	if (*ptr != '\r') ptr++;    }    if (res < 0) goto get_more;    ctxt->controlBufIndex = ptr - ctxt->controlBuf;#ifdef DEBUG_FTP    ptr = &ctxt->controlBuf[ctxt->controlBufIndex];    xmlGenericError(xmlGenericErrorContext, "\n---\n%s\n--\n", ptr);#endif#ifdef DEBUG_FTP    xmlGenericError(xmlGenericErrorContext, "Got %d\n", res);#endif    return(res / 100);}/** * xmlNanoFTPGetResponse: * @ctx:  an FTP context * * Get the response from the FTP server after a command. * Returns the code number */intxmlNanoFTPGetResponse(void *ctx) {    int res;    res = xmlNanoFTPReadResponse(ctx);    return(res);}/** * xmlNanoFTPCheckResponse: * @ctx:  an FTP context * * Check if there is a response from the FTP server after a command. * Returns the code number, or 0 */intxmlNanoFTPCheckResponse(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    fd_set rfd;    struct timeval tv;    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);    tv.tv_sec = 0;    tv.tv_usec = 0;    FD_ZERO(&rfd);    FD_SET(ctxt->controlFd, &rfd);    switch(select(ctxt->controlFd + 1, &rfd, NULL, NULL, &tv)) {	case 0:	    return(0);	case -1:	    __xmlIOErr(XML_FROM_FTP, 0, "select");	    return(-1);			    }    return(xmlNanoFTPReadResponse(ctx));}/** * Send the user authentication */static intxmlNanoFTPSendUser(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    char buf[200];    int len;    int res;    if (ctxt->user == NULL)	snprintf(buf, sizeof(buf), "USER anonymous\r\n");    else	snprintf(buf, sizeof(buf), "USER %s\r\n", ctxt->user);    buf[sizeof(buf) - 1] = 0;    len = strlen(buf);#ifdef DEBUG_FTP    xmlGenericError(xmlGenericErrorContext, "%s", buf);#endif    res = send(ctxt->controlFd, buf, len, 0);    if (res < 0) {	__xmlIOErr(XML_FROM_FTP, 0, "send failed");	return(res);    }    return(0);}/** * Send the password authentication */static intxmlNanoFTPSendPasswd(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    char buf[200];    int len;    int res;    if (ctxt->passwd == NULL)	snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");    else	snprintf(buf, sizeof(buf), "PASS %s\r\n", ctxt->passwd);    buf[sizeof(buf) - 1] = 0;    len = strlen(buf);#ifdef DEBUG_FTP    xmlGenericError(xmlGenericErrorContext, "%s", buf);#endif    res = send(ctxt->controlFd, buf, len, 0);    if (res < 0) {	__xmlIOErr(XML_FROM_FTP, 0, "send failed");	return(res);    }    return(0);}/** * xmlNanoFTPQuit: * @ctx:  an FTP context * * Send a QUIT command to the server * * Returns -1 in case of error, 0 otherwise */intxmlNanoFTPQuit(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    char buf[200];    int len, res;    if ((ctxt == NULL) || (ctxt->controlFd < 0)) return(-1);    snprintf(buf, sizeof(buf), "QUIT\r\n");    len = strlen(buf);#ifdef DEBUG_FTP    xmlGenericError(xmlGenericErrorContext, "%s", buf); /* Just to be consistent, even though we know it can't have a % in it */#endif    res = send(ctxt->controlFd, buf, len, 0);    if (res < 0) {	__xmlIOErr(XML_FROM_FTP, 0, "send failed");	return(res);    }    return(0);}/** * xmlNanoFTPConnect: * @ctx:  an FTP context * * Tries to open a control connection * * Returns -1 in case of error, 0 otherwise */intxmlNanoFTPConnect(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    struct hostent *hp;    int port;    int res;    int addrlen = sizeof (struct sockaddr_in);    if (ctxt == NULL)	return(-1);    if (ctxt->hostname == NULL)	return(-1);    /*     * do the blocking DNS query.     */    if (proxy) {        port = proxyPort;    } else {	port = ctxt->port;    }    if (port == 0)	port = 21;    memset (&ctxt->ftpAddr, 0, sizeof(ctxt->ftpAddr));#ifdef SUPPORT_IP6    if (have_ipv6 ()) {	struct addrinfo hints, *tmp, *result;	result = NULL;	memset (&hints, 0, sizeof(hints));	hints.ai_socktype = SOCK_STREAM;	if (proxy) {	    if (getaddrinfo (proxy, NULL, &hints, &result) != 0) {		__xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");		return (-1);	    }	}	else	    if (getaddrinfo (ctxt->hostname, NULL, &hints, &result) != 0) {		__xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");		return (-1);	    }	for (tmp = result; tmp; tmp = tmp->ai_next)	    if (tmp->ai_family == AF_INET || tmp->ai_family == AF_INET6)		break;	if (!tmp) {	    if (result)		freeaddrinfo (result);	    __xmlIOErr(XML_FROM_FTP, 0, "getaddrinfo failed");	    return (-1);	}	if (tmp->ai_addrlen > sizeof(ctxt->ftpAddr)) {	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");	    return (-1);	}	if (tmp->ai_family == AF_INET6) {	    memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen);	    ((struct sockaddr_in6 *) &ctxt->ftpAddr)->sin6_port = htons (port);	    ctxt->controlFd = socket (AF_INET6, SOCK_STREAM, 0);	}	else {	    memcpy (&ctxt->ftpAddr, tmp->ai_addr, tmp->ai_addrlen);	    ((struct sockaddr_in *) &ctxt->ftpAddr)->sin_port = htons (port);	    ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);	}	addrlen = tmp->ai_addrlen;	freeaddrinfo (result);    }    else#endif    {	if (proxy)	    hp = gethostbyname (proxy);	else	    hp = gethostbyname (ctxt->hostname);	if (hp == NULL) {	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname failed");	    return (-1);	}	if ((unsigned int) hp->h_length >	    sizeof(((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr)) {	    __xmlIOErr(XML_FROM_FTP, 0, "gethostbyname address mismatch");	    return (-1);	}	/*	 * Prepare the socket	 */	((struct sockaddr_in *)&ctxt->ftpAddr)->sin_family = AF_INET;	memcpy (&((struct sockaddr_in *)&ctxt->ftpAddr)->sin_addr,		hp->h_addr_list[0], hp->h_length);	((struct sockaddr_in *)&ctxt->ftpAddr)->sin_port = htons (port);	ctxt->controlFd = socket (AF_INET, SOCK_STREAM, 0);	addrlen = sizeof (struct sockaddr_in);    }    if (ctxt->controlFd < 0) {	__xmlIOErr(XML_FROM_FTP, 0, "socket failed");        return(-1);    }    /*     * Do the connect.     */    if (connect(ctxt->controlFd, (struct sockaddr *) &ctxt->ftpAddr,	    addrlen) < 0) {	__xmlIOErr(XML_FROM_FTP, 0, "Failed to create a connection");        closesocket(ctxt->controlFd); ctxt->controlFd = -1;        ctxt->controlFd = -1;	return(-1);    }    /*     * Wait for the HELLO from the server.     */    res = xmlNanoFTPGetResponse(ctxt);    if (res != 2) {        closesocket(ctxt->controlFd); ctxt->controlFd = -1;        ctxt->controlFd = -1;	return(-1);    }    /*     * State diagram for the login operation on the FTP server     *     * Reference: RFC 959     *     *                       1     * +---+   USER    +---+------------->+---+     * | B |---------->| W | 2       ---->| E |     * +---+           +---+------  |  -->+---+     *                  | |       | | |     *                3 | | 4,5   | | |     *    --------------   -----  | | |     *   |                      | | | |     *   |                      | | | |     *   |                 ---------  |     *   |               1|     | |   |     *   V                |     | |   |     * +---+   PASS    +---+ 2  |  ------>+---+     * |   |---------->| W |------------->| S |     * +---+           +---+   ---------->+---+     *                  | |   | |     |     *                3 | |4,5| |     |     *    --------------   --------   |     *   |                    | |  |  |     *   |                    | |  |  |     *   |                 -----------     *   |             1,3|   | |  |     *   V                |  2| |  |     * +---+   ACCT    +---+--  |   ----->+---+     * |   |---------->| W | 4,5 -------->| F |     * +---+           +---+------------->+---+     *     * Of course in case of using a proxy this get really nasty and is not     * standardized at all :-(     */    if (proxy) {        int len;	char buf[400];        if (proxyUser != NULL) {	    /*	     * We need proxy auth	     */	    snprintf(buf, sizeof(buf), "USER %s\r\n", proxyUser);            buf[sizeof(buf) - 1] = 0;            len = strlen(buf);#ifdef DEBUG_FTP	    xmlGenericError(xmlGenericErrorContext, "%s", buf);#endif	    res = send(ctxt->controlFd, buf, len, 0);	    if (res < 0) {		__xmlIOErr(XML_FROM_FTP, 0, "send failed");		closesocket(ctxt->controlFd);		ctxt->controlFd = -1;	        return(res);	    }	    res = xmlNanoFTPGetResponse(ctxt);	    switch (res) {		case 2:		    if (proxyPasswd == NULL)			break;		case 3:		    if (proxyPasswd != NULL)			snprintf(buf, sizeof(buf), "PASS %s\r\n", proxyPasswd);		    else			snprintf(buf, sizeof(buf), "PASS anonymous@\r\n");                    buf[sizeof(buf) - 1] = 0;                    len = strlen(buf);#ifdef DEBUG_FTP		    xmlGenericError(xmlGenericErrorContext, "%s", buf);#endif		    res = send(ctxt->controlFd, buf, len, 0);		    if (res < 0) {			__xmlIOErr(XML_FROM_FTP, 0, "send failed");			closesocket(ctxt->controlFd);			ctxt->controlFd = -1;			return(res);		    }		    res = xmlNanoFTPGetResponse(ctxt);		    if (res > 3) {

⌨️ 快捷键说明

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