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

📄 ftpdlib.c

📁 s3c2410 vxworks 的bsp
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (ftpsCurrentClients != 0)        serverActive = TRUE;    ftpsShutdownFlag = TRUE;    pData = (FTPD_SESSION_DATA *)lstFirst (&ftpsSessionList);    while (pData != NULL)        {        ftpdSockFree (&pData->cmdSock);        pData = (FTPD_SESSION_DATA *)lstNext (&pData->node);        }    semGive (ftpsMutexSem);       if (serverActive)        {         semTake (ftpsSignalSem, WAIT_FOREVER);        }    ftpdSockFree (&ftpdServerSock);    lstFree (&ftpsSessionList);       semDelete (ftpsMutexSem);    semDelete (ftpsSignalSem);    ftpsActive = FALSE;    return (OK);    }/********************************************************************************/LOCAL FTPD_SESSION_DATA *ftpdSessionAdd (void)    {    FAST FTPD_SESSION_DATA 	*pSlot;    if (ftpsCurrentClients >= ftpsMaxClients)        return (NULL);    pSlot = (FTPD_SESSION_DATA *) calloc (sizeof (FTPD_SESSION_DATA), 1);    if (pSlot == NULL)	{	return (NULL);	}    if (ftpdWindowSize < 0 || ftpdWindowSize > 65536)	    ftpdWindowSize = FTPD_WINDOW_SIZE;        pSlot->bufSize = ftpdWindowSize ;    ftpdDebugMsg ("allocating new session buffer %d bytes\n",	pSlot->bufSize,0,0,0);    pSlot->buf = malloc( pSlot->bufSize );    if( pSlot->buf == NULL )	{	free(pSlot);	return (NULL);	}    pSlot->dataSock = FTPD_SOCK_FREE;    pSlot->cmdSock = FTPD_SOCK_FREE;    pSlot->cmdSockError = OK;    pSlot->status = FTPD_STREAM_MODE | FTPD_BINARY_TYPE | FTPD_NO_RECORD_STRU;    pSlot->byteCount = 0;	strcpy( pSlot->curDirName,"/tffs0/" );	    semTake (ftpsMutexSem, WAIT_FOREVER);    lstAdd (&ftpsSessionList, &pSlot->node);    ftpdNumTasks++;    ftpsCurrentClients++;    semGive (ftpsMutexSem);    return (pSlot);    }/********************************************************************************/LOCAL void ftpdSessionDelete    (    FAST FTPD_SESSION_DATA *pSlot          )    {    if (pSlot == NULL)			/* null slot? don't do anything */        return;    semTake (ftpsMutexSem, WAIT_FOREVER);    --ftpdNumTasks;    --ftpsCurrentClients;    lstDelete (&ftpsSessionList, &pSlot->node);    ftpdSockFree (&pSlot->cmdSock);	/* release data and command sockets */    ftpdSockFree (&pSlot->dataSock);    free (pSlot->buf);    free (pSlot);    if (ftpsShutdownFlag)        {        if (ftpsCurrentClients == 0)            semGive (ftpsSignalSem);        }    semGive (ftpsMutexSem);    return;    }/********************************************************************************* ftpPathAccessVerify - verify client access to a path**/LOCAL STATUS ftpPathAccessVerify    (    FTPD_SESSION_DATA *pSlot,    char * path,    int mode    )    {    char * where ;    int len;    /* allways allow access if not anonymous user */    if( (pSlot->status & FTPD_ANONYMOUS) == 0 )	return (OK);    if( mode == O_RDONLY )	{	where = guestHomeDir ;	}    else	{	where = writeDirName ;	}        len = strlen(where);        if (*where==EOS||*path==EOS) goto deny;        /* perform case-insensitive comparison a la strncmp() */	{	FAST char *s1, *s2;	FAST int i;	for( s1 = where, s2 = path, i = 0; 		(*s1!=EOS && *s2!=EOS) && i<len;		s1++, s2++, i-- )	    {	    if(toupper(*s1) == toupper(*s2))		continue ;	    else		goto deny;	    }	}    ftpdDebugMsg ("access mode %d allowed for path %s\n", mode, (int)path,0,0);    return OK ;deny:    ftpdDebugMsg ("access mode %d denied for path %s\n", mode, (int)path,0,0);    return ERROR;    }/********************************************************************************* ftpdPathForPrint - prepare a path to be printed to client**/LOCAL char * ftpdPathForPrint( FTPD_SESSION_DATA *pSlot, char * path )    {    if( pSlot->status & FTPD_ANONYMOUS )	{	int len = strlen( guestHomeDir );	if( strncmp( guestHomeDir, path, len) != 0)	    return NULL ;	strcpy( path, path+len );		}    return(path);    }/***********************************************************************************/LOCAL void ftpPathNormalize    (    FTPD_SESSION_DATA   *pSlot,    char *		path,    char *		buffer,    char **		pResult    )    {    if ( (strcmp(path,".") == 0) || (path[0] == EOS) )	{	*pResult = &pSlot->curDirName [0];	return ;	}    (void) pathCat (pSlot->curDirName, path, buffer);    pathCondense (buffer);		/* condense ".." shit */    *pResult = buffer;    }/********************************************************************************/LOCAL STATUS ftpdWorkTask    (    FTPD_SESSION_DATA   *pSlot  /* pointer to the active slot to be handled */    )    {    FAST int		sock;		    FAST char		*pBuf, *pBufEnd;    struct sockaddr_in	passiveAddr;	    char		*dirName;	    FAST int		numRead;    int			addrLen = sizeof (passiveAddr);	    int			portNum [6];	    u_long 		value;    char 		renFile [MAX_FILENAME_LENGTH];    char 		newPath [MAX_FILENAME_LENGTH];    char		*pFileName;    FILE 		*outStream;    char                *upperCommand;       pBuf = &pSlot->buf [0];	    pBufEnd = pSlot->bufSize-1 + pBuf ;    sock = pSlot->cmdSock;    if (ftpsShutdownFlag)        {        ftpdCmdSend (pSlot, sock, 421,                      "Service not available, closing control connection",                     0, 0, 0, 0, 0, 0);        ftpdSessionDelete (pSlot);        return (OK);        }    if (ftpdCmdSend (pSlot, sock, 220, messages [MSG_SERVER_READY],		(int)vxWorksVersion, 0, 0, 0, 0, 0) == ERROR)	goto connectionLost;    FOREVER	{	taskDelay (0);		/* time share among same priority tasks */	if (pSlot->cmdSockError == ERROR)	    goto connectionLost;	pSlot->byteCount = 0 ;	(void) time( &pSlot->timeUsed );	        if (ftpsShutdownFlag)            break;	bzero( pBuf, 8 );	FOREVER	    {	    taskDelay (0);		    if ((numRead = read (sock, pBuf, 1)) <= 0)		{                if (ftpsShutdownFlag)                    {                    *pBuf = EOS;                    break;                    }		if (numRead == 0)		    ftpdCmdSend (pSlot, sock, 221, messages [MSG_NO_GOOD_BYE],		    0, 0, 0, 0, 0, 0);		ftpdSessionDelete (pSlot);		return ERROR;		}	    	    if ( *pBuf == '\r' )		continue;	    if (( *pBuf == '\n' ) || (pBuf == pBufEnd))	    {		*pBuf = EOS;		break;	    }	    pBuf++;			    } /* FOREVER - read line */	pBuf = &pSlot->buf [0];	for (upperCommand = pBuf; (*upperCommand != ' ') &&	     (*upperCommand != EOS); upperCommand++)	    *upperCommand = toupper (*upperCommand);	ftpdDebugMsg ("read command %s\n", (int)pBuf,0,0,0);        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)	    {            if ( *(pBuf + 4) == '\0' )               pSlot->curUserName[0] = '\0';                else               strncpy(pSlot->curUserName, pBuf+5, MAX_LOGIN_NAME_LEN);	    pSlot->status &= ~(FTPD_USER_OK | FTPD_ANONYMOUS);	    if( (strcmp(pSlot->curUserName, FTPD_ANONYMOUS_USER_1) ==0) ||		(strcmp(pSlot->curUserName, FTPD_ANONYMOUS_USER_2) ==0) ||		(strcmp(pSlot->curUserName, FTPD_ANONYMOUS_USER_3) ==0)  )		{		pSlot->status |= FTPD_ANONYMOUS ;	/* tentative */		ftpdCmdSend (pSlot, sock, 331, messages [MSG_GUEST_PASS],			0, 0, 0, 0, 0, 0) ;		continue;		}	    if (ftpdCmdSend (pSlot, sock, 331, messages [MSG_PASSWORD_REQUIRED],			 0, 0, 0, 0, 0, 0) == ERROR)		goto connectionLost;	    continue;	    }	else if (strncmp (pBuf, "PASS", 4) == 0)	    {	    if( pSlot->status & FTPD_ANONYMOUS )		{		if( (guestHomeDir[0] == EOS) || (pBuf[5]==EOS) )		    {		    ftpdCmdSend (pSlot, sock, 530,			messages [MSG_USER_LOGIN_FAILED], 0, 0, 0, 0, 0, 0);		    continue;		    }		pSlot->status |= FTPD_USER_OK;		strcpy (pSlot->curDirName, guestHomeDir);		if( guestHomeDir [ strlen(guestHomeDir) -1 ] != '/');		    strcat(pSlot->curDirName, "/");		strcpy(newPath, writeDirName);		if( writeDirName[0] == EOS )		    ftpdCmdSend (pSlot, sock, 230,			messages [MSG_GUEST_OK], 0, 0, 0, 0, 0, 0);		else		    ftpdCmdSend (pSlot, sock, 230,			messages [MSG_GUEST_UPLOAD_OK], 			(int) ftpdPathForPrint(pSlot, newPath),			0, 0, 0, 0, 0);		continue;		}	   if ( pLoginVrfyFunc != (FUNCPTR)NULL )	       {		ftpdDebugMsg ("Verifying login for user %s\n",			(int)pSlot->curUserName,0,0,0);	       if ( (*pLoginVrfyFunc)(pSlot->curUserName, pBuf+5) != OK )		   {		   if (ftpdCmdSend (pSlot, sock,                                    530, messages [MSG_USER_LOGIN_FAILED],                                     0, 0, 0, 0, 0, 0) == ERROR)		       goto connectionLost;		   pSlot->status &= ~FTPD_USER_OK;		   continue;		   }	        }	     	    else if( guestHomeDir[0] != EOS )		{	        if (ftpdCmdSend (pSlot, sock,				530, messages [MSG_USER_LOGIN_FAILED], 				0, 0, 0, 0, 0, 0) == ERROR)		   goto connectionLost;	        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)		goto connectionLost;	    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, "SYST", 4) == 0)	    {	    ftpdCmdSend (pSlot, sock, 215, messages [MSG_SYST_REPLY],			 0, 0, 0, 0, 0, 0);	    continue;	    }	else if (strncmp (pBuf, "HELP", 4) == 0)	    {	    if (ftpdCmdSend (pSlot, sock, FTPD_MULTI_LINE | 214,			messages [MSG_COMMAND_LIST_BEGIN], 0, 0, 0, 0, 0, 0) 			 == ERROR)		goto connectionLost;	    if (write (pSlot->cmdSock, ftpdCommandList,				strlen (ftpdCommandList)) <= 0)		goto connectionLost;	    if (ftpdCmdSend (pSlot, sock, 214, messages [MSG_COMMAND_LIST_END],			 0, 0, 0, 0, 0, 0) == ERROR)				goto connectionLost;	    continue;		/* All is well go wait for the next command */	    }	else if ((pSlot->status & FTPD_USER_OK) == 0)	/* validated yet? */	    {	    if (ftpdCmdSend (pSlot, sock, 530, messages [MSG_USER_PASS_REQ],			 0, 0, 0, 0, 0, 0) == ERROR)				goto connectionLost;	    /* do not proceed further until he's legit */	    continue;	    }	if (strncmp (pBuf, "LIST", 4) == 0 ||		 strncmp (pBuf, "NLST", 4) == 0)	    {	    STATUS retVal;	    	    ftpPathNormalize ( pSlot, &pBuf[5], newPath, &dirName );	    ftpdDebugMsg ("listing %s\n", (int)dirName,0,0,0);	    if( ftpPathAccessVerify(pSlot, dirName, O_RDONLY) == ERROR )		{		if (ftpdCmdSend (pSlot, sock,                                  550, messages [MSG_GUEST_ACCESS],                                 0, 0, 0, 0, 0, 0) == ERROR)		    goto connectionLost;		continue;		}		    if (ftpdDataConnGet (pSlot) == ERROR)		{		if (ftpdCmdSend (pSlot, sock,                                  426, messages [MSG_DATA_CONN_ERROR],                                 0, 0, 0, 0, 0, 0) == ERROR)		    goto connectionLost;		continue;		}	    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)		    		    goto connectionLost;		}	    else		{                if (ftpdCmdSend (pSlot, sock,                                  226, messages [MSG_TRANS_COMPLETE],                                 0, 0, 0, 0, 0, 0) == ERROR)		    goto connectionLost;		}	    ftpdSockFree (&pSlot->dataSock);	    }	else if ( (strncmp (pBuf, "RETR", 4) == 0) ||		  (strncmp (pBuf, "SIZE", 4) == 0) ||		  (strncmp (pBuf, "MDTM", 4) == 0) )	    {	    struct stat fileStat ;	    ftpPathNormalize ( pSlot, &pBuf[5], newPath, &pFileName );

⌨️ 快捷键说明

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