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

📄 rosftplib.c

📁 vxworks MPC8541 BSP
💻 C
📖 第 1 页 / 共 3 页
字号:
/* ROS FTP server test result done by tongxj 2001-07-18 */

#include "RosFtpLib.h"
#include "lib/5906lib.h" /*yuqiang changed on 2003-2-17:统一各产品启动打印信息*/

extern int tcp_keepintvl;
extern int tcp_keepcnt;
extern int tcp_keepidle;
extern int tcp_maxidle;

int RosFtpClntDebug = 0;
int FtpClntSndWindow = 1460;
int FtpClntSndLowWait= 1460;

static unsigned int fileLength = 0;
static int getFileLength = 0;


LOCAL STATUS ftpClntSocketConfig( SOCKET sock);

LOCAL STATUS ftpClntNodeInit(FTP_CLIENT_NODE *pClnt);
LOCAL STATUS ftpClntClose(FTP_CLIENT_NODE *pClnt);

LOCAL STATUS ftpClntEventHandler( FTP_CLIENT_NODE* ,struct fd_set *,struct fd_set *);
LOCAL STATUS ftpClntReplyHandler(FTP_CLIENT_NODE* pClnt);

LOCAL STATUS ftpClntDataNodeReadHandler(FTP_CLIENT_NODE* pClnt);
LOCAL STATUS ftpClntCtrlNodeReadHandler(FTP_CLIENT_NODE* pClnt);

LOCAL STATUS ftpClntSendCommand(FTP_CLIENT_NODE *pClnt,char* pBuf);
LOCAL STATUS ftpClntDownload(FTP_CLIENT_NODE* pClnt);

LOCAL STATUS ftpClntSockNodeAccept(FTP_SOCK_NODE* pn);
LOCAL STATUS ftpClntSockNodeListen(FTP_SOCK_NODE* pn);

#define FTP_ERR_MSG(x,p1,p2,p3,p4) { \
    if( RosFtpClntDebug>0 ) logMsg(x,p1,p2,p3,p4,5,6);\
    if( RosFtpClntDebug>1 ) taskSuspend(taskIdSelf());   \
}

#define FTP_DBG_MSG(x,p1,p2,p3,p4) { \
    if( RosFtpClntDebug>0 ) logMsg(x,p1,p2,p3,p4,5,6);\
}

LOCAL void  ctrlSockNodeClose(FTP_SOCK_NODE* pn)
{
    if (pn->sockFd != INVALID_SOCK)
    {
        close(pn->sockFd);
        pn->sockFd = INVALID_SOCK;
    }
    pn->state = End;
}

/*----------------------------------------------------------------------
 * NAME:        ftpClntNodeInit
 * PARAMETERS:
 * RETURN:      OK
 * FUNCTION:    initialze socket node with specific type.
 */
LOCAL STATUS  ftpClntNodeInit(FTP_CLIENT_NODE *pClnt)
{
    pClnt->ctrlNode.sockFd   = INVALID_SOCK;
    pClnt->ctrlNode.state    = Initial;

    pClnt->dataNode.sockFd   = INVALID_SOCK;
    pClnt->dataNode.state    = Initial;

    pClnt->mode     = 0;      /* positive */
    pClnt->reply    = FTP_NONE;
    pClnt->continuedReply    = FALSE;

    bzero(pClnt->replyBuf,sizeof(pClnt->replyBuf));
    pClnt->replyLen = 0;

    bzero(pClnt->user,sizeof(pClnt->user));
    bzero(pClnt->password,sizeof(pClnt->password));
    bzero(pClnt->sfile,sizeof(pClnt->sfile));
    bzero(pClnt->dfile,sizeof(pClnt->dfile));
    bzero(pClnt->cmdBuf,sizeof(pClnt->cmdBuf));


    pClnt->totalRcv = 0;
    pClnt->dMem     = NULL;
    pClnt->memSize  = 0;
    pClnt->dfp      = NULL;
    pClnt->pRcvBuf  = NULL;

    return OK;
}

/*----------------------------------------------------------------------
 * NAME:        ftpClntClose
 * PARAMETERS:
 * RETURN:      OK
 * FUNCTION:    close client anytime.
 */
LOCAL STATUS  ftpClntClose(FTP_CLIENT_NODE *pClnt)
{
     taskDelay(1);   /* delay for server close connection.*/

    if (pClnt->ctrlNode.sockFd != INVALID_SOCK)
        close(pClnt->ctrlNode.sockFd);

    if (pClnt->dataNode.sockFd != INVALID_SOCK)
        close(pClnt->dataNode.sockFd);

    if (pClnt->dfp != NULL)
        fclose(pClnt->dfp);

    if (pClnt->pRcvBuf != NULL)
        free(pClnt->pRcvBuf);

    /* for deflated-version */

    return OK;
}

