📄 rosftplib.c
字号:
sockAddrSize = sizeof(sockAddr);
getsockname(pClnt->dataNode.sockFd,(struct sockaddr*)&sockAddr,&sockAddrSize);
dataPort = ntohs(sockAddr.sin_port);
pChar = ipStr;
while(*pChar++ != '\0' )
*pChar = (*pChar=='.'?',':*pChar);
sprintf(buf,"PORT %s,%d,%d"CR_LF,ipStr,dataPort>>8,dataPort & 0x0FF);
return(ftpClntSendCommand(pClnt,buf));
}
} /* end TYPE */
else if(strncmp(pClnt->cmdBuf,"PORT",4)==0)
{
sprintf(buf,"RETR %s"CR_LF,pClnt->sfile);
return(ftpClntSendCommand(pClnt,buf));
} /* end PORT */
break;
case 220: /* Service ready for new user. */
sprintf(buf,"USER %s"CR_LF,pClnt->user);
return(ftpClntSendCommand(pClnt,buf));
case 225: /* Data connection open; no transfer in progress.*/
case 350: /* Requested file action pending further information. */
case 421: /* Service not available, closing control connection. */
case 425: /* Can't open data connection. */
case 426: /* Connection closed; transfer aborted. */
case 450: /* Requested file action not taken. */
case 451: /* Requested action aborted: local error in processing. */
case 452: /* Requested action not taken.Insufficient storage space in system. */
case 501: /* This may include errors such as command line too long.*/
case 502: /* Syntax error in parameters or arguments. */
case 503: /* Command not implemented. */
case 504: /* Bad sequence of commands. */
case 550: /* Requested action not taken.File unavailable (e.g., file not found, no access). */
case 551: /* Requested action aborted: page type unknown. */
case 552: /* Requested file action aborted.Exceeded storage allocation (for current directory or dataset). */
case 553: /* Requested action not taken. File name not allowed. */
case 530: /* 530 Not logged in. */
case 532: /* 532 Need account for storing files. */
sprintf(buf,"QUIT "CR_LF);
return(ftpClntSendCommand(pClnt,buf));
case 500: /* Syntax error, command unrecognized. */
break;
case 226: /* 226 transfer file or abort successful. */
case 250: /* 250 Requested file action okay, completed.*/
/* discard any reply from now */
sprintf(buf,"QUIT "CR_LF);
comdResult = ftpClntSendCommand(pClnt,buf);
ctrlSockNodeClose(&(pClnt->ctrlNode));
return comdResult;
case 230: /* 230 User logged in, proceed. */
if(pClnt->mode & ZAR_MODE)
{
sprintf(buf,"ZAR"CR_LF);
ftpClntSendCommand(pClnt,buf);
}
if(getFileLength)
{
sprintf(buf,"GETLEN %s"CR_LF,pClnt->sfile);
}
else
{
sprintf(buf,"TYPE I "CR_LF);
}
return(ftpClntSendCommand(pClnt,buf));
case 111: /* 111 get file length */
sprintf(buf, "%s", pClnt->replyBuf+4);
fileLength = (UINT32)atoi(buf);
printf("file length = %u\n", fileLength);
sprintf(buf,"QUIT "CR_LF);
return(ftpClntSendCommand(pClnt,buf));
case 331: /* User name okay, need password. */
case 332: /* Need account for login.*/
sprintf(buf,"PASS %s"CR_LF,pClnt->password);
return(ftpClntSendCommand(pClnt,buf));
default:
break;
}
return OK;
}
/*----------------------------------------------------------------------
* NAME: ftpClntDataNodeReadHandler
* PARAMETERS:
* RETURN: OK/ERROR
* FUNCTION: handle data socket read event.
*/
LOCAL STATUS ftpClntDataNodeReadHandler(FTP_CLIENT_NODE* pClnt)
{
int result;
if(pClnt->dataNode.sockFd == INVALID_SOCK )
return ERROR;
if(pClnt->dataNode.state == Listening)
{
if(ftpClntSockNodeAccept(&pClnt->dataNode)==OK)
return OK;
else
return ERROR;
}
result = recv(pClnt->dataNode.sockFd,pClnt->pRcvBuf,TCP_RCV_SIZE_DFLT,0);
if( result == ERROR)
{
if( errnoGet() == EWOULDBLOCK )
return (OK);
else
{
pClnt->dataNode.state = Error;
return ERROR;
}
}
if ( result == 0) /* get EOF */
{ /* close normally */
close(pClnt->dataNode.sockFd);
pClnt->dataNode.sockFd = INVALID_SOCK;
pClnt->dataNode.state = End;
return OK;
}
/* received data from data socket */
pClnt->totalRcv += (UINT32)result;
if ( pClnt->dMem != NULL)
{
if(pClnt->mode & ZAR_MODE) /* zar file stream */
{
/* 1. 计算校验和。*/
pClnt->z_checksum = z_cksum( pClnt->z_checksum,
(UINT8*)pClnt->pRcvBuf,
(UINT32)result,
((int)pClnt->totalRcv - result) &0x1);
/* 2. 如果解压流没有结束,解压当前的输入并输出。 */
pClnt->z_stream.next_in = (UINT8*)pClnt->pRcvBuf;
pClnt->z_stream.avail_in = (UINT32)result;
while( pClnt->z_stream.avail_in > 0 && pClnt->z_state != Z_STREAM_END)
{
switch( zinflate(&pClnt->z_stream, 0) )
{
case Z_STREAM_END:
pClnt->z_state = Z_STREAM_END;
pClnt->totalRcv=pClnt->z_stream.total_out;
break;
case Z_STREAM_ERROR:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ERROR;
default:
break;
}
if ( pClnt->z_stream.avail_out < OUTBUF_SIZE )
{
if (pClnt->z_stream.total_out > (UINT32)pClnt->memSize)
return ERROR;
bcopy(pClnt->z_outbuf,pClnt->dMem,OUTBUF_SIZE - pClnt->z_stream.avail_out);
pClnt->dMem += ( OUTBUF_SIZE - pClnt->z_stream.avail_out );
pClnt->z_stream.next_out = pClnt->z_outbuf;
pClnt->z_stream.avail_out = OUTBUF_SIZE;
}
}
}
else /* non-zar file stream */
{
if(pClnt->totalRcv > pClnt->memSize)
return ERROR;
bcopy(pClnt->pRcvBuf,pClnt->dMem,result);
pClnt->dMem += result;
}
}
if ( pClnt->dfp != NULL)
{
if(pClnt->mode & ZAR_MODE)
{ /* zar file stream */
/* 1. 计算校验和。*/
pClnt->z_checksum = z_cksum( pClnt->z_checksum,
pClnt->pRcvBuf,
result,
(pClnt->totalRcv - result) &0x1);
/* 2. 如果解压流没有结束,解压当前的输入并输出。 */
pClnt->z_stream.next_in = pClnt->pRcvBuf;
pClnt->z_stream.avail_in = result;
while( pClnt->z_stream.avail_in > 0 && pClnt->z_state != Z_STREAM_END)
{
switch( zinflate(&pClnt->z_stream, 0) )
{
case Z_STREAM_END:
pClnt->z_state = Z_STREAM_END;
pClnt->totalRcv=pClnt->z_stream.total_out;
break;
case Z_STREAM_ERROR:
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ERROR;
break;
default:
break;
}
if ( pClnt->z_stream.avail_out < OUTBUF_SIZE )
{
if ( fwrite (pClnt->z_outbuf, 1,
OUTBUF_SIZE - pClnt->z_stream.avail_out, pClnt->dfp)
!= OUTBUF_SIZE-pClnt->z_stream.avail_out)
return ERROR;
pClnt->z_stream.next_out = pClnt->z_outbuf;
pClnt->z_stream.avail_out = OUTBUF_SIZE;
}
}
}
else /* non-zar file stream */
{
if ( fwrite (pClnt->pRcvBuf,1,result,pClnt->dfp) != result)
return ERROR;
}
}
FTP_DBG_MSG(" %d bytes data received.\n",result,2,3,4);
return OK;
}
/*----------------------------------------------------------------------
* NAME: ftpClntCtrlNodeReadHandler
* PARAMETERS:
* RETURN: OK/ERROR
* FUNCTION: handle control socket read event.
*/
LOCAL STATUS ftpClntCtrlNodeReadHandler(FTP_CLIENT_NODE* pClnt)
{
int rcvLen;
FAST char *pChar;
if(pClnt->ctrlNode.sockFd == INVALID_SOCK )
return ERROR;
if(pClnt->replyLen == 0 )
bzero(pClnt->replyBuf,sizeof(pClnt->replyBuf));
/* reserve space for fragment; then receive from socket */
rcvLen = recv ( pClnt->ctrlNode.sockFd ,
&pClnt->replyBuf[0] + pClnt->replyLen,
1,0);
if( rcvLen == ERROR)
{
if( errnoGet() == EWOULDBLOCK )
return (OK);
else
{
pClnt->ctrlNode.state = Error;
return ERROR;
}
}
if ( rcvLen == 0)
{
pClnt->ctrlNode.state = End;
return ERROR;
}
/* then analyze the reply string */
pClnt->replyLen += rcvLen;
pChar = strstr(pClnt->replyBuf,CR_LF);
if(pChar != NULL)
{
*pChar = '\0';
if ( ftpClntReplyHandler(pClnt) == ERROR )
return ERROR;
pClnt->replyLen = 0;
}
else
{
if(pClnt->replyLen >= FTP_REPLY_LINE_LEN )
pClnt->replyLen = FTP_REPLY_LINE_LEN - 2;
}
return OK;
}
/*----------------------------------------------------------------------
* NAME: ftpClntSockNodeListen
* PARAMETERS:
* RETURN: OK/ERROR
* FUNCTION: startup listen node.
*/
LOCAL STATUS ftpClntSockNodeListen(FTP_SOCK_NODE* pn)
{
struct sockaddr_in toAddr;
int optVal,sockFd;
bzero ((char *) &toAddr, sizeof(toAddr));
toAddr.sin_family = AF_INET;
toAddr.sin_len = (UINT8) sizeof(toAddr);
toAddr.sin_port = htons(0); /* system assign a port */
toAddr.sin_addr.s_addr = INADDR_ANY;
if((sockFd = socket (AF_INET, SOCK_STREAM, 0)) == ERROR)
return ERROR;
optVal=1;
if ( setsockopt (sockFd, SOL_SOCKET, SO_REUSEADDR,
(char*)&optVal, sizeof (optVal))==ERROR)
{ close(sockFd); return ERROR; }
if (bind (sockFd ,(struct sockaddr *) &toAddr, sizeof(toAddr)) == ERROR)
{
close(sockFd);
return ERROR;
}
if (listen (sockFd ,1) == ERROR)
{
close(sockFd);
return ERROR;
}
/* nonblock */
optVal = 1;
if( ioctl (sockFd, FIONBIO, (int)&optVal) == ERROR)
{
close(sockFd);
return ERROR;
}
if( pn->sockFd != INVALID_SOCK )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -