示例#1
0
/*--成功返回连接句柄 Handle,失败返回-1---*/
int network_tcp_connection_open(uint8 *hostname, uint16 port) 
{
		int handle=-1;
		
		handle = util_tcp_connect(hostname, port);
		return handle;
}
示例#2
0
文件: ftp.c 项目: alkap007/ali3606
int ftp_transfer(UrlResource *rsrc, libnet_callback notify)
{
	Url 	*u		= NULL;
	FILE 	*out		= NULL;
	char 	*line		= NULL;
	int 	sock		= -1;
	int 	data_sock	= -1;
	int	passive		= 1;
	int	retval		= 0;
    int msg_code    = 0;

	u = rsrc->url;

	/* first of all, if this is proxied, just pass it off to the
	   http module, since that's how we support proxying. */

	rsrc->proxy = get_proxy("FTP_PROXY");

	if ( rsrc->proxy )
	{
		return http_transfer(rsrc, notify);
	}

	ftp_set_defaults(rsrc, u);

	sock = util_tcp_connect(u->host, u->port);
	if (sock < 0)
	{
        if (rsrc->running)
        {
		    notify(NET_MSG_DOWNLOAD_FINISH, (UINT32)-NET_ERR_CONNECT_FAILED);
        }
        //S_CLOSE(sock);
		return 0;
	}

	if ( !(line = get_line(rsrc, sock)) )
	{
        if (rsrc->running)
        {
            notify(NET_MSG_DOWNLOAD_FINISH, (UINT32)-NET_ERR_FTP_SERVER_ERROR);
        }
        S_CLOSE(sock);
		return 0;
	}

	if ( !check_numeric("220", line) )
	{
		safe_free(line);
        S_CLOSE(sock);
		LIBNET_DEBUG("bad server greeting");        
        if (rsrc->running)
        {
            notify(NET_MSG_DOWNLOAD_FINISH, (UINT32)-NET_ERR_FTP_SERVER_ERROR);
        }
		return 0;
	}
	safe_free(line);


	send_control(sock, "USER ", u->username, "\r\n", NULL);

	if ( !(line = get_line(rsrc, sock)) )
	{
        msg_code = -NET_ERR_LOGIN_FAILED;
        goto cleanup;
	}

	/* do the password dance */
	if ( !check_numeric("230", line) )
	{
		if ( !check_numeric("331", line))
		{
			safe_free(line);
			LIBNET_DEBUG("bad/unexpected response: %s", line);
            msg_code = -NET_ERR_LOGIN_FAILED;
            goto cleanup;
		}
		else
		{
			safe_free(line);

			send_control(sock, "PASS ", u->password, "\r\n", NULL);

			if ( !((line = get_line(rsrc, sock)) &&
					check_numeric("230", line)) )
			{
				safe_free(line);
				LIBNET_DEBUG("login failed");
				msg_code = -NET_ERR_LOGIN_FAILED;
                goto cleanup;
			}
			//safe_free(line);
		}
	}

    safe_free(line);

	/* set binmode */
	send_control(sock, "TYPE I\r\n", NULL);

	if ( !(line = get_line(rsrc, sock)) )
	{      
        msg_code = -NET_ERR_FTP_SERVER_ERROR;
        goto cleanup;
	}
	safe_free(line);
#if 1 // user can't change ftp path to "/" if server don't support it
	if ( u->path && (STRCMP(u->path, "/") != 0))
	{
		/* CWD using relative path */
		char *relative_path = u->path[0] == '/' ? &u->path[1] : &u->path[0];
		send_control(sock, "CWD ", relative_path, "\r\n", NULL);

		if ( !((line = get_line(rsrc, sock)) &&
				check_numeric("250", line)) )
		{
			safe_free(line);
            msg_code = -NET_ERR_OPERATION_NOT_PERMIT;
            goto cleanup;
		}
		safe_free(line);
	}
#endif
	/* finally, the good stuff */

	/* get a socket for reading. try passive first. */

	if ( ! (rsrc->options & OPT_ACTIVE) )
	{
		if ( (data_sock = get_passive_sock(rsrc, sock)) < 0 )
		{          
          msg_code = -NET_ERR_CONNECT_FAILED;
          goto cleanup;
		}
	}


	if ( data_sock < 0 )
	{
		if ( (data_sock = get_sock(rsrc, sock)) < 1 )
		{          
          msg_code = -NET_ERR_CONNECT_FAILED;
          goto cleanup;
		}
		else
			passive = 0;
	}

	if (u->file)
	{
		send_control(sock, "SIZE ", u->file, "\r\n", NULL);
		line = get_line(rsrc, sock);
		if (line && check_numeric("213", line))
		{
			rsrc->outfile_size = ATOI(line + 4);
		}
		else if (line && check_numeric("550", line))
		{
			safe_free(line);
			msg_code = -NET_ERR_FILE_NOT_FOUND;
            goto cleanup;
		}
		else
		{
			rsrc->outfile_size = 0;
		}
		if (line) FREE(line);
	}

	/* handle resume */
	if ( rsrc->outfile_offset && (rsrc->options & OPT_RESUME) )
	{
		char numstring[32]; /* ugly hack */

		sprintf(numstring, "%ld", (long int )rsrc->outfile_offset);
		send_control(sock, "REST ", numstring, "\r\n", NULL);

		if ( !((line = get_line(rsrc, sock)) &&
				check_numeric("350", line)) )
		{
			safe_free(line);
			LIBNET_DEBUG("server does not support FTP resume, try again without -r");
			msg_code = -NET_ERR_OPERATION_NOT_PERMIT;
            goto cleanup;
		}
		safe_free(line);
	}

	if (u->file)
		send_control(sock, "RETR ", u->file, "\r\n", NULL);
	else
		send_control(sock, "NLST\r\n", NULL);

	if ( !((line = get_line(rsrc, sock)) &&
			(check_numeric("150", line) || check_numeric("125", line))) )
	{
		safe_free(line);
        msg_code = -NET_ERR_OPERATION_NOT_PERMIT;
        goto cleanup;
	}

    LIBNET_DEBUG("ftp reply(RETR): %s\n", line);
	if ( !passive )
		data_sock = S_ACCEPT(data_sock, NULL, NULL);

	/*        rsrc->outfile_size = guess_file_size(line); */

	safe_free(line);

	if (rsrc->outfile)
	{
		if (get_file_size(rsrc->outfile) > 0)
			out = fopen(rsrc->outfile, "rb+");
		else
			out = fopen(rsrc->outfile, "wb");

		if ( !out )
		{
			//report(ERR, "opening %s: %s", rsrc->outfile,
			//	   strerror(errno));
            msg_code = -NET_ERR_FILE_SAVE_ERROR;
            goto cleanup;
		}
	}

	retval = dump_data(rsrc, data_sock, out, notify);

    if (rsrc->running)
    {
    	line = get_line(rsrc, sock); /* 226 Transfer complete */
        LIBNET_DEBUG("ftp(done): %s\n", line);
    	safe_free(line);
    }

cleanup:
    
	send_control(sock, "QUIT\r\n", NULL);
	line = get_line(rsrc, sock); /* 221 Goodbye */    
    LIBNET_DEBUG("ftp(QUIT): %s\n", line);
	safe_free(line);
    
	if (out)
		fclose(out);

    if (data_sock >= 0)
    {
        S_CLOSE(data_sock);
    }
    
	if (sock >= 0)
    {
        S_CLOSE(sock);
	}
	
#ifndef WIN32
	if (rsrc->outfile)
		fs_sync(rsrc->outfile);
#endif

    if (msg_code < 0 && rsrc->running)
    { 
		notify(NET_MSG_DOWNLOAD_FINISH, (UINT32)msg_code);
    }
	return retval;
}
示例#3
0
int http_transfer(UrlResource *rsrc, libnet_callback notify)
{
	FILE *out 		= NULL;
	Url *u			= NULL;
	Url *proxy_url		= NULL;
	Url *redir_u		= NULL;
	char *request		= NULL;
	//char *raw_header	= NULL;
	HttpHeader *header	= NULL;
	//char *len_string 	= NULL;
	//char *new_location	= NULL;
    char *tmp_string    = NULL;
	//char buf[BUFSIZE];
	int sock 		= -1;
	ssize_t bytes_read	= 0;
    int msg_code    = 0;
	int retval		= 0;
	int i;

    char *buf = MALLOC(BUFSIZE);
    if (!buf)
    {
        LIBNET_DEBUG("No enough memory!\n");
        return 0;
    }
	/* make sure we haven't recursed too much */
	if ( redirect_count > REDIRECT_MAX )
	{
		LIBNET_DEBUG("redirection max count exceeded (looping redirect?)");
		redirect_count = 0;
        msg_code = -NET_ERR_CONNECT_FAILED;
        goto cleanup;
	}


	/* make sure everything's initialized to something useful */
	u = rsrc->url;
	if ( !u->host )
	{
		LIBNET_DEBUG("no host specified");
        msg_code = -NET_ERR_CONNECT_FAILED;
        goto cleanup;
	}

	/* fill in proxyness */
	if ( !rsrc->proxy )
	{
		rsrc->proxy = get_proxy("HTTP_PROXY");
	}

	if (( NULL == rsrc->outfile ) && (NULL == rsrc->buffer))
	{
		if ( u->file )
			rsrc->outfile = strdup(u->file);
		else
			rsrc->outfile = strdup("index.html");
	}

	if ( !u->path )
		u->path = strdup("/");

	if ( !u->file )
		u->file = strdup("");  /* funny looking */

	if ( !u->port )
		u->port = 80;

	rsrc->options |= default_opts;

	/* send the request to either the proxy or the remote host */
	if ( rsrc->proxy )
	{
		proxy_url = url_new();
		url_init(proxy_url, rsrc->proxy);

		if ( !proxy_url->port )
			proxy_url->port = 80;

		if ( !proxy_url->host )
		{
			LIBNET_DEBUG( "bad proxy `%s'", rsrc->proxy);
            msg_code = -NET_ERR_CONNECT_FAILED;
            goto cleanup;
		}

		if ( proxy_url->username )
			rsrc->proxy_username = strdup(proxy_url->username);
		if ( proxy_url->password )
			rsrc->proxy_password = strdup(proxy_url->password);

#ifdef LIB_W5300
		sock = w5300_tcp_connect(proxy_url->host, proxy_url->port, rsrc->srcip, rsrc->srcport);		
#else
		sock = util_tcp_connect(proxy_url->host, proxy_url->port);
#endif
		if (sock < 0)
		{
            msg_code = -NET_ERR_CONNECT_FAILED;
            goto cleanup;            
		}

		safe_free(u->path);
		safe_free(u->file);
		u->path = strdup("");
		u->file = strdup(u->full_url);
		request = get_request(rsrc);
        LIBNET_DEBUG("sending request:\n%s", request);
		S_WRITE(sock, request, STRLEN(request));

		FREE(request);
	}
	else /* no proxy */
	{
#ifdef LIB_W5300
		sock = w5300_tcp_connect(u->host, u->port, rsrc->srcip, rsrc->srcport);		
#else
		sock = util_tcp_connect(u->host, u->port);
#endif
		if (sock < 0)
		{
            msg_code = -NET_ERR_CONNECT_FAILED;
            goto cleanup;            
		}
		request = get_request(rsrc);
        LIBNET_DEBUG("sending request:\n%s", request);
		S_WRITE(sock, request, STRLEN(request));

		FREE(request);
	}

	if (rsrc->outfile)
	{
		if ((get_file_size(rsrc->outfile) > 0) && (rsrc->options & OPT_RESUME))
			out = fopen(rsrc->outfile, "rb+");
		else
			out = fopen(rsrc->outfile, "wb");

		if ( !out )
		{
			LIBNET_DEBUG( "opening %s: %s", rsrc->outfile, "");			
            msg_code = -NET_ERR_FILE_SAVE_ERROR;
            goto cleanup;
			
		}
	}

	/* check to see if it returned a HTTP 1.x response */
	MEMSET(buf, '\0', 5);

#ifdef LIB_W5300
	bytes_read = S_READ(sock, buf, BUFSIZE);
    buf[bytes_read] = '\0';
    LIBNET_DEBUG("receive respond:(%d)\n%s", bytes_read, buf);
#else
	bytes_read = S_READ(sock, buf, 8);
#endif

	if ( bytes_read <= 0 )
	{
        msg_code = -NET_ERR_HTTP_SERVER_ERROR;
        goto cleanup;
	}

	if ( ! (buf[0] == 'H' && buf[1] == 'T'
			&& buf[2] == 'T' && buf[3] == 'P') )
	{
		if((rsrc->options & OPT_RESUME) &&	rsrc->outfile_offset)
		{
			LIBNET_DEBUG("server does not support resume!");
            msg_code = -NET_ERR_OPERATION_NOT_PERMIT;
			goto cleanup;
		}
		//fwrite(buf, bytes_read, 1,out);
	}
	else
	{
		/* skip the header */
#ifdef LIB_W5300
        buf[bytes_read] = '\0';
#else
		char *raw_header1 = NULL;
		buf[bytes_read] = '\0';
		raw_header1 = get_raw_header(sock);
		strconcat2(buf, raw_header1, NULL);
		FREE(raw_header1);
        LIBNET_DEBUG("receive respond:(%d)\n%s", bytes_read, buf);
#endif
		header = make_http_header(buf);

		/* check for redirects */
		tmp_string = get_header_value("location", header);

		if (buf[9] == '3' && tmp_string )
		{
#if 1			//diable redirec function
			redir_u = url_new();

			/* make sure we still send user/password along */
			redir_u->username = safe_strdup(u->username);
			redir_u->password = safe_strdup(u->password);

			url_init(redir_u, tmp_string);
			rsrc->url = redir_u;
			redirect_count++;
			//retval = transfer(rsrc, notify);
			transfer((UINT32)rsrc, (UINT32)notify);
			rsrc->url =u;
			redirect_count--;
			if(redirect_count<0) redirect_count=0;
			if (redir_u)
			{
				url_destroy(redir_u);
				FREE(redir_u);
			}
#endif			
            FREE(tmp_string);
            tmp_string = NULL;
            //msg_code = -NET_ERR_OPERATION_NOT_PERMIT;//we can support redirect now, remove this line.
			goto cleanup;
		}
        if (tmp_string)
        {
            FREE(tmp_string);
            tmp_string = NULL;
        }

		if (buf[9] == '4' || buf[9] == '5')
		{
			for (i = 0; buf[i] && buf[i] != '\n'; i++);
			buf[i] = '\0';
			LIBNET_DEBUG("HTTP error from server: %s\n", buf);

			if( buf[9] == '4' && buf[10] == '0' && buf[11] == '4') 
				msg_code = -NET_ERR_FILE_NOT_FOUND;
			else
				msg_code = -NET_ERR_HTTP_SERVER_ERROR;
			
			goto cleanup;
		}

		tmp_string = get_header_value("content-length", header);

		if (tmp_string)
		{
			rsrc->outfile_size = (off_t )ATOI(tmp_string);
	            FREE(tmp_string);
	            tmp_string = NULL;		
			if(rsrc->use_pecache ==0)
			{
				if ((rsrc->buffer) && (rsrc->buffer_len < rsrc->outfile_size))
				{
					LIBNET_DEBUG("the buffer length less than the file fize (%d < %d)\n", rsrc->buffer, (int)rsrc->outfile_size);
				    msg_code = -NET_ERR_FILE_SAVE_ERROR;
					goto cleanup;
				}
			}				
		}

        tmp_string = get_header_value("content-range", header);
		if (tmp_string)
		{
            FREE(tmp_string);
            tmp_string = NULL;
			rsrc->outfile_size += rsrc->outfile_offset;
		}

		if ((!rsrc->outfile_size) &&
				(rsrc->options & OPT_RESUME) &&
				!(rsrc->options & OPT_NORESUME)
				&& rsrc->outfile_offset )
		{
			LIBNET_DEBUG("unable to determine remote file size");
            msg_code = -NET_ERR_FILE_SAVE_ERROR;
			goto cleanup;
		}
	}

if(rsrc->use_pecache ==0)
	retval = dump_data(rsrc, sock, out, notify);
else
	retval = dump_data_to_pecache(rsrc, sock, out, notify);

cleanup:
	free_http_header(header);

    //if (raw_header)
	//	FREE(raw_header);
		

	if (proxy_url)
	{
		url_destroy(proxy_url);
		FREE(proxy_url);
	}

    if (sock >= 0)
    {
	    S_CLOSE(sock);
    }

	if (out)
		fclose(out);

    if (buf)
    {
        FREE(buf);
    }

#ifndef WIN32
	if (rsrc->outfile)
		fs_sync(rsrc->outfile);
#endif

    if (msg_code < 0 && rsrc->running)
    { 
		notify(NET_MSG_DOWNLOAD_FINISH, (UINT32)msg_code);
		libnet_abort_url_read(TRUE);//to break url_open while loop //retval!=1 means transfer fail
    }

	return retval;

}