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

📄 ftplib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************* ftpReplyGet - get an FTP command reply** This routine gets a command reply on the specified control socket.* All the lines of a reply are read (multi-line replies are* indicated with the continuation character "-" as the fourth character* of all but the last line).** The three-digit reply code from the first line is saved and interpreted.* The left-most digit of the reply code identifies the type of code* (see RETURNS below).** The caller's error status is set to the complete three-digit reply code* (see the manual entry for errnoGet()).* If the reply code indicates an error, the entire reply* is printed on standard error.** If an EOF is encountered on the specified control socket, but no EOF was* expected (<expecteof> == FALSE), then ERROR is returned.** RETURNS:*  1 = FTP_PRELIM (positive preliminary)*  2 = FTP_COMPLETE (positive completion)*  3 = FTP_CONTINUE (positive intermediate)*  4 = FTP_TRANSIENT (transient negative completion)*  5 = FTP_ERROR (permanent negative completion)** ERROR if there is a read/write error or an unexpected EOF.*/int ftpReplyGet    (    int ctrlSock,       /* control socket fd of FTP connection */    BOOL expecteof      /* TRUE = EOF expected, FALSE = EOF is error */    )    {    char c;    FAST int codeType;    FAST int code;    FAST int dig;    int continuation;    int origCode;    BOOL eof;    /* read all lines of a reply:     *    do     *	      while not eof and not eol     *	          process char     *    while not eof and not last line of reply     */    origCode = 0;    codeType = 0;    do	{	/* read all characters of a line */	dig  = 0;	code = 0;	continuation = FALSE;	while (!(eof = (read (ctrlSock, &c, 1) == 0)) && (c != '\n'))	    {	    dig++;	    if (dig == 1)		/* char 1 is code type */		codeType = c - '0';	    if (dig <= 3)		/* chars 1-3 are code */		{		if (!isdigit (c))		    code = -1;		else		    if (code != -1)			code = code * 10 + (c - '0');		}	    if (dig == 4)		/* char 4 is continuation marker */		continuation = (c == '-');	    if ((c != '\r') &&		((ftpVerbose || ((codeType == FTP_ERROR) && (dig > 4))) &&		 !ftpErrorSuppress))		write (STD_ERR, &c, 1);	    }	/* print newline if we've been printing this reply */	if ((ftpVerbose || (codeType == FTP_ERROR)) && !ftpErrorSuppress)	    printErr ("\n");	/* save the original reply code */	if (origCode == 0)	    origCode = code;	}    /* while not eof and not last line of reply */    while (!eof && !((dig >= 3) && (code == origCode) && !continuation));    errnoSet (origCode);	/* set status to entire reply code */    /* return error if unexpected eof encountered */    if (eof & !expecteof)	return (ERROR);    else	return (origCode / 100);	/* return most signif digit of reply */    }/********************************************************************************* ftpHookup - get a control connection to the FTP server on a specified host** This routine establishes a control connection to the FTP server on the* specified host.  This is the first step in interacting with a remote FTP* server at the lowest level.  (For a higher-level interaction with a remote* FTP server, see the manual entry for ftpXfer().)** RETURNS:* The file descriptor of the control socket, or ERROR if the Internet* address or the host name is invalid, if a socket could not be created, or* if a connection could not be made.** SEE ALSO: ftpLogin(), ftpXfer()*/int ftpHookup    (    char *host          /* server host name or inet address */    )    {    FAST int ctrlSock;    FAST int inetAddr;    SOCKADDR_IN ctrlAddr;    if (((inetAddr = (int) inet_addr (host)) == ERROR) &&	((inetAddr = hostGetByName (host)) == ERROR))	return (ERROR);    /* make our control socket */    ctrlSock = socket (AF_INET, SOCK_STREAM, 0);    if (ctrlSock < 0)	return (ERROR);    /* bind a name with no inet address and let system pick port;     * this is just so we can find our socket address later */    ctrlAddr.sin_family      = AF_INET;    ctrlAddr.sin_addr.s_addr = INADDR_ANY;    ctrlAddr.sin_port        = htons (0);    if (bind (ctrlSock, (struct sockaddr *)&ctrlAddr, sizeof (ctrlAddr)) < 0)	{	close (ctrlSock);	return (ERROR);        }    /* connect to other side */    ctrlAddr.sin_addr.s_addr = inetAddr;    ctrlAddr.sin_port        = htons (FTP_PORT);    if (connect (ctrlSock, (struct sockaddr *)&ctrlAddr, sizeof (ctrlAddr)) < 0)	{	close (ctrlSock);	return (ERROR);        }    ftpReplyGet (ctrlSock, FALSE);	/* read startup message from server */    return (ctrlSock);    }/********************************************************************************* ftpLogin - log in to a remote FTP server** This routine logs in to a remote server with the specified user name,* password, and account name, as required by the specific remote host.  This* is typically the next step after calling ftpHookup() in interacting with a* remote FTP server at the lowest level.  (For a higher-level interaction* with a remote FTP server, see the manual entry for ftpXfer()).** RETURNS:* OK, or ERROR if the routine is unable to log in.** SEE ALSO: ftpHookup(), ftpXfer()*/STATUS ftpLogin    (    FAST int ctrlSock,  /* fd of login control socket */    char *user,         /* user name for host login */    char *passwd,       /* password for host login */    char *account       /* account for host login */    )    {    FAST int n;    n = ftpCommand (ctrlSock, "USER %s", (int)user,0,0,0,0,0);    if (n == FTP_CONTINUE)	n = ftpCommand (ctrlSock, "PASS %s", (int)passwd,0,0,0,0,0);    if (n == FTP_CONTINUE)	n = ftpCommand (ctrlSock, "ACCT %s", (int)account,0,0,0,0,0);    if (n != FTP_COMPLETE)	return (ERROR);    return (OK);    }/********************************************************************************* ftpDataConnInit - initialize an FTP data connection** This routine sets up the client side of a data connection for the* specified control connection.  It creates the data port, informs the* remote FTP server of the data port address, and listens* on that data port.  The server will then connect to this data port* in response to a subsequent data-transfer command sent on the* control connection (see the manual entry for ftpCommand()).** This routine must be called \f2before\fP the data-transfer command is sent;* otherwise, the server's connect may fail.** This routine is called after ftpHookup() and ftpLogin() to establish a* connection with a remote FTP server at the lowest level.  (For a* higher-level interaction with a remote FTP server, see ftpXfer().)** RETURNS: The file descriptor of the data socket created, or ERROR.** SEE ALSO: ftpHookup(), ftpLogin(), ftpCommand(), ftpXfer()*/int ftpDataConnInit    (    int ctrlSock        /* fd of associated control socket */    )    {    FAST int dataSock;    int result;    int len;    int optval;    SOCKADDR_IN ctrlAddr;    SOCKADDR_IN dataAddr;    /* find out our inet address */    len = sizeof (ctrlAddr);    if (getsockname (ctrlSock, (struct sockaddr *)&ctrlAddr, &len) < 0)	return (ERROR);    /* first try - try to send port */    dataSock = socket (AF_INET, SOCK_STREAM, 0);    if (dataSock < 0)	return (ERROR);    dataAddr = ctrlAddr;	/* set our inet address */    dataAddr.sin_port = htons (0);	/* let system pick port num */    if (bind (dataSock, (struct sockaddr *)&dataAddr, sizeof (dataAddr)) < 0)	{	close (dataSock);	return (ERROR);	}    if (listen (dataSock, 1) < 0)	{	close (dataSock);	return (ERROR);	}    /* try to send socket address to other side */    len = sizeof (dataAddr);    if (getsockname (dataSock, (struct sockaddr *)&dataAddr, &len) < 0)	{	close (dataSock);	return (ERROR);	}#define UCA(n)	(((int)(((char *)&dataAddr.sin_addr)[n])) & 0xff)#define UCP(n)	(((int)(((char *)&dataAddr.sin_port)[n])) & 0xff)    result = ftpCommand (ctrlSock, "PORT %d,%d,%d,%d,%d,%d",		         UCA(0), UCA(1), UCA(2), UCA(3), UCP(0), UCP(1));    if (result != FTP_ERROR)	{	if (result != FTP_COMPLETE)	    {	    close (dataSock);	    return (ERROR);	    }	else	    return (dataSock);	}    /* second try - try to get port # correct by default */    close (dataSock);    dataSock = socket (AF_INET, SOCK_STREAM, 0);    if (dataSock < 0)	return (ERROR);    optval = 1;    if ((setsockopt (dataSock, SOL_SOCKET, SO_REUSEADDR,		     (caddr_t) &optval, sizeof (optval)) < 0) ||        (bind (dataSock, (struct sockaddr *)&ctrlAddr, sizeof (ctrlAddr)) < 0))	{	close (dataSock);	return (ERROR);	}    if (listen (dataSock, 1) < 0)	{	close (dataSock);	return (ERROR);	}    return (dataSock);    }/********************************************************************************* ftpDataConnGet - get a completed FTP data connection** This routine completes a data connection initiated by a call to* ftpDataConnInit().  It waits for a connection on the specified socket from* the remote FTP server.  The specified socket should be the one returned by* ftpDataConnInit().  The connection is established on a new socket, whose* file descriptor is returned as the result of this function.  The original * socket, specified in the argument to this routine, is closed.** Usually this routine is called after ftpDataConnInit() and ftpCommand() to* initiate a data transfer from/to the remote FTP server.** RETURNS:* The file descriptor of the new data socket, or ERROR if the connection* failed.** SEE ALSO: ftpDataConnInit(), ftpCommand()*/int ftpDataConnGet    (    int dataSock        /* fd of data socket on which to await connection */    )    {    int newDataSock;    SOCKADDR_IN from;    int fromlen = sizeof (from);    newDataSock = accept (dataSock, (struct sockaddr *) &from, &fromlen);    close (dataSock);    return (newDataSock);    }/********************************************************************************* ftpLs - list directory contents via FTP** This routine lists the contents of a directory.  The content list* is obtained via an NLST FTP transaction.** The local device name must be the same as the remote host name* with a colon ":" as a suffix.  (For example "wrs:" is the device* name for the "wrs" host.)** RETURNS : OK, or ERROR if could not open directory.*/STATUS ftpLs    (    char *	dirName		/* name of directory to list */    )    {    DEV_HDR *	pDevHdr;    char 	fullFileName [MAX_FILENAME_LENGTH];    char	hostName [MAXHOSTNAMELEN];    int		hostLength;    char  	usr [MAX_IDENTITY_LEN];    char 	passwd [MAX_IDENTITY_LEN];    int	 	dataSock;    int	 	cntrlSock;    char *	buffer [BUFSIZ];    int  	nChars;    /* Get device header and complete filename */    ioFullFileNameGet (dirName, &pDevHdr, fullFileName);    /* Get the host name, and remove the trailing ":" */    strcpy (hostName, pDevHdr->name);    hostLength = strlen (hostName);    hostName [hostLength - 1] = EOS;    /* Get user ID information */    remCurIdGet (usr, passwd);    if (ftpXfer (hostName, usr, passwd, "", "NLST", fullFileName, "",    		 &cntrlSock, &dataSock) != OK)    	{    	printErr ("Can't open directory \"%s\"\n", dirName);    	return (ERROR);    	}    /* Write out the listing */    while ((nChars = read (dataSock, (char *) buffer, BUFSIZ)) > 0)        write (STD_OUT, (char *) buffer, nChars);        /* Close the sockets opened by ftpXfer */    close (cntrlSock);    close (dataSock);    return (OK);    }

⌨️ 快捷键说明

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