[axel-commits] r68 - in /branches/3.x-broken: doc/CHANGES doc/ROADMAP src/axel.c src/axel.h src/conn.h src/helper.c src/helper.h src/url.c src/url.h test/test_url.c test/test_urllist.c
phihag-guest at users.alioth.debian.org
phihag-guest at users.alioth.debian.org
Sat Dec 20 12:10:15 UTC 2008
Author: phihag-guest
Date: Sat Dec 20 12:10:14 2008
New Revision: 68
URL: http://svn.debian.org/wsvn/axel/?sc=1&rev=68
Log:
Scratch excessive multi threading, remove some errors
Modified:
branches/3.x-broken/doc/CHANGES
branches/3.x-broken/doc/ROADMAP
branches/3.x-broken/src/axel.c
branches/3.x-broken/src/axel.h
branches/3.x-broken/src/conn.h
branches/3.x-broken/src/helper.c
branches/3.x-broken/src/helper.h
branches/3.x-broken/src/url.c
branches/3.x-broken/src/url.h
branches/3.x-broken/test/test_url.c
branches/3.x-broken/test/test_urllist.c
Modified: branches/3.x-broken/doc/CHANGES
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/doc/CHANGES?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/doc/CHANGES (original)
+++ branches/3.x-broken/doc/CHANGES Sat Dec 20 12:10:14 2008
@@ -1,5 +1,4 @@
-
-Version 2.99.0 (preview release):
+Version 3.0_rc1 (preview release):
- Complete overhaul of the whole code structure
- New folder structure: src/ contains all *.c and *.h files, test/ CUnit test files, all compiled files reside in out/, all configured files in cfg/
@@ -20,6 +19,15 @@
- Splitted usage text (=> simplifies i18n)
- Temporarily thrown out: ftp, search
+
+Version 2.3:
+
+- Wait for thread termination in axel.c:axel_do (Closes: #311255), thanks John Ripa
+- New Chinese translation and manpage, thanks Shuge Lee
+
+Version 2.2:
+
+- Fix a buffer overflow in http.c:http_encode.
Version 2.1:
Modified: branches/3.x-broken/doc/ROADMAP
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/doc/ROADMAP?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/doc/ROADMAP (original)
+++ branches/3.x-broken/doc/ROADMAP Sat Dec 20 12:10:14 2008
@@ -2,7 +2,7 @@
===================
Note: This document provides only a rough overview what to do next. Refer to the bugtracker ( https://alioth.debian.org/tracker/?group_id=100070&atid=413085 ) for detailled information.
-Pre-release version numbers of Axel 3 will begin with 2.99. Starting with the 3.x series, the following version scheme will be adopted:
+Starting with the 3.x series, the following version scheme will be adopted:
x.y.z
@@ -15,6 +15,10 @@
* Parse Content-Disposition header (#311101)
Look if the specific problem mentioned in the bug is fixed by this.
+* Do not rerequest != 20x more than once
+* Exponential backoff, exponential backoff, and make sure to include exponential backoff
+* readd proxy support
+
Code structure
==============
@@ -40,9 +44,8 @@
* Cleanup AXEL_LEGACY
* save_setup: Can we flush instead of close?
* Check chinese man file, correct installation
-* Find out whether chinese manpage should be installed
+* Find out where chinese manpage should be installed
* Scrap crappy OS workaround? (Test on Windows)
-* axel: new -> init, free -> destroy ?
Bugs
====
@@ -53,6 +56,7 @@
Fix/test/simplify i18n regeneration (paths!) (remove .SUFFIXES?)
Check speed limit
+Check on BSD, Mac OS X, Cygwin
(User) Documentation
====================
@@ -91,7 +95,7 @@
* A -1 option: Just make one request, and only one.
* IPv6 support
* Add AXEL_THREADED option: If not set, don't use threads, but select()
-* OUTPUT_FLAGS option to output all the flag's names in --help or so
+* OUTPUT_FLAGS option to output all set flags' names in --help or so
* configure options minimal and allfeatures
3.3
@@ -107,24 +111,25 @@
* splint
* Test very large -n values. Check pthread thread stack size.
* Unicode domain names
-* --shrink / --all-features flags in configure
* gzip, deflate compression? (optional)
* Check NOGETOPTLONG definition. Is this really up to date? Can't we test it in an other way than looking at the platform?
* Check whether we need to test the result of malloc for NULL. Does this significantly increase code size? Can we just call exit(42)?
-* Remove stdio.h, varargs.h and friends from axel.h , add them to text.c if needed
Future/Ideas
============
+* libaxel?
+* Remove stdio.h, varargs.h and friends from axel.h , add them to text.c if needed?
* Does open(O_DIRECT) hurt? Do we need it?
-* Could we employ less/even only one thread than -n using select() to get the next available fd
* Automatically compare different revisions of axel regarding size
* Read URLs from a file to encourage using passwords
* Real FTPS (AUTH)?
-* Allow downloading to /dev/null for debugging or speed test purposes (Statefile in memory or so)
+* Allow downloading to /dev/null for debugging or speed test purposes
* Desktop integration, look who likes download accelerators
* Check the syscalls we make. Check whether timing and read() calls can be optimized
* Write automated tests to test all these nifty corner cases. Either a test webserver or LD_PRELOAD injection of all syscalls (see libfake*)
* Write a helper script that displays the final binary size for different configurations to determine what a particular feature costs
* Document and implement coding conventions, versioning scheme
* Revive the GUI?
+* Switch to C++?
+* Check synchronization
Modified: branches/3.x-broken/src/axel.c
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/src/axel.c?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/src/axel.c (original)
+++ branches/3.x-broken/src/axel.c Sat Dec 20 12:10:14 2008
@@ -25,63 +25,11 @@
#include "axel.h"
-static void axel_examine(axel_t* axel);
static void axel_prepare(axel_t* axel);
static void axel_teardown(axel_t* axel);
-
-
-static void axel_save_state(axel_t *axel);
-static void* setup_thread(void *);
-static void axel_divide(axel_t *axel);
-
-/**
-* @param message The message to send. Note that this must be freed by the caller
-*/
-void axel_message(const axel_t* axel, const char* message, int verbosity) {
- if (axel->message_handler != NULL) {
- axel->message_handler(axel, message, verbosity);
- }
-}
-
-void axel_message_fmt(const axel_t *axel, const char *format, ... ) {
- const MAX_MSG_SIZE = 1024;
- char* buf
- va_list params;
-
- va_start(params, format);
- vsnprintf(buf, MAX_MSG_SIZE - 1, format, params );
- va_end(params );
-
- if( axel->message == NULL )
- {
- axel->message = m;
- }
- else
- {
- while( n->next != NULL )
- n = n->next;
- n->next = m;
- }
-}
-
-void axel_update_status(const axel_t* axel) {
- if (axel->status_handler != NULL) {
- axel->status_handler(axel);
- }
-}
-
-void axel_abort(axel_t* axel, int ret) {
- axel->state = ret == 0 ? AXEL_STATE_ERROR;
- axel_update_status(axel);
-
- axel_teardown(axel);
-
- if (axel->abort_handler != NULL) {
- axel->abort_handler(axel, ret);
- } else {
- exit(ret);
- }
-}
+static void axel_save_state(axel_t* axel);
+static void axel_set_state(axel_t* axel, int state);
+static void axel_update_display(const axel_t* axel);
/**
* Add a URL. urlstr is a pointer to a string specified by the user
@@ -99,80 +47,82 @@
url->priority = priority;
}
- urllist_add(axel->urls, url);
+ urllist_add(& axel->urls, url);
return 1;
}
-axel_t* axel_new(const conf_t* conf) {
- axel_t* res = malloc( sizeof( axel_t ) );
-
- res->conf = conf;
- urllist_init(&(res->urls));
-
- res->conncount = -1;
+void axel_init(axel_t* ax, const conf_t* conf) {
+ ax->message_handler = NULL;
+ ax->display_handler = NULL;
+
+ ax->conf = conf;
+ urllist_init(& ax->urls);
+
+ ax->conncount = -1;
// conn is set once we know conncount
- res->filename = NULL;
- res->outfd = -1;
-
- res->statefilename = NULL;
-
- res->size = -1;
+ ax->filename = NULL;
+ ax->outfd = -1;
+
+ ax->statefilename = NULL;
+
+ ax->size = -1;
// start_utime is set once we're ready to start downloading
- axel->state = AXEL_STATE_INIT;
-
- res->delay_time = 0;
-
- res->message_handler = NULL;
- res->abort_handler = NULL;
- res->status_handler = NULL;
-
- return res;
-}
-
-void axel_free(axel_t* axel) {
- urllist_free(axel->urls);
+ ax->state = AXEL_STATE_INIT;
+
+ ax->delay_time = 0;
+}
+
+void axel_destroy(axel_t* axel) {
+ urllist_destroy(& axel->urls);
free(axel->filename);
free(axel->statefilename);
-
- free(axel);
}
/**
-* Start downloading a file. If you want to know anything more about the download, register handlers.
+* Download a file. If you want to know anything more about the download, register handlers.
+* While the download is running, the current thread will dispatch the callback functions
+* Afterwards, a program has still to call axel_destroy() and then exit.
+* @return 0 on success, an error code otherwise
*/
-void axel_start(axel_t* axel) {
- axel_examine(axel);
-
- if (axel->state == AXEL_STATE_READY) {
- axel_prepare(axel);
- }
-}
-
+int axel_download(axel_t* axel) {
+ axel_prepare(axel);
+
+ if (axel->state != AXEL_STATE_DOWNLOADING) {
+ axel_set_state(axel, AXEL_STATE_ERROR);
+
+ return axel->state;
+ }
+
+
+ for (int cid = 0;;cid = (cid < axel->conncount) ? cid + 1 : 0) {
+ // Main loop, visit all connections
+
+
+
+
+ }
+
+
+ // TODO set state to finished if not erred
+
+
+ return axel->state;
+}
/**
-* Find out file size, file name and stuff
-*/
-static void axel_examine(axel_t* axel) {
- // TODO determine filename
- // TODO determine file size
-
- axel->state = AXEL_STATE_READY;
- axel_update_status();
-}
-
-/**
-* Initialize a prepared download, start all threads
+* Prepare a download, start all threads
*/
static void axel_prepare(axel_t* axel) {
- // TODO set conncount according to conf
-
- // Determine file name
+ // TODO Determine file name
+ // TODO determine file size
+
+
if (axel->filename == NULL) {
- axel->filename = strdup(conf->default_filename);
+ axel->filename = strdup(axel->conf->default_filename);
}
// TODO Open outfile
@@ -186,42 +136,105 @@
axel->statefilename[fnlen + SUFFIXLEN + SUFFIXLEN] = '\0';
// Start counting time
- axel->state = AXEL_STATE_DOWNLOADING;
- axel->start_time = getutime();
+ axel->start_utime = getutime();
+ axel_set_state(axel, AXEL_STATE_DOWNLOADING);
// TODO start threads
-
-
- axel_update_status(axel);
+ // TODO set conncount according to conf
}
/**
* Prepare axel to be freed (cancel all connections, close outfile etc.)
*/
static void axel_teardown(axel_t* axel) {
- // TODO Cancel connections
+ // TODO Cancel all remaining connections
// TODO Close outfile
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-static char *buffer = NULL; /* TODO: remove this in favor of dynamic allocation (wanna bet this isn't thread-safe?) */
+/**
+* @param message The message to send. Note that this must be freed by the caller
+*/
+void axel_message(const axel_t* axel, int verbosity, const char* message) {
+ if (axel->message_handler != NULL) {
+ axel->message_handler(axel, verbosity, message);
+ }
+ axel_update_display();
+}
+
+void axel_message_fmt(const axel_t *axel, int verbosity, const char *format, ...) {
+ const MAX_MSG_SIZE = 1024;
+ char* buf = alloca(MAX_MSG_SIZE);
+
+ va_list params;
+ va_start(params, format);
+ vsnprintf(buf, MAX_MSG_SIZE, format, params );
+ va_end(params);
+
+ axel_message(axel, verbosity, buf);
+
+ free(buf);
+}
+
+static void axel_update_display(const axel_t* axel) {
+ if (axel->display_handler != NULL) {
+ axel->display_handler(axel);
+ }
+}
+
+static void axel_set_state(axel_t* axel, int state) {
+ axel->state = state;
+ axel_update_display();
+}
+
+/**
+* Setup a worker thread.
+*/
+// TODO define return value, NULL for delete the URL, otherwise for new value, input for unchanged?
+// TODO define param
+void* axel_thread(void *c) {
+ /* TODO check the following code */
+ conn_t *conn = c;
+
+ /* Allow this thread to be killed at any time. */
+ pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
+ pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate );
+
+ if( conn_setup( conn ) )
+ {
+ conn->last_transfer = gettime();
+ if( conn_exec( conn ) )
+ {
+ conn->last_transfer = gettime();
+ conn->enabled = 1;
+ conn->state = 0;
+ return( NULL );
+ }
+ }
+
+ conn_disconnect( conn );
+
+ return( NULL );
+}
+
+void axel_save_state(axel_t* axel) {
+ // TODO copy stuff from save_state, sanitize
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/* Create a new axel_t structure */
axel_t *axel_new( conf_t *conf, int count, void *url )
@@ -241,7 +254,7 @@
{
if( (float) axel->conf->max_speed / axel->conf->buffer_size < 0.5 )
{
- axel_message( axel, _("Buffer resized for this speed."), VERBOSITY_NORMAL );
+ axel_message( axel, VERBOSITY_NORMAL, _("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 );
@@ -459,7 +472,7 @@
/* Wait for data on (one of) the connections */
FD_ZERO( fds );
hifd = 0;
- for( i = 0; i < axel->conf->num_connections; i ++ )
+ for( i = 0; i < axel->conncount; i ++ )
{
if( axel->conn[i].enabled )
FD_SET( axel->conn[i].fd, fds );
@@ -669,13 +682,8 @@
int fd, i;
char fn[MAX_STRING+4];
- /* No use for such a file if the server doesn't support
- resuming anyway.. */
- if( !axel->conn[0].supported )
- return;
-
- snprintf( fn, MAX_STRING, "%s.st", axel->filename );
- if( ( fd = open( fn, O_CREAT | O_TRUNC | O_WRONLY, 0666 ) ) == -1 )
+ snprintf( fn, MAX_STRING, "%s" STATEFILE_SUFFIX, axel->filename );
+ if( ( fd = open( fn, O_CREAT | O_TRUNC | O_WRONLY, 0600 ) ) == -1 )
{
return; /* Not 100% fatal.. */
}
@@ -686,33 +694,6 @@
write( fd, &axel->conn[i].currentbyte, sizeof( axel->conn[i].currentbyte ) );
}
close( fd );
-}
-
-/* Thread used to set up a connection */
-void *setup_thread( void *c )
-{
- conn_t *conn = c;
- int oldstate;
-
- /* Allow this thread to be killed at any time. */
- pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
- pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate );
-
- if( conn_setup( conn ) )
- {
- conn->last_transfer = gettime();
- if( conn_exec( conn ) )
- {
- conn->last_transfer = gettime();
- conn->enabled = 1;
- conn->state = 0;
- return( NULL );
- }
- }
-
- conn_disconnect( conn );
- conn->state = 0;
- return( NULL );
}
/* Divide the file and set the locations for each connection */
Modified: branches/3.x-broken/src/axel.h
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/src/axel.h?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/src/axel.h (original)
+++ branches/3.x-broken/src/axel.h Sat Dec 20 12:10:14 2008
@@ -65,13 +65,9 @@
/* Compiled-in settings */
#define MAX_REDIR 5
-#define AXEL_VERSION_STRING "2.99.0"
+#define AXEL_VERSION_STRING "3.0_rc1"
#define DEFAULT_USER_AGENT "Axel " AXEL_VERSION_STRING " (" ARCH ")"
#define STATEFILE_SUFFIX ".st"
-
-#define VERBOSITY_VERBOSE 2
-#define VERBOSITY_NORMAL 1
-#define VERBOSITY_QUIET 0
#include "helper.h"
#include "url.h"
@@ -84,32 +80,69 @@
#include "search.h"
#include "urllist.h"
-// Special value for delay_time, see below
-#define AXEL_DELAY_TIME_ABORT (-1)
+// Message relevance
+#define VERBOSITY_VERBOSE 2
+#define VERBOSITY_NORMAL 1
+#define VERBOSITY_QUIET 0
+
+// Emergency error codes
+#define AXEL_EXIT_MALLOC_FAIL 91
+#define AXEL_EXIT_REALLOC_FAIL 92
// Actual file size is unknown
#define AXEL_SIZE_UNDETERMINED (-1)
+// Download correctly finished
+#define AXEL_STATE_FINISHED 0
// axel struct just created
#define AXEL_STATE_INIT 1
-// preparations complete
-#define AXEL_STATE_READY 2
// Downloading
-#define AXEL_STATE_DOWNLOADING 3
+#define AXEL_STATE_DOWNLOADING 2
// Finished with an error
-#define AXEL_STATE_ERROR 4
-// Download correctly finished
-#define AXEL_STATE_FINISHED 5
+#define AXEL_STATE_ERROR 3
-// TODO can we guarantee anything for the handlers?
+struct string_li_struct {
+ char* str;
+ struct string_li_struct* next;
+};
+typedef struct string_li_struct string_li_t;
+
+struct int_li_struct {
+ int i;
+ struct int_li_struct* next;
+};
+typedef struct int_li_struct int_li_t;
+
// A download to a single file, probably from multiple sources
struct axel_struct {
+ /*
+ Unlike all other elements of this structure, the following handlers may be set by functions not starting with axel_.
+ They are guaranteed to be called in a single thread, i.e. may safely ignore any multithread issues.
+ */
+
+ /** A function that displays messages with the following parameters:
+
+ axel: A pointer to the calling axel structure
+ verbosity: one of the VERBOSITY_* values
+ message: The message to display (already i18ned), will be freed upon returning
+
+ NULL for no message display
+ */
+ void (*message_handler)(const struct axel_struct* axel, int verbosity, const char* message);
+ /**
+ * A handler that displays the current download state.
+ * May be called frequently. Is guaranteed to be called on state changes and messages.
+ * Leave as NULL for no update notifications.
+ */
+ void (*display_handler)(const struct axel_struct* axel);
+
const conf_t* conf; // Not owned by this structure
- urllist_t urls; // Linked list of URLs to read
+ urllist_t urls; // Sorted list of URLs to read
int conncount; // The number of connections, -1 if conn is not yet initialized
conn_t** conn; // array of connections, of size conncount. Owned by this struct.
+
/**
* The local file name to write to. Belongs to this struct.
@@ -120,47 +153,24 @@
char* statefilename; // Name of the state file, NULL for no state file
-
long long size; // The full file size in Byte, or AXEL_SIZE_UNDETERMINED if the file size is not yet determined or undeterminable
long long start_utime; // Start time in microseconds
+
// The download's state, one of the AXEL_STATE_* constants
- volatile sig_atomic_t state; // TODO check whether we read this state at all
+ int state;
- /**
- * Time to wait because of speed limit.
- * AXEL_DELAY_TIME_ABORT if all threads should stop instantaneously.
- */
- volatile sig_atomic_t delay_time;
-
- /** A function that displays messages with the following parameters:
-
- axel: A pointer to the calling axel structure
- message: The message to display (already i18ned), will be freed upon returning
- verbosity: one of the VERBOSITY_* values
-
- NULL for no messages
- */
- void (*message_handler)(const struct axel_struct* axel, const char* message, int verbosity);
- /** A pointer to a function that aborts this run of Axel. ret is a return value (non-zero for errornous abort). Leave as NULL for an exit call.
- Note the axel structure is already torn down at the point and can be cleaned with axel_free.
- */
- void (*abort_handler)(struct axel_struct* axel, int ret);
- /**
- * A handler that displays the download's state. Is called "frequently" and on every update of state.
- * Leave as NULL for no status display
- */
- void (*status_handler)(const struct axel_struct* axel);
+ // Time to wait because of speed limit.
+ int delay_time;
};
typedef struct axel_struct axel_t;
// Main axel API: The following methods are used by the frontend.
-axel_t* axel_new(const conf_t *conf);
+void axel_init(axel_t* ax, const conf_t *conf);
_Bool axel_addurlstr(axel_t* axel, const char* urlstr, int priority);
-void axel_start(axel_t* axel);
-void axel_free(axel_t* axel);
+int axel_download(axel_t* axel);
+void axel_destroy(axel_t* axel);
-void axel_message(const axel_t* axel, const char* message, int verbosity);
-void axel_message_fmt(const axel_t *axel, const char *format, ... );
-void axel_update_status(const axel_t* axel);
-void axel_abort(axel_t* axel, int ret);
+// These functions are only called from axel's core
+void axel_message(const axel_t* axel, int verbosity, const char* message);
+void axel_message_fmt(const axel_t *axel, int verbosity, const char *format, ... );
Modified: branches/3.x-broken/src/conn.h
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/src/conn.h?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/src/conn.h (original)
+++ branches/3.x-broken/src/conn.h Sat Dec 20 12:10:14 2008
@@ -4,7 +4,7 @@
* Copyright 2001 Wilmer van der Gaast *
\********************************************************************/
-/* Connection stuff */
+/* A single downloading thread */
/*
This program is free software; you can redistribute it and/or modify
@@ -23,33 +23,33 @@
Suite 330, Boston, MA 02111-1307 USA
*/
+enum connstate {
+ INITIALIZED, // Just initialized
+ REQUESTED, // First byte went out to the network
+ DOWNLOADING, // Read complete header, currently downloading the file itself
+ FINISHED, // Completed entire download
+ ERROR
+};
+
typedef struct {
conf_t *conf;
url_t* url; /* The URL to download from. Not owned by this struct */
proto_t* proto;
- /* TODO: document this */
- int proxy;
-
- long long size; /* File size, not 'connection size'.. */
long long currentbyte;
long long lastbyte;
+
int fd;
int enabled;
int supported;
int last_transfer;
+
+ connstate cstate;
char *message;
- char *local_if;
-
- int state;
- pthread_t setup_thread[1];
+
+ pthread_t 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 );
+void conn_init(conn_t *conn, url_t* url, conf_t* conf, long long startbyte, long long endbyte);
+
Modified: branches/3.x-broken/src/helper.c
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/src/helper.c?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/src/helper.c (original)
+++ branches/3.x-broken/src/helper.c Sat Dec 20 12:10:14 2008
@@ -1,6 +1,34 @@
/* Helper functions */
#include "axel.h"
+
+/**
+* A malloc implementation that exits on error.
+*/
+void* safe_malloc(size_t size) {
+ void* res = malloc(size);
+
+ if (res == NULL) {
+ fprintf(stderr, _("FATAL ERROR: Can't allocate %d Bytes of memory\n"), (int) size);
+ exit(AXEL_EXIT_MALLOC_FAIL);
+ }
+
+ return res;
+}
+
+/**
+* A realloc implementation that exits on error.
+*/
+void* safe_realloc(void* ptr, size_t size) {
+ void* res = realloc(ptr, size);
+
+ if (res == NULL) {
+ fprintf(stderr, _("FATAL ERROR: Can't realloc %d Bytes of memory\n"), (int) size);
+ exit(AXEL_EXIT_REALLOC_FAIL);
+ }
+
+ return res;
+}
char* helper_strdup(const char* str) {
if (str == NULL) {
@@ -8,7 +36,7 @@
}
size_t len = strlen(str);
- char* res = malloc(len + 1);
+ char* res = safe_malloc(len + 1);
memcpy(res, str, len);
res[len] = '\0';
Modified: branches/3.x-broken/src/helper.h
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/src/helper.h?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/src/helper.h (original)
+++ branches/3.x-broken/src/helper.h Sat Dec 20 12:10:14 2008
@@ -5,6 +5,9 @@
// C99 does not actually include strdup
#define strdup(str) helper_strdup(str)
+
+void* safe_malloc(size_t size);
+void* safe_realloc(void *ptr, size_t size);
char* helper_strdup(const char* str);
const char* strchr_upto(const char* haystack, char needle, const char* upto);
Modified: branches/3.x-broken/src/url.c
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/src/url.c?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/src/url.c (original)
+++ branches/3.x-broken/src/url.c Sat Dec 20 12:10:14 2008
@@ -32,7 +32,7 @@
char* url_encode(const char* origurl) {
int resp = 0; // Position of the next character in the result
int ressize = 256; // Physical size of the result
- char* res = (char*) malloc(ressize);
+ char* res = (char*) safe_malloc(ressize);
char c;
for (;(c = *origurl) != '\0';origurl++) {
@@ -40,7 +40,7 @@
// Note 3 is a magic constant here because we write at most that much characters (plus a null byte)
if (resp >= ressize - 3) {
ressize *= 2;
- res = (char*) realloc(res, ressize);
+ res = (char*) safe_realloc(res, ressize);
}
if (isdigit(c) ||
@@ -59,7 +59,7 @@
res[resp] = '\0';
- res = (char*) realloc(res, resp+1);
+ res = (char*) safe_realloc(res, resp+1);
return res;
}
@@ -69,7 +69,7 @@
* @return A decoded string. Must be freed by the caller.
*/
char* url_heuristic_decode(const char * urlstr) {
- char* res = malloc(strlen(urlstr));
+ char* res = safe_malloc(strlen(urlstr));
char* resp = res;
const char* origp = urlstr;
@@ -93,7 +93,7 @@
resp++;
}
- res = (char*) realloc(res, resp - res + 1);
+ res = (char*) safe_realloc(res, resp - res + 1);
#ifdef DEBUG
debug_printf("Original|Result of heuristic URL decoding:\n%s\n%s", urlstr, res);
@@ -119,7 +119,7 @@
url_t* res;
const char* host = urlstr;
- res = (url_t*) malloc(sizeof(url_t));
+ res = (url_t*) safe_malloc(sizeof(url_t));
memset(res, 0, sizeof(res));
// Scheme (aka protocol)
@@ -284,7 +284,7 @@
s += sizeof(URL_QUERY_SEPCHAR) + s_query;
}
- char* const res = malloc(sizeof(char) * (s + 1));
+ char* const res = safe_malloc(sizeof(char) * (s + 1));
register char* p = res;
memcpy(p, protoname, s_proto);
@@ -370,7 +370,7 @@
s += sizeof(URL_QUERY_SEPCHAR) + s_query;
}
- char* const res = malloc(sizeof(char) * (s + 1));
+ char* const res = safe_malloc(sizeof(char) * (s + 1));
register char* p = res;
*p = URL_DIR_SEPCHAR;
Modified: branches/3.x-broken/src/url.h
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/src/url.h?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/src/url.h (original)
+++ branches/3.x-broken/src/url.h Sat Dec 20 12:10:14 2008
@@ -30,6 +30,10 @@
#define URL_PORT_SEPCHAR ':'
#define URL_DIR_SEPCHAR '/'
#define URL_QUERY_SEPCHAR '?'
+
+// Nonstandard extensions to define URL priority
+#define URL_PRIO_STARTCHAR '}'
+#define URL_PRIO_ENDCHAR '{'
#define URL_PRIO_MAX INT_MAX
#define URL_PRIO_MIN INT_MIN
Modified: branches/3.x-broken/test/test_url.c
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/test/test_url.c?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/test/test_url.c (original)
+++ branches/3.x-broken/test/test_url.c Sat Dec 20 12:10:14 2008
@@ -110,14 +110,14 @@
NULL, "filename", NULL
);
- test_url_parse_unencoded_single_long("http://example.org/1/2/3asd?x=y&z=.",
+ test_url_parse_unencoded_single_long("htTp://example.org/1/2/3asd?x=y&z=.",
PROTO_HTTP,
NULL, NULL,
"example.org", 80,
"1/2", "3asd", "x=y&z=."
);
- test_url_parse_unencoded_single_long("http://a.x:b@example.org/1/2/3asd?x=y&z=.",
+ test_url_parse_unencoded_single_long("HTTP://a.x:b@example.org/1/2/3asd?x=y&z=.",
PROTO_HTTP,
"a.x", "b",
"example.org", 80,
@@ -132,7 +132,7 @@
);
#ifdef FTP
- test_url_parse_unencoded_single_long("ftp://example.org/1/2/3",
+ test_url_parse_unencoded_single_long("fTp://example.org/1/2/3",
PROTO_FTP,
NULL, NULL,
"example.org", 4223,
Modified: branches/3.x-broken/test/test_urllist.c
URL: http://svn.debian.org/wsvn/axel/branches/3.x-broken/test/test_urllist.c?rev=68&op=diff
==============================================================================
--- branches/3.x-broken/test/test_urllist.c (original)
+++ branches/3.x-broken/test/test_urllist.c Sat Dec 20 12:10:14 2008
@@ -19,11 +19,11 @@
url_t* url1 = url_parse_heuristic("http://example.org/1");
ulrllist_add(ul, url1, URL_PRIO_DEFAULT);
- url_t* url2 = url_parse_heuristic("{42}http://example.org/2");
- ulrllist_add(ul, url2);
+ url_t* url2 = url_parse_heuristic(URL_PRIO_ENDCHAR "42" URL_PRIO_ENDCHAR "http://example.org/2");
+ ulrllist_add(ul, url2, URL_PRIO_NONE);
url_t* url3 = url_parse_heuristic("{42}http://example.org/3");
- ulrllist_add(ul, url3);
+ ulrllist_add(ul, url3, URL_PRIO_NONE);
url_t* url4 = url_parse_heuristic("http://example.org/4");
ulrllist_add(ul, url4, 47);
More information about the axel-commits
mailing list