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

📄 ftpdlib.c

📁 ftp源代码。大名鼎鼎的嵌入式操作系统vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* parsing the request indicates a valid command, ftpdWorkTask() will* call appropriate functions to handle the request and return the* result of the request.  The parsing of the requests are done via* a list of strncmp routines for simplicity.** RETURNS: N/A** ERRNO: N/A** NOMANUAL** INTERNAL* To handle multiple simultaneous connections, this routine and all secondary* routines which process client commands must be re-entrant. If the server's* halt routine is started, the shutdown flag is set, causing this routine to* exit after completing any operation already in progress.*/LOCAL STATUS ftpdWorkTask    (    FTPD_SESSION_DATA   *pSlot  /* pointer to the active slot to be handled */    )    {    FAST int		sock;		/* command socket descriptor */    FAST char		*pBuf;		/* pointer to session specific buffer */    struct sockaddr_in	passiveAddr;	/* socket address in passive mode */    FAST char		*dirName;	/* directory name place holder */    FAST int		numRead;    int			addrLen = sizeof (passiveAddr);	/* for getpeername */    int			portNum [6];	/* used for "%d,%d,%d,%d,%d,%d" */    u_long 		value;    char 		*pTail;    char 		newPath [MAX_FILENAME_LENGTH];    char 		curDirName [MAX_FILENAME_LENGTH];    char		*pFileName;    FILE		*inStream;    FILE 		*outStream;    char                *upperCommand;    /* convert command to uppercase */    pBuf = &pSlot->buf [0];	/* use session specific buffer area */    sock = pSlot->cmdSock;    if (ftpsShutdownFlag)        {        /* Server halt in progress - send abort message to client. */        ftpdCmdSend (pSlot, sock, 421,                      "Service not available, closing control connection",                     0, 0, 0, 0, 0, 0);        ftpdSessionDelete (pSlot);        return (OK);        }    /* tell the client we're ready to rock'n'roll */    if (ftpdCmdSend (pSlot, sock, 220, messages [MSG_SERVER_READY],		(int)vxWorksVersion, 0, 0, 0, 0, 0) == ERROR)	{	ftpdSessionDelete (pSlot);	return (ERROR);	}    FOREVER	{	taskDelay (1);		/* time share among same priority tasks */	/* Check error in writting to the control socket */	if (pSlot->cmdSockError == ERROR)	    {	    ftpdSessionDelete (pSlot);	    return (ERROR);	    }        /*         * Stop processing client requests if a server halt is in progress.         * These tests of the shutdown flag are not protected with the         * mutual exclusion semaphore to prevent unnecessary synchronization         * between client sessions. Because the secondary tasks execute at         * a lower priority than the primary task, the worst case delay         * before ending this session after shutdown has started would only         * allow a single additional command to be performed.         */        if (ftpsShutdownFlag)            break;	/* get a request command */	FOREVER	    {	    taskDelay (1);	/* time share among same priority tasks */	    if ((numRead = read (sock, pBuf, 1)) <= 0)		{                /*                 * The primary server task will close the control connection                 * when a halt is in progress, causing an error on the socket.                 * In this case, ignore the error and exit the command loop                 * to send a termination message to the connected client.                 */                if (ftpsShutdownFlag)                    {                    *pBuf = EOS;                    break;                    }                /*                  * Send a final message if the control socket                  * closed unexpectedly.                 */		if (numRead == 0)		    ftpdCmdSend (pSlot, sock, 221, messages [MSG_NO_GOOD_BYE],		    0, 0, 0, 0, 0, 0);		ftpdSessionDelete (pSlot);		return ERROR;		}	    	    /* Skip the CR in the buffer. */	    if ( *pBuf == '\r' )		continue;	    /* End Of Command delimeter. exit loop and process command */	    if ( *pBuf == '\n' )	    {		*pBuf = EOS;		break;	    }	    pBuf++;		/* Advance to next character to read */	    }	/*  Reset Buffer Pointer before we use it */	pBuf = &pSlot->buf [0];	/* convert the command to upper-case */	for (upperCommand = pBuf; (*upperCommand != ' ') &&	     (*upperCommand != EOS); upperCommand++)	    *upperCommand = toupper (*upperCommand);	ftpdDebugMsg ("read command %s\n", (int)pBuf,0,0,0);        /*         * Send an abort message to the client if a server         * shutdown was started while reading the next command.         */        if (ftpsShutdownFlag)            {            ftpdCmdSend (pSlot, sock, 421,                          "Service not available, closing control connection",                         0, 0, 0, 0, 0, 0);            break;            }	if (strncmp (pBuf, "USER", 4) == 0)	    {	    /* check user name */           /* Actually copy the user name into a buffer and save it */           /* till the password comes in. Name is located one space */           /* character after USER string */           if ( *(pBuf + 4) == '\0' )               pSlot->user[0] = '\0';          /* NOP user for null user */           else               strncpy(pSlot->user, pBuf+5, MAX_LOGIN_NAME_LEN);           pSlot->status &= ~FTPD_USER_OK;	    if (ftpdCmdSend (pSlot, sock, 331, messages [MSG_PASSWORD_REQUIRED],			 0, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    continue;	    }	else if (strncmp (pBuf, "PASS", 4) == 0)	    {	    /* check user passwd */           /* Actually check it against earlier supplied user name */	   if ( loginVerifyRtn != (FUNCPTR)NULL )	       {	       if ( (FUNCPTR *)(loginVerifyRtn)(pSlot->user, pBuf+5) != OK )		   {		   if (ftpdCmdSend (pSlot, sock,                                    530, messages [MSG_USER_LOGIN_FAILED],                                     0, 0, 0, 0, 0, 0) == ERROR)		       {		       ftpdSessionDelete (pSlot);		       return (ERROR);		       }		   pSlot->status &= ~FTPD_USER_OK;		   continue;		   }	        }	    pSlot->status |= FTPD_USER_OK;	    if (ftpdCmdSend (pSlot, sock, 230, messages [MSG_USER_LOGGED_IN],			 0, 0, 0, 0, 0, 0) == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    continue;	    }	else if (strncmp (pBuf, "QUIT", 4) == 0)	    {	    /* sayonara */	    ftpdCmdSend (pSlot, sock, 221, messages [MSG_SEE_YOU_LATER],			 0, 0, 0, 0, 0, 0);	    ftpdSessionDelete (pSlot);	    return OK;	    }	else if (strncmp (pBuf, "HELP", 4) == 0)	    {	    /* send list of supported commands with multiple line response */	    if (ftpdCmdSend (pSlot, sock, FTPD_MULTI_LINE | 214,			messages [MSG_COMMAND_LIST_BEGIN], 0, 0, 0, 0, 0, 0) 			 == ERROR)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    if (write (pSlot->cmdSock, ftpdCommandList,				strlen (ftpdCommandList)) <= 0)		{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    /* this signifies the end of the multiple line response */	    if (ftpdCmdSend (pSlot, sock, 214, messages [MSG_COMMAND_LIST_END],			 0, 0, 0, 0, 0, 0) == ERROR)				{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    continue;		/* All is well go wait for the next command */	    }	else if ((pSlot->status & FTPD_USER_OK) == 0)	/* validated yet? */	    {	    /* user is not validated yet.  tell him to log in first */	    if (ftpdCmdSend (pSlot, sock, 530, messages [MSG_USER_PASS_REQ],			 0, 0, 0, 0, 0, 0) == ERROR)				{		ftpdSessionDelete (pSlot);		return (ERROR);		}	    /* do not proceed further until he's legit */	    continue;	    }	if (strncmp (pBuf, "LIST", 4) == 0 ||		 strncmp (pBuf, "NLST", 4) == 0)	    {	    STATUS retVal;	    /* client wants to list out the contents of a directory */	    /* if no directory specified or "." specified as a directory	     * we use the currently active directory name	     */	    if (strlen (pBuf) < 6 || pBuf [5] == '.')	        dirName = &pSlot->curDirName [0];	    else 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]);	        dirName = newPath;               }             else               dirName = &pBuf [5];	    ftpdDebugMsg ("LIST %s\n", (int)dirName,0,0,0);	    /* get a new data socket connection for the transmission of	     * the directory listing data	     */	    if (ftpdDataConnGet (pSlot) == ERROR)		{		if (ftpdCmdSend (pSlot, sock,                                  426, messages [MSG_DATA_CONN_ERROR],                                 0, 0, 0, 0, 0, 0) == ERROR)		    		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		continue;		}	    /* print out the directory contents over the data connection */	    retVal = ftpdDirListGet (pSlot->dataSock, dirName,				     (strncmp (pBuf, "LIST", 4) == 0));	    if (retVal == ERROR)		{		if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_DIR_ERROR],			     0, 0, 0, 0, 0, 0) == ERROR)		    		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    else		{                if (ftpdCmdSend (pSlot, sock,                                  226, messages [MSG_TRANS_COMPLETE],                                 0, 0, 0, 0, 0, 0) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		}	    /* free up the data socket */	    ftpdSockFree (&pSlot->dataSock);	    }	else if (strncmp (pBuf, "RETR", 4) == 0)	    {	    /* retrieve a file */	    /* open the file to be sent to the client */	    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 ("RETR %s\n", (int)pFileName,0,0,0);	    if ((inStream = fopen (pFileName, "r")) == NULL)	        {		if (ftpdCmdSend (pSlot, sock, 550, messages [MSG_FILE_ERROR],			     (int)(&pBuf[5]), 0, 0, 0, 0, 0) == ERROR)		    		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		continue;		}	    /* ship it away */	    ftpdDataStreamSend (pSlot, inStream);	    (void) fclose (inStream);	    }	else if (strncmp (pBuf, "STOR", 4) == 0)	    {	    /* store a file */	    /* create a local file */	    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 ("STOR %s\n", (int)pFileName,0,0,0);	    if ((outStream = fopen (pFileName, "w")) == NULL)	        {		if (ftpdCmdSend (pSlot, sock, 553, messages[MSG_CREATE_ERROR],			(int)(&pBuf[5]), 0, 0, 0, 0, 0) == ERROR)		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		continue;		}	    /* receive the file */	    ftpdDataStreamReceive (pSlot, outStream);	    (void) fclose (outStream);	    }	else if (strncmp (pBuf, "CWD", 3) == 0)	    {	    /* change directory */	    dirName = &pBuf [4];	    /* there is no default device for the specified directory */	    if (iosDevFind (dirName, &pTail) == NULL)		{                if (ftpdCmdSend (pSlot, sock,                                  501, messages [MSG_DIR_NOT_PRESENT],                                 0, 0, 0, 0, 0, 0) == ERROR)			    		    {		    ftpdSessionDelete (pSlot);		    return (ERROR);		    }		continue;		}

⌨️ 快捷键说明

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