mirror of
https://github.com/aria2/aria2.git
synced 2025-01-04 09:03:46 +00:00
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:
parent
003a474357
commit
78eff23254
72
ChangeLog
72
ChangeLog
@ -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
|
||||
|
@ -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
3
TODO
@ -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
189
aclocal.m4
vendored
@ -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, µ) != 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
|
||||
|
@ -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
340
configure
vendored
@ -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, µ) != 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
|
||||
|
12
configure.ac
12
configure.ac
@ -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
|
||||
|
@ -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@
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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_
|
||||
|
@ -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@
|
@ -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
81
src/MetalinkEntry.cc
Normal 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
55
src/MetalinkEntry.h
Normal 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
35
src/MetalinkProcessor.h
Normal 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
26
src/MetalinkResource.cc
Normal 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
47
src/MetalinkResource.h
Normal 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
74
src/Metalinker.cc
Normal 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
46
src/Metalinker.h
Normal 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_
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -81,6 +81,7 @@ void PieceMessage::receivedAction() {
|
||||
onGotNewPiece(piece);
|
||||
} else {
|
||||
onGotWrongPiece(piece);
|
||||
peerInteraction->abortPiece(piece);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,4 +103,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
typedef deque<Request*> Requests;
|
||||
|
||||
#endif // _D_REQUEST_H_
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
}
|
||||
|
80
src/Util.cc
80
src/Util.cc
@ -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;
|
||||
}
|
||||
|
12
src/Util.h
12
src/Util.h
@ -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_
|
||||
|
188
src/Xml2MetalinkProcessor.cc
Normal file
188
src/Xml2MetalinkProcessor.cc
Normal 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;
|
||||
}
|
51
src/Xml2MetalinkProcessor.h
Normal file
51
src/Xml2MetalinkProcessor.h
Normal 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_
|
180
src/main.cc
180
src/main.cc
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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@
|
||||
|
@ -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 $@ $<; \
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user