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

📄 ftplib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
**     if (ftpXfer ("server", "fred", "magic", "",*                  "RETR %s", "/usr/fred", "myfile",*                  &ctrlSock, &dataSock) == ERROR)*         return (ERROR);**     while ((nBytes = read (dataSock, buf, sizeof (buf))) > 0)*         {*         ...*         }**     close (dataSock);**     if (nBytes < 0)             /@ read error? @/*         status = ERROR;**     if (ftpReplyGet (ctrlSock, TRUE) != FTP_COMPLETE)*         status = ERROR;**     if (ftpCommand (ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0) != FTP_COMPLETE)*         status = ERROR;**     close (ctrlSock);* .CE** RETURNS:* OK, or ERROR if any socket cannot be created or if a connection cannot be* made.** SEE ALSO: ftpReplyGet()*/STATUS ftpXfer    (    char *host,         /* name of server host */    char *user,         /* user name for host login */    char *passwd,       /* password for host login */    char *acct,         /* account for host login */    char *cmd,          /* command to send to host */    char *dirname,      /* directory to 'cd' to before sending command */    char *filename,     /* filename to send with command */    int *pCtrlSock,     /* where to return control socket fd */    int *pDataSock      /* where to return data socket fd, */                        /* (NULL == don't open data connection) */    )    {    FAST int ctrlSock = ERROR;    FAST int dataSock = ERROR;    UINT32 ftpReply   = 0;    UINT32 retryCount = 0;    int    cmdResult;          struct fd_set readFds; /* Used by select for PORT method */    int    width;          /* Used by select for PORT method */    BOOL   dataSockPassive = TRUE;    FTPLDEBUG ("ftpXfer: host:%s user:%s passwd:%s acct:%s cmd:%s dir:%s\n",  \               FTPL_DEBUG_ERRORS,host,user,passwd,acct,cmd,dirname);    if (((ctrlSock = ftpHookup (host)) == ERROR)    ||        (ftpLogin (ctrlSock, user, passwd, acct) != OK)    ||        (ftpCommand (ctrlSock, "TYPE I",0,0,0,0,0,0) != FTP_COMPLETE)  ||        ((dirname[0] != EOS) && (ftpCommand (ctrlSock, "CWD %s",         (int)dirname,0,0,0,0,0) != FTP_COMPLETE)))        {        /* Detected an error during command establishment */        FTPLDEBUG ("ftpXfer: Detected an error during command establishment errno:0x%08x",  \                    FTPL_DEBUG_ERRORS,errno,1,2,3,4,5);        close (ctrlSock);        return (ERROR);        }    /*     * This is a special when an FTP command does not need to establish a     * data connection.     */    if (pDataSock == NULL)        {        if (ftpCommand (ctrlSock, cmd, (int)filename, 0, 0, 0, 0, 0)                         != FTP_COMPLETE)            {            /* FTP command error. */            FTPLDEBUG ("ftpXfer: error during command.  errno:0x%08x",  \            FTPL_DEBUG_ERRORS, errno,1,2,3,4,5);            close (ctrlSock);            return (ERROR);            }        }           /*      * At this point we are trying to establish the data socket.     * We will first try using the modern, client-initiated PASV command.        * If PASV fails,  then we will fall back to the PORT command.      */    /*  Set up local data port and send the PORT command */    do         {        if ((dataSock = ftpDataConnInitPassiveMode (ctrlSock)) != ERROR)            {            FTPLDEBUG ("ftpXfer: notice - mode succeeded.\n ", \                FTPL_DEBUG_ERRORS, 0, 1, 2, 3, 4, 5);            dataSockPassive = TRUE; /* We do not need to listen() on the socket */            }        else            {            FTPLDEBUG ("ftpXfer: notice - PASV mode failed. Now trying older PORT connect method", \                FTPL_DEBUG_ERRORS, 0, 1, 2, 3, 4, 5);            if ((dataSock = ftpDataConnInit (ctrlSock)) == ERROR)                {                FTPLDEBUG ("ftpXfer:  ftpDataConnInit - error during trying of another port. errno:0x%08x",  \                    FTPL_DEBUG_ERRORS, errno, 1, 2, 3, 4, 5);                close (ctrlSock);                return (ERROR);                }             else                dataSockPassive = FALSE; /* We will need to listen() on the socket */            }        /* Send the FTP command.  */        cmdResult = ftpCommandEnhanced (ctrlSock,                                         cmd,                                         (int)filename,                                        0, 0, 0, 0, 0, NULL, 0);        if ((cmdResult/100) != FTP_PRELIM)            {            /*              * The command has failed.  Close the data socket and decode the error.             */            close (dataSock);            /* Check if something really bad happened: File not found, etc. */            if ((cmdResult/100) == FTP_ERROR)                {                FTPLDEBUG ("ftpXfer:  response 0x%08x - aborting transfer.\n", \                    FTPL_DEBUG_ERRORS, cmdResult, 1, 2, 3, 4, 5);                close (ctrlSock);                return (ERROR);                }            if ((cmdResult/100) == FTP_TRANSIENT && _func_ftpTransientFatal != NULL)                {                FTPLDEBUG ("ftpXfer:  calling user-supplied applette to see if 0x%08x FTP_TRANSIENT is fatal for this command.\n", \                    FTPL_DEBUG_ERRORS, cmdResult, 1, 2, 3, 4, 5);                if ((* _func_ftpTransientFatal) (cmdResult) == TRUE)                    {                    FTPLDEBUG ("ftpXfer:  user-supplied applette says 0x%08x FTP_TRANSIENT  ** IS ** fatal for this command.\n", \                    FTPL_DEBUG_ERRORS, cmdResult, 1, 2, 3, 4, 5);                    close (ctrlSock);                    errno = S_ftpLib_FATAL_TRANSIENT_RESPONSE;                    return (ERROR);                    }                FTPLDEBUG ("ftpXfer:  user-supplied applette says 0x%08x is  ** NOT ** fatal for this command.\n", \                    FTPL_DEBUG_ERRORS, cmdResult, 1, 2, 3, 4, 5);                }            if ((ftpReply = (cmdResult/100)) == FTP_TRANSIENT)                {                /*                 * If the error was due to transient error (e.x. the data port                 * was not available) retry the command                  * ftplTransientMaxRetryCount times.                   */                if (retryCount < ftplTransientMaxRetryCount)                    {                    ++retryCount;                    FTPLDEBUG ("ftpXfer: warning - reply was %d(decimal) - FTP_PRELIM - #%d attempt in %d ticks.\n", \                                FTPL_DEBUG_ERRORS,cmdResult,retryCount,                                ftplTransientRetryInterval, 5, 6, 7);                    if (ftplTransientRetryInterval)                        taskDelay (ftplTransientRetryInterval);                    continue; /* try another port */                }                else                {                /* Too many retries,  close socket and return failure */                FTPLDEBUG ("ftpXfer: error - reply was %d(decimal) - FTP_PRELIM - attempt limit (%d) exceeded.\n", \                           FTPL_DEBUG_ERRORS,                           cmdResult,                           ftplTransientMaxRetryCount,                           5, 6, 7, 8);                close (ctrlSock);                errno = S_ftpLib_TRANSIENT_RETRY_LIMIT_EXCEEDED;                return (ERROR);                }                /* Exit for any other error */                FTPLDEBUG ("ftpXfer: error - ftpCommand != FTP_PRELIM.  errno:0x%08x\n", \                           FTPL_DEBUG_ERRORS, errno, 1, 2, 3, 4, 5);                close (ctrlSock);                return (ERROR);                }            }        if ( dataSockPassive == FALSE)            {            /* At this point do a select on the data & control socket */            FTPLDEBUG ("ftpXfer: notice - cmdResult:%d dataSock:%d ctrlSock:%d  errno:0x%08x\n", \                FTPL_DEBUG_ERRORS, cmdResult, dataSock, ctrlSock, errno, 4, 5);            FD_ZERO (&readFds);            FD_SET  (ctrlSock, &readFds);            FD_SET  (dataSock, &readFds);            width = (dataSock > ctrlSock) ? dataSock : ctrlSock;            width++;            if (select (width, &readFds, NULL, NULL, NULL) == ERROR)                {                FTPLDEBUG ("ftpXfer: error - select()==ERROR. errno:0x%08x\n", \                           FTPL_DEBUG_ERRORS,errno, 1, 2, 3, 4, 5);                close (dataSock);                close (ctrlSock);                return (ERROR);                }            /* If the control socket is ready process it and take a decision,             * try again or return error. If the data socket is ready call             * ftpDataConnGet next.             */            if (FD_ISSET (ctrlSock, &readFds) && ! FD_ISSET (dataSock, &readFds))                {                close (dataSock);                FTPLDEBUG ("ftpXfer: warning - control socket ready but data socket not ready\n", \                           FTPL_DEBUG_ERRORS,0, 1, 2, 3, 4, 5);                if ((ftpReply = ftpReplyGet (ctrlSock, FALSE)) == FTP_TRANSIENT)                    continue; /* Try another port */                /* Regardless of response close sockets */                FTPLDEBUG ("ftpXfer:  error - sending QUIT command to host. errno:0x%08x\n", \                            FTPL_DEBUG_ERRORS,errno,1,2,3,4,5);                (void) ftpCommand (ctrlSock, "QUIT", 0, 0, 0, 0, 0, 0);                close (ctrlSock);                return (ERROR);                }            } /* PORT method requires checking for data socket connection */        } while ( ftpReply == FTP_TRANSIENT); /* Try again, we might need a different port */    /* If we used PASV mode,  then the socket is ready for use */    if (!dataSockPassive)        {        /*          * We used the PORT method to establish a connection.         * The data socket connection is configured. Wait for the FTP server to connect         * to us.         */        if ((dataSock = ftpDataConnGet (dataSock)) == ERROR)            {            FTPLDEBUG ("ftpXfer: error - ftpDataConnGet()==ERROR. errno:0x%08x\n", \                FTPL_DEBUG_ERRORS,errno, 1, 2, 3, 4, 5);            close (ctrlSock);            return (ERROR);            }        }    /* Store the control and data sockets */    if (pCtrlSock != NULL)        *pCtrlSock = ctrlSock;    if (pDataSock != NULL)        *pDataSock = dataSock;    return (OK);    }/********************************************************************************* ftpReplyGet - get an FTP command reply** This routine has been superceded by ftpReplyGetEnhanced()** This routine gets a command reply on the specified control socket.** 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 always set to the complete three-digit reply code* regardless of the actual reply value (see the manual entry for errnoGet()).* If the reply code indicates an error, the entire reply* is printed if the ftp error printing is enabled (see the manual* entry for ftpLibDebugOptionsSet()).** 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 */    )    {    /* return most significant digit of reply */    return (ftpReplyGetEnhanced (ctrlSock, expecteof, NULL, 0) / 100);    }/********************************************************************************* ftpReplyGetEnhanced - get an FTP command reply** This routine supercedes ftpReplyGet()** This routine gets a command reply on the specified control socket.** 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 always 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 if the ftp error printing is enabled (see the manual* entry for ftpLibDebugOptionsSet()).** The last line of text retrieved from the servers response is stored*     in the location specified by replyString.   If replyString is NULL*     the parameter is ignored.** If an EOF is encountered on the specified control socket, but no EOF was* expected (<expecteof> == FALSE), then ERROR is returned.** RETURNS:*  The complete FTP response code (see RFC #959)** ERROR if there is a read/write error or an unexpected EOF.*/int ftpReplyGetEnhanced    (    int ctrlSock,       /* control socket fd of FTP connection */    BOOL expecteof,     /* TRUE = EOF expected, FALSE = EOF is error */    char *replyString,  /* Location to store text of reply, or NULL */    int  stringLengthMax /* Maximum length of reply (not including NULL) */     )    {    char c;    FAST int codeType;    FAST int code;    FAST int dig;    int continuation;    int origCode;    int stringIndex;    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;        stringIndex = 0;        continuation = FALSE;        while (!(eof = (read (ctrlSock, &c, 1) == 0)) && (c != '\n'))            {            /* Store the reply */            if (replyString != NULL)                {                if (stringIndex < stringLengthMax)                    {                    replyString[stringIndex] = c;                    stringIndex++;                    }                }            dig++;            

⌨️ 快捷键说明

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