[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