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

📄 nanoftp.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
intxmlNanoFTPCloseConnection(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    int res;    fd_set rfd, efd;    struct timeval tv;    closesocket(ctxt->dataFd); ctxt->dataFd = -1;    tv.tv_sec = 15;    tv.tv_usec = 0;    FD_ZERO(&rfd);    FD_SET(ctxt->controlFd, &rfd);    FD_ZERO(&efd);    FD_SET(ctxt->controlFd, &efd);    res = select(ctxt->controlFd + 1, &rfd, NULL, &efd, &tv);    if (res < 0) {#ifdef DEBUG_FTP	perror("select");#endif	closesocket(ctxt->controlFd); ctxt->controlFd = -1;	return(-1);    }    if (res == 0) {#ifdef DEBUG_FTP	xmlGenericError(xmlGenericErrorContext,		"xmlNanoFTPCloseConnection: timeout\n");#endif	closesocket(ctxt->controlFd); ctxt->controlFd = -1;    } else {	res = xmlNanoFTPGetResponse(ctxt);	if (res != 2) {	    closesocket(ctxt->controlFd); ctxt->controlFd = -1;	    return(-1);	}    }    return(0);}/** * xmlNanoFTPParseList: * @list:  some data listing received from the server * @callback:  the user callback * @userData:  the user callback data * * Parse at most one entry from the listing.  * * Returns -1 incase of error, the length of data parsed otherwise */static intxmlNanoFTPParseList(const char *list, ftpListCallback callback, void *userData) {    const char *cur = list;    char filename[151];    char attrib[11];    char owner[11];    char group[11];    char month[4];    int year = 0;    int minute = 0;    int hour = 0;    int day = 0;    unsigned long size = 0;    int links = 0;    int i;    if (!strncmp(cur, "total", 5)) {        cur += 5;	while (*cur == ' ') cur++;	while ((*cur >= '0') && (*cur <= '9'))	    links = (links * 10) + (*cur++ - '0');	while ((*cur == ' ') || (*cur == '\n')  || (*cur == '\r'))	    cur++;	return(cur - list);    } else if (*list == '+') {	return(0);    } else {	while ((*cur == ' ') || (*cur == '\n')  || (*cur == '\r'))	    cur++;	if (*cur == 0) return(0);	i = 0;	while (*cur != ' ') {	    if (i < 10) 		attrib[i++] = *cur;	    cur++;	    if (*cur == 0) return(0);	}	attrib[10] = 0;	while (*cur == ' ') cur++;	if (*cur == 0) return(0);	while ((*cur >= '0') && (*cur <= '9'))	    links = (links * 10) + (*cur++ - '0');	while (*cur == ' ') cur++;	if (*cur == 0) return(0);	i = 0;	while (*cur != ' ') {	    if (i < 10) 		owner[i++] = *cur;	    cur++;	    if (*cur == 0) return(0);	}	owner[i] = 0;	while (*cur == ' ') cur++;	if (*cur == 0) return(0);	i = 0;	while (*cur != ' ') {	    if (i < 10) 		group[i++] = *cur;	    cur++;	    if (*cur == 0) return(0);	}	group[i] = 0;	while (*cur == ' ') cur++;	if (*cur == 0) return(0);	while ((*cur >= '0') && (*cur <= '9'))	    size = (size * 10) + (*cur++ - '0');	while (*cur == ' ') cur++;	if (*cur == 0) return(0);	i = 0;	while (*cur != ' ') {	    if (i < 3)		month[i++] = *cur;	    cur++;	    if (*cur == 0) return(0);	}	month[i] = 0;	while (*cur == ' ') cur++;	if (*cur == 0) return(0);        while ((*cur >= '0') && (*cur <= '9'))	    day = (day * 10) + (*cur++ - '0');	while (*cur == ' ') cur++;	if (*cur == 0) return(0);	if ((cur[1] == 0) || (cur[2] == 0)) return(0);	if ((cur[1] == ':') || (cur[2] == ':')) {	    while ((*cur >= '0') && (*cur <= '9'))		hour = (hour * 10) + (*cur++ - '0');	    if (*cur == ':') cur++;	    while ((*cur >= '0') && (*cur <= '9'))		minute = (minute * 10) + (*cur++ - '0');	} else {	    while ((*cur >= '0') && (*cur <= '9'))		year = (year * 10) + (*cur++ - '0');	}	while (*cur == ' ') cur++;	if (*cur == 0) return(0);	i = 0;	while ((*cur != '\n')  && (*cur != '\r')) {	    if (i < 150)		filename[i++] = *cur;	    cur++;	    if (*cur == 0) return(0);	}	filename[i] = 0;	if ((*cur != '\n') && (*cur != '\r'))	    return(0);	while ((*cur == '\n')  || (*cur == '\r'))	    cur++;    }    if (callback != NULL) {        callback(userData, filename, attrib, owner, group, size, links,		 year, month, day, hour, minute);    }    return(cur - list);}/** * xmlNanoFTPList: * @ctx:  an FTP context * @callback:  the user callback * @userData:  the user callback data * @filename:  optional files to list * * Do a listing on the server. All files info are passed back * in the callbacks. * * Returns -1 incase of error, 0 otherwise */intxmlNanoFTPList(void *ctx, ftpListCallback callback, void *userData,	       char *filename) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    char buf[4096 + 1];    int len, res;    int indx = 0, base;    fd_set rfd, efd;    struct timeval tv;    if (filename == NULL) {        if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)	    return(-1);	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);	if (ctxt->dataFd == -1)	    return(-1);	snprintf(buf, sizeof(buf), "LIST -L\r\n");    } else {	if (filename[0] != '/') {	    if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)		return(-1);	}	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);	if (ctxt->dataFd == -1)	    return(-1);	snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);    }    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->dataFd); ctxt->dataFd = -1;	return(res);    }    res = xmlNanoFTPReadResponse(ctxt);    if (res != 1) {	closesocket(ctxt->dataFd); ctxt->dataFd = -1;	return(-res);    }    do {	tv.tv_sec = 1;	tv.tv_usec = 0;	FD_ZERO(&rfd);	FD_SET(ctxt->dataFd, &rfd);	FD_ZERO(&efd);	FD_SET(ctxt->dataFd, &efd);	res = select(ctxt->dataFd + 1, &rfd, NULL, &efd, &tv);	if (res < 0) {#ifdef DEBUG_FTP	    perror("select");#endif	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;	    return(-1);	}	if (res == 0) {	    res = xmlNanoFTPCheckResponse(ctxt);	    if (res < 0) {		closesocket(ctxt->dataFd); ctxt->dataFd = -1;		ctxt->dataFd = -1;		return(-1);	    }	    if (res == 2) {		closesocket(ctxt->dataFd); ctxt->dataFd = -1;		return(0);	    }	    continue;	}	if ((len = recv(ctxt->dataFd, &buf[indx], sizeof(buf) - (indx + 1), 0)) < 0) {	    __xmlIOErr(XML_FROM_FTP, 0, "recv");	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;	    ctxt->dataFd = -1;	    return(-1);	}#ifdef DEBUG_FTP        write(1, &buf[indx], len);#endif	indx += len;	buf[indx] = 0;	base = 0;	do {	    res = xmlNanoFTPParseList(&buf[base], callback, userData);	    base += res;	} while (res > 0);	memmove(&buf[0], &buf[base], indx - base);	indx -= base;    } while (len != 0);    xmlNanoFTPCloseConnection(ctxt);    return(0);}/** * xmlNanoFTPGetSocket: * @ctx:  an FTP context * @filename:  the file to retrieve (or NULL if path is in context). * * Initiate fetch of the given file from the server. * * Returns the socket for the data connection, or <0 in case of error */intxmlNanoFTPGetSocket(void *ctx, const char *filename) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    char buf[300];    int res, len;    if ((filename == NULL) && (ctxt->path == NULL))	return(-1);    ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);    if (ctxt->dataFd == -1)	return(-1);    snprintf(buf, sizeof(buf), "TYPE I\r\n");    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->dataFd); ctxt->dataFd = -1;	return(res);    }    res = xmlNanoFTPReadResponse(ctxt);    if (res != 2) {	closesocket(ctxt->dataFd); ctxt->dataFd = -1;	return(-res);    }    if (filename == NULL)	snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);    else	snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);    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->dataFd); ctxt->dataFd = -1;	return(res);    }    res = xmlNanoFTPReadResponse(ctxt);    if (res != 1) {	closesocket(ctxt->dataFd); ctxt->dataFd = -1;	return(-res);    }    return(ctxt->dataFd);}/** * xmlNanoFTPGet: * @ctx:  an FTP context * @callback:  the user callback * @userData:  the user callback data * @filename:  the file to retrieve * * Fetch the given file from the server. All data are passed back * in the callbacks. The last callback has a size of 0 block. * * Returns -1 incase of error, 0 otherwise */intxmlNanoFTPGet(void *ctx, ftpDataCallback callback, void *userData,	      const char *filename) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    char buf[4096];    int len = 0, res;    fd_set rfd;    struct timeval tv;    if ((filename == NULL) && (ctxt->path == NULL))	return(-1);    if (callback == NULL)	return(-1);    if (xmlNanoFTPGetSocket(ctxt, filename) < 0)	return(-1);    do {	tv.tv_sec = 1;	tv.tv_usec = 0;	FD_ZERO(&rfd);	FD_SET(ctxt->dataFd, &rfd);	res = select(ctxt->dataFd + 1, &rfd, NULL, NULL, &tv);	if (res < 0) {#ifdef DEBUG_FTP	    perror("select");#endif	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;	    return(-1);	}	if (res == 0) {	    res = xmlNanoFTPCheckResponse(ctxt);	    if (res < 0) {		closesocket(ctxt->dataFd); ctxt->dataFd = -1;		ctxt->dataFd = -1;		return(-1);	    }	    if (res == 2) {		closesocket(ctxt->dataFd); ctxt->dataFd = -1;		return(0);	    }	    continue;	}	if ((len = recv(ctxt->dataFd, buf, sizeof(buf), 0)) < 0) {	    __xmlIOErr(XML_FROM_FTP, 0, "recv failed");	    callback(userData, buf, len);	    closesocket(ctxt->dataFd); ctxt->dataFd = -1;	    return(-1);	}	callback(userData, buf, len);    } while (len != 0);    return(xmlNanoFTPCloseConnection(ctxt));}/** * xmlNanoFTPRead: * @ctx:  the FTP context * @dest:  a buffer * @len:  the buffer length * * This function tries to read @len bytes from the existing FTP connection * and saves them in @dest. This is a blocking call. * * Returns the number of byte read. 0 is an indication of an end of connection. *         -1 indicates a parameter error. */intxmlNanoFTPRead(void *ctx, void *dest, int len) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    if (ctx == NULL) return(-1);    if (ctxt->dataFd < 0) return(0);    if (dest == NULL) return(-1);    if (len <= 0) return(0);    len = recv(ctxt->dataFd, dest, len, 0);    if (len <= 0) {        __xmlIOErr(XML_FROM_FTP, 0, "recv failed");	xmlNanoFTPCloseConnection(ctxt);    }#ifdef DEBUG_FTP    xmlGenericError(xmlGenericErrorContext, "Recvd %d bytes\n", len);#endif    return(len);}/** * xmlNanoFTPOpen: * @URL: the URL to the resource * * Start to fetch the given ftp:// resource * * Returns an FTP context, or NULL  */void*xmlNanoFTPOpen(const char *URL) {    xmlNanoFTPCtxtPtr ctxt;    int sock;    xmlNanoFTPInit();    if (URL == NULL) return(NULL);    if (strncmp("ftp://", URL, 6)) return(NULL);    ctxt = (xmlNanoFTPCtxtPtr) xmlNanoFTPNewCtxt(URL);    if (ctxt == NULL) return(NULL);    if (xmlNanoFTPConnect(ctxt) < 0) {	xmlNanoFTPFreeCtxt(ctxt);	return(NULL);    }    sock = xmlNanoFTPGetSocket(ctxt, ctxt->path);    if (sock < 0) {	xmlNanoFTPFreeCtxt(ctxt);	return(NULL);    }    return(ctxt);}/** * xmlNanoFTPClose: * @ctx: an FTP context * * Close the connection and both control and transport * * Returns -1 incase of error, 0 otherwise */intxmlNanoFTPClose(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    if (ctxt == NULL)	return(-1);    if (ctxt->dataFd >= 0) {	closesocket(ctxt->dataFd);	ctxt->dataFd = -1;    }    if (ctxt->controlFd >= 0) {	xmlNanoFTPQuit(ctxt);	closesocket(ctxt->controlFd);	ctxt->controlFd = -1;    }    xmlNanoFTPFreeCtxt(ctxt);    return(0);}#ifdef STANDALONE/************************************************************************ * 									* * 			Basic test in Standalone mode			* * 									* ************************************************************************/staticvoid ftpList(void *userData, const char *filename, const char* attrib,	     const char *owner, const char *group, unsigned long size, int links,	     int year, const char *month, int day, int hour, int minute) {    xmlGenericError(xmlGenericErrorContext,	    "%s %s %s %ld %s\n", attrib, owner, group, size, filename);}staticvoid ftpData(void *userData, const char *data, int len) {    if (userData == NULL) return;    if (len <= 0) {	fclose((FILE*)userData);	return;    }	    fwrite(data, len, 1, (FILE*)userData);}int main(int argc, char **argv) {    void *ctxt;    FILE *output;    char *tstfile = NULL;    xmlNanoFTPInit();    if (argc > 1) {	ctxt = xmlNanoFTPNewCtxt(argv[1]);	if (xmlNanoFTPConnect(ctxt) < 0) {	    xmlGenericError(xmlGenericErrorContext,		    "Couldn't connect to %s\n", argv[1]);	    exit(1);	}	if (argc > 2)	    tstfile = argv[2];    } else	ctxt = xmlNanoFTPConnectTo("localhost", 0);    if (ctxt == NULL) {        xmlGenericError(xmlGenericErrorContext,		"Couldn't connect to localhost\n");        exit(1);    }    xmlNanoFTPList(ctxt, ftpList, NULL, tstfile);    output = fopen("/tmp/tstdata", "w");    if (output != NULL) {	if (xmlNanoFTPGet(ctxt, ftpData, (void *) output, tstfile) < 0)	    xmlGenericError(xmlGenericErrorContext,		    "Failed to get file\n");	    }    xmlNanoFTPClose(ctxt);    xmlMemoryDump();    exit(0);}#endif /* STANDALONE */#else /* !LIBXML_FTP_ENABLED */#ifdef STANDALONE#include <stdio.h>int main(int argc, char **argv) {    xmlGenericError(xmlGenericErrorContext,	    "%s : FTP support not compiled in\n", argv[0]);    return(0);}#endif /* STANDALONE */#endif /* LIBXML_FTP_ENABLED */

⌨️ 快捷键说明

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