| 1 |
/********************************************************************\
|
| 2 |
* Axel -- A lighter download accelerator for Linux and other Unices. *
|
| 3 |
* *
|
| 4 |
* Copyright 2001 Wilmer van der Gaast *
|
| 5 |
\********************************************************************/
|
| 6 |
|
| 7 |
|
| 8 |
/* Short API description */
|
| 9 |
|
| 10 |
Until version 0.97, a lot of Axel downloading code was 'stuck' in main().
|
| 11 |
This made the development of alternate (ie graphical) interfaces to the
|
| 12 |
program quite difficult. That's why Axel 0.97 is a major redesign: All the
|
| 13 |
downloading code is out of main() now. Writing your own downloader which
|
| 14 |
uses Axel should not be too difficult now.
|
| 15 |
|
| 16 |
This document contains basic instructions on how to write a program which
|
| 17 |
uses the Axel >=0.97 code to download data.
|
| 18 |
|
| 19 |
Some work needs to be done before I can convert axel into a library. I don't
|
| 20 |
know whether I'll do it at all.. So this API description is only useful if
|
| 21 |
you want to create an alternate interface for the program, at the moment.
|
| 22 |
Later on, I might change this. A Perl port of Axel would be nice too. :-)
|
| 23 |
|
| 24 |
|
| 25 |
/* The structures */
|
| 26 |
|
| 27 |
If you want to use Axel, you should have all the *.[ch] files in your
|
| 28 |
program's directory (or subdir, whatever you want...) and include the axel.h
|
| 29 |
file into your program. Then, the following structures and functions will be
|
| 30 |
available:
|
| 31 |
|
| 32 |
typedef struct
|
| 33 |
{
|
| 34 |
conn_t *conn;
|
| 35 |
conf_t conf[1];
|
| 36 |
char filename[MAX_STRING];
|
| 37 |
double start_time;
|
| 38 |
int next_state, finish_time;
|
| 39 |
int bytes_done, start_byte, size;
|
| 40 |
int bytes_per_second;
|
| 41 |
int delay_time;
|
| 42 |
int outfd;
|
| 43 |
int ready;
|
| 44 |
message_t *message;
|
| 45 |
url_t *url;
|
| 46 |
} axel_t;
|
| 47 |
|
| 48 |
This is probably the most important structure.. Each axel structure can
|
| 49 |
handle a separate download, each with a variable amount of connections.
|
| 50 |
There is no maximum amount of connections hard-coded into the program
|
| 51 |
anymore, by the way. The way conn_t and conf_t structures work is not very
|
| 52 |
important for most people, it's mainly important for internal use. You /can/
|
| 53 |
use those structures, if you want, they're not that complex...
|
| 54 |
|
| 55 |
The filename string is set correctly by axel_new(). If you want data to
|
| 56 |
be put into a different file, you can change the variable /after/ calling
|
| 57 |
axel_new(), and /before/ calling axel_open(). The string can also include
|
| 58 |
a full pathname.
|
| 59 |
|
| 60 |
start_time contains the time at which the download started. Not very
|
| 61 |
interesting for you, probably. Neither should next_state be very important,
|
| 62 |
it just contains the time at which the next state file should be saved.
|
| 63 |
(State files are important for resuming support, as described in the README
|
| 64 |
file..) finish_time might be interesting, though. It contains the estimated
|
| 65 |
time at which the download should be finished.
|
| 66 |
|
| 67 |
bytes_done contains the number of bytes downloaded for this file, size
|
| 68 |
contains the total file size. start_byte should be zero, usually, unless
|
| 69 |
you're resuming a download.
|
| 70 |
|
| 71 |
The code also calculates the average speed. This speed is put in the
|
| 72 |
bytes_per_second variable.
|
| 73 |
|
| 74 |
delay_time is not interesting at all. It's just used for the code which
|
| 75 |
tries to slow down the download. You shouldn't really touch outfd either,
|
| 76 |
it contains the file descriptor of the local file.
|
| 77 |
|
| 78 |
ready is set to non-zero as soon as all data is downloaded, or as soon as
|
| 79 |
something goes wrong. You shouldn't call axel_do() anymore, when ready is
|
| 80 |
set.
|
| 81 |
|
| 82 |
Last but not least, message. This is a linked list of messages to the user.
|
| 83 |
You, as the programmer, may decide what to do with them. You can just
|
| 84 |
destroy them (don't just ignore them, the messages do eat memory!) or you
|
| 85 |
can log/display them. The structure is very simple, and I hope this is clear
|
| 86 |
enough:
|
| 87 |
|
| 88 |
typedef struct {
|
| 89 |
void *next;
|
| 90 |
char text[MAX_STRING];
|
| 91 |
} message_t;
|
| 92 |
|
| 93 |
Just don't forget to free() the message structures after printing them, and
|
| 94 |
set axel->message to NULL to prevent crashes. See the print_messages()
|
| 95 |
function in text.c for an example.
|
| 96 |
|
| 97 |
message used to be the last, but I added url. It's a linked list as well,
|
| 98 |
and in fact url_t == message_t. Not really of any importance, though. This
|
| 99 |
element contains a number of URL's that'll be used by Axel for the download.
|
| 100 |
The program can use multiple mirrors at the same time. This structure is
|
| 101 |
filled in by axel_new, you shouldn't touch it yourself.
|
| 102 |
|
| 103 |
|
| 104 |
/* The functions */
|
| 105 |
|
| 106 |
int conf_init( conf_t *conf );
|
| 107 |
|
| 108 |
Axel needs some settings. Your program has to allocate a conf_t structure
|
| 109 |
and initialize it using this function. It sets some defaults, and then it
|
| 110 |
scans your environment variables for some settings, and it tries to read
|
| 111 |
a system-wide and personal user configuration file.
|
| 112 |
|
| 113 |
axel_t *axel_new( conf_t *conf, char count, char *url );
|
| 114 |
axel_t *axel_new( conf_t *conf, char count, search_t *urls );
|
| 115 |
|
| 116 |
axel_new() allocates a new axel_t structure. You should pass a configuration
|
| 117 |
structure and an URL. A pointer to a new axel_t structure will be returned.
|
| 118 |
axel->filename is set now. You can change it, if you want data to be stored
|
| 119 |
to a different file. Changing axel->filename after calling axel_open does
|
| 120 |
not make sense, so be quick. :-)
|
| 121 |
If you want axel to download from more than one mirror at once, you can use
|
| 122 |
the second syntax. A search_t structure can be generated by the search_*
|
| 123 |
functions. If you use the second syntax, count should contain the number of
|
| 124 |
mirrors to be used from the structure. If you just want to pass a string
|
| 125 |
with one URL (first syntax), count should be zero. Please note that all the
|
| 126 |
mirrors passed to axel_new() should support acceleration. The support check
|
| 127 |
should be done before downloading, which isn't much of a problem because
|
| 128 |
search_getspeeds does it automatically.
|
| 129 |
The ready element of the returned structure is set to one if nothing goes
|
| 130 |
wrong. If it's zero, you shouldn't use the returned structure for anything
|
| 131 |
else than displaying the error message(s) and closing it.
|
| 132 |
|
| 133 |
int axel_open( axel_t *axel );
|
| 134 |
|
| 135 |
axel_open() opens a local file to store downloaded data. Returns non-zero if
|
| 136 |
nothing goes wrong. If anything goes wrong, you should still call
|
| 137 |
axel_close() to clean things up. This is not done automatically, so that you
|
| 138 |
can read any message still left in the structure.
|
| 139 |
|
| 140 |
void axel_start( axel_t *axel );
|
| 141 |
|
| 142 |
axel_start() starts the actual downloading. Normally, nothing should go
|
| 143 |
wrong during this call, so it does not return anything.
|
| 144 |
|
| 145 |
void axel_do( axel_t *axel );
|
| 146 |
|
| 147 |
axel_do() should be called regularly (ie as often as possible...) to handle
|
| 148 |
any incoming data. You don't have to do anything else, all data is stored in
|
| 149 |
the local file automatically. You should stop calling this one as soon as
|
| 150 |
axel->ready is set. Or you can stop calling it yourself, that's possible.
|
| 151 |
Just don't forget to call axel_close()!
|
| 152 |
|
| 153 |
void axel_close( axel_t *axel );
|
| 154 |
|
| 155 |
If you want to stop downloading (ie if the download is complete) you should
|
| 156 |
deallocate the axel_t structure using this function. Any connection still
|
| 157 |
open will be closed and deallocated, all messages in the structure are
|
| 158 |
deleted. You should always call this one when you're ready, if you don't
|
| 159 |
want to waste memory.
|
| 160 |
|
| 161 |
double gettime();
|
| 162 |
|
| 163 |
This one is just a 'bonus'... I use it myself in text.c and axel.c, so I
|
| 164 |
decided to make it global. It just returns the actual time, but with more
|
| 165 |
precision.
|
| 166 |
|
| 167 |
|
| 168 |
/* filesearcher.com interface */
|
| 169 |
|
| 170 |
If you want to search for a faster mirror to download your file, or if you
|
| 171 |
want to download from more than one server at once, you can use this
|
| 172 |
interface. It's quite simple. You should create an array of this type:
|
| 173 |
|
| 174 |
typedef struct
|
| 175 |
{
|
| 176 |
char url[MAX_STRING];
|
| 177 |
double speed_start_time;
|
| 178 |
int speed, size;
|
| 179 |
pthread_t speed_thread[1];
|
| 180 |
conf_t *conf;
|
| 181 |
} search_t;
|
| 182 |
|
| 183 |
And it's wise to memset() it to zero before you start, btw. You also have to
|
| 184 |
set the conf pointer for the first index of the array. Other fields will
|
| 185 |
be filled in by these functions:
|
| 186 |
|
| 187 |
int search_makelist( search_t *results, char *url );
|
| 188 |
|
| 189 |
This function checks your URL, fetches the file size (needed for the search)
|
| 190 |
and queries the ftpsearcher.com server for any mirror of this file. This one
|
| 191 |
is finished in a few seconds on my system. It returns the number of mirrors
|
| 192 |
found. Please note that, after calling this function, the first index of
|
| 193 |
your search_t array contains the URL you used as an argument to this
|
| 194 |
function. The speed field is filled in already for that one.
|
| 195 |
|
| 196 |
int search_getspeeds( search_t *results, int count );
|
| 197 |
|
| 198 |
This is quite time consuming. It tries all the URL's from the list, and
|
| 199 |
checks the speed. URL's which do not exist, or URL's on non-supported
|
| 200 |
servers are marked as bad, they can't be used. This is more time-consuming
|
| 201 |
than a simple ping (it takes about twenty seconds on my system, but it
|
| 202 |
heavily depends on the connection and your settings), but it makes sure only
|
| 203 |
usable URL's are passed to the downloader. The function returns the number
|
| 204 |
of not-bad servers.
|
| 205 |
|
| 206 |
void search_sortlist( search_t *results, int count );
|
| 207 |
|
| 208 |
It's very wise to sort the list of mirrors using this function before
|
| 209 |
passing it to axel_new(). The fastest URL will be put on top of the list,
|
| 210 |
bad URL's will be put at the bottom. Please note that count has to be the
|
| 211 |
total number of servers, returned by search_makelist(), and not just the
|
| 212 |
number of not-bad servers returned by search_getspeed().
|