2006-07-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

To add Metalink support(http/ftp only):

	* src/AbstractCommand.h
	(tryReserved): New function.
	* src/AbstractCommand.cc
	(execute): Call tryReserved().
	(tryReserved): New function.
	* src/Request.h
	(Requests): New type definition.
	* src/SegmentMan.h
	(reserved): New variable.
	* src/Util.h
	(fileChecksum): New function.
	(toUpper): New function.
	(toLower): New function.
	* src/Util.cc
	(messageDigest.h): Included.
	(trim): Trim \r\n\t.
	(fileChecksum): New function.
	(toUpper): New function.
	(toLower): New function.
	* src/main.cc
	(normalDownload): New function.
	(main): Added 2 command-line options: metalink-file,
	metalink-connection. Their usage has not been written yet.
	* src/MetalinkProcessor.h: New class.
	* src/Xml2MetalinkProcessor.h: New class.
	* src/Xml2MetalinkProcessor.cc: New class.
	* src/MetalinkEntry.h: New class.
	* src/MetalinkEntry.cc: New class.
	* src/MetalinkResource.h: New class.
	* src/MetalinkResource.cc: New class.
	
	To add md5 message digest checking:

	* src/messageDigest.h: Rewritten.
	* src/MultiDiskWriter.cc: Updated according to the changes in
	messageDigest.h.
	* src/ShaVisitor.cc: Updated according to the changes in
	messageDigest.h.
	* src/Util.cc: Updated according to the changes in 
messageDigest.h.
	* src/AbstractDiskWriter.cc: Updated according to the changes in
	messageDigest.h.
	
	To fix a bug that causes segfault when the payload length in 
peer
	message is less than 0:

	* src/PeerConnection.cc:
	(receiveMessage): Fixed the bug.
	* src/PeerMessageUtil.cc
	(checkLength): Throw an exception if length is less than or 
equals to
	0.
	
	To add new interfaces to Base64 encoding/decoding:

	* src/Base64.h
	(part_encode): Changed the method signature.
	(encode): New function(overload).
	(decode): New function(overload).
	* src/Base64.cc
	(part_encode): Rewritten.
	(encode): Rewritten.
	(encode): New function(overload).

	To prevent a peer to download same piece if there is an error in
	checksum:

	* src/PieceMessage.cc
	(receivedAction): Call peerInteraction->abortPiece().
This commit is contained in:
Tatsuhiro Tsujikawa 2006-07-03 14:19:23 +00:00
parent 003a474357
commit 78eff23254
39 changed files with 1724 additions and 156 deletions

View File

@ -1,3 +1,75 @@
2006-07-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To add Metalink support(http/ftp only):
* src/AbstractCommand.h
(tryReserved): New function.
* src/AbstractCommand.cc
(execute): Call tryReserved().
(tryReserved): New function.
* src/Request.h
(Requests): New type definition.
* src/SegmentMan.h
(reserved): New variable.
* src/Util.h
(fileChecksum): New function.
(toUpper): New function.
(toLower): New function.
* src/Util.cc
(messageDigest.h): Included.
(trim): Trim \r\n\t.
(fileChecksum): New function.
(toUpper): New function.
(toLower): New function.
* src/main.cc
(normalDownload): New function.
(main): Added 2 command-line options: metalink-file,
metalink-connection. Their usage has not been written yet.
* src/MetalinkProcessor.h: New class.
* src/Xml2MetalinkProcessor.h: New class.
* src/Xml2MetalinkProcessor.cc: New class.
* src/MetalinkEntry.h: New class.
* src/MetalinkEntry.cc: New class.
* src/MetalinkResource.h: New class.
* src/MetalinkResource.cc: New class.
To add md5 message digest checking:
* src/messageDigest.h: Rewritten.
* src/MultiDiskWriter.cc: Updated according to the changes in
messageDigest.h.
* src/ShaVisitor.cc: Updated according to the changes in
messageDigest.h.
* src/Util.cc: Updated according to the changes in messageDigest.h.
* src/AbstractDiskWriter.cc: Updated according to the changes in
messageDigest.h.
To fix a bug that causes segfault when the payload length in peer
message is less than 0:
* src/PeerConnection.cc:
(receiveMessage): Fixed the bug.
* src/PeerMessageUtil.cc
(checkLength): Throw an exception if length is less than or equals to
0.
To add new interfaces to Base64 encoding/decoding:
* src/Base64.h
(part_encode): Changed the method signature.
(encode): New function(overload).
(decode): New function(overload).
* src/Base64.cc
(part_encode): Rewritten.
(encode): Rewritten.
(encode): New function(overload).
To prevent a peer to download same piece if there is an error in
checksum:
* src/PieceMessage.cc
(receivedAction): Call peerInteraction->abortPiece().
2006-06-25 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To fix the bug that causes same have message is sent many times to

View File

@ -163,6 +163,9 @@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
XML2_CONFIG = @XML2_CONFIG@
XML_CPPFLAGS = @XML_CPPFLAGS@
XML_LIBS = @XML_LIBS@
YACC = @YACC@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@

3
TODO
View File

@ -14,3 +14,6 @@
* Add Mainline-compatible DHT support
* Add Message stream encryption support
* Refacturing HttpConnection and FtpConnection
* Use EXIT_SUCCESS and EXIT_FAILURE
* Query resource by location
* Conditional compilation based on ENABLE_LIBXML2

189
aclocal.m4 vendored
View File

@ -362,6 +362,195 @@ main ()
dnl *-*wedit:notab*-* Please keep this as the last line.
# Configure paths for LIBXML2
# Mike Hommey 2004-06-19
# use CPPFLAGS instead of CFLAGS
# Toshio Kuratomi 2001-04-21
# Adapted from:
# Configure paths for GLIB
# Owen Taylor 97-11-3
dnl AM_PATH_XML2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for XML, and define XML_CPPFLAGS and XML_LIBS
dnl
AC_DEFUN([AM_PATH_XML2],[
AC_ARG_WITH(xml-prefix,
[ --with-xml-prefix=PFX Prefix where libxml is installed (optional)],
xml_config_prefix="$withval", xml_config_prefix="")
AC_ARG_WITH(xml-exec-prefix,
[ --with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)],
xml_config_exec_prefix="$withval", xml_config_exec_prefix="")
AC_ARG_ENABLE(xmltest,
[ --disable-xmltest Do not try to compile and run a test LIBXML program],,
enable_xmltest=yes)
if test x$xml_config_exec_prefix != x ; then
xml_config_args="$xml_config_args"
if test x${XML2_CONFIG+set} != xset ; then
XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
fi
fi
if test x$xml_config_prefix != x ; then
xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
if test x${XML2_CONFIG+set} != xset ; then
XML2_CONFIG=$xml_config_prefix/bin/xml2-config
fi
fi
AC_PATH_PROG(XML2_CONFIG, xml2-config, no)
min_xml_version=ifelse([$1], ,2.0.0,[$1])
AC_MSG_CHECKING(for libxml - version >= $min_xml_version)
no_xml=""
if test "$XML2_CONFIG" = "no" ; then
no_xml=yes
else
XML_CPPFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_xmltest" = "xyes" ; then
ac_save_CPPFLAGS="$CPPFLAGS"
ac_save_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
LIBS="$XML_LIBS $LIBS"
dnl
dnl Now check if the installed libxml is sufficiently new.
dnl (Also sanity checks the results of xml2-config to some extent)
dnl
rm -f conf.xmltest
AC_TRY_RUN([
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libxml/xmlversion.h>
int
main()
{
int xml_major_version, xml_minor_version, xml_micro_version;
int major, minor, micro;
char *tmp_version;
system("touch conf.xmltest");
/* Capture xml2-config output via autoconf/configure variables */
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = (char *)strdup("$min_xml_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string from xml2-config\n", "$min_xml_version");
exit(1);
}
free(tmp_version);
/* Capture the version information from the header files */
tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
exit(1);
}
free(tmp_version);
/* Compare xml2-config output to the libxml headers */
if ((xml_major_version != $xml_config_major_version) ||
(xml_minor_version != $xml_config_minor_version) ||
(xml_micro_version != $xml_config_micro_version))
{
printf("*** libxml header files (version %d.%d.%d) do not match\n",
xml_major_version, xml_minor_version, xml_micro_version);
printf("*** xml2-config (version %d.%d.%d)\n",
$xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
return 1;
}
/* Compare the headers to the library to make sure we match */
/* Less than ideal -- doesn't provide us with return value feedback,
* only exits if there's a serious mismatch between header and library.
*/
LIBXML_TEST_VERSION;
/* Test that the library is greater than our minimum version */
if ((xml_major_version > major) ||
((xml_major_version == major) && (xml_minor_version > minor)) ||
((xml_major_version == major) && (xml_minor_version == minor) &&
(xml_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
xml_major_version, xml_minor_version, xml_micro_version);
printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
major, minor, micro);
printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
printf("***\n");
printf("*** If you have already installed a sufficiently new version, this error\n");
printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
printf("*** being found. The easiest way to fix this is to remove the old version\n");
printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
printf("*** correct copy of xml2-config. (In this case, you will have to\n");
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
printf("*** so that the correct libraries are found at run-time))\n");
}
return 1;
}
],, no_xml=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CPPFLAGS="$ac_save_CPPFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_xml" = x ; then
AC_MSG_RESULT(yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version))
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$XML2_CONFIG" = "no" ; then
echo "*** The xml2-config script installed by LIBXML could not be found"
echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the XML2_CONFIG environment variable to the"
echo "*** full path to xml2-config."
else
if test -f conf.xmltest ; then
:
else
echo "*** Could not run libxml test program, checking why..."
CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
LIBS="$LIBS $XML_LIBS"
AC_TRY_LINK([
#include <libxml/xmlversion.h>
#include <stdio.h>
], [ LIBXML_TEST_VERSION; return 0;],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
echo "*** may want to edit the xml2-config script: $XML2_CONFIG" ])
CPPFLAGS="$ac_save_CPPFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
XML_CPPFLAGS=""
XML_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(XML_CPPFLAGS)
AC_SUBST(XML_LIBS)
rm -f conf.xmltest
])
# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation

