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

📄 nanoftp.c

📁 SIP 1.5.0源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        getsockname(ctxt->dataFd, (struct sockaddr *) &dataAddr, &dataAddrLen);	if (listen(ctxt->dataFd, 1) < 0) {	    fprintf(stderr, "Could not listen on port %d\n",	            ntohs(dataAddr.sin_port));	    close(ctxt->dataFd); ctxt->dataFd = -1;	    return (-1);	}	adp = (unsigned char *) &dataAddr.sin_addr;	portp = (unsigned char *) &dataAddr.sin_port;#ifndef HAVE_SNPRINTF	len = sprintf(buf, "PORT %d,%d,%d,%d,%d,%d\r\n",	       adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,	       portp[0] & 0xff, portp[1] & 0xff);#else /* HAVE_SNPRINTF */	len = snprintf(buf, sizeof(buf), "PORT %d,%d,%d,%d,%d,%d\r\n",	       adp[0] & 0xff, adp[1] & 0xff, adp[2] & 0xff, adp[3] & 0xff,	       portp[0] & 0xff, portp[1] & 0xff);#endif /* HAVE_SNPRINTF */        buf[sizeof(buf) - 1] = 0;#ifdef DEBUG_FTP	printf(buf);#endif	res = send(ctxt->controlFd, buf, len, 0);	if (res < 0) {	    close(ctxt->dataFd); ctxt->dataFd = -1;	    return(res);	}        res = xmlNanoFTPGetResponse(ctxt);	if (res != 2) {	    close(ctxt->dataFd); ctxt->dataFd = -1;	    return(-1);        }    }    return(ctxt->dataFd);    }/** * xmlNanoFTPCloseConnection: * @ctx:  an FTP context * * Close the data connection from the server * * Returns -1 incase of error, 0 otherwise */intxmlNanoFTPCloseConnection(void *ctx) {    xmlNanoFTPCtxtPtr ctxt = (xmlNanoFTPCtxtPtr) ctx;    int res;    fd_set rfd, efd;    struct timeval tv;    close(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	close(ctxt->controlFd); ctxt->controlFd = -1;	return(-1);    }    if (res == 0) {	fprintf(stderr, "xmlNanoFTPCloseConnection: timeout\n");	close(ctxt->controlFd); ctxt->controlFd = -1;    } else {	res = xmlNanoFTPGetResponse(ctxt);	if (res != 2) {	    close(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 lenght 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 index = 0, base;    fd_set rfd, efd;    struct timeval tv;    if (filename == NULL) {        if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)	    return(-1);	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);#ifndef HAVE_SNPRINTF	len = sprintf(buf, "LIST -L\r\n");#else /* HAVE_SNPRINTF */	len = snprintf(buf, sizeof(buf), "LIST -L\r\n");#endif /* HAVE_SNPRINTF */    } else {	if (filename[0] != '/') {	    if (xmlNanoFTPCwd(ctxt, ctxt->path) < 1)		return(-1);	}	ctxt->dataFd = xmlNanoFTPGetConnection(ctxt);#ifndef HAVE_SNPRINTF	len = sprintf(buf, "LIST -L %s\r\n", filename);#else /* HAVE_SNPRINTF */	len = snprintf(buf, sizeof(buf), "LIST -L %s\r\n", filename);#endif /* HAVE_SNPRINTF */    }#ifdef DEBUG_FTP    printf(buf);#endif    res = send(ctxt->controlFd, buf, len, 0);    if (res < 0) {	close(ctxt->dataFd); ctxt->dataFd = -1;	return(res);    }    res = xmlNanoFTPReadResponse(ctxt, buf, sizeof(buf) -1);    if (res != 1) {	close(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	    close(ctxt->dataFd); ctxt->dataFd = -1;	    return(-1);	}	if (res == 0) {	    res = xmlNanoFTPCheckResponse(ctxt);	    if (res < 0) {		close(ctxt->dataFd); ctxt->dataFd = -1;		ctxt->dataFd = -1;		return(-1);	    }	    if (res == 2) {		close(ctxt->dataFd); ctxt->dataFd = -1;		return(0);	    }	    continue;	}	if ((len = read(ctxt->dataFd, &buf[index], sizeof(buf) - (index + 1))) < 0) {#ifdef DEBUG_FTP	    perror("read");#endif	    close(ctxt->dataFd); ctxt->dataFd = -1;	    ctxt->dataFd = -1;	    return(-1);	}#ifdef DEBUG_FTP        write(1, &buf[index], len);#endif	index += len;	buf[index] = 0;	base = 0;	do {	    res = xmlNanoFTPParseList(&buf[base], callback, userData);	    base += res;	} while (res > 0);	memmove(&buf[0], &buf[base], index - base);	index -= 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);#ifndef HAVE_SNPRINTF    len = sprintf(buf, "TYPE I\r\n");#else /* HAVE_SNPRINTF */    len = snprintf(buf, sizeof(buf), "TYPE I\r\n");#endif /* HAVE_SNPRINTF */#ifdef DEBUG_FTP    printf(buf);#endif    res = send(ctxt->controlFd, buf, len, 0);    if (res < 0) {	close(ctxt->dataFd); ctxt->dataFd = -1;	return(res);    }    res = xmlNanoFTPReadResponse(ctxt, buf, sizeof(buf) -1);    if (res != 2) {	close(ctxt->dataFd); ctxt->dataFd = -1;	return(-res);    }    if (filename == NULL)#ifndef HAVE_SNPRINTF	len = sprintf(buf, "RETR %s\r\n", ctxt->path);#else /* HAVE_SNPRINTF */	len = snprintf(buf, sizeof(buf), "RETR %s\r\n", ctxt->path);#endif /* HAVE_SNPRINTF */    else#ifndef HAVE_SNPRINTF	len = sprintf(buf, "RETR %s\r\n", filename);#else /* HAVE_SNPRINTF */	len = snprintf(buf, sizeof(buf), "RETR %s\r\n", filename);#endif /* HAVE_SNPRINTF */#ifdef DEBUG_FTP    printf(buf);#endif    res = send(ctxt->controlFd, buf, len, 0);    if (res < 0) {	close(ctxt->dataFd); ctxt->dataFd = -1;	return(res);    }    res = xmlNanoFTPReadResponse(ctxt, buf, sizeof(buf) -1);    if (res != 1) {	close(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	    close(ctxt->dataFd); ctxt->dataFd = -1;	    return(-1);	}	if (res == 0) {	    res = xmlNanoFTPCheckResponse(ctxt);	    if (res < 0) {		close(ctxt->dataFd); ctxt->dataFd = -1;		ctxt->dataFd = -1;		return(-1);	    }	    if (res == 2) {		close(ctxt->dataFd); ctxt->dataFd = -1;		return(0);	    }	    continue;	}	if ((len = read(ctxt->dataFd, &buf, sizeof(buf))) < 0) {	    callback(userData, buf, len);	    close(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 = read(ctxt->dataFd, dest, len);#ifdef DEBUG_FTP    printf("Read %d bytes\n", len);#endif    if (len <= 0) {	xmlNanoFTPCloseConnection(ctxt);    }    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 = 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) {	close(ctxt->dataFd);	ctxt->dataFd = -1;    }    if (ctxt->controlFd >= 0) {	xmlNanoFTPQuit(ctxt);	close(ctxt->controlFd);	ctxt->controlFd = -1;    }    xmlNanoFTPFreeCtxt(ctxt);    return(0);}#ifdef STANDALONE/************************************************************************ * 									* * 			Basic test in Standalone mode			* * 									* ************************************************************************/void 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) {    printf("%s %s %s %ld %s\n", attrib, owner, group, size, filename);}void ftpData(void *userData, const char *data, int len) {    if (userData == NULL) return;    if (len <= 0) {	fclose(userData);	return;    }	    fwrite(data, len, 1, 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) {	    fprintf(stderr, "Couldn't connect to %s\n", argv[1]);	    exit(1);	}	if (argc > 2)	    tstfile = argv[2];    } else	ctxt = xmlNanoFTPConnectTo("localhost", 0);    if (ctxt == NULL) {        fprintf(stderr, "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)	    fprintf(stderr, "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) {    printf("%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 + -