/*----------------------------------------------------------------------
 * NAME:        ftpClntSockNodeAccept
 * PARAMETERS:
 * RETURN:      OK/ERROR
 * FUNCTION:    intialize data node by accept a data client.
 */
LOCAL STATUS ftpClntSockNodeAccept(FTP_SOCK_NODE* pn)
{
    SOCKET               sockFd;
    struct sockaddr      from;
    int                  fromLen;

    if(pn->sockFd == INVALID_SOCK )
        return ERROR;

    fromLen = sizeof(from);
    sockFd = accept(pn->sockFd,&from, &fromLen);
    if(sockFd == ERROR || ftpClntSocketConfig(sockFd) == ERROR )
        return ERROR;

    close(pn->sockFd);
    pn->sockFd = sockFd;
    pn->state  = Active;

    return OK;
}

/*----------------------------------------------------------------------
 * NAME:        sockEventHandle
 * PARAMETERS:
 * RETURN:      OK/ERROR
 * FUNCTION:    socket event handle.
 */
LOCAL STATUS ftpClntEventHandler(   FTP_CLIENT_NODE *pClnt,
                                    struct fd_set *pReadFds,
                                    struct fd_set *pExceptFds )
{
    STATUS  result=OK;

    if ( pClnt->ctrlNode.sockFd != INVALID_SOCK )
    {
        if ( FD_ISSET(pClnt->ctrlNode.sockFd,pExceptFds) )
            return ERROR;

        /* handle control stream read event */
        if ( FD_ISSET(pClnt->ctrlNode.sockFd,pReadFds) )
            if ( ftpClntCtrlNodeReadHandler(pClnt) == ERROR)
                return ERROR;
    }

    if ( pClnt->dataNode.sockFd != INVALID_SOCK )
    {
        if ( FD_ISSET(pClnt->dataNode.sockFd,pExceptFds) )
            return ERROR;
        /* handle control stream read event */
        if ( FD_ISSET(pClnt->dataNode.sockFd,pReadFds) )
            if ( ftpClntDataNodeReadHandler(pClnt) == ERROR)
                return ERROR;
    }

    return (result);
}

/*----------------------------------------------------------------------
 * NAME:        ftpClntSocketConfig
 * PARAMETERS:  sock
 * RETURN:      OK/ERROR
 * FUNCTION:    set stream socket with options.
 */
LOCAL STATUS ftpClntSocketConfig( SOCKET sock)
{
    int             optKeepAlive,optDebug,optNoDelay;
    int             optVal;
    int             optSndLowWait,optRcvLowWait;
    struct timeval  tmout;

    optKeepAlive        = 1;    /* 1 keepalive */
    optDebug            = 0;    /* 1 debug enable */
    optNoDelay          = 1;    /* 1 no neagle algorithm */
    optSndLowWait       = FtpClntSndLowWait;
    optRcvLowWait       = 1;

    tmout.tv_sec        = 0;
    tmout.tv_usec       = 0;

    optVal = 1;

    if(setsockopt( sock, SOL_SOCKET, SO_KEEPALIVE,(char*)&optKeepAlive, sizeof (optKeepAlive))==ERROR)
    {
        FTP_ERR_MSG("setsockopt %u with SO_KEEPALIVE failed.\n",sock,2,3,4);
        return ERROR;
    }
    if(setsockopt(sock, SOL_SOCKET, SO_DEBUG,(char*)&optDebug, sizeof (optDebug))==ERROR)
    {
        FTP_ERR_MSG("setsockopt %u with SO_DEBUG failed.\n",sock,2,3,4);
        return ERROR;
    }
    if( setsockopt (sock, IPPROTO_TCP, TCP_NODELAY,(char*)&optNoDelay, sizeof (optNoDelay))==ERROR)
    {
        FTP_ERR_MSG("setsockopt %u with TCP_NODELAY failed.\n",sock,2,3,4);
        return ERROR;
    }

    if (setsockopt (sock, SOL_SOCKET, SO_SNDLOWAT,(char*)&optSndLowWait, sizeof (optSndLowWait))==ERROR)
    {
        FTP_ERR_MSG("setsockopt %u with SO_SNDLOWAT failed.\n",sock,2,3,4);
        return ERROR;
    }

    if(setsockopt (sock, SOL_SOCKET, SO_RCVLOWAT,(char*)&optRcvLowWait, sizeof (optRcvLowWait))==ERROR)
    {
        FTP_ERR_MSG("setsockopt %u with SO_RCVLOWAT failed.\n",sock,2,3,4);
        return ERROR;
    }

    if( setsockopt (sock, SOL_SOCKET, SO_SNDTIMEO,(char*)&tmout, sizeof (tmout))==ERROR)
    {
        FTP_ERR_MSG("setsockopt %u with SO_SNDTIMEO failed.\n",sock,2,3,4);
        return ERROR;
    }

    if( setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO,(char*)&tmout, sizeof (tmout))==ERROR)
    {
        FTP_ERR_MSG("setsockopt %u with SO_RCVTIMEO failed.\n",sock,2,3,4);
        return ERROR;
    }

    /* set nonblock mode  */
    optVal = 1;
    if( ioctl (sock, FIONBIO, (int)&optVal) == ERROR)
    {
        FTP_ERR_MSG("ioctl %u with FIONBIO failed.\n",sock,2,3,4);
        return ERROR;
    }

    return OK;
}

