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

📄 connection.c

📁 prozgui是一款Linxu下著名的下载工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** libprozilla - a download accelerator library Copyright (C) 2001 Kalum Somaratna This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA******************************************************************************//* Several connection-related routines. *//* $Id: connection.c,v 1.42 2001/10/27 11:24:40 kalum Exp $ */#include "common.h"#include "prozilla.h"#include "connection.h"#include "misc.h"#include "connect.h"#include "ftp.h"#include "http.h"#include "debug.h"/****************************************************************************** ...******************************************************************************/void init_response(connection_t * connection){  connection->serv_ret_lines = 0;}/****************************************************************************** This will free up the serv_ret_lines array if necessary, in order to prepare it for the storage of the servers response.******************************************************************************/void done_with_response(connection_t * connection){  response_line *p, *p1;  /* Return if the array is not allocated. */  if (connection->serv_ret_lines == 0)    return;  p1 = connection->serv_ret_lines;  do  {    p = p1;    p1 = p->next;    kfree(p);  }  while (p1 != 0);  connection->serv_ret_lines = 0;}/****************************************************************************** Initialises the connection and sets it with values from the runtime struct.******************************************************************************/connection_t * proz_connection_init(urlinfo *url,pthread_mutex_t * mutex){  connection_t * connection=kmalloc(sizeof(connection_t));   memset(connection, 0, sizeof(connection_t));  /*  memcpy(&connection->u, url, sizeof(urlinfo));*/  if(url)    memcpy(&connection->u,		     proz_copy_url(url),		     sizeof(urlinfo));  /* Copy the proxy structs. */  if (libprozrtinfo.ftp_proxy)  {    connection->ftp_proxy = kmalloc(sizeof(proxy_info));    memcpy(connection->ftp_proxy, libprozrtinfo.ftp_proxy,	   sizeof(proxy_info));    /*       connection->use_ftp_proxy = libprozrtinfo.use_ftp_proxy;     */  }  if (libprozrtinfo.http_proxy)  {    connection->http_proxy = kmalloc(sizeof(proxy_info));    memcpy(connection->http_proxy, libprozrtinfo.http_proxy,	   sizeof(proxy_info));    /*       connection->use_http_proxy = libprozrtinfo.use_http_proxy;     */  }  connection->use_netrc = libprozrtinfo.use_netrc;  connection->retry = TRUE;  connection->ftp_use_pasv = libprozrtinfo.ftp_use_pasv;  connection->http_no_cache = libprozrtinfo.http_no_cache;  connection->user_agent = strdup(DEFAULT_USER_AGENT);  connection->file_mode = strdup("wb");  /*NOTE: default of unlimited attempts */  connection->max_attempts = 0;  connection->attempts = 0;  /* Initialise all with default timeouts */  memcpy(&connection->xfer_timeout, &libprozrtinfo.conn_timeout,	 sizeof(connection->xfer_timeout));  memcpy(&connection->ctrl_timeout, &libprozrtinfo.conn_timeout,	 sizeof(connection->ctrl_timeout));  memcpy(&connection->conn_timeout, &libprozrtinfo.conn_timeout,	 sizeof(connection->conn_timeout));  memcpy(&connection->retry_delay, &libprozrtinfo.conn_retry_delay,	 sizeof(&connection->retry_delay));  connection->max_attempts = libprozrtinfo.max_attempts;  connection->rate_bps = 0;  /* Unlimited bandwith (0) */  connection->max_allowed_bps = 0;  pthread_cond_init(&connection->connecting_cond, NULL);  connection->status_change_mutex = mutex;  if (connection->status_change_mutex != 0)  {    pthread_mutex_init(connection->status_change_mutex, NULL);  }  pthread_mutex_init(&connection->access_mutex, NULL);  return connection;}/* Locks the connections mutex befoer chaging state. */void connection_change_status(connection_t * connection, dl_status status){  if (connection->status_change_mutex != 0)  {    pthread_mutex_lock(connection->status_change_mutex);    connection->status = status;    pthread_mutex_unlock(connection->status_change_mutex);  }}/* this will open connection->localfile and read from connection->data_sock    (which should be already setup) till a EOF is reached or    the server closes the connection, in which case there is no way to know    whether we got the complete file.  */uerr_t connection_retr_fsize_not_known(connection_t * connection,				       char *read_buffer,				       int read_buffer_size){  long bytes_read;  connection_change_status(connection, DOWNLOADING);  gettimeofday(&connection->time_begin, NULL);  do  {    bytes_read =	krecv(connection->data_sock, read_buffer, read_buffer_size, 0,	      &connection->xfer_timeout);    if (bytes_read > 0)    {      if (write_data_with_lock(connection, read_buffer, sizeof(char), bytes_read) < bytes_read)      {	proz_debug(_("write failed"));	connection_show_message(connection,				_				("Unable to write to file %s: %s!"),				connection->localfile, strerror(errno));	connection_change_status(connection, LOCALFATAL);	return FWRITEERR;      }      pthread_mutex_lock(&connection->access_mutex);      connection->remote_bytes_received += bytes_read;      pthread_mutex_unlock(&connection->access_mutex);      /*TODO: caclculate and throttle connections speed here */      /*DONE: */      connection_calc_ratebps(connection);      connection_throttle_bps(connection);    }  }  while (bytes_read > 0);  if (bytes_read == -1)  {    if (errno == ETIMEDOUT)    {      proz_debug(_("connection timed out"));      connection_change_status(connection, TIMEDOUT);      return READERR;    }    connection_change_status(connection, REMOTEFATAL);    return READERR;  }  connection_change_status(connection, COMPLETED);  connection_show_message(connection,			  _("download for this connection completed"			    "%s : %ld received"), connection->localfile,			  connection->remote_bytes_received);  return FILEGETOK;}/* This will open connection->localfile and read from connection->data_sock    (which should be already setup) till the requested number of bytes are read.   Now since we explicitly know how much bytes to get we can do so, and is the server    closes the connection prematurely we know that has hapenned (because it hasn't supplied    the required number of bytes) and return a READERR.*/uerr_t connection_retr_fsize_known(connection_t * connection,				   char *read_buffer, int read_buffer_size){  long bytes_read;  long bytes_to_get;  pthread_mutex_lock(&connection->access_mutex);  bytes_to_get = connection->remote_endpos - connection->remote_startpos;  pthread_mutex_unlock(&connection->access_mutex);  connection_change_status(connection, DOWNLOADING);  gettimeofday(&connection->time_begin, NULL);  while (bytes_to_get > 0)  {    bytes_read =	krecv(connection->data_sock, read_buffer,	      bytes_to_get >	      read_buffer_size ? read_buffer_size : bytes_to_get, 0,	      &connection->xfer_timeout);    if (bytes_read == 0 && bytes_to_get > 0)    {      connection_show_message(connection,			      _("Server Closed Connection Prematurely!"));      connection_change_status(connection, REMOTEFATAL);      return READERR;    }    if (bytes_read == -1)    {      if (errno == ETIMEDOUT)      {	proz_debug(_("connection timed out"));	connection_change_status(connection, TIMEDOUT);	return READERR;      }      connection_change_status(connection, REMOTEFATAL);      return READERR;    }    bytes_to_get -= bytes_read;    if (bytes_read > 0)    {           if (write_data_with_lock(connection, read_buffer, sizeof(char), bytes_read) < bytes_read)      {	proz_debug(_("write failed"));	connection_show_message(connection,				_				("Unable to write to file %s: %s!"),				connection->localfile, strerror(errno));	connection_change_status(connection, LOCALFATAL);	return FWRITEERR;      }      pthread_mutex_lock(&connection->access_mutex);      connection->remote_bytes_received += bytes_read;      pthread_mutex_unlock(&connection->access_mutex);      /*TODO: caclculate and throttle connections speed here */      /*DONE: */      connection_calc_ratebps(connection);      connection_throttle_bps(connection);    }  }  connection_change_status(connection, COMPLETED);  connection_show_message(connection,			  _("download for this connection completed"			    "%s : %ld received"), connection->localfile,			  connection->remote_bytes_received);  return FILEGETOK;}/* This function modifies a single connections download start and    end info it returns 1 on sucess and -1 on error. */int connection_load_resume_info(connection_t * connection){      if(connection->remote_startpos-connection->orig_remote_startpos!=connection->remote_bytes_received)      connection->remote_startpos +=connection->remote_bytes_received;  return 1;}dl_status proz_connection_get_status(connection_t * connection){  dl_status status;  pthread_mutex_lock(connection->status_change_mutex);  status = connection->status;  pthread_mutex_unlock(connection->status_change_mutex);  return status;}/*This will return a textual representation of the status of a conenction. */char *proz_connection_get_status_string(connection_t * connection){  dl_status status;  pthread_mutex_lock(connection->status_change_mutex);  status = connection->status;  pthread_mutex_unlock(connection->status_change_mutex);  switch (connection->status)  {  case IDLE:    return (_("Idle"));  case CONNECTING:    return (_("Connecting"));  case LOGGININ:    return (_("Logging in"));  case DOWNLOADING:    return (_("Downloading"));    break;  case COMPLETED:    return (_("Completed"));  case LOGINFAIL:    return (_("Login Denied"));

⌨️ 快捷键说明

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