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

📄 ftpxfer2.c

📁 Vxworks下的C例子程序
💻 C
字号:
/* * Replacement for ftpXfer. * * Author: Curt McDowell (csm@broadcom.com) * * * $Id: ftpXfer2.c,v 1.2 1999/10/25 18:22:05 borkhuis Exp $ * */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <selectLib.h>#include <errnoLib.h>#include <ftpLib.h>#include "config.h"#include "sysLib.h"#include "netinet/in.h"#include "sockLib.h"#define FTP_DATA_CONN_TIMEOUT		20	/* sec *//* * ftpXfer2 * * This routine replaces VxWorks ftpXfer and doesn't have a bug that can * cause very small file transfers to fail.  In particular, it calls * select() on both the data and control sockets, and if they become * ready at the SAME TIME (as opposed to just the data socket), vxWorks * falsely assumes an error. */extern BOOL ftpVerbose;STATUS ftpXfer2(char *host, char *user, char *passwd, char *acct,		char *cmd, char *dirname, char *filename,		int *pCtrlSock, int *pDataSock){    int			ctrlSock = ERROR, dataSock = ERROR;    struct fd_set 	rfd;    int			result;    struct timeval	tmo;    char		*errmsg = NULL;    if (ftpVerbose)	printf("ftpXfer2: hookup host=%s file=%s\n", host, filename);    if ((ctrlSock = ftpHookup(host)) == ERROR) {	errmsg = "server unreachable";	goto error;    }    *pCtrlSock = ctrlSock;    if (ftpVerbose)	printf("ftpXfer2: login user=%s\n", user);    if (ftpLogin(ctrlSock, user, passwd, acct) != OK) {	errmsg = "authentication failed";	goto error;    }    if (ftpVerbose)	printf("ftpXfer2: set binary\n");    if (ftpCommand(ctrlSock, "TYPE I", 0, 0, 0, 0, 0, 0) != FTP_COMPLETE) {	errmsg = "set binary mode failed";	goto error;    }    if (dirname[0]) {	if (ftpVerbose)	    printf("ftpXfer2: cd %s\n", dirname);	if (ftpCommand(ctrlSock, "CWD %s",		       (int) dirname, 0, 0, 0, 0, 0) != FTP_COMPLETE) {	    errmsg = "change directory failed";	    goto error;	}    }    /*     * Retry loop for transient errors, such as the remote host being     * unable to assign the requested port number.     */ retry_transient_error:    /*     * If this is a transfer command requiring a data connection,     * first establish socket for server to connect back to.     */    if (pDataSock) {	int			len;	short			port;	struct sockaddr_in 	ownAddr;	struct sockaddr_in 	dataAddr;	if (ftpVerbose)	    printf("ftpXfer2: set binary\n");	/* Find out our own address */	len = sizeof (ownAddr);	if (getsockname(ctrlSock, (struct sockaddr *) &ownAddr, &len) < 0) {	    errmsg = "FTP could not get own addr";	    goto error;	}	if ((dataSock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {	    errmsg = "FTP could not create data socket";	    goto error;	}	dataAddr = ownAddr;	dataAddr.sin_port = htons(0);	if (bind(dataSock,		 (struct sockaddr *) &dataAddr,		 sizeof (dataAddr)) != OK) {	    close(dataSock);	    errmsg = "FTP could not bind data socket";	    goto error;	}	/* Read back to find out what port was bound */	len = sizeof (dataAddr);	if (getsockname(dataSock, (struct sockaddr *) &dataAddr, &len) < 0) {	    errmsg = "FTP could not get data addr";	    goto error;	}	port = ntohs(dataAddr.sin_port);	if (listen(dataSock, 1) < 0) {	    close(dataSock);	    errmsg = "FTP could not listen on data socket";	    goto error;	}	/* Use PORT command to inform server of data socket address */	if (ftpCommand(ctrlSock,		       "PORT %d,%d,%d,%d,%d,%d",		       (int) ((UINT8 *) &dataAddr.sin_addr)[0],		       (int) ((UINT8 *) &dataAddr.sin_addr)[1],		       (int) ((UINT8 *) &dataAddr.sin_addr)[2],		       (int) ((UINT8 *) &dataAddr.sin_addr)[3],		       (int) (port >> 8),		       (int) (port & 0xff)) != FTP_COMPLETE) {	    close(dataSock);	    errmsg = "FTP could not send PORT command";	    goto error;	}    }    /*     * Send the FTP command.     */    if (ftpVerbose)	printf("ftpXfer2: command %s\n", cmd);    result = ftpCommand(ctrlSock, cmd, (int) filename, 0, 0, 0, 0, 0);    if (ftpVerbose)	printf("ftpXfer2: result %d\n", result);    switch (result) {    case FTP_TRANSIENT:	if (pDataSock)	    close(dataSock);	goto retry_transient_error;    case FTP_COMPLETE:    case FTP_CONTINUE:	if (pDataSock) {	    close(dataSock);	    errmsg = "server returned COMPLETE or CONTINUE instead of PRELIM";	    goto error;	}	return OK;	/* Non-transfer command succeeded */    case FTP_PRELIM:	if (! pDataSock) {	    errmsg = "server returned PRELIM for non-transfer command";	    goto error;	}	break;		/* Continue below to start transfer */    default:	if (pDataSock)	    close(dataSock);	errmsg = "command failed";	goto error;    }    /*     * Wait for server to connect back on data socket.     * Use select to provide a timeout.     */    FD_ZERO(&rfd);    FD_SET(dataSock, &rfd);    tmo.tv_sec = FTP_DATA_CONN_TIMEOUT;    tmo.tv_usec = 0;    if (ftpVerbose)	printf("ftpXfer2: wait for data\n");    if (select(FD_SETSIZE, &rfd, NULL, NULL, &tmo) < 0) {	if (pDataSock)	    close(dataSock);	errmsg = "data conn failed or timed out";	goto error;    }    if (ftpVerbose)	printf("ftpXfer2: get data conn\n");    if ((dataSock = ftpDataConnGet(dataSock)) == ERROR) {	errmsg = "failed to accept server connection";	goto error;    }    *pDataSock = dataSock;    if (ftpVerbose)	printf("ftpXfer2: return OK\n");    return OK; error:    if (errmsg && ftpVerbose)	printErr("FTP ERROR: %s (errno=%d)\n", errmsg, errnoGet());    if (ctrlSock != ERROR) {	(void) ftpCommand(ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0);	close(ctrlSock);    }    if (ftpVerbose)	printf("ftpXfer2: return ERROR\n");    return ERROR;}

⌨️ 快捷键说明

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