View File

@ -11,6 +11,9 @@
/* Define to 1 if BitTorrent support is enabled. */
#undef ENABLE_BITTORRENT
/* Define to 1 if Metalink support is enabled. */
#undef ENABLE_METALINK
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#undef ENABLE_NLS
@ -114,6 +117,9 @@
/* Define to 1 if you have openssl. */
#undef HAVE_LIBSSL
/* Define to 1 if you have libxml2. */
#undef HAVE_LIBXML2
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H

340
configure vendored
View File

@ -311,7 +311,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CPPUNIT_CONFIG CPPUNIT_CFLAGS CPPUNIT_LIBS localedir CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB YACC LIBGNUTLS_CONFIG LIBGNUTLS_CFLAGS LIBGNUTLS_LIBS LIBGCRYPT_CONFIG LIBGCRYPT_CFLAGS LIBGCRYPT_LIBS OPENSSL_LIBS OPENSSL_CFLAGS ALLOCA CPP EGREP MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE build build_cpu build_vendor build_os host host_cpu host_vendor host_os GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CPPUNIT_CONFIG CPPUNIT_CFLAGS CPPUNIT_LIBS localedir CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB YACC XML2_CONFIG XML_CPPFLAGS XML_LIBS LIBGNUTLS_CONFIG LIBGNUTLS_CFLAGS LIBGNUTLS_LIBS LIBGCRYPT_CONFIG LIBGCRYPT_CFLAGS LIBGCRYPT_LIBS OPENSSL_LIBS OPENSSL_CFLAGS ALLOCA CPP EGREP MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE build build_cpu build_vendor build_os host host_cpu host_vendor host_os GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -863,6 +863,7 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors
--disable-xmltest Do not try to compile and run a test LIBXML program
--disable-nls do not use Native Language Support
--disable-rpath do not hardcode runtime library paths
@ -873,6 +874,9 @@ Optional Packages:
--with-cppunit-exec-prefix=PFX Exec prefix where CppUnit is installed (optional)
--with-gnutls use gnutls library if installed. Default: yes
--with-openssl use openssl library if installed. Default: yes
--with-libxml2 use libxml2 library if installed. Default: yes
--with-xml-prefix=PFX Prefix where libxml is installed (optional)
--with-xml-exec-prefix=PFX Exec prefix where libxml is installed (optional)
--with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional)
--with-libgcrypt-prefix=PFX
prefix where LIBGCRYPT is installed (optional)
@ -1934,6 +1938,14 @@ else
with_openssl=yes
fi;
# Check whether --with-libxml2 or --without-libxml2 was given.
if test "${with_libxml2+set}" = set; then
withval="$with_libxml2"
with_libxml2=$enableval
else
with_libxml2=yes
fi;
# Checks for programs.
ac_ext=cc
@ -3696,9 +3708,322 @@ test -n "$YACC" || YACC="yacc"
# Checks for libraries.
if test "x$with_gnutls" = "xyes"; then
if test "x$with_libxml2" = "xyes"; then
# Check whether --with-xml-prefix or --without-xml-prefix was given.
if test "${with_xml_prefix+set}" = set; then
withval="$with_xml_prefix"
xml_config_prefix="$withval"
else
xml_config_prefix=""
fi;
# Check whether --with-xml-exec-prefix or --without-xml-exec-prefix was given.
if test "${with_xml_exec_prefix+set}" = set; then
withval="$with_xml_exec_prefix"
xml_config_exec_prefix="$withval"
else
xml_config_exec_prefix=""
fi;
# Check whether --enable-xmltest or --disable-xmltest was given.
if test "${enable_xmltest+set}" = set; then
enableval="$enable_xmltest"
else
enable_xmltest=yes
fi;
if test x$xml_config_exec_prefix != x ; then
xml_config_args="$xml_config_args"
if test x${XML2_CONFIG+set} != xset ; then
XML2_CONFIG=$xml_config_exec_prefix/bin/xml2-config
fi
fi
if test x$xml_config_prefix != x ; then
xml_config_args="$xml_config_args --prefix=$xml_config_prefix"
if test x${XML2_CONFIG+set} != xset ; then
XML2_CONFIG=$xml_config_prefix/bin/xml2-config
fi
fi
# Extract the first word of "xml2-config", so it can be a program name with args.
set dummy xml2-config; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_XML2_CONFIG+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
case $XML2_CONFIG in
[\\/]* | ?:[\\/]*)
ac_cv_path_XML2_CONFIG="$XML2_CONFIG" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_XML2_CONFIG="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
test -z "$ac_cv_path_XML2_CONFIG" && ac_cv_path_XML2_CONFIG="no"
;;
esac
fi
XML2_CONFIG=$ac_cv_path_XML2_CONFIG
if test -n "$XML2_CONFIG"; then
echo "$as_me:$LINENO: result: $XML2_CONFIG" >&5
echo "${ECHO_T}$XML2_CONFIG" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
min_xml_version=2.6.26
echo "$as_me:$LINENO: checking for libxml - version >= $min_xml_version" >&5
echo $ECHO_N "checking for libxml - version >= $min_xml_version... $ECHO_C" >&6
no_xml=""
if test "$XML2_CONFIG" = "no" ; then
no_xml=yes
else
XML_CPPFLAGS=`$XML2_CONFIG $xml_config_args --cflags`
XML_LIBS=`$XML2_CONFIG $xml_config_args --libs`
xml_config_major_version=`$XML2_CONFIG $xml_config_args --version | \
sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
xml_config_minor_version=`$XML2_CONFIG $xml_config_args --version | \
sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
xml_config_micro_version=`$XML2_CONFIG $xml_config_args --version | \
sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
if test "x$enable_xmltest" = "xyes" ; then
ac_save_CPPFLAGS="$CPPFLAGS"
ac_save_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
LIBS="$XML_LIBS $LIBS"
rm -f conf.xmltest
if test "$cross_compiling" = yes; then
echo $ac_n "cross compiling; assumed OK... $ac_c"
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libxml/xmlversion.h>
int
main()
{
int xml_major_version, xml_minor_version, xml_micro_version;
int major, minor, micro;
char *tmp_version;
system("touch conf.xmltest");
/* Capture xml2-config output via autoconf/configure variables */
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = (char *)strdup("$min_xml_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string from xml2-config\n", "$min_xml_version");
exit(1);
}
free(tmp_version);
/* Capture the version information from the header files */
tmp_version = (char *)strdup(LIBXML_DOTTED_VERSION);
if (sscanf(tmp_version, "%d.%d.%d", &xml_major_version, &xml_minor_version, &xml_micro_version) != 3) {
printf("%s, bad version string from libxml includes\n", "LIBXML_DOTTED_VERSION");
exit(1);
}
free(tmp_version);
/* Compare xml2-config output to the libxml headers */
if ((xml_major_version != $xml_config_major_version) ||
(xml_minor_version != $xml_config_minor_version) ||
(xml_micro_version != $xml_config_micro_version))
{
printf("*** libxml header files (version %d.%d.%d) do not match\n",
xml_major_version, xml_minor_version, xml_micro_version);
printf("*** xml2-config (version %d.%d.%d)\n",
$xml_config_major_version, $xml_config_minor_version, $xml_config_micro_version);
return 1;
}
/* Compare the headers to the library to make sure we match */
/* Less than ideal -- doesn't provide us with return value feedback,
* only exits if there's a serious mismatch between header and library.
*/
LIBXML_TEST_VERSION;
/* Test that the library is greater than our minimum version */
if ((xml_major_version > major) ||
((xml_major_version == major) && (xml_minor_version > minor)) ||
((xml_major_version == major) && (xml_minor_version == minor) &&
(xml_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** An old version of libxml (%d.%d.%d) was found.\n",
xml_major_version, xml_minor_version, xml_micro_version);
printf("*** You need a version of libxml newer than %d.%d.%d. The latest version of\n",
major, minor, micro);
printf("*** libxml is always available from ftp://ftp.xmlsoft.org.\n");
printf("***\n");
printf("*** If you have already installed a sufficiently new version, this error\n");
printf("*** probably means that the wrong copy of the xml2-config shell script is\n");
printf("*** being found. The easiest way to fix this is to remove the old version\n");
printf("*** of LIBXML, but you can also set the XML2_CONFIG environment to point to the\n");
printf("*** correct copy of xml2-config. (In this case, you will have to\n");
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
printf("*** so that the correct libraries are found at run-time))\n");
}
return 1;
}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
:
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
no_xml=yes
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
CPPFLAGS="$ac_save_CPPFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_xml" = x ; then
echo "$as_me:$LINENO: result: yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version)" >&5
echo "${ECHO_T}yes (version $xml_config_major_version.$xml_config_minor_version.$xml_config_micro_version)" >&6
have_libxml2=yes
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
if test "$XML2_CONFIG" = "no" ; then
echo "*** The xml2-config script installed by LIBXML could not be found"
echo "*** If libxml was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the XML2_CONFIG environment variable to the"
echo "*** full path to xml2-config."
else
if test -f conf.xmltest ; then
:
else
echo "*** Could not run libxml test program, checking why..."
CPPFLAGS="$CPPFLAGS $XML_CPPFLAGS"
LIBS="$LIBS $XML_LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <libxml/xmlversion.h>
#include <stdio.h>
int
main ()
{
LIBXML_TEST_VERSION; return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding LIBXML or finding the wrong"
echo "*** version of LIBXML. If it is not finding LIBXML, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means LIBXML was incorrectly installed"
echo "*** or that you have moved LIBXML since it was installed. In the latter case, you"
echo "*** may want to edit the xml2-config script: $XML2_CONFIG"
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
CPPFLAGS="$ac_save_CPPFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
XML_CPPFLAGS=""
XML_LIBS=""
:
fi
rm -f conf.xmltest
if test "x$have_libxml2" = "xyes"; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_LIBXML2 1
_ACEOF
fi
fi
if test "x$with_gnutls" = "xyes"; then
# Check whether --with-libgnutls-prefix or --without-libgnutls-prefix was given.
if test "${with_libgnutls_prefix+set}" = set; then
withval="$with_libgnutls_prefix"
@ -4292,6 +4617,14 @@ CPPFLAGS=$CPPFLAGS_save
fi
if test "x$have_libxml2" = "xyes"; then
cat >>confdefs.h <<\_ACEOF
#define ENABLE_METALINK 1
_ACEOF
fi
if test "x$have_libgnutls" = "xyes" || test "x$have_openssl" = "xyes"; then
cat >>confdefs.h <<\_ACEOF
@ -11853,6 +12186,9 @@ s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
s,@RANLIB@,$RANLIB,;t t
s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
s,@YACC@,$YACC,;t t
s,@XML2_CONFIG@,$XML2_CONFIG,;t t
s,@XML_CPPFLAGS@,$XML_CPPFLAGS,;t t
s,@XML_LIBS@,$XML_LIBS,;t t
s,@LIBGNUTLS_CONFIG@,$LIBGNUTLS_CONFIG,;t t
s,@LIBGNUTLS_CFLAGS@,$LIBGNUTLS_CFLAGS,;t t
s,@LIBGNUTLS_LIBS@,$LIBGNUTLS_LIBS,;t t

View File

@ -15,6 +15,7 @@ AC_SUBST(localedir)
# Checks for arguments.
AC_ARG_WITH([gnutls], [ --with-gnutls use gnutls library if installed. Default: yes], [with_gnutls=$enableval], [with_gnutls=yes])
AC_ARG_WITH([openssl], [ --with-openssl use openssl library if installed. Default: yes], [with_openssl=$enableval], [with_openssl=yes])
AC_ARG_WITH([libxml2], [ --with-libxml2 use libxml2 library if installed. Default: yes], [with_libxml2=$enableval], [with_libxml2=yes])
# Checks for programs.
@ -25,6 +26,13 @@ AC_PROG_RANLIB
AC_PROG_YACC
# Checks for libraries.
if test "x$with_libxml2" = "xyes"; then
AM_PATH_XML2([2.6.26], [have_libxml2=yes])
if test "x$have_libxml2" = "xyes"; then
AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have libxml2.])
fi
fi
if test "x$with_gnutls" = "xyes"; then
AM_PATH_LIBGNUTLS([1.2.9], [have_libgnutls=yes])
if test "x$have_libgnutls" = "xyes"; then
@ -51,6 +59,10 @@ if test "x$with_openssl" = "xyes" && test "x$have_libgnutls" != "xyes"; then
AM_PATH_OPENSSL
fi
if test "x$have_libxml2" = "xyes"; then
AC_DEFINE([ENABLE_METALINK], [1], [Define to 1 if Metalink support is enabled.])
fi
if test "x$have_libgnutls" = "xyes" || test "x$have_openssl" = "xyes"; then
AC_DEFINE([ENABLE_SSL], [1], [Define to 1 if ssl support is enabled.])
fi

View File

@ -137,6 +137,9 @@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
XML2_CONFIG = @XML2_CONFIG@
XML_CPPFLAGS = @XML_CPPFLAGS@
XML_LIBS = @XML_LIBS@
YACC = @YACC@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@

View File

@ -77,6 +77,7 @@ bool AbstractCommand::execute() {
delete(err);
req->resetUrl();
e->segmentMan->errors++;
tryReserved();
return true;
} catch(DlRetryEx* err) {
logger->error(MSG_RESTARTING_DOWNLOAD, err, cuid);
@ -90,6 +91,7 @@ bool AbstractCommand::execute() {
if(isAbort) {
logger->error(MSG_MAX_TRY, cuid, req->getTryCount());
e->segmentMan->errors++;
tryReserved();
return true;
} else {
return prepareForRetry(e->option->getAsInt(PREF_RETRY_WAIT));
@ -97,6 +99,15 @@ bool AbstractCommand::execute() {
}
}
void AbstractCommand::tryReserved() {
if(!e->segmentMan->reserved.empty()) {
Request* req = e->segmentMan->reserved.front();
e->segmentMan->reserved.pop_front();
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e);
e->commands.push_back(command);
}
}
bool AbstractCommand::prepareForRetry(int wait) {
Command* command = InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e);
if(wait == 0) {

View File

@ -37,6 +37,7 @@ protected:
DownloadEngine* e;
Socket* socket;
void tryReserved();
virtual bool prepareForRetry(int wait);
virtual void onAbort(Exception* ex);
virtual bool executeInternal(Segment segment) = 0;

View File

@ -32,14 +32,15 @@
AbstractDiskWriter::AbstractDiskWriter():fd(0) {
#ifdef ENABLE_SHA1DIGEST
sha1DigestInit(ctx);
ctx.setAlgo(MessageDigestContext::ALGO_SHA1);
digestInit(ctx);
#endif // ENABLE_SHA1DIGEST
}
AbstractDiskWriter::~AbstractDiskWriter() {
closeFile();
#ifdef ENABLE_SHA1DIGEST
sha1DigestFree(ctx);
digestFree(ctx);
#endif // ENABLE_SHA1DIGEST
}
@ -99,7 +100,7 @@ int AbstractDiskWriter::readDataInternal(char* data, int len) {
string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
#ifdef ENABLE_SHA1DIGEST
sha1DigestReset(ctx);
digestReset(ctx);
try {
int BUFSIZE = 16*1024;
char buf[BUFSIZE];
@ -107,7 +108,7 @@ string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
if(BUFSIZE != readData(buf, BUFSIZE, offset)) {
throw string("error");
}
sha1DigestUpdate(ctx, buf, BUFSIZE);
digestUpdate(ctx, buf, BUFSIZE);
offset += BUFSIZE;
}
int r = length%BUFSIZE;
@ -115,10 +116,10 @@ string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) {
if(r != readData(buf, r, offset)) {
throw string("error");
}
sha1DigestUpdate(ctx, buf, r);
digestUpdate(ctx, buf, r);
}
unsigned char hashValue[20];
sha1DigestFinal(ctx, hashValue);
digestFinal(ctx, hashValue);
return Util::toHex(hashValue, 20);
} catch(string ex) {
throw new DlAbortEx(EX_FILE_SHA1SUM, filename.c_str(), strerror(errno));

View File

@ -21,62 +21,69 @@
/* copyright --> */
#include "Base64.h"
string Base64::part_encode(const string& subplain)
static char base64_table[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
};
void Base64::part_encode(const unsigned char* sub, int subLength,
unsigned char* buf)
{
static char base64_table[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
};
int shift = 2;
char carry = 0;
bool ignore_flag = false;
string crypted;
for(unsigned int index = 0; index < subplain.size(); ++index) {
if(ignore_flag) {
crypted += '=';
} else {
char cur = subplain.at(index) >> shift | carry;
if(subplain.at(index) == 0) ignore_flag = true;
carry = (subplain.at(index) << (6-shift)) & 0x3F;
shift += 2;
crypted += base64_table[(unsigned int)cur];
}
unsigned char carry = 0;
int index;
for(index = 0; index < subLength; index++) {
unsigned char cur = sub[index] >> shift | carry;
carry = (sub[index] << (6-shift)) & 0x3f;
shift += 2;
buf[index] = base64_table[(unsigned int)cur];
}
if(subplain.at(subplain.size()-1) == 0) {
crypted += '=';
if(subLength == 1) {
buf[index] = base64_table[(unsigned int)carry];
buf[index+1] = buf[index+2] = '=';
} else if(subLength == 2) {
buf[index] = base64_table[(unsigned int)carry];
buf[index+1] = '=';
} else {
char cur = subplain.at(subplain.size()-1) & 0x3F;
crypted += base64_table[(unsigned int)cur];
unsigned char cur = sub[subLength-1] & 0x3f;
buf[index] = base64_table[(unsigned int)cur];
}
return crypted;
}
string Base64::encode(const string& plainSrc)
{
string plain = plainSrc;
int remainder = plain.size() % 3;
if( remainder ) remainder = 3-remainder;
for(int i = 0; i < remainder; ++i) plain += (char)0;
string crypted;
int start_pos = 0;
for(unsigned int index = 0; plain.size() > index; index += 3) {
string subplain = plain.substr(start_pos, 3);
string subcrypted = part_encode(subplain);
start_pos += 3;
crypted += subcrypted;
}
return crypted;
unsigned char* result = 0;
int resultLength = 0;
encode((const unsigned char*)plainSrc.c_str(), plainSrc.size(),
result, resultLength);
string encoded(&result[0], &result[resultLength]);
delete [] result;
return encoded;
}
void Base64::encode(const unsigned char* src, int srcLength,
unsigned char*& result, int& resultLength) {
resultLength = (srcLength+(srcLength%3 == 0 ? 0 : 3-srcLength%3))/3*4;
result = new unsigned char[resultLength];
unsigned char* tail = result;
for(int index = 0; srcLength > index; index += 3) {
unsigned char temp[4];
part_encode(&src[index],
srcLength >= index+3 ? 3 : srcLength-index,
temp);
memcpy(tail, temp, sizeof(temp));
tail += sizeof(temp);
}
}
char Base64::getValue(char ch)
{
char retch;

View File

@ -28,12 +28,21 @@ using namespace std;
class Base64
{
private:
static void part_encode(const unsigned char* sub, int subLength,
unsigned char* buf);
static string part_encode(const string& subplain);
static string part_decode(const string& subCrypted);
static char getValue(char ch);
public:
static string encode(const string& plain);
// caller must deallocate the memory used by result.
static void encode(const unsigned char* src, int srcLength,
unsigned char*& result, int& resultLength);
static string decode(const string& crypted);
// caller must deallocate the memory used by result.
static void decode(const unsigned char* src, int srcLength,
unsigned char*& result, int& resultLength);
};
#endif // _BASE64_H_

View File

@ -102,12 +102,17 @@ SRCS = Socket.cc Socket.h\
SuggestPieceMessage.cc SuggestPieceMessage.h\
SimplePeerMessage.cc SimplePeerMessage.h\
NullLogger.h\
Time.cc Time.h
Time.cc Time.h\
Metalinker.cc Metalinker.h\
MetalinkEntry.cc MetalinkEntry.h\
MetalinkResource.cc MetalinkResource.h\
MetalinkProcessor.h\
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@

View File

@ -109,7 +109,9 @@ am__objects_1 = Socket.$(OBJEXT) SocketCore.$(OBJEXT) \
PortMessage.$(OBJEXT) HaveAllMessage.$(OBJEXT) \
HaveNoneMessage.$(OBJEXT) RejectMessage.$(OBJEXT) \
AllowedFastMessage.$(OBJEXT) SuggestPieceMessage.$(OBJEXT) \
SimplePeerMessage.$(OBJEXT) Time.$(OBJEXT)
SimplePeerMessage.$(OBJEXT) Time.$(OBJEXT) \
Metalinker.$(OBJEXT) MetalinkEntry.$(OBJEXT) \
MetalinkResource.$(OBJEXT) Xml2MetalinkProcessor.$(OBJEXT)
am_libaria2c_a_OBJECTS = $(am__objects_1)
libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS)
am__installdirs = "$(DESTDIR)$(bindir)"
@ -215,6 +217,9 @@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
XML2_CONFIG = @XML2_CONFIG@
XML_CPPFLAGS = @XML_CPPFLAGS@
XML_LIBS = @XML_LIBS@
YACC = @YACC@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
@ -361,16 +366,21 @@ SRCS = Socket.cc Socket.h\
SuggestPieceMessage.cc SuggestPieceMessage.h\
SimplePeerMessage.cc SimplePeerMessage.h\
NullLogger.h\
Time.cc Time.h
Time.cc Time.h\
Metalinker.cc Metalinker.h\
MetalinkEntry.cc MetalinkEntry.h\
MetalinkResource.cc MetalinkResource.h\
MetalinkProcessor.h\
Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h
noinst_LIBRARIES = libaria2c.a
libaria2c_a_SOURCES = $(SRCS)
aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
AM_CPPFLAGS = -Wall\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@
all: all-am
@ -493,6 +503,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/List.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogFactory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtil.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntry.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkResource.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Metalinker.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskAdaptor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskWriter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NotInterestedMessage.Po@am__quote@
@ -535,6 +548,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommand.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Util.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Xml2MetalinkProcessor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
.cc.o:

81
src/MetalinkEntry.cc Normal file
View File

@ -0,0 +1,81 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "MetalinkEntry.h"
#include "Util.h"
#include <algorithm>
MetalinkEntry::MetalinkEntry() {}
MetalinkEntry::~MetalinkEntry() {
for_each(resources.begin(), resources.end(), Deleter());
}
bool MetalinkEntry::check(const string& filename) const {
unsigned char buf[20];
int digestLength;
const string* digestPtr;
MessageDigestContext::HashAlgo algo;
if(!sha1.empty()) {
digestLength = 20;
algo = MessageDigestContext::ALGO_SHA1;
digestPtr = &sha1;
} else if(!md5.empty()) {
digestLength = 16;
algo = MessageDigestContext::ALGO_MD5;
digestPtr = &md5;
} else {
return true;
}
Util::fileChecksum(filename, buf, algo);
return *digestPtr == Util::toHex(buf, digestLength);
}
class PrefOrder {
public:
bool operator()(const MetalinkResource* res1, const MetalinkResource* res2) {
return res1->preference > res2->preference;
}
};
void MetalinkEntry::reorderResourcesByPreference() {
random_shuffle(resources.begin(), resources.end());
sort(resources.begin(), resources.end(), PrefOrder());
}
class Supported {
public:
bool operator()(const MetalinkResource* res) {
switch(res->type) {
case MetalinkResource::TYPE_FTP:
case MetalinkResource::TYPE_HTTP:
return true;
default:
return false;
}
}
};
void MetalinkEntry::dropUnsupportedResource() {
MetalinkResources::iterator split =
partition(resources.begin(), resources.end(), Supported());
resources.erase(split, resources.end());
}

55
src/MetalinkEntry.h Normal file
View File

@ -0,0 +1,55 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_METALINK_ENTRY_H_
#define _D_METALINK_ENTRY_H_
#include "common.h"
#include "MetalinkResource.h"
#include <deque>
typedef deque<MetalinkResource*> MetalinkResources;
class MetalinkEntry {
public:
string filename;
string version;
string language;
string os;
long long int size;
string md5;
string sha1;
public:
MetalinkResources resources;
public:
MetalinkEntry();
~MetalinkEntry();
MetalinkEntry& operator=(const MetalinkEntry& metalinkEntry);
bool check(const string& filename) const;
void dropUnsupportedResource();
void reorderResourcesByPreference();
};
#endif // _D_METALINK_ENTRY_H_

35
src/MetalinkProcessor.h Normal file
View File

@ -0,0 +1,35 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_METALINK_PROCESSOR_H_
#define _D_METALINK_PROCESSOR_H_
#include "Metalinker.h"
#include "common.h"
class MetalinkProcessor {
public:
virtual ~MetalinkProcessor() {}
virtual Metalinker* parseFile(const string& filename) = 0;
};
#endif // _D_METALINK_PROCESSOR_H_

26
src/MetalinkResource.cc Normal file
View File

@ -0,0 +1,26 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "MetalinkResource.h"
MetalinkResource::MetalinkResource() {}
MetalinkResource::~MetalinkResource() {}

47
src/MetalinkResource.h Normal file
View File

@ -0,0 +1,47 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_METALINK_RESOURCE_H_
#define _D_METALINK_RESOURCE_H_
#include "common.h"
class MetalinkResource {
public:
enum TYPE {
TYPE_FTP,
TYPE_HTTP,
TYPE_BITTORRENT,
TYPE_NOT_SUPPORTED
};
public:
string url;
int type;
string location;
int preference;
public:
MetalinkResource();
~MetalinkResource();
MetalinkResource& operator=(const MetalinkResource& metalinkResource);
};
#endif // _D_METALINK_RESOURCE_H_

74
src/Metalinker.cc Normal file
View File

@ -0,0 +1,74 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "Metalinker.h"
#include <algorithm>
Metalinker::Metalinker() {
}
Metalinker::~Metalinker() {
for_each(entries.begin(), entries.end(), Deleter());
}
class EntryQuery {
private:
string version;
string language;
string os;
public:
EntryQuery(const string& version,
const string& language,
const string& os):version(version),
language(language),
os(os) {}
bool operator()(const MetalinkEntry* entry) {
if(!version.empty()) {
if(version != entry->version) {
return false;
}
}
if(!language.empty()) {
if(language != entry->language) {
return false;
}
}
if(!os.empty()) {
if(os != entry->os) {
return false;
}
}
return true;
}
};
MetalinkEntry* Metalinker::queryEntry(const string& version,
const string& language,
const string& os) const {
MetalinkEntries::const_iterator itr =
find_if(entries.begin(), entries.end(),
EntryQuery(version, language, os));
if(itr == entries.end()) {
return NULL;
} else {
return *itr;
}
}

46
src/Metalinker.h Normal file
View File

@ -0,0 +1,46 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_METALINKER_H_
#define _D_METALINKER_H_
#include "common.h"
#include "MetalinkEntry.h"
#include <deque>
#include <libxml/xpath.h>
typedef deque<MetalinkEntry*> MetalinkEntries;
class Metalinker {
public:
MetalinkEntries entries;
public:
Metalinker();
~Metalinker();
Metalinker& operator=(const Metalinker& metalinker);
MetalinkEntry* queryEntry(const string& version, const string& language,
const string& os) const;
};
#endif // _D_METALINKER_H_

View File

@ -27,14 +27,15 @@
MultiDiskWriter::MultiDiskWriter(int pieceLength):pieceLength(pieceLength) {
#ifdef ENABLE_SHA1DIGEST
sha1DigestInit(ctx);
ctx.setAlgo(MessageDigestContext::ALGO_SHA1);
digestInit(ctx);
#endif // ENABLE_SHA1DIGEST
}
MultiDiskWriter::~MultiDiskWriter() {
clearEntries();
#ifdef ENABLE_SHA1DIGEST
sha1DigestFree(ctx);
digestFree(ctx);
#endif // ENABLE_SHA1DIGEST
}
@ -150,7 +151,7 @@ void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, l
if(BUFSIZE != entry->diskWriter->readData(buf, BUFSIZE, offset)) {
throw string("error");
}
sha1DigestUpdate(ctx, buf, BUFSIZE);
digestUpdate(ctx, buf, BUFSIZE);
offset += BUFSIZE;
}
int r = length%BUFSIZE;
@ -158,7 +159,7 @@ void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, l
if(r != entry->diskWriter->readData(buf, r, offset)) {
throw string("error");
}
sha1DigestUpdate(ctx, buf, r);
digestUpdate(ctx, buf, r);
}
}
#endif // ENABLE_SHA1DIGEST
@ -168,7 +169,7 @@ string MultiDiskWriter::sha1Sum(long long int offset, long long int length) {
long long int fileOffset = offset;
bool reading = false;
int rem = length;
sha1DigestReset(ctx);
digestReset(ctx);
try {
for(DiskWriterEntries::iterator itr = diskWriterEntries.begin();
itr != diskWriterEntries.end() && rem != 0; itr++) {
@ -186,7 +187,7 @@ string MultiDiskWriter::sha1Sum(long long int offset, long long int length) {
throw new DlAbortEx(EX_FILE_OFFSET_OUT_OF_RANGE, offset);
}
unsigned char hashValue[20];
sha1DigestFinal(ctx, hashValue);
digestFinal(ctx, hashValue);
return Util::toHex(hashValue, 20);
} catch(string ex) {
throw new DlAbortEx(EX_FILE_SHA1SUM, "", strerror(errno));

View File

@ -71,8 +71,8 @@ bool PeerConnection::receiveMessage(char* msg, int& length) {
}
//payloadLen = ntohl(nPayloadLen);
int payloadLength = ntohl(*((int*)lenbuf));
if(payloadLength > MAX_PAYLOAD_LEN) {
throw new DlAbortEx("max payload length exceeded. length = %d",
if(payloadLength > MAX_PAYLOAD_LEN || payloadLength < 0) {
throw new DlAbortEx("max payload length exceeded or invalid. length = %d",
payloadLength);
}
currentPayloadLength = payloadLength;

View File

@ -57,6 +57,9 @@ void PeerMessageUtil::checkLength(int length) {
throw new DlAbortEx("too large length %d > %dKB", length,
MAX_BLOCK_LENGTH/1024);
}
if(length <= 0) {
throw new DlAbortEx("invalid length %d", length);
}
if(!Util::isPowerOf(length, 2)) {
throw new DlAbortEx("invalid length %d, which is not power of 2",
length);

View File

@ -81,6 +81,7 @@ void PieceMessage::receivedAction() {
onGotNewPiece(piece);
} else {
onGotWrongPiece(piece);
peerInteraction->abortPiece(piece);
}
}
}

View File

@ -103,4 +103,6 @@ public:
};
typedef deque<Request*> Requests;
#endif // _D_REQUEST_H_

View File

@ -28,6 +28,7 @@
#include "Option.h"
#include "SegmentSplitter.h"
#include "DiskWriter.h"
#include "Request.h"
using namespace std;
@ -92,6 +93,7 @@ public:
const Option* option;
SegmentSplitter* splitter;
DiskWriter* diskWriter;
Requests reserved;
SegmentMan();
~SegmentMan();

View File

@ -24,56 +24,57 @@
ShaVisitor::ShaVisitor() {
#ifdef ENABLE_SHA1DIGEST
sha1DigestInit(ctx);
sha1DigestReset(ctx);
ctx.setAlgo(MessageDigestContext::ALGO_SHA1);
digestInit(ctx);
digestReset(ctx);
#endif // ENABLE_SHA1DIGEST
}
ShaVisitor::~ShaVisitor() {
#ifdef ENABLE_SHA1DIGEST
sha1DigestFree(ctx);
digestFree(ctx);
#endif // ENABLE_SHA1DIGEST
}
void ShaVisitor::visit(const Data* d) {
#ifdef ENABLE_SHA1DIGEST
if(d->isNumber()) {
sha1DigestUpdate(ctx, "i", 1);
digestUpdate(ctx, "i", 1);
} else {
string lenStr = Util::llitos(d->getLen());
sha1DigestUpdate(ctx, lenStr.c_str(), lenStr.size());
sha1DigestUpdate(ctx, ":", 1);
digestUpdate(ctx, lenStr.c_str(), lenStr.size());
digestUpdate(ctx, ":", 1);
}
sha1DigestUpdate(ctx, d->getData(), d->getLen());
digestUpdate(ctx, d->getData(), d->getLen());
if(d->isNumber()) {
sha1DigestUpdate(ctx, "e", 1);
digestUpdate(ctx, "e", 1);
}
#endif // ENABLE_SHA1DIGEST
}
void ShaVisitor::visit(const Dictionary* d) {
#ifdef ENABLE_SHA1DIGEST
sha1DigestUpdate(ctx, "d", 1);
digestUpdate(ctx, "d", 1);
const Order& v = d->getOrder();
for(Order::const_iterator itr = v.begin(); itr != v.end(); itr++) {
string lenStr = Util::llitos(itr->size());
sha1DigestUpdate(ctx, lenStr.c_str(), lenStr.size());
sha1DigestUpdate(ctx, ":", 1);
sha1DigestUpdate(ctx, itr->c_str(), itr->size());
digestUpdate(ctx, lenStr.c_str(), lenStr.size());
digestUpdate(ctx, ":", 1);
digestUpdate(ctx, itr->c_str(), itr->size());
const MetaEntry* e = d->get(*itr);
this->visit(e);
}
sha1DigestUpdate(ctx, "e", 1);
digestUpdate(ctx, "e", 1);
#endif // ENABLE_SHA1DIGEST
}
void ShaVisitor::visit(const List* l) {
#ifdef ENABLE_SHA1DIGEST
sha1DigestUpdate(ctx, "l", 1);
digestUpdate(ctx, "l", 1);
for(MetaList::const_iterator itr = l->getList().begin(); itr != l->getList().end(); itr++) {
this->visit(*itr);
}
sha1DigestUpdate(ctx, "e", 1);
digestUpdate(ctx, "e", 1);
#endif // ENABLE_SHA1DIGEST
}
@ -89,7 +90,7 @@ void ShaVisitor::visit(const MetaEntry* e) {
void ShaVisitor::getHash(unsigned char* hashValue, int& len) {
#ifdef ENABLE_SHA1DIGEST
sha1DigestFinal(ctx, hashValue);
digestFinal(ctx, hashValue);
len = 20;
#endif // ENABLE_SHA1DIGEST
}

View File

@ -23,9 +23,6 @@
#include "DlAbortEx.h"
#include "File.h"
#include "message.h"
#ifdef ENABLE_SHA1DIGEST
#include "messageDigest.h"
#endif // ENABLE_SHA1DIGEST
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -68,8 +65,8 @@ string Util::llitos(long long int value, bool comma)
}
string Util::trim(const string& src) {
string::size_type sp = src.find_first_not_of(" ");
string::size_type ep = src.find_last_not_of(" ");
string::size_type sp = src.find_first_not_of("\r\n\t ");
string::size_type ep = src.find_last_not_of("\r\n\t ");
if(sp == string::npos || ep == string::npos) {
return "";
} else {
@ -365,12 +362,47 @@ string Util::getContentDispositionFilename(const string& header) {
void Util::sha1Sum(unsigned char* digest, const void* data, int dataLength) {
#ifdef ENABLE_SHA1DIGEST
MessageDigestContext ctx;
sha1DigestInit(ctx);
sha1DigestReset(ctx);
sha1DigestUpdate(ctx, data, dataLength);
sha1DigestFinal(ctx, digest);
sha1DigestFree(ctx);
MessageDigestContext ctx(MessageDigestContext::ALGO_SHA1);
digestInit(ctx);
digestReset(ctx);
digestUpdate(ctx, data, dataLength);
digestFinal(ctx, digest);
digestFree(ctx);
#endif // ENABLE_SHA1DIGEST
}
void Util::fileChecksum(const string& filename, unsigned char* digest,
MessageDigestContext::HashAlgo algo) {
#ifdef ENABLE_SHA1DIGEST
MessageDigestContext ctx(algo);
digestInit(ctx);
digestReset(ctx);
int BUFLEN = 4096;
char buf[BUFLEN];
int fd;
if((fd = open(filename.c_str(), O_RDWR, S_IRUSR|S_IWUSR)) < 0) {
throw new DlAbortEx(EX_FILE_OPEN, filename.c_str(), strerror(errno));
}
while(1) {
int size = read(fd, buf, BUFLEN);
if(size == -1) {
if(errno == EINTR) {
continue;
} else {
close(fd);
throw new DlAbortEx(EX_FILE_READ, filename.c_str(), strerror(errno));
}
} else if(size > 0) {
digestUpdate(ctx, buf, size);
}
if(size < BUFLEN) {
break;
}
}
digestFinal(ctx, digest);
digestFree(ctx);
#endif // ENABLE_SHA1DIGEST
}
@ -471,3 +503,29 @@ string Util::randomAlpha(int length) {
}
return str;
}
class UpperCase {
public:
void operator()(char& ch) {
ch = toupper(ch);
}
};
string Util::toUpper(const string& src) {
string temp = src;
for_each(temp.begin(), temp.end(), UpperCase());
return temp;
}
class LowerCase {
public:
void operator()(char& ch) {
ch = tolower(ch);
}
};
string Util::toLower(const string& src) {
string temp = src;
for_each(temp.begin(), temp.end(), LowerCase());
return temp;
}

View File

@ -23,6 +23,9 @@
#define _D_UTIL_H_
#include "common.h"
#ifdef ENABLE_SHA1DIGEST
#include "messageDigest.h"
#endif // ENABLE_SHA1DIGEST
#include <string>
#include <utility>
#include <deque>
@ -82,12 +85,21 @@ public:
// digest must be at least 20 bytes long.
static void sha1Sum(unsigned char* digest, const void* data, int dataLength);
// Before call this method, allocate enough memory to the parameter "digest".
// For sha1, you need 20 bytes. For md5, 16 bytes.
static void fileChecksum(const string& filename, unsigned char* digest,
MessageDigestContext::HashAlgo algo);
static Integers computeFastSet(string ipaddr, const unsigned char* infoHash,
int pieces, int fastSetSize);
static int countBit(unsigned int);
static string randomAlpha(int length);
static string toUpper(const string& src);
static string toLower(const string& src);
};
#endif // _D_UTIL_H_

View File

@ -0,0 +1,188 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#include "Xml2MetalinkProcessor.h"
#include "DlAbortEx.h"
#include "Util.h"
#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
Xml2MetalinkProcessor::Xml2MetalinkProcessor():doc(NULL), context(NULL) {}
Xml2MetalinkProcessor::~Xml2MetalinkProcessor() {
release();
}
void Xml2MetalinkProcessor::release() {
if(context) {
xmlXPathFreeContext(context);
context = NULL;
}
if(doc) {
xmlFreeDoc(doc);
doc = NULL;
}
}
Metalinker* Xml2MetalinkProcessor::parseFile(const string& filename) {
release();
doc = xmlParseFile(filename.c_str());
if(doc == NULL) {
throw new DlAbortEx("Cannot parse metalink file %s", filename.c_str());
}
context = xmlXPathNewContext(doc);
if(context == NULL) {
throw new DlAbortEx("Cannot create new xpath context");
}
string defaultNamespace = "http://www.metalinker.org/";
if(xmlXPathRegisterNs(context, (xmlChar*)"m",
(xmlChar*)defaultNamespace.c_str()) != 0) {
throw new DlAbortEx("Cannot register namespace %s", defaultNamespace.c_str());
}
string xpath = "/m:metalink/m:files/m:file";
Metalinker* metalinker = new Metalinker();
try {
for(int index = 1; 1; index++) {
MetalinkEntry* entry = getEntry(xpath+"["+Util::itos(index)+"]");
if(entry == NULL) {
break;
} else {
metalinker->entries.push_back(entry);
}
}
} catch(Exception* e) {
delete metalinker;
throw;
}
return metalinker;
}
MetalinkEntry* Xml2MetalinkProcessor::getEntry(const string& xpath) {
xmlXPathObjectPtr result = xpathEvaluation(xpath);
if(result == NULL) {
return NULL;
}
xmlXPathFreeObject(result);
MetalinkEntry* entry = new MetalinkEntry();
try {
entry->version = Util::trim(xpathContent(xpath+"/m:version"));
entry->language = Util::trim(xpathContent(xpath+"/m:language"));
entry->os = Util::trim(xpathContent(xpath+"/m:os"));
entry->md5 = Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]"));
entry->sha1 = Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]"));
for(int index = 1; 1; index++) {
MetalinkResource* resource =
getResource(xpath+"/m:resources/m:url["+Util::itos(index)+"]");
if(resource == NULL) {
break;
} else {
entry->resources.push_back(resource);
}
}
} catch(Exception* e) {
delete entry;
throw;
}
return entry;
}
MetalinkResource* Xml2MetalinkProcessor::getResource(const string& xpath) {
xmlXPathObjectPtr result = xpathEvaluation(xpath);
if(result == NULL) {
return NULL;
}
MetalinkResource* resource = new MetalinkResource();
try {
xmlNodeSetPtr nodeSet = result->nodesetval;
xmlNodePtr node = nodeSet->nodeTab[0];
string type = Util::trim(xmlAttribute(node, "type"));
if(type == "ftp") {
resource->type = MetalinkResource::TYPE_FTP;
} else if(type == "http") {
resource->type = MetalinkResource::TYPE_HTTP;
} else if(type == "bittorrent") {
resource->type = MetalinkResource::TYPE_BITTORRENT;
} else {
resource->type = MetalinkResource::TYPE_NOT_SUPPORTED;
}
string pref = Util::trim(xmlAttribute(node, "preference"));
if(pref.empty()) {
resource->preference = 100;
} else {
resource->preference = STRTOLL(pref.c_str());
}
resource->url = Util::trim(xmlContent(node));
} catch(Exception* e) {
delete resource;
throw e;
}
return resource;
}
xmlXPathObjectPtr Xml2MetalinkProcessor::xpathEvaluation(const string& xpath) {
xmlXPathObjectPtr result = xmlXPathEvalExpression((xmlChar*)xpath.c_str(),
context);
if(result == NULL) {
throw new DlAbortEx("Cannot evaluate xpath %s", xpath.c_str());
}
if(xmlXPathNodeSetIsEmpty(result->nodesetval)) {
xmlXPathFreeObject(result);
return NULL;
}
return result;
}
string Xml2MetalinkProcessor::xmlAttribute(xmlNodePtr node, const string& attrName) {
xmlChar* temp = xmlGetNoNsProp(node, (xmlChar*)attrName.c_str());
if(temp == NULL) {
return "";
} else {
string attr = (char*)temp;
xmlFree(temp);
return attr;
}
}
string Xml2MetalinkProcessor::xmlContent(xmlNodePtr node) {
xmlChar* temp = xmlNodeGetContent(node);
if(temp == NULL) {
return "";
} else {
string content = (char*)temp;
xmlFree(temp);
return content;
}
}
string Xml2MetalinkProcessor::xpathContent(const string& xpath) {
xmlXPathObjectPtr result = xpathEvaluation(xpath);
if(result == NULL) {
return "";
}
xmlNodeSetPtr nodeSet = result->nodesetval;
xmlNodePtr node = nodeSet->nodeTab[0]->children;
string content = (char*)node->content;
xmlXPathFreeObject(result);
return content;
}

View File

@ -0,0 +1,51 @@
/* <!-- copyright */
/*
* aria2 - a simple utility for downloading files faster
*
* Copyright (C) 2006 Tatsuhiro Tsujikawa
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* copyright --> */
#ifndef _D_XML2_METALINK_PROCESSOR_H_
#define _D_XML2_METALINK_PROCESSOR_H_
#include "MetalinkProcessor.h"
#include <libxml/parser.h>
#include <libxml/xpath.h>
class Xml2MetalinkProcessor : public MetalinkProcessor {
private:
xmlDocPtr doc;
xmlXPathContextPtr context;
MetalinkEntry* getEntry(const string& xpath);
MetalinkResource* getResource(const string& xpath);
xmlXPathObjectPtr xpathEvaluation(const string& xpath);
string xpathContent(const string& xpath);
string xmlAttribute(xmlNodePtr node, const string& attrName);
string xmlContent(xmlNodePtr node);
void release();
public:
Xml2MetalinkProcessor();
virtual ~Xml2MetalinkProcessor();
virtual Metalinker* parseFile(const string& filename);
};
#endif // _D_XML2_METALINK_PROCESSOR_H_

View File

@ -37,6 +37,7 @@
#include "TrackerUpdateCommand.h"
#include "ByteArrayDiskWriter.h"
#include "PeerChokeCommand.h"
#include "Xml2MetalinkProcessor.h"
#include <deque>
#include <algorithm>
#include <time.h>
@ -59,7 +60,10 @@ extern int optind, opterr, optopt;
using namespace std;
typedef deque<Request*> Requests;
bool readyToTorrentMode = false;
string downloadedTorrentFile;
bool readyToMetalinkMode = false;
string downloadedMetalinkFile;
void printDownloadCompeleteMessage(string filename) {
printf(_("\nThe download was complete. <%s>\n"), filename.c_str());
@ -115,11 +119,10 @@ void torrentHandler(int signal) {
te->torrentMan->setHalt(true);
}
void addCommand(int cuid, const string& url, string referer, Requests& requests) {
void createRequest(int cuid, const string& url, string referer, Requests& requests) {
Request* req = new Request();
req->setReferer(referer);
if(req->setUrl(url)) {
e->commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuid, req, e));
requests.push_back(req);
} else {
fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"), req->getUrl().c_str());
@ -258,6 +261,54 @@ void showUsage() {
cout << endl;
}
bool normalDownload(const Requests& requests,
const Requests& reserved,
Option* op,
const string& dir,
const string& ufilename,
string& downloadedFilename) {
setSignalHander(SIGINT, handler, 0);
setSignalHander(SIGTERM, handler, 0);
e = new ConsoleDownloadEngine();
e->option = op;
e->segmentMan = new SegmentMan();
e->segmentMan->diskWriter = new DefaultDiskWriter();
e->segmentMan->dir = dir;
e->segmentMan->ufilename = ufilename;
e->segmentMan->option = op;
e->segmentMan->splitter = new SplitSlowestSegmentSplitter();
e->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
e->segmentMan->reserved = reserved;
int cuidCounter = 1;
for(Requests::const_iterator itr = requests.begin();
itr != requests.end();
itr++, cuidCounter++) {
e->commands.push_back(InitiateConnectionCommandFactory::createInitiateConnectionCommand(cuidCounter, *itr, e));
}
e->run();
bool success = false;
if(e->segmentMan->finished()) {
printDownloadCompeleteMessage(e->segmentMan->getFilePath());
if(Util::endsWith(e->segmentMan->getFilePath(), ".torrent")) {
downloadedTorrentFile = e->segmentMan->getFilePath();
readyToTorrentMode = true;
} else if(Util::endsWith(e->segmentMan->getFilePath(), ".metalink")) {
downloadedMetalinkFile = e->segmentMan->getFilePath();
readyToMetalinkMode = true;
}
downloadedFilename = e->segmentMan->getFilePath();
success = true;
} else {
printDownloadAbortMessage();
}
e->cleanQueue();
delete e;
return success;
}
int main(int argc, char* argv[]) {
#ifdef ENABLE_NLS
setlocale (LC_CTYPE, "");
@ -273,13 +324,23 @@ int main(int argc, char* argv[]) {
bool daemonMode = false;
string referer;
string torrentFile;
string metalinkFile;
int listenPort = -1;
string metalinkVersion;
string metalinkLanguage;
string metalinkOs;
int metalinkConnection = 15;
Integers selectFileIndexes;
#ifdef ENABLE_BITTORRENT
bool followTorrent = true;
#else
bool followTorrent = false;
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
bool followMetalink = true;
#else
bool followMetalink = false;
#endif // ENABLE_METALINK
int c;
Option* op = new Option();
@ -333,11 +394,15 @@ int main(int argc, char* argv[]) {
{ "upload-limit", required_argument, &lopt, 20 },
{ "select-file", required_argument, &lopt, 21 },
#endif // ENABLE_BITTORRENT
#ifdef ENABLE_METALINK
{ "metalink-file", required_argument, NULL, 'M' },
{ "metalink-connection", required_argument, NULL, 'C' },
#endif // ENABLE_METALINK
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "Dd:o:l:s:pt:m:vhST:", longOpts, &optIndex);
c = getopt_long(argc, argv, "Dd:o:l:s:pt:m:vhST:M:C:", longOpts, &optIndex);
if(c == -1) {
break;
}
@ -549,6 +614,17 @@ int main(int argc, char* argv[]) {
case 'T':
torrentFile = string(optarg);
break;
case 'M':
metalinkFile = string(optarg);
break;
case 'C':
metalinkConnection = (int)strtol(optarg, NULL, 10);
if(metalinkConnection <= 0) {
cerr << _("metalink-connection must be greater than 0.") << endl;
showUsage();
exit(1);
}
break;
case 'v':
showVersion();
exit(0);
@ -560,7 +636,7 @@ int main(int argc, char* argv[]) {
exit(1);
}
}
if(torrentFile.empty()) {
if(torrentFile.empty() && metalinkFile.empty()) {
if(optind == argc) {
cerr << _("specify at least one URL") << endl;
showUsage();
@ -584,6 +660,9 @@ int main(int argc, char* argv[]) {
#ifdef HAVE_LIBGNUTLS
gnutls_global_init();
#endif // HAVE_LIBGNUTLS
#ifdef HAVE_LIBXML2
xmlInitParser();
#endif // HAVE_LIBXML2
srandom(time(NULL));
if(stdoutLog) {
LogFactory::setLogFile("/dev/stdout");
@ -601,50 +680,76 @@ int main(int argc, char* argv[]) {
setSignalHander(SIGPIPE, SIG_IGN, 0);
bool readyToTorrentMode = false;
string downloadedTorrentFile;
if(torrentFile.empty()) {
setSignalHander(SIGINT, handler, 0);
setSignalHander(SIGTERM, handler, 0);
e = new ConsoleDownloadEngine();
e->option = op;
e->segmentMan = new SegmentMan();
e->segmentMan->diskWriter = new DefaultDiskWriter();
e->segmentMan->dir = dir;
e->segmentMan->ufilename = ufilename;
e->segmentMan->option = op;
e->segmentMan->splitter = new SplitSlowestSegmentSplitter();
e->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE));
if(torrentFile.empty() && metalinkFile.empty()) {
Requests requests;
int cuidCounter = 1;
for(Strings::const_iterator itr = args.begin(); itr != args.end(); itr++) {
for(int s = 1; s <= split; s++) {
addCommand(cuidCounter, *itr, referer, requests);
createRequest(cuidCounter, *itr, referer, requests);
cuidCounter++;
}
}
setSignalHander(SIGINT, handler, 0);
setSignalHander(SIGTERM, handler, 0);
e->run();
Requests reserved;
string downloadedFilename;
normalDownload(requests, reserved, op, dir, ufilename, downloadedFilename);
for_each(requests.begin(), requests.end(), Deleter());
requests.clear();
}
if(!metalinkFile.empty() || followMetalink && readyToMetalinkMode) {
string targetMetalinkFile = metalinkFile.empty() ?
downloadedMetalinkFile : metalinkFile;
Xml2MetalinkProcessor proc;
Metalinker* metalinker = proc.parseFile(targetMetalinkFile);
if(e->segmentMan->finished()) {
printDownloadCompeleteMessage(e->segmentMan->getFilePath());
if(Util::endsWith(e->segmentMan->getFilePath(), ".torrent")) {
downloadedTorrentFile = e->segmentMan->getFilePath();
readyToTorrentMode = true;
}
} else {
printDownloadAbortMessage();
MetalinkEntry* entry = metalinker->queryEntry(metalinkVersion,
metalinkLanguage,
metalinkOs);
if(entry == NULL) {
printf("No file matched with your preference");
exit(1);
}
entry->dropUnsupportedResource();
entry->reorderResourcesByPreference();
Requests requests;
int cuidCounter = 1;
for(MetalinkResources::const_iterator itr = entry->resources.begin();
itr != entry->resources.end(); itr++) {
MetalinkResource* resource = *itr;
createRequest(cuidCounter, resource->url, referer, requests);
cuidCounter++;
}
Requests reserved;
if((int)requests.size() > metalinkConnection) {
copy(requests.begin()+metalinkConnection, requests.end(),
insert_iterator<Requests>(reserved, reserved.end()));
requests.erase(requests.begin()+metalinkConnection, requests.end());
}
setSignalHander(SIGINT, handler, 0);
setSignalHander(SIGTERM, handler, 0);
string downloadedFilename;
bool success = normalDownload(requests, reserved, op, dir, ufilename,
downloadedFilename);
for_each(requests.begin(), requests.end(), Deleter());
requests.clear();
e->cleanQueue();
delete e;
}
if(!torrentFile.empty() || followTorrent && readyToTorrentMode) {
if(success) {
if(entry->check(downloadedFilename)) {
printf("checksum OK.\n");
} else {
printf("checksum ERROR.\n");
exit(EXIT_FAILURE);
}
}
delete metalinker;
} else if(!torrentFile.empty() || followTorrent && readyToTorrentMode) {
try {
//op->put(PREF_MAX_TRIES, "0");
setSignalHander(SIGINT, torrentHandler, SA_RESETHAND);
@ -735,5 +840,8 @@ int main(int argc, char* argv[]) {
#ifdef HAVE_LIBGNUTLS
gnutls_global_deinit();
#endif // HAVE_LIBGNUTLS
#ifdef HAVE_LIBXML2
xmlCleanupParser();
#endif // HAVE_LIBXML2
return 0;
}

View File

@ -28,30 +28,79 @@
#ifdef HAVE_LIBSSL
#include <openssl/evp.h>
#define MessageDigestContext EVP_MD_CTX
#define sha1DigestInit(CTX) EVP_MD_CTX_init(&CTX)
#define sha1DigestReset(CTX) EVP_DigestInit_ex(&CTX, EVP_sha1(), NULL)
#define sha1DigestUpdate(CTX, DATA, LENGTH) EVP_DigestUpdate(&CTX, DATA, LENGTH)
#define sha1DigestFinal(CTX, HASH) \
{\
int len;\
EVP_DigestFinal_ex(&CTX, HASH, (unsigned int*)&len);\
}
#define sha1DigestFree(CTX) EVP_MD_CTX_cleanup(&CTX)
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
#include <gcrypt.h>
#define MessageDigestContext gcry_md_hd_t
#define sha1DigestInit(CTX) gcry_md_open(&CTX, GCRY_MD_SHA1, 0)
#define sha1DigestReset(CTX) gcry_md_reset(CTX)
#define sha1DigestUpdate(CTX, DATA, LENGTH) gcry_md_write(CTX, DATA, LENGTH)
#define sha1DigestFinal(CTX, HASH) \
#endif // HAVE_LIBGCRYPT
class MessageDigestContext {
public:
enum HashAlgo {
ALGO_MD5,
ALGO_SHA1
};
#ifdef HAVE_LIBSSL
EVP_MD_CTX ctx;
const EVP_MD* algo;
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
gcry_md_hd_t ctx;
int algo;
#endif // HAVE_LIBGCRYPT
MessageDigestContext() {}
MessageDigestContext(HashAlgo algo) {
setAlgo(algo);
}
void setAlgo(HashAlgo algo) {
switch(algo) {
case ALGO_MD5:
#ifdef HAVE_LIBSSL
this->algo = EVP_md5();
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
this->algo = GCRY_MD_MD5;
#endif // HAVE_LIBGCRYPT
break;
case ALGO_SHA1:
#ifdef HAVE_LIBSSL
this->algo = EVP_sha1();
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
this->algo = GCRY_MD_SHA1;
#endif // HAVE_LIBGCRYPT
break;
default:
break;
}
}
};
#ifdef HAVE_LIBSSL
#define digestInit(CTX) EVP_MD_CTX_init(&CTX.ctx)
#define digestReset(CTX) EVP_DigestInit_ex(&CTX.ctx, CTX.algo, NULL)
#define digestUpdate(CTX, DATA, LENGTH) EVP_DigestUpdate(&CTX.ctx, DATA, LENGTH)
#define digestFinal(CTX, HASH) \
{\
gcry_md_final(CTX);\
memcpy(HASH, gcry_md_read(CTX, 0), 20);\
int len;\
EVP_DigestFinal_ex(&CTX.ctx, HASH, (unsigned int*)&len);\
}
#define sha1DigestFree(CTX) gcry_md_close(CTX)
#define digestFree(CTX) EVP_MD_CTX_cleanup(&CTX.ctx)
#endif // HAVE_LIBSSL
#ifdef HAVE_LIBGCRYPT
#define digestInit(CTX) gcry_md_open(&CTX.ctx, CTX.algo, 0)
#define digestReset(CTX) gcry_md_reset(CTX.ctx)
#define digestUpdate(CTX, DATA, LENGTH) gcry_md_write(CTX.ctx, DATA, LENGTH)
#define digestFinal(CTX, HASH) \
{\
gcry_md_final(CTX.ctx);\
memcpy(HASH, gcry_md_read(CTX.ctx, 0), gcry_md_get_algo_dlen(CTX.algo));\
}
#define digestFree(CTX) gcry_md_close(CTX.ctx)
#endif // HAVE_LIBGCRYPT
#endif // ENABLE_BITTORRENT

View File

@ -26,6 +26,14 @@ CPPUNIT_TEST_SUITE_REGISTRATION( Base64Test );
void Base64Test::testEncode() {
CPPUNIT_ASSERT_EQUAL(string("SGVsbG8gV29ybGQh"),
Base64::encode("Hello World!"));
CPPUNIT_ASSERT_EQUAL(string("SGVsbG8gV29ybGQ="),
Base64::encode("Hello World"));
CPPUNIT_ASSERT_EQUAL(string("SGVsbG8gV29ybA=="),
Base64::encode("Hello Worl"));
CPPUNIT_ASSERT_EQUAL(string("YQ=="),
Base64::encode("a"));
CPPUNIT_ASSERT_EQUAL(string(""),
Base64::encode(""));
}
void Base64Test::testDecode() {

View File

@ -31,16 +31,19 @@ aria2c_SOURCES = AllTest.cc\
PieceMessageTest.cc\
RejectMessageTest.cc\
AllowedFastMessageTest.cc\
SuggestPieceMessageTest.cc
SuggestPieceMessageTest.cc\
Xml2MetalinkProcessorTest.cc\
MetalinkerTest.cc\
MetalinkEntryTest.cc
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS}
aria2c_LDADD = ../src/libaria2c.a\
${CPPUNIT_LIBS} @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
AM_CPPFLAGS = -Wall\
${CPPUNIT_CFLAGS}\
-I ../src\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@

View File

@ -71,7 +71,9 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \
BitfieldMessageTest.$(OBJEXT) RequestMessageTest.$(OBJEXT) \
CancelMessageTest.$(OBJEXT) PieceMessageTest.$(OBJEXT) \
RejectMessageTest.$(OBJEXT) AllowedFastMessageTest.$(OBJEXT) \
SuggestPieceMessageTest.$(OBJEXT)
SuggestPieceMessageTest.$(OBJEXT) \
Xml2MetalinkProcessorTest.$(OBJEXT) MetalinkerTest.$(OBJEXT) \
MetalinkEntryTest.$(OBJEXT)
aria2c_OBJECTS = $(am_aria2c_OBJECTS)
am__DEPENDENCIES_1 =
aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@ -168,6 +170,9 @@ USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
XML2_CONFIG = @XML2_CONFIG@
XML_CPPFLAGS = @XML_CPPFLAGS@
XML_LIBS = @XML_LIBS@
YACC = @YACC@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
@ -243,19 +248,22 @@ aria2c_SOURCES = AllTest.cc\
PieceMessageTest.cc\
RejectMessageTest.cc\
AllowedFastMessageTest.cc\
SuggestPieceMessageTest.cc
SuggestPieceMessageTest.cc\
Xml2MetalinkProcessorTest.cc\
MetalinkerTest.cc\
MetalinkEntryTest.cc
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS}
aria2c_LDADD = ../src/libaria2c.a\
${CPPUNIT_LIBS} @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@
AM_CPPFLAGS = -Wall\
${CPPUNIT_CFLAGS}\
-I ../src\
-I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@
all: all-am
@ -323,6 +331,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InterestedMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ListTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetaFileUtilTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkEntryTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MetalinkerTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultiDiskWriterTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NotInterestedMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OptionTest.Po@am__quote@
@ -336,6 +346,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentManTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Xml2MetalinkProcessorTest.Po@am__quote@
.cc.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \

View File

@ -17,6 +17,9 @@ class UtilTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testGetContentDispositionFilename);
CPPUNIT_TEST(testComputeFastSet);
CPPUNIT_TEST(testRandomAlpha);
CPPUNIT_TEST(testFileChecksum);
CPPUNIT_TEST(testToUpper);
CPPUNIT_TEST(testToLower);
CPPUNIT_TEST_SUITE_END();
private:
@ -34,6 +37,9 @@ public:
// may be moved to other helper class in the future.
void testGetContentDispositionFilename();
void testRandomAlpha();
void testFileChecksum();
void testToUpper();
void testToLower();
};
@ -214,3 +220,31 @@ void UtilTest::testComputeFastSet() {
void UtilTest::testRandomAlpha() {
CPPUNIT_ASSERT_EQUAL(string("rUopvKRn"), Util::randomAlpha(8));
}
void UtilTest::testFileChecksum() {
unsigned char buf[20];
string filename = "4096chunk.txt";
Util::fileChecksum(filename, buf, MessageDigestContext::ALGO_SHA1);
string sha1 = Util::toHex(buf, 20);
CPPUNIT_ASSERT_EQUAL(string("608cabc0f2fa18c260cafd974516865c772363d5"),
sha1);
Util::fileChecksum(filename, buf, MessageDigestContext::ALGO_MD5);
string md5 = Util::toHex(buf, 16);
CPPUNIT_ASSERT_EQUAL(string("82a7348c2e03731109d0cf45a7325b88"),
md5);
}
void UtilTest::testToUpper() {
string src = "608cabc0f2fa18c260cafd974516865c772363d5";
string upp = "608CABC0F2FA18C260CAFD974516865C772363D5";
CPPUNIT_ASSERT_EQUAL(upp, Util::toUpper(src));
}
void UtilTest::testToLower() {
string src = "608CABC0F2FA18C260CAFD974516865C772363D5";
string upp = "608cabc0f2fa18c260cafd974516865c772363d5";
CPPUNIT_ASSERT_EQUAL(upp, Util::toLower(src));
}