Example #1
0
//下载的实现函数
int ftp_download(int control_sockfd)
{
    
    int pasv_or_port;// 定义the ftp协议的两种不同工作mode
    int recvbytes,sendbytes;
    char sendline[1024],recvline[1024];
    struct sockaddr_in serv_addr;
    FILE *fd;
    int i,j;
    int data_sockfd;
    //rest
    ftp_rest(control_sockfd);
    //type
    zeromery(recvline,1024);
    zeromery(sendline,1024);
    strcat(sendline,"TYPE ");
    strcat(sendline,"I");
    strcat(sendline,"\r\n");
    sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
    if(sendbytes<0)
    {
            printf(" type send is error!\n");
    }
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(strncmp(recvline,"200",3)==0)
    {
        printf("使用二进制传输数据\n");
    }
    else
    {
        printf("type recv is error!\n");
    }

    if(npsupport==1)
    {
        //open the file
        int size;
        char localpathname[60];//预打开的文件路径字符串
        int flags;
        char pathname[60];
        unsigned int mode;
        //用户来选择pasv 或者是 port mode
        char selectdata_mode_tran[1024];
        zeromery(selectdata_mode_tran,1024);
        zeromery(sendline,1024);
        zeromery(recvline,1024);
        pasv_or_port=0;//(默认是pasv模式)
        //pasv mode
        if(pasv_or_port==0)
        {
            strcat(sendline,"PASV");
            strcat(sendline,"\r\n");
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf("pasv send is error!\n");
            }
            zeromery(recvline,1024);
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes<0)
            {
                printf("pasv recv is error!\n");
            }
            if(strncmp(recvline,"227",3)==0)
            {
                char buf[55];
                snprintf(buf,51,">>> %s\n",recvline);
                printf("%s\n",buf);
            }
            else
            {
                printf("pasv recv is error!\n");
            }    
            //处理ftp server 端口
            char *ptr1,*ptr2;
            char num[1024];
            zeromery(num,1024);
            //取低位字节
            ptr1=recvline+strlen(recvline);
            while(*(ptr1)!=')')
            {
                ptr1--;
            }
            ptr2=ptr1;
            while(*(ptr2)!=',')
                ptr2--;
            strncpy(num,ptr2+1,ptr1-ptr2-1);
            i=atoi(num);//将字符串转换成整数
            //取高位字节
            zeromery(num,1024);
            ptr1=ptr2;
            ptr2--;
            while(*(ptr2)!=',')
                ptr2--;
            strncpy(num,ptr2+1,ptr1-ptr2-1);
            j=atoi(num);
            //初始化服务器数据连接时的端口信息
            int data_serviceport;
            data_serviceport=j*256+i;
            data_sockfd=socket(AF_INET,SOCK_STREAM,0);
                
            serv_addr.sin_family=AF_INET;
            serv_addr.sin_addr.s_addr=INADDR_ANY;
            serv_addr.sin_port=htons(data_serviceport);
            if(connect(data_sockfd,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr))==-1)
            {
                printf("pasv data connect is error!\n");
            }
            printf("remote-file-pathname=");
            scanf("%s",pathname);
            printf("local-file-pathname=");
            scanf("%s",localpathname);
            printf("local:%s remore:%s\n",localpathname,pathname);
            fd=fopen(localpathname,"w+");
            if(fd==NULL)
            {
                printf("cannot open file\n");
                exit(1);
            }

    
            //send the command retr;
            zeromery(sendline,1024);
            zeromery(recvline,1024);
            strcat(sendline,"RETR ");
            strcat(sendline,pathname);
            strcat(sendline,"\r\n");
            printf("%s\n",sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf("retr send is error!\n");
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(recvbytes<0)
            {
                printf("retr recv is error!\n");
            }
            if(strncmp(recvline,"400",3)>0)
            {
                printf("return is error!\n");
            }
        }
        //port mode
        /*if(pasv_or_port==1)
        {
            data_sockfd=socket(AF_INET,SOCK_STREAM,0);
            if(data_sockfd<0)
            {
                printf("创建数据端口连接失败!\n");
            }
            serv_addr.sin_family=AF_INET;
            serv_addr.sin_addr.s_addr=INADDR_ANY;
            serv_addr.sin_port=htons(SERV_PORT);
        
            int ret;
            int addrlen;
            ret=sizeof(struct sockaddr_in);
            getsockname(data_sockfd,(SA*)&serv_addr,&ret);
        
            //处理port 后面要带的参数
            char ip[1024];
            int i,j;
            char data[1024];
            zeromery(ip,1024);
            zeromery(data,1024);
            inet_ntop(AF_INET,&(serv_addr.sin_addr),ip,sizeof(ip));
            printf("%s\n",ip);
            i=data_sockfd/256;
            j=data_sockfd%256;

            //将点分十进制的点转换为逗号。
            char *ptr1;
            ptr1=ip;
            while(*(ptr1)!='/0')
            {
                if(*(ptr1)=='.')
                {
                    *(ptr1)=',';
                }
                ptr1++;
            }

            strcat(sendline,"PORT ");
            strcat(sendline,ip);
            strcat(sendline,",");
            strcat(sendline,itoa(i,data,10));
            strcat(sendline,",");
            strcat(sendline,itoa(j,data,10));
            strcat(sendline,"\r\n");
            printf("--->%s\n",sendline);
            sendbytes=send(control_sockfd,sendline,strlen(sendline),0);
            if(sendbytes<0)
            {
                printf("port send is error!\n");
                exit(1);
            }
            recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
            if(strncmp(recvline,"200",3)==0)
            {
                printf("%s\n",recv);
            }
            else
            {
                printf("port recv is error!\n");
            }

        }*/
        //begin to transpotr data
        sleep(1);
        int flag=0;
        char buffer[65536];
