From 45795bc8d912c401077912fcb7d50376deac1797 Mon Sep 17 00:00:00 2001 From: ryr1990 <516248814@qq.com> Date: Sun, 29 Mar 2015 20:38:34 +0800 Subject: [PATCH] axel1.0 download running --- axel1.0/axel.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++ axel1.0/axel.h | 115 ++++++++++++++++++++++++++ axel1.0/conf.c | 58 +++++++++++++ axel1.0/conf.h | 55 +++++++++++++ axel1.0/config.h | 7 ++ axel1.0/conn.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++ axel1.0/conn.h | 65 +++++++++++++++ axel1.0/ftp.c | 18 ++++ axel1.0/ftp.h | 46 +++++++++++ axel1.0/http.c | 118 ++++++++++++++++++++++++++ axel1.0/http.h | 51 ++++++++++++ axel1.0/search.h | 37 +++++++++ axel1.0/tcp.c | 59 +++++++++++++ axel1.0/tcp.h | 27 ++++++ axel1.0/text.c | 61 ++++++++++++++ 15 files changed, 1136 insertions(+) create mode 100644 axel1.0/axel.c create mode 100644 axel1.0/axel.h create mode 100644 axel1.0/conf.c create mode 100644 axel1.0/conf.h create mode 100644 axel1.0/config.h create mode 100644 axel1.0/conn.c create mode 100644 axel1.0/conn.h create mode 100644 axel1.0/ftp.c create mode 100644 axel1.0/ftp.h create mode 100644 axel1.0/http.c create mode 100644 axel1.0/http.h create mode 100644 axel1.0/search.h create mode 100644 axel1.0/tcp.c create mode 100644 axel1.0/tcp.h create mode 100644 axel1.0/text.c diff --git a/axel1.0/axel.c b/axel1.0/axel.c new file mode 100644 index 0000000..93429fa --- /dev/null +++ b/axel1.0/axel.c @@ -0,0 +1,209 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* Main control */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "axel.h" + +/* Axel */ +static void save_state( axel_t *axel ); +static void *setup_thread( void * ); +static void axel_message( axel_t *axel, char *format, ... ); +static void axel_divide( axel_t *axel ); + +static char *buffer = NULL; + +/* Create a new axel_t structure */ +axel_t *axel_new( conf_t *conf, int count, void *url ) +{ + search_t *res; + axel_t *axel; + url_t *u; + char *s; + int i; + + /* 分配axel结构体内存 */ + axel = malloc( sizeof( axel_t ) ); + memset( axel, 0, sizeof( axel_t ) ); + + /* 赋值axel结构体 begin */ + + /* 赋值axel->conf */ + *axel->conf = *conf; + /* 赋值axel->conn */ + axel->conn = malloc( sizeof( conn_t ) * axel->conf->num_connections ); + memset( axel->conn, 0, sizeof( conn_t ) * axel->conf->num_connections ); + + if( axel->conf->max_speed > 0 ) + { + if( (float) axel->conf->max_speed / axel->conf->buffer_size < 0.5 ) + { + if( axel->conf->verbose >= 2 ) + axel_message( axel, _("Buffer resized for this speed.") ); + axel->conf->buffer_size = axel->conf->max_speed; + } + axel->delay_time = (int) ( (float) 1000000 / axel->conf->max_speed * axel->conf->buffer_size * axel->conf->num_connections ); + } + + if( buffer == NULL ) + buffer = malloc( max( MAX_STRING, axel->conf->buffer_size ) ); + + /* 连接数为0 */ + if( count == 0 ) + { + axel->url = malloc( sizeof( url_t ) ); + axel->url->next = axel->url; + strncpy( axel->url->text, (char *) url, MAX_STRING ); + } + else + { + res = (search_t *) url; + u = axel->url = malloc( sizeof( url_t ) ); + for( i = 0; i < count; i ++ ) + { + /* 赋值url为text */ + strncpy( u->text, res[i].url, MAX_STRING ); + if( i < count - 1 ) + { + u->next = malloc( sizeof( url_t ) ); + u = u->next; + } + else + { + u->next = axel->url; + } + } + } + + /* 重要点: 前面main中的conf已经赋予axel->conf,现在赋值axel->conn->conf */ + axel->conn[0].conf = axel->conf; + + printf("text:%s\n",axel->url->text); + + + /* 用一个url来构造conn_t数据结构 */ + if( !conn_set( &axel->conn[0], axel->url->text ) ) + { + axel_message( axel, _("Could not parse URL.\n") ); + axel->ready = -1; + return( axel ); + } + + printf("file:%s\n",axel->conn[0].file); + + + axel->conn[0].local_if = axel->conf->interfaces->text; + axel->conf->interfaces = axel->conf->interfaces->next; + + printf("===========before conn init ...=====\n"); + printf("local_if:%s\n",axel->conn[0].local_if); + printf("axel->conn[0].conf->no_proxy:%s\n",axel->conn[0].conf->no_proxy); + printf("axel->conn[0].file:%s\n",axel->conn[0].file); + printf("axel->conn[0].message:%s\n",axel->conn[0].message); + + + /* 解析下载文件名 */ + strncpy( axel->filename, axel->conn[0].file, MAX_STRING ); + http_decode( axel->filename ); + printf("axel->filename:%s\n",axel->filename); + if( *axel->filename == 0 ) /* Index page == no fn */ + strncpy( axel->filename, axel->conf->default_filename, MAX_STRING ); + if( ( s = strchr( axel->filename, '?' ) ) != NULL && axel->conf->strip_cgi_parameters ) + *s = 0; /* Get rid of CGI parameters */ + + /* 打开到http服务器的连接或者打开到FTP服务器的连接并且切换到ftp的下载目录 */ + if( !conn_init( &axel->conn[0] ) ) + { + axel_message( axel, axel->conn[0].message ); + axel->ready = -1; + return( axel ); + } + printf("===========after conn init ...=====\n"); + printf("axel->conn[0].message:%s\n",axel->conn[0].message); + printf("axel->conn[0].host:%s\n",axel->conn[0].host); + printf("axel->conn[0].dir:%s\n",axel->conn[0].dir); + printf("axel->conn[0].file:%s\n",axel->conn[0].file); + printf("axel->conn[0].user:%s\n",axel->conn[0].user); + printf("axel->conn[0].pass:%s\n",axel->conn[0].pass); + printf("axel->conn[0].size:%s\n",axel->conn[0].size); + printf("axel->conn[0].currentbyte:%s\n",axel->conn[0].currentbyte); + printf("axel->conn[0].lastbyte:%s\n",axel->conn[0].lastbyte); + + + /* Get file size and other information */ + /* This does more than just checking the file size, it all depends + on the protocol used. */ + /*if( !conn_info( &axel->conn[0] ) ) + { + axel_message( axel, axel->conn[0].message ); + axel->ready = -1; + return( axel ); + } + */ + + + /* Generate a nice URL string. */ + s = conn_url( axel->conn ); + strncpy( axel->url->text, s, MAX_STRING ); + printf("axel->url->text:%s\n",axel->url->text); + if( ( axel->size = axel->conn[0].size ) != INT_MAX ) + { + if( axel->conf->verbose > 0 ) + axel_message( axel, _("File size: %lld bytes"), axel->size ); + } + + /* Wildcards in URL --> Get complete filename */ + if( strchr( axel->filename, '*' ) || strchr( axel->filename, '?' ) ) + strncpy( axel->filename, axel->conn[0].file, MAX_STRING ); + + + return( axel ); +} + + + + +/* Add a message to the axel->message structure */ +/* axel_message( axel, _("Could not parse URL.\n") ); */ +static void axel_message( axel_t *axel, char *format, ... ) +{ + message_t *m = malloc( sizeof( message_t ) ), *n = axel->message; + va_list params; + + memset( m, 0, sizeof( message_t ) ); + va_start( params, format ); + vsnprintf( m->text, MAX_STRING, format, params ); + va_end( params ); + + /* 将format的信息置于axel->message的栈尾 */ + if( axel->message == NULL ) + { + axel->message = m; + } + else + { + while( n->next != NULL ) + n = n->next; + n->next = m; + } +} \ No newline at end of file diff --git a/axel1.0/axel.h b/axel1.0/axel.h new file mode 100644 index 0000000..e54c95b --- /dev/null +++ b/axel1.0/axel.h @@ -0,0 +1,115 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* Main include file */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#ifndef NOGETOPTLONG +#define _GNU_SOURCE +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Internationalization */ +#ifdef I18N +#define PACKAGE "axel" +#define _( x ) gettext( x ) +#include +#include +#else +#define _( x ) x +#endif + +/* Compiled-in settings */ +#define MAX_STRING 1024 +#define MAX_ADD_HEADERS 10 +#define MAX_REDIR 5 +#define AXEL_VERSION_STRING "2.4" +#define DEFAULT_USER_AGENT "Axel " AXEL_VERSION_STRING " (" ARCH ")" + +/* axel结构体中的信息 */ +typedef struct +{ + void *next; + char text[MAX_STRING]; +} message_t; + +typedef message_t url_t; +typedef message_t if_t; + +#include "conf.h" +#include "tcp.h" +#include "ftp.h" +#include "http.h" +#include "conn.h" +#include "search.h" + +#define min( a, b ) ( (a) < (b) ? (a) : (b) ) +#define max( a, b ) ( (a) > (b) ? (a) : (b) ) + +typedef struct +{ + conn_t *conn; + conf_t conf[1]; + char filename[MAX_STRING]; + double start_time; + int next_state, finish_time; + long long bytes_done, start_byte, size; + int bytes_per_second; + int delay_time; + int outfd; + int ready; + message_t *message; + url_t *url; +} axel_t; + +axel_t *axel_new( conf_t *conf, int count, void *url ); +int axel_open( axel_t *axel ); +void axel_start( axel_t *axel ); +void axel_do( axel_t *axel ); +void axel_close( axel_t *axel ); + +double gettime(); diff --git a/axel1.0/conf.c b/axel1.0/conf.c new file mode 100644 index 0000000..c2983bf --- /dev/null +++ b/axel1.0/conf.c @@ -0,0 +1,58 @@ +#include "axel.h" + +int conf_init( conf_t *conf ) +{ + char s[MAX_STRING], *s2; + int i; + + /* Set defaults */ + memset( conf, 0, sizeof( conf_t ) ); + strcpy( conf->default_filename, "default" ); + *conf->http_proxy = 0; + *conf->no_proxy = 0; + conf->strip_cgi_parameters = 1; + conf->save_state_interval = 10; + conf->connection_timeout = 45; + conf->reconnect_delay = 20; + conf->num_connections = 4; + conf->buffer_size = 5120; + conf->max_speed = 0; + conf->verbose = 1; + conf->alternate_output = 0; + + conf->search_timeout = 10; + conf->search_threads = 3; + conf->search_amount = 15; + conf->search_top = 3; + conf->add_header_count = 0; + strncpy( conf->user_agent, DEFAULT_USER_AGENT, MAX_STRING ); + + /* if_t *interfaces; */ + conf->interfaces = malloc( sizeof( if_t ) ); + memset( conf->interfaces, 0, sizeof( if_t ) ); + conf->interfaces->next = conf->interfaces; + + if( ( s2 = getenv( "http_proxy" ) ) != NULL ) + strncpy( conf->http_proxy, s2, MAX_STRING ); + else if( ( s2 = getenv( "HTTP_PROXY" ) ) != NULL ) + strncpy( conf->http_proxy, s2, MAX_STRING ); + /* + if( !conf_loadfile( conf, ETCDIR "/axelrc" ) ) + return( 0 ); + */ + if( ( s2 = getenv( "HOME" ) ) != NULL ) + { + sprintf( s, "%s/%s", s2, ".axelrc" ); + /*if( !conf_loadfile( conf, s ) ) + return( 0 ); + */ + } + + /* Convert no_proxy to a 0-separated-and-00-terminated list.. */ + for( i = 0; conf->no_proxy[i]; i ++ ) + if( conf->no_proxy[i] == ',' ) + conf->no_proxy[i] = 0; + conf->no_proxy[i+1] = 0; + + return( 1 ); +} \ No newline at end of file diff --git a/axel1.0/conf.h b/axel1.0/conf.h new file mode 100644 index 0000000..a44a117 --- /dev/null +++ b/axel1.0/conf.h @@ -0,0 +1,55 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* Configuration handling include file */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +typedef struct +{ + char default_filename[MAX_STRING]; + char http_proxy[MAX_STRING]; + char no_proxy[MAX_STRING]; + int strip_cgi_parameters; + int save_state_interval; + int connection_timeout; + int reconnect_delay; + int num_connections; + int buffer_size; + int max_speed; + int verbose; + int alternate_output; + + if_t *interfaces; + + int search_timeout; + int search_threads; + int search_amount; + int search_top; + + int add_header_count; + char add_header[MAX_ADD_HEADERS][MAX_STRING]; + + char user_agent[MAX_STRING]; +} conf_t; + +int conf_loadfile( conf_t *conf, char *file ); +int conf_init( conf_t *conf ); diff --git a/axel1.0/config.h b/axel1.0/config.h new file mode 100644 index 0000000..f77278e --- /dev/null +++ b/axel1.0/config.h @@ -0,0 +1,7 @@ +/* Axel settings, generated by configure */ +#define _REENTRANT +#define _THREAD_SAFE +#define ETCDIR "/usr/local/etc" +#define LOCALE "/usr/local/share/locale" +#define ARCH "Linux" + diff --git a/axel1.0/conn.c b/axel1.0/conn.c new file mode 100644 index 0000000..1e6a6d8 --- /dev/null +++ b/axel1.0/conn.c @@ -0,0 +1,210 @@ +#include "axel.h" + +char string[MAX_STRING]; + +/* Convert an URL to a conn_t structure */ +int conn_set( conn_t *conn, char *set_url ) +{ + char url[MAX_STRING]; + char *i, *j; + + /* protocol:// */ + if( ( i = strstr( set_url, "://" ) ) == NULL ) + { + conn->proto = PROTO_DEFAULT; + strncpy( url, set_url, MAX_STRING ); + } + else + { + if( set_url[0] == 'f' ) + conn->proto = PROTO_FTP; + else if( set_url[0] == 'h' ) + conn->proto = PROTO_HTTP; + else + { + return( 0 ); + } + strncpy( url, i + 3, MAX_STRING ); + } + + printf("url : %s\n",url); + + /* Split */ + if( ( i = strchr( url, '/' ) ) == NULL ) + { + strcpy( conn->dir, "/" ); + } + else + { + *i = 0; + snprintf( conn->dir, MAX_STRING, "/%s", i + 1 ); + if( conn->proto == PROTO_HTTP ) + http_encode( conn->dir ); + } + strncpy( conn->host, url, MAX_STRING ); + j = strchr( conn->dir, '?' ); + if( j != NULL ) + *j = 0; + i = strrchr( conn->dir, '/' ); + *i = 0; + if( j != NULL ) + *j = '?'; + if( i == NULL ) + { + strncpy( conn->file, conn->dir, MAX_STRING ); + strcpy( conn->dir, "/" ); + } + else + { + strncpy( conn->file, i + 1, MAX_STRING ); + strcat( conn->dir, "/" ); + } + + printf("conn->file : %s\n",conn->file); + /* Check for username in host field */ + if( strrchr( conn->host, '@' ) != NULL ) + { + strncpy( conn->user, conn->host, MAX_STRING ); + i = strrchr( conn->user, '@' ); + *i = 0; + strncpy( conn->host, i + 1, MAX_STRING ); + *conn->pass = 0; + } + /* If not: Fill in defaults */ + else + { + if( conn->proto == PROTO_FTP ) + { + /* Dash the password: Save traffic by trying + to avoid multi-line responses */ + strcpy( conn->user, "anonymous" ); + strcpy( conn->pass, "mailto:axel-devel@lists.alioth.debian.org" ); + } + else + { + *conn->user = *conn->pass = 0; + } + } + + /* Password? */ + if( ( i = strchr( conn->user, ':' ) ) != NULL ) + { + *i = 0; + strncpy( conn->pass, i + 1, MAX_STRING ); + } + /* Port number? */ + if( ( i = strchr( conn->host, ':' ) ) != NULL ) + { + *i = 0; + sscanf( i + 1, "%i", &conn->port ); + } + /* Take default port numbers from /etc/services */ + else + { +#ifndef DARWIN + struct servent *serv; + + if( conn->proto == PROTO_FTP ) + serv = getservbyname( "ftp", "tcp" ); + else + serv = getservbyname( "www", "tcp" ); + + if( serv ) + conn->port = ntohs( serv->s_port ); + else +#endif + if( conn->proto == PROTO_HTTP ) + conn->port = 80; + else + conn->port = 21; + } + + return( conn->port > 0 ); +} + + +/* 打开到http服务器的连接或者打开到FTP服务器的连接并且切换到ftp的下载目录 */ +int conn_init( conn_t *conn ) +{ + char *proxy = conn->conf->http_proxy, *host = conn->conf->no_proxy; + int i; + + if( *conn->conf->http_proxy == 0 ) + { + proxy = NULL; + } + else if( *conn->conf->no_proxy != 0 ) + { + for( i = 0; ; i ++ ) + if( conn->conf->no_proxy[i] == 0 ) + { + if( strstr( conn->host, host ) != NULL ) + proxy = NULL; + host = &conn->conf->no_proxy[i+1]; + if( conn->conf->no_proxy[i+1] == 0 ) + break; + } + } + + conn->proxy = proxy != NULL; + + if( conn->proto == PROTO_FTP && !conn->proxy ) + { + conn->ftp->local_if = conn->local_if; + conn->ftp->ftp_mode = FTP_PASSIVE; + /*if( !ftp_connect( conn->ftp, conn->host, conn->port, conn->user, conn->pass ) ) + { + conn->message = conn->ftp->message; + conn_disconnect( conn ); + return( 0 ); + } + conn->message = conn->ftp->message; + if( !ftp_cwd( conn->ftp, conn->dir ) ) + { + conn_disconnect( conn ); + return( 0 ); + }*/ + } + else + { + conn->http->local_if = conn->local_if; + if( !http_connect( conn->http, conn->proto, proxy, conn->host, conn->port, conn->user, conn->pass ) ) + { + conn->message = conn->http->headers; + conn_disconnect( conn ); + return( 0 ); + } + conn->message = conn->http->headers; + conn->fd = conn->http->fd; + } + return( 1 ); +} + +/* Simple... */ +void conn_disconnect( conn_t *conn ) +{ + if( conn->proto == PROTO_FTP && !conn->proxy ) + ftp_disconnect( conn->ftp ); + else + http_disconnect( conn->http ); + conn->fd = -1; +} + + +/* Generate a nice URL string. */ +char *conn_url( conn_t *conn ) +{ + if( conn->proto == PROTO_FTP ) + strcpy( string, "ftp://" ); + else + strcpy( string, "http://" ); + + if( *conn->user != 0 && strcmp( conn->user, "anonymous" ) != 0 ) + sprintf( string + strlen( string ), "%s:%s@", + conn->user, conn->pass ); + + sprintf( string + strlen( string ), "%s:%i%s%s", + conn->host, conn->port, conn->dir, conn->file ); + + return( string ); +} \ No newline at end of file diff --git a/axel1.0/conn.h b/axel1.0/conn.h new file mode 100644 index 0000000..06b868d --- /dev/null +++ b/axel1.0/conn.h @@ -0,0 +1,65 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* Connection stuff */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +#define PROTO_FTP 1 +#define PROTO_HTTP 2 +#define PROTO_DEFAULT PROTO_FTP + +typedef struct +{ + conf_t *conf; + + int proto; + int port; + int proxy; + char host[MAX_STRING]; + char dir[MAX_STRING]; + char file[MAX_STRING]; + char user[MAX_STRING]; + char pass[MAX_STRING]; + + ftp_t ftp[1]; + http_t http[1]; + long long int size; /* File size, not 'connection size'.. */ + long long int currentbyte; + long long int lastbyte; + int fd; + int enabled; + int supported; + int last_transfer; + char *message; + char *local_if; + + int state; + pthread_t setup_thread[1]; +} conn_t; + +int conn_set( conn_t *conn, char *set_url ); +char *conn_url( conn_t *conn ); +void conn_disconnect( conn_t *conn ); +int conn_init( conn_t *conn ); +int conn_setup( conn_t *conn ); +int conn_exec( conn_t *conn ); +int conn_info( conn_t *conn ); diff --git a/axel1.0/ftp.c b/axel1.0/ftp.c new file mode 100644 index 0000000..5de4ed5 --- /dev/null +++ b/axel1.0/ftp.c @@ -0,0 +1,18 @@ +#include "axel.h" + + +void ftp_disconnect( ftp_t *conn ) +{ + if( conn->fd > 0 ) + close( conn->fd ); + if( conn->data_fd > 0 ) + close( conn->data_fd ); + if( conn->message ) + { + free( conn->message ); + conn->message = NULL; + } + + *conn->cwd = 0; + conn->fd = conn->data_fd = -1; +} \ No newline at end of file diff --git a/axel1.0/ftp.h b/axel1.0/ftp.h new file mode 100644 index 0000000..14efb17 --- /dev/null +++ b/axel1.0/ftp.h @@ -0,0 +1,46 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* FTP control include file */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +#define FTP_PASSIVE 1 +#define FTP_PORT 2 + +typedef struct +{ + char cwd[MAX_STRING]; + char *message; + int status; + int fd; + int data_fd; + int ftp_mode; + char *local_if; +} ftp_t; + +int ftp_connect( ftp_t *conn, char *host, int port, char *user, char *pass ); +void ftp_disconnect( ftp_t *conn ); +int ftp_wait( ftp_t *conn ); +int ftp_command( ftp_t *conn, char *format, ... ); +int ftp_cwd( ftp_t *conn, char *cwd ); +int ftp_data( ftp_t *conn ); +long long int ftp_size( ftp_t *conn, char *file, int maxredir ); diff --git a/axel1.0/http.c b/axel1.0/http.c new file mode 100644 index 0000000..c5edd6f --- /dev/null +++ b/axel1.0/http.c @@ -0,0 +1,118 @@ +#include "axel.h" + + +int http_connect( http_t *conn, int proto, char *proxy, char *host, int port, char *user, char *pass ) +{ + char base64_encode[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + char auth[MAX_STRING]; + conn_t tconn[1]; + int i; + + strncpy( conn->host, host, MAX_STRING ); + conn->proto = proto; + + if( proxy != NULL ) { if( *proxy != 0 ) + { + sprintf( conn->host, "%s:%i", host, port ); + if( !conn_set( tconn, proxy ) ) + { + /* We'll put the message in conn->headers, not in request */ + sprintf( conn->headers, _("Invalid proxy string: %s\n"), proxy ); + return( 0 ); + } + host = tconn->host; + port = tconn->port; + conn->proxy = 1; + } + else + { + conn->proxy = 0; + } } + + if( ( conn->fd = tcp_connect( host, port, conn->local_if ) ) == -1 ) + { + /* We'll put the message in conn->headers, not in request */ + sprintf( conn->headers, _("Unable to connect to server %s:%i\n"), host, port ); + return( 0 ); + } + + if( *user == 0 ) + { + *conn->auth = 0; + } + else + { + memset( auth, 0, MAX_STRING ); + snprintf( auth, MAX_STRING, "%s:%s", user, pass ); + for( i = 0; auth[i*3]; i ++ ) + { + conn->auth[i*4] = base64_encode[(auth[i*3]>>2)]; + conn->auth[i*4+1] = base64_encode[((auth[i*3]&3)<<4)|(auth[i*3+1]>>4)]; + conn->auth[i*4+2] = base64_encode[((auth[i*3+1]&15)<<2)|(auth[i*3+2]>>6)]; + conn->auth[i*4+3] = base64_encode[auth[i*3+2]&63]; + if( auth[i*3+2] == 0 ) conn->auth[i*4+3] = '='; + if( auth[i*3+1] == 0 ) conn->auth[i*4+2] = '='; + } + } + + return( 1 ); +} + +void http_encode( char *s ) +{ + char t[MAX_STRING]; + int i, j; + + for( i = j = 0; s[i]; i ++, j ++ ) + { + /* Fix buffer overflow */ + if (j >= MAX_STRING - 1) { + break; + } + + t[j] = s[i]; + if( s[i] == ' ' ) + { + /* Fix buffer overflow */ + if (j >= MAX_STRING - 3) { + break; + } + + strcpy( t + j, "%20" ); + j += 2; + } + } + t[j] = 0; + + strcpy( s, t ); +} + +/* Decode%20a%20file%20name */ +void http_decode( char *s ) +{ + char t[MAX_STRING]; + int i, j, k; + + for( i = j = 0; s[i]; i ++, j ++ ) + { + t[j] = s[i]; + if( s[i] == '%' ) + if( sscanf( s + i + 1, "%2x", &k ) ) + { + t[j] = k; + i += 2; + } + } + t[j] = 0; + + strcpy( s, t ); +} + + +void http_disconnect( http_t *conn ) +{ + if( conn->fd > 0 ) + close( conn->fd ); + conn->fd = -1; +} \ No newline at end of file diff --git a/axel1.0/http.h b/axel1.0/http.h new file mode 100644 index 0000000..38f95c4 --- /dev/null +++ b/axel1.0/http.h @@ -0,0 +1,51 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* HTTP control include file */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +#define MAX_QUERY 2048 /* Should not grow larger.. */ + +typedef struct +{ + char host[MAX_STRING]; + char auth[MAX_STRING]; + char request[MAX_QUERY]; + char headers[MAX_QUERY]; + int proto; /* FTP through HTTP proxies */ + int proxy; + long long int firstbyte; + long long int lastbyte; + int status; + int fd; + char *local_if; +} http_t; + +int http_connect( http_t *conn, int proto, char *proxy, char *host, int port, char *user, char *pass ); +void http_disconnect( http_t *conn ); +void http_get( http_t *conn, char *lurl ); +void http_addheader( http_t *conn, char *format, ... ); +int http_exec( http_t *conn ); +char *http_header( http_t *conn, char *header ); +long long int http_size( http_t *conn ); +void http_encode( char *s ); +void http_decode( char *s ); diff --git a/axel1.0/search.h b/axel1.0/search.h new file mode 100644 index 0000000..6f79309 --- /dev/null +++ b/axel1.0/search.h @@ -0,0 +1,37 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* filesearching.com searcher include file */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +typedef struct +{ + char url[MAX_STRING]; + double speed_start_time; + int speed, size; + pthread_t speed_thread[1]; + conf_t *conf; +} search_t; + +int search_makelist( search_t *results, char *url ); +int search_getspeeds( search_t *results, int count ); +void search_sortlist( search_t *results, int count ); diff --git a/axel1.0/tcp.c b/axel1.0/tcp.c new file mode 100644 index 0000000..e515083 --- /dev/null +++ b/axel1.0/tcp.c @@ -0,0 +1,59 @@ +#include "axel.h" + +/* Get a TCP connection */ +int tcp_connect( char *hostname, int port, char *local_if ) +{ + struct hostent *host = NULL; + struct sockaddr_in addr; + struct sockaddr_in local; + int fd; + +#ifdef DEBUG + socklen_t i = sizeof( local ); + + fprintf( stderr, "tcp_connect( %s, %i ) = ", hostname, port ); +#endif + + /* Why this loop? Because the call might return an empty record. + At least it very rarely does, on my system... */ + for( fd = 0; fd < 5; fd ++ ) + { + if( ( host = gethostbyname( hostname ) ) == NULL ) + return( -1 ); + if( *host->h_name ) break; + } + if( !host || !host->h_name || !*host->h_name ) + return( -1 ); + + if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) + return( -1 ); + + if( local_if && *local_if ) + { + local.sin_family = AF_INET; + local.sin_port = 0; + local.sin_addr.s_addr = inet_addr( local_if ); + if( bind( fd, (struct sockaddr *) &local, sizeof( struct sockaddr_in ) ) == -1 ) + { + close( fd ); + return( -1 ); + } + } + + addr.sin_family = AF_INET; + addr.sin_port = htons( port ); + addr.sin_addr = *( (struct in_addr *) host->h_addr ); + + if( connect( fd, (struct sockaddr *) &addr, sizeof( struct sockaddr_in ) ) == -1 ) + { + close( fd ); + return( -1 ); + } + +#ifdef DEBUG + getsockname( fd, &local, &i ); + fprintf( stderr, "%i\n", ntohs( local.sin_port ) ); +#endif + + return( fd ); +} \ No newline at end of file diff --git a/axel1.0/tcp.h b/axel1.0/tcp.h new file mode 100644 index 0000000..3fe3dcd --- /dev/null +++ b/axel1.0/tcp.h @@ -0,0 +1,27 @@ + /********************************************************************\ + * Axel -- A lighter download accelerator for Linux and other Unices. * + * * + * Copyright 2001 Wilmer van der Gaast * + \********************************************************************/ + +/* TCP control include file */ + +/* + 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 with + the Debian GNU/Linux distribution in file /usr/doc/copyright/GPL; + if not, write to the Free Software Foundation, Inc., 59 Temple Place, + Suite 330, Boston, MA 02111-1307 USA +*/ + +int tcp_connect( char *hostname, int port, char *local_if ); +int get_if_ip( char *iface, char *ip ); diff --git a/axel1.0/text.c b/axel1.0/text.c new file mode 100644 index 0000000..c2a67bb --- /dev/null +++ b/axel1.0/text.c @@ -0,0 +1,61 @@ +#include +#include "axel.h" + + +/* For returning string values from functions */ +static char string[MAX_STRING]; + +int main( int argc, char *argv[] ) +{ + char fn[MAX_STRING] = ""; + int i, j, cur_head = 0; + conf_t conf[1]; + axel_t *axel; + char *s; + s = malloc( MAX_STRING ); + + memset(s, 0, sizeof(s)); + /*strcpy(s,"http://ftp.iij.ad.jp/pub/db/mysql/Downloads/MySQL-5.5/MySQL-5.5.16-1.linux2.6.x86_64.tar"); + */ + /*strcpy(s,"http://bbs.chinaunix.net/forum.php?mod=attachment&aid=NTA3NTc0fDI3YmZjMmIzfDE0Mjc2MzE5MjV8MHwzNjAwOT"); */ + + strcpy(s,argv[1]); + if( !conf_init( conf ) ) + { + return( 1 ); + } + + + axel = axel_new( conf, 0, s ); + + if( *fn ) + { + sprintf( string, "%s.st", fn ); + } + else + { + /* Local file existence check */ + i = 0; + s = axel->filename + strlen( axel->filename ); + while( 1 ) + { + sprintf( string, "%s.st", axel->filename ); + if( access( axel->filename, F_OK ) == 0 ) + { + if( axel->conn[0].supported ) + { + if( access( string, F_OK ) == 0 ) + break; + } + } + else + { + if( access( string, F_OK ) ) + break; + } + sprintf( s, ".%i", i ); + i ++; + } + } + return 0; +} \ No newline at end of file