/*----------------------------------------------------------------------
 * NAME:        ftpClntReplyHandler
 * PARAMETERS:
 * RETURN:      OK/ERROR
 * FUNCTION:    handle control node code string.
 */
LOCAL STATUS ftpClntReplyHandler(FTP_CLIENT_NODE* pClnt)
{
    int                 reply,sockFd,nCnt,result;
    struct sockaddr_in  sockAddr;
    int                 sockAddrSize;
    char                buf[MAX_CMD_STR_LEN],*pChar;
    char                ipStr[INET_ADDR_LEN];
    UINT16              dataPort;
    UINT32              portNum [6];
    struct timeval      timeo;
    STATUS              comdResult;
    result = ERROR;
    FTP_DBG_MSG("%s\n",(int)pClnt->replyBuf,2,3,4);

    /* intermediary line */
    if (   isdigit((int)(pClnt->replyBuf[0])) == 0
        || isdigit((int)(pClnt->replyBuf[1])) == 0
        || isdigit((int)(pClnt->replyBuf[2])) == 0 )
        return OK;

    reply =   (pClnt->replyBuf[0]-'0')*100
            + (pClnt->replyBuf[1]-'0')*10
            + (pClnt->replyBuf[2]-'0');

    if ( reply == pClnt->reply && pClnt->continuedReply == TRUE )
    {
        pClnt->continuedReply = FALSE;
        return OK;
    }

    if ( pClnt->replyBuf[3] == '-')
        pClnt->continuedReply = TRUE;

    pClnt->reply = reply;
    switch(reply)
    {
        case 227: /* pasv mode */
                /* 1. connect to server.*/
            sscanf (strrchr(pClnt->replyBuf,'(')+1, "%u,%u,%u,%u,%u,%u",
                    &portNum [0], &portNum [1], &portNum [2],
                    &portNum [3], &portNum [4], &portNum [5]);
            bzero ((char *) &sockAddr, sizeof(sockAddr));
            sockAddr.sin_family     = AF_INET;
    	    sockAddr.sin_len        = (u_char) sizeof(sockAddr);
            sockAddr.sin_port       = (UINT16)(portNum [4] * 256 + portNum [5]);
            sockAddr.sin_port       = htons(sockAddr.sin_port);
            sockAddr.sin_addr.s_addr= (portNum [0] << 24) | (portNum [1] << 16) |
                                        (portNum [2] << 8) | portNum [3];
            sockAddr.sin_addr.s_addr = htonl(sockAddr.sin_addr.s_addr);

            if( (sockFd = socket( AF_INET,SOCK_STREAM,0))== ERROR)
                return ERROR;

            timeo.tv_sec  = FTP_CONNECT_TIMEO;
            timeo.tv_usec = 0;

            nCnt = 0;
            while(nCnt++ < 3)
                if( (result = connectWithTimeout( sockFd,(struct sockaddr *)&sockAddr,
                            sizeof(sockAddr), &timeo) ) == OK )
                break;

            if (result != OK)
            {
                close(sockFd);
                return ERROR;
            }

            if(pClnt->dataNode.sockFd != INVALID_SOCK)
                close(pClnt->dataNode.sockFd);

            pClnt->dataNode.state = Active;
            pClnt->dataNode.sockFd = sockFd;


            /* 2. RETR. */
            sprintf(buf,"RETR %s"CR_LF,pClnt->sfile);
            return(ftpClntSendCommand(pClnt,buf));
            

        case 200:   /*Command okay.*/
            if(strncmp(pClnt->cmdBuf,"TYPE",4)==0)
            {
                if(pClnt->mode & PASV_MODE)
                {   /* PASV */
                    sprintf(buf,"PASV "CR_LF);
                    return(ftpClntSendCommand(pClnt,buf));
                }
                else
                {   /* PORT */
                    if ( ftpClntSockNodeListen(&pClnt->dataNode) == ERROR)
                        return ERROR;

                    sockAddrSize = sizeof(sockAddr);
                    getsockname(pClnt->ctrlNode.sockFd,(struct sockaddr*)&sockAddr,&sockAddrSize);
                    inet_ntoa_b(sockAddr.sin_addr,ipStr);

⌨️ 快捷键说明

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