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

📄 ftpdlib.c

📁 ftp源代码。大名鼎鼎的嵌入式操作系统vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    /* dirName doesn't start with a device name, prepend old path */	    if (dirName == pTail)		{		(void) strcpy (curDirName, pSlot->curDirName);		(void) pathCat (curDirName, dirName, newPath);		}	    else				/* it starts with a dev name */		(void) strcpy (newPath, dirName);/* use the whole thing */	    pathCondense (newPath);		/* condense ".." shit */	    /* remember where we are */	    (void) strcpy (pSlot->curDirName, newPath);	    /* notify successful chdir */	    if (ftpdCmdSend (pSlot, sock, 250, messages [MSG_CHANGED_DIR],			    (int)newPath, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    }	else if (strncmp (pBuf, "TYPE", 4) == 0)	    {	    /* we only support BINARY and ASCII representation types */	    if (pBuf [5] == 'I' || pBuf [5] == 'i' ||		pBuf [5] == 'L' || pBuf [5] == 'l')		{	        pSlot->status |= FTPD_BINARY_TYPE;		pSlot->status &= ~FTPD_ASCII_TYPE;		if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_TYPE_BINARY],			     0, 0, 0, 0, 0, 0) == ERROR)					    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    else if (pBuf [5] == 'A' || pBuf [5] == 'a')		{	        pSlot->status |= FTPD_ASCII_TYPE;		pSlot->status &= ~FTPD_BINARY_TYPE;		if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_TYPE_ASCII],			     0, 0, 0, 0, 0, 0) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    else		{		if (ftpdCmdSend (pSlot, sock, 504, messages [MSG_PARAM_BAD],			     0, 0, 0, 0, 0, 0) == ERROR)		    		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    }	else if (strncmp (pBuf, "PORT", 4) == 0)	    {	    /* client specifies the port to be used in setting up	     * active data connections later on (see ftpdDataConnGet ()).	     * format:  first four decimal digits separated by commas	     * indicate the internet address; the last two decimal	     * digits separated by a comma represents hi and low	     * bytes of a port number.	     */	    (void) sscanf (&pBuf [5], "%d,%d,%d,%d,%d,%d",			   &portNum [0], &portNum [1], &portNum [2],			   &portNum [3], &portNum [4], &portNum [5]);	    pSlot->dataAddr.sin_port = portNum [4] * 256 + portNum [5];	    /* convert port number to network byte order */	    pSlot->dataAddr.sin_port = htons (pSlot->dataAddr.sin_port);            /* Set remote host to given value. */            value = (portNum [0] << 24) | (portNum [1] << 16) |                    (portNum [2] << 8) | portNum [3];            pSlot->dataAddr.sin_addr.s_addr = htonl (value);	    if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_PORT_SET],			 0, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    }	else if (strncmp (pBuf, "PWD", 3) == 0)	    {	    /* get current working directory */	    (void) strcpy (pBuf, pSlot->curDirName);	    if (ftpdCmdSend (pSlot, sock, 257, messages [MSG_CUR_DIR],			 (int)pBuf, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    }	else if (strncmp (pBuf, "STRU", 4) == 0)	    {	    /* specify the file structure */	    /* we only support normal byte stream oriented files;	     * we don't support IBM-ish record block oriented files	     */	    if (pBuf [5] == 'F' || pBuf [5] == 'f')		{	        if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_FILE_STRU],			     0, 0, 0, 0, 0, 0) == ERROR)		    		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    else		{	        if (ftpdCmdSend (pSlot, sock, 504, messages [MSG_PARAM_BAD],			     0, 0, 0, 0, 0, 0) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    }	else if (strncmp (pBuf, "MODE", 4) == 0)	    {	    /* specify transfer mode */	    /* we only support stream mode -- no block or compressed mode */	    if (pBuf [5] == 'S' || pBuf [5] == 's')		{	        if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_STREAM_MODE],			     0, 0, 0, 0, 0, 0) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    else		{	        if (ftpdCmdSend (pSlot, sock, 504, messages [MSG_PARAM_BAD],			     0, 0, 0, 0, 0, 0) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    }	else if (strncmp (pBuf, "ALLO", 4) == 0 ||		 strncmp (pBuf, "ACCT", 4) == 0)	    {	    /* allocate and account commands are not need */	    if (ftpdCmdSend (pSlot, sock, 202, messages [MSG_ALLOC_ACCOUNT],			 0, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    }	else if (strncmp (pBuf, "PASV", 4) == 0)	    {	    /* client wants to connect to us instead of waiting	     * for us to make a connection to its data connection	     * socket	     */	    ftpdSockFree (&pSlot->dataSock);	    /* we need to open a socket and start listening on it	     * to accommodate his request.	     */	    if ((pSlot->dataSock = socket (AF_INET, SOCK_STREAM, 0)) < 0)		{		if (ftpdCmdSend (pSlot, sock, 425, messages [MSG_PASSIVE_ERROR],			     0, 0, 0, 0, 0, 0) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    else		{                int outval1;                int outval2;                int outval3;                int outval4;                int outval5;                int outval6;                if (getsockname (pSlot->cmdSock,                                 (struct sockaddr *) &pSlot->dataAddr,                                 &addrLen) < 0)                    {                    /* Couldn't find address for local end of connection. */                    if (ftpdCmdSend (pSlot, sock,                                     425, messages [MSG_PASSIVE_ERROR],                                     0, 0, 0, 0, 0, 0) == ERROR)                        {                        ftpdSessionDelete (pSlot);                        return (ERROR);                        }                    }                /*                 * Find an ephemeral port for the expected connection                 * and initialize connection queue.                  */                pSlot->dataAddr.sin_port = htons (0);                addrLen = sizeof (struct sockaddr_in);		if (bind (pSlot->dataSock, (struct sockaddr *)&pSlot->dataAddr,			  sizeof (struct sockaddr_in)) < 0 ||		    getsockname (pSlot->dataSock,				 (struct sockaddr *) &pSlot->dataAddr,				 &addrLen) < 0 ||		    listen (pSlot->dataSock, 1) < 0)		    {		    ftpdSockFree (&pSlot->dataSock);                    if (ftpdCmdSend (pSlot, sock,                                      425, messages [MSG_PASSIVE_ERROR],                                     0, 0, 0, 0, 0, 0) == ERROR)			{			ftpdSessionDelete (pSlot);			return (ERROR);			}		    continue;		    }		/* we're passive, let us keep that in mind */		pSlot->status |= FTPD_PASSIVE;                value = pSlot->dataAddr.sin_addr.s_addr;                outval1 = ( (u_char *)&value)[0];                outval2 = ( (u_char *)&value)[1];                outval3 = ( (u_char *)&value)[2];                outval4 = ( (u_char *)&value)[3];                 /* Separate port number into bytes. */                outval5 = ( (u_char *)&pSlot->dataAddr.sin_port)[0];                outval6 = ( (u_char *)&pSlot->dataAddr.sin_port)[1];		/* tell the client to which port to connect */                if (ftpdCmdSend (pSlot, pSlot->cmdSock,                                  227, messages [MSG_PASSIVE_MODE],                                 outval1, outval2, outval3, outval4,                                 outval5, outval6) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    }	else if (strncmp (pBuf, "NOOP", 4) == 0)	    {	    /* don't do anything */	    if (ftpdCmdSend (pSlot, sock, 200, messages [MSG_NOOP_OKAY],			 0, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    }        else if (strncmp (pBuf, "DELE", 4) == 0)            {             if (pBuf [5] != '/')                 {                 if (pSlot->curDirName [strlen (pSlot->curDirName) - 1] == '/')                     (void) sprintf (newPath,                                     "%s%s", pSlot->curDirName, &pBuf [5]);                 else                     (void) sprintf (newPath,                                     "%s/%s", pSlot->curDirName, &pBuf [5]);                 pFileName = newPath;                 }             else                 pFileName = &pBuf [5];             ftpdDebugMsg ("DELE %s\n", (int)pFileName,0,0,0);             if (remove (pFileName) != OK)                 {                 if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_FILE_ERROR],                                  (int) pFileName, 0, 0, 0, 0, 0) == ERROR)                     {                      ftpdSessionDelete (pSlot);                      return (ERROR);                      }                 continue;                 }             else                 {                  if (ftpdCmdSend (pSlot, sock, 250, messages [MSG_DELE_OKAY],                                   0, 0, 0, 0, 0, 0) == ERROR)                      {                       ftpdSessionDelete (pSlot);                       return (ERROR);                      }                 }           }       else           {	    /* unrecognized command or command not supported */	    if (ftpdCmdSend (pSlot, sock, 500, messages [MSG_BAD_COMMAND],			 0, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    }	}    /*     * Processing halted due to pending server shutdown.     * Remove all resources and exit.     */    ftpdSessionDelete (pSlot);    return (OK);    }/********************************************************************************* ftpdDataConnGet - get a fresh data connection socket for FTP data transfer** FTP uses upto two connections per session (as described above) at any* time.  The command connection (cmdSock) is maintained throughout the* FTP session to pass the request command strings and replies between* the client and the server.  For commands that require bulk data transfer* such as contents of a file or a list of files in a directory, FTP* sets up dynamic data connections separate from the command connection.* This function, ftpdDataConnGet, is responsible for creating* such connections.** Setting up the data connection is performed in two ways.  If the dataSock* is already initialized and we're in passive mode (as indicated by the* FTPD_PASSIVE bit of the status field in the FTPD_SESSION_SLOT) we need to* wait for our client to make a connection to us -- so we just do an accept* on this already initialized dataSock.  If the dataSock is already* initialized and we're not in passive mode, we just use the already* existing connection.  Otherwise, we need to initialize a new socket and* make a connection to the the port where client is accepting new* connections.  This port number is in general set by "PORT" command (see* ftpdWorkTask()).*/LOCAL STATUS ftpdDataConnGet    (    FTPD_SESSION_DATA   *pSlot          /* pointer to the work slot */    )    {    FAST int		newSock;	/* new connection socket */    int			addrLen;	/* to be used with accept */    struct sockaddr_in	addr;		/* to be used with accept */    int			on = 1;		/* to be used to turn things on */    int			retry = 0;	/* retry counter initialized to zero */    /* command socket is invalid, return immediately */    if (pSlot->cmdSock == FTPD_SOCK_FREE)        return (ERROR);    pSlot->byteCount = 0;    if (pSlot->dataSock != FTPD_SOCK_FREE)        {	/* data socket is already initialized */	/* are we being passive? (should we wait for client to connect	 * to us rather than connecting to the client?)	 */	if (pSlot->status & FTPD_PASSIVE)	    {	    /* we're being passive.  wait for our client to connect to us. */	    addrLen = sizeof (struct sockaddr);	    if ((newSock = accept (pSlot->dataSock, (struct sockaddr *) &addr,				   &addrLen)) < 0)		{                ftpdCmdSend (pSlot, pSlot->cmdSock,                             425, "Can't open data connection",                             0, 0, 0, 0, 0, 0);                ftpdSockFree (&pSlot->dataSock);		/* we can't be passive no more */		pSlot->status &= ~FTPD_PASSIVE;		return (ERROR);		}            /*             * Enable the keep alive option to prevent misbehaving clients             * from locking the server.             */            if (setsockopt (newSock, SOL_SOCKET, SO_KEEPALIVE, (char *) &on,                            sizeof (on)) != 0)                {                ftpdSockFree (&pSlot->dataSock);                return (ERROR);                }	/* Check for window size validity */

⌨️ 快捷键说明

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