recvdata:
        zeromery(buffer,1024);
        recvbytes=recv(data_sockfd,buffer,sizeof(buffer),0);
        if(recvbytes<0)
        {
            close(data_sockfd);
            goto end;
        }
        fwrite(buffer,1,recvbytes,fd);
        zeromery(recvline,1024);
        recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
        if(flag==0)
        {
            if(strncmp(recvline,"226",3)!=0)
            {
                    flag=1;
                    goto recvdata;
            }
        }
end:
        if(flag!=1)
        {
            zeromery(recvline,1024);
            shutdown(data_sockfd,SHUT_WR);
            close(data_sockfd);
        }
        close(data_sockfd);
/*    int err;
    char buffer[65535];
    err=read(data_sockfd,buffer,sizeof(buffer));
    sleep(5);
    fwrite(buffer,1,err,fd);
    sleep(5);
    zeromery(recvline,1024);
    recvbytes=recv(control_sockfd,recvline,sizeof(recvline),0);
    if(strncmp(recvline,"226",3)==0)
    {
    end:    printf("226 transfer complete\n");
        close(data_sockfd);
    }*/
    return 0;
    }
}
Example #2
0
//
//	To transfer data, we do these things in order as specifed by
//	the RFC.
// 
//	First, we tell the other side to set up a data line.  This
//	is done by opendataconn() which sets up  the socket.  When we do that,
//	the other side detects a connection  attempt, so it knows we're
//	there.  Then tell the other side (by using listen()) that we're
//	willing to receive a connection going to our side.
//
//	Initialize the data connection prior to a transfer operation
//	Send the PORT command followed by the optional REST command for a resume
//	Finally send the LIST, RETR, or STOR command
//
//	Returns >= 0 (socket) for success
//	Returns -2 if cmd failed
//	Returns -3 under some (forgotten) circumstances
//	Returns -1 for other errors
//
static int dataconna( struct ftp_info *info, int restart, const char *fmt, ... )
{
struct opusftp_globals *ogp = info->fi_og;
va_list                 ap;			// For varargs
int                     ts, ds = -1;		// Temporary socket, Data socket
struct linger           linger = { 1, 120 };	// Socket option
int                     tos = IPTOS_THROUGHPUT;	// Another socket option
struct sockaddr_in      from;			// Socket address
int                     reply;
BOOL                    okay = FALSE;

if	((ts = opendataconn( ogp, info )) >= 0)
	{
	okay = TRUE;

	// Have the system make an effort to deliver any unsent data
	// even after we close the connection
	setsockopt( ts, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger) );

	// Data connection is a non-interactive data stream, so
	// high throughput is desired, at the expense of low
	// response time
	setsockopt( ts, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(tos) );

	// Resuming a transfer?
	if	(restart)
		{
		// Can we use REST command?
		if	(!(info->fi_flags & FTP_NO_REST))
			{
			// Can TIMEOUT
			ftp_rest( info, restart );
			}
		}

	// Result if something failed after opendataconn and before here
	ds = -3;
	}

if	(okay)
	{
	va_start( ap, fmt );

	// Send main command - Can TIMEOUT
	reply = vftpa( info, fmt, ap );
	va_end( ap );

	if	(reply/100 == PRELIM || ((info->fi_flags & FTP_FEAT_MLST) && reply == 200)) // better check the actual command?
		{
		LONG len = sizeof(from);

		// Sendport mode?
		if	((info->fi_flags & FTP_NO_PASV) || !(info->fi_flags & FTP_PASSIVE))
			{
			ds = accept( ts, (struct sockaddr*)&from, &len );

			CloseSocket( ts );
			}

		// Passive mode?
		else
			{
			ds = ts;
			}
		}
	else
		ds = -2;
	}

return ds;
}