diff --git a/ChangeLog b/ChangeLog index 7a3e0c00..23f08517 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,119 @@ +2006-08-08 Tatsuhiro Tsujikawa + + * src/FtpNegotiateCommand.cc + (recvGreeting): Call disableWriteCheckSocket just after + socket->setBlockingMode(). This avoids unnecessary CPU-hog loop. + +2006-08-07 Tatsuhiro Tsujikawa + + * src/PeerChokeCommand.h + (PeerChokeCommand): Rearranged the arguments. + * src/PeerChokeCommand.cc + (PeerChokeCommand): Rearranged the arguments. + + * src/MetalinkEntry.h + (Checksum.h): Included. + (md5): Removed. + (sha1): Removed. + (checksum): New variable. + (operator=): Updated. + (check): Removed. + + * src/prefs.h + (PREF_LOWEST_SPEED_LIMIT): New definition. + (PREF_FOLLOW_TORRENT): New definition. + (PREF_SELECT_FILE): New definition. + (PREF_FOLLOW_METALINK): New definition. + + * src/MetalinkResource.h + (TYPE_HTTPS): Added to enum TYPE. + + * src/TorrentMan.cc + (~TorrentMan): Rewritten. + + * src/MultiDiskWriter.cc + (MultiDiskAdaptor): Updated according to the changes in + MessageDigestContext. + (~MultiDiskAdaptor): Updated according to the changes in + MessageDigestContext. + (hashUpdate): Updated according to the changes in MessageDigestContext. + (sha1Sum): Updated according to the changes in MessageDigestContext. + + * src/Util.h + (fileChecksum): Updated according to the changes in + MessageDigestContext. + * src/Util.cc + (sha1Sum): Updated according to the changes in MessageDigestContext. + (fileChecksum): Updated according to the changes in + MessageDigestContext. + + * src/messageDigest.h: Rewritten. + + * src/MetalinkEntry.cc + (check): Removed. + (Supported): Updated. + (dropUnsupportedResource): Fixed a memory leak. + + * src/ShaVisitor.cc + (ShaVisitor): Updated according to the changes in MessageDigestContext. + (~ShaVisitor): Updated according to the changes in + MessageDigestContext. + (visit): Updated according to the changes in MessageDigestContext. + + * src/main.cc + (main): Rewritten the portion of download loop. --lowest-speed-limit + command-line option added. + + * src/DownloadEngine.h + (SocketEntry): New class. + (SocketEntries): New definition. + (PairFind): Removed. + (SockCmdMap): Removed. + * src/DownloadEngine.cc + (DownloadEngine): Rewritten. + (~DownloadEngine): Rewritten. + (run): Renamed activeCommandUuids as activeUuids. + (SetDescriptor): Rewritten. + (AccumulateActiveCommandUuid): Removed. + (AccumulateActiveUuid): New function object. + (waitData): Rewritten. + (updateFdSet): Rewritten. + (addSocket): Rewritten. + (deleteSocket): Rewritten. + (addSocketForReadCheck): Rewritten. + (deleteSocketForReadCheck): Rewritten. + (addSocketForWriteCheck): Rewritten. + (deleteSocketForWriteCheck): Rewritten. + + * src/Xml2MetalinkProcessor.cc + (getEntry): Rewritten the portion of MetalinkEntry creation. + + * src/DownloadCommand.cc + (executeInternal): Added the check routine for lowest speed limit. + + * src/AbstractDiskWriter.cc + (AbstractDiskWriter): Updated according to the changes in + MessageDigestContext. + (~AbstractDiskWriter): Updated according to the changes in + MessageDigestContext. + (sha1Sum): Updated according to the changes in MessageDigestContext. + + * src/RequestInfo.h: New class. + + * src/UrlRequestInfo.h: New class. + * src/UrlRequestInfo.cc: New class. + + * src/TorrentRequestInfo.h: New class. + * src/TorrentRequestInfo.cc: New class. + + * src/MetalinkRequestInfo.h: New class. + * src/MetalinkRequestInfo.cc: New class. + + * src/Checksum.h: New class. + + * src/DownloadEngineFactory.h: New class. + * src/DownloadEngineFactory.cc: New class. + 2006-08-03 Tatsuhiro Tsujikawa * src/Option.h diff --git a/TODO b/TODO index 44ec8097..ab8cf7c3 100644 --- a/TODO +++ b/TODO @@ -10,8 +10,7 @@ * Add max peers command-line option * Refacturing HttpConnection and FtpConnection * Query resource by location -* Log version * List available os, version, etc for metalink -* bittorrent in metalink * rename Time to something appropriate * ipv6(RFC2428 for ftp) +* add ru.po diff --git a/configure b/configure index 7b37a431..196d67ce 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for aria2c 0.6.1. +# Generated by GNU Autoconf 2.59 for aria2c 0.7.0. # # Report bugs to . # @@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='aria2c' PACKAGE_TARNAME='aria2c' -PACKAGE_VERSION='0.6.1' -PACKAGE_STRING='aria2c 0.6.1' +PACKAGE_VERSION='0.7.0' +PACKAGE_STRING='aria2c 0.7.0' PACKAGE_BUGREPORT='tujikawa@rednoah.com' ac_unique_file="src/Socket.h" @@ -788,7 +788,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures aria2c 0.6.1 to adapt to many kinds of systems. +\`configure' configures aria2c 0.7.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -854,7 +854,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of aria2c 0.6.1:";; + short | recursive ) echo "Configuration of aria2c 0.7.0:";; esac cat <<\_ACEOF @@ -1000,7 +1000,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -aria2c configure 0.6.1 +aria2c configure 0.7.0 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -1014,7 +1014,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by aria2c $as_me 0.6.1, which was +It was created by aria2c $as_me 0.7.0, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1657,7 +1657,7 @@ fi # Define the identity of the package. PACKAGE='aria2c' - VERSION='0.6.1' + VERSION='0.7.0' cat >>confdefs.h <<_ACEOF @@ -1927,7 +1927,7 @@ localedir=${datadir}/locale # Check whether --with-gnutls or --without-gnutls was given. if test "${with_gnutls+set}" = set; then withval="$with_gnutls" - with_gnutls=$enableval + with_gnutls=$withval else with_gnutls=yes fi; @@ -1935,7 +1935,7 @@ fi; # Check whether --with-openssl or --without-openssl was given. if test "${with_openssl+set}" = set; then withval="$with_openssl" - with_openssl=$enableval + with_openssl=$withval else with_openssl=yes fi; @@ -1943,7 +1943,7 @@ fi; # Check whether --with-libxml2 or --without-libxml2 was given. if test "${with_libxml2+set}" = set; then withval="$with_libxml2" - with_libxml2=$enableval + with_libxml2=$withval else with_libxml2=yes fi; @@ -11943,7 +11943,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by aria2c $as_me 0.6.1, which was +This file was extended by aria2c $as_me 0.7.0, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12006,7 +12006,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -aria2c config.status 0.6.1 +aria2c config.status 0.7.0 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.ac b/configure.ac index 483e91ed..f6e40949 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. # AC_PREREQ(2.59) -AC_INIT(aria2c, 0.6.1, tujikawa@rednoah.com) +AC_INIT(aria2c, 0.7.0, tujikawa@rednoah.com) AM_INIT_AUTOMAKE() AM_PATH_CPPUNIT(1.10.2) AC_CONFIG_SRCDIR([src/Socket.h]) @@ -13,9 +13,9 @@ localedir=${datadir}/locale 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]) +AC_ARG_WITH([gnutls], [ --with-gnutls use gnutls library if installed. Default: yes], [with_gnutls=$withval], [with_gnutls=yes]) +AC_ARG_WITH([openssl], [ --with-openssl use openssl library if installed. Default: yes], [with_openssl=$withval], [with_openssl=yes]) +AC_ARG_WITH([libxml2], [ --with-libxml2 use libxml2 library if installed. Default: yes], [with_libxml2=$withval], [with_libxml2=yes]) AC_ARG_ENABLE([bittorrent], [ --enable-bittorrent enable BitTorrent support. Default: yes], [enable_bittorrent=$enableval], [enable_bittorrent=yes]) AC_ARG_ENABLE([metalink], [ --enable-metalink enable Metalink support. Default: yes], [enable_metalink=$enableval], [enable_metalink=yes]) diff --git a/po/POTFILES b/po/POTFILES index ea42be2c..f73cc6a1 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,2 +1,6 @@ + ../src/RequestInfo.h \ ../src/message.h \ + ../src/DownloadEngineFactory.cc \ + ../src/TorrentRequestInfo.cc \ + ../src/UrlRequestInfo.cc \ ../src/main.cc diff --git a/po/POTFILES.in b/po/POTFILES.in index 7e010fe0..8c87df31 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,2 +1,6 @@ +src/RequestInfo.h src/message.h +src/DownloadEngineFactory.cc +src/TorrentRequestInfo.cc +src/UrlRequestInfo.cc src/main.cc diff --git a/po/aria2c.pot b/po/aria2c.pot index b9fe287b..43838c16 100644 --- a/po/aria2c.pot +++ b/po/aria2c.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n" -"POT-Creation-Date: 2006-07-21 00:57+0900\n" +"POT-Creation-Date: 2006-08-07 22:15+0900\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,6 +16,19 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" +#: src/RequestInfo.h:76 +#, c-format +msgid "" +"\n" +"The download was complete. <%s>\n" +msgstr "" + +#: src/RequestInfo.h:84 +msgid "" +"\n" +"The download was not complete because of errors. Check the log.\n" +msgstr "" + #: src/message.h:27 #, c-format msgid "CUID#%d - The download for one segment completed successfully." @@ -329,39 +342,34 @@ msgstr "" msgid "Failed to peek data, cause: %s" msgstr "" -#: src/main.cc:76 -#, c-format -msgid "" -"\n" -"The download was complete. <%s>\n" +#: src/DownloadEngineFactory.cc:102 +msgid "Errors occurred while binding port.\n" msgstr "" -#: src/main.cc:84 -msgid "" -"\n" -"The download was not complete because of errors. Check the log.\n" +#: src/TorrentRequestInfo.cc:71 +msgid "Files:" msgstr "" -#: src/main.cc:101 +#: src/UrlRequestInfo.cc:57 msgid "" "\n" "stopping application...\n" msgstr "" -#: src/main.cc:107 +#: src/UrlRequestInfo.cc:62 msgid "done\n" msgstr "" -#: src/main.cc:123 +#: src/UrlRequestInfo.cc:86 #, c-format msgid "Unrecognized URL or unsupported protocol: %s\n" msgstr "" -#: src/main.cc:129 +#: src/main.cc:71 msgid " version " msgstr "" -#: src/main.cc:133 +#: src/main.cc:78 msgid "" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" @@ -378,50 +386,50 @@ msgid "" "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" msgstr "" -#: src/main.cc:147 +#: src/main.cc:92 #, c-format msgid "Contact Info: %s\n" msgstr "" -#: src/main.cc:153 +#: src/main.cc:98 #, c-format msgid "Usage: %s [options] URL ...\n" msgstr "" -#: src/main.cc:155 +#: src/main.cc:100 #, c-format msgid " %s [options] -T TORRENT_FILE FILE ...\n" msgstr "" -#: src/main.cc:158 +#: src/main.cc:103 #, c-format msgid " %s [options] -M METALINK_FILE\n" msgstr "" -#: src/main.cc:161 +#: src/main.cc:106 msgid "Options:" msgstr "" -#: src/main.cc:162 +#: src/main.cc:107 msgid " -d, --dir=DIR The directory to store downloaded file." msgstr "" -#: src/main.cc:163 +#: src/main.cc:108 msgid " -o, --out=FILE The file name for downloaded file." msgstr "" -#: src/main.cc:164 +#: src/main.cc:109 msgid "" " -l, --log=LOG The file path to store log. If '-' is " "specified,\n" " log is written to stdout." msgstr "" -#: src/main.cc:166 +#: src/main.cc:111 msgid " -D, --daemon Run as daemon." msgstr "" -#: src/main.cc:167 +#: src/main.cc:112 msgid "" " -s, --split=N Download a file using N connections. N must " "be\n" @@ -431,65 +439,65 @@ msgid "" " N connections." msgstr "" -#: src/main.cc:171 +#: src/main.cc:116 msgid "" " --retry-wait=SEC Set amount of time in second between requests\n" " for errors. Specify a value between 0 and 60.\n" " Default: 5" msgstr "" -#: src/main.cc:174 +#: src/main.cc:119 msgid " -t, --timeout=SEC Set timeout in second. Default: 60" msgstr "" -#: src/main.cc:175 +#: src/main.cc:120 msgid "" " -m, --max-tries=N Set number of tries. 0 means unlimited.\n" " Default: 5" msgstr "" -#: src/main.cc:177 +#: src/main.cc:122 msgid "" " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n" " K or M(1K = 1024, 1M = 1024K). This\n" " value must be greater than or equal to\n" -" 1024." +" 1024. Default: 1M" msgstr "" -#: src/main.cc:181 +#: src/main.cc:126 msgid "" " --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all\n" " URLs." msgstr "" -#: src/main.cc:183 +#: src/main.cc:128 msgid " --http-user=USER Set HTTP user. This affects to all URLs." msgstr "" -#: src/main.cc:184 +#: src/main.cc:129 msgid "" " --http-passwd=PASSWD Set HTTP password. This affects to all URLs." msgstr "" -#: src/main.cc:185 +#: src/main.cc:130 msgid "" " --http-proxy-user=USER Set HTTP proxy user. This affects to all URLs" msgstr "" -#: src/main.cc:186 +#: src/main.cc:131 msgid "" " --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects to all " "URLs." msgstr "" -#: src/main.cc:187 +#: src/main.cc:132 msgid "" " --http-proxy-method=METHOD Set the method to use in proxy request.\n" " METHOD is either 'get' or 'tunnel'.\n" " Default: tunnel" msgstr "" -#: src/main.cc:190 +#: src/main.cc:135 msgid "" " --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, " "basic\n" @@ -497,23 +505,23 @@ msgid "" " Default: basic" msgstr "" -#: src/main.cc:193 +#: src/main.cc:138 msgid " --referer=REFERER Set Referer. This affects to all URLs." msgstr "" -#: src/main.cc:194 +#: src/main.cc:139 msgid "" " --ftp-user=USER Set FTP user. This affects to all URLs.\n" " Default: anonymous" msgstr "" -#: src/main.cc:196 +#: src/main.cc:141 msgid "" " --ftp-passwd=PASSWD Set FTP password. This affects to all URLs.\n" " Default: ARIA2USER@" msgstr "" -#: src/main.cc:198 +#: src/main.cc:143 msgid "" " --ftp-type=TYPE Set FTP transfer type. TYPE is either " "'binary'\n" @@ -521,11 +529,11 @@ msgid "" " Default: binary" msgstr "" -#: src/main.cc:201 +#: src/main.cc:146 msgid " -p, --ftp-pasv Use passive mode in FTP." msgstr "" -#: src/main.cc:202 +#: src/main.cc:147 msgid "" " --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' " "or\n" @@ -533,11 +541,26 @@ msgid "" " Default: tunnel" msgstr "" -#: src/main.cc:206 +#: src/main.cc:150 +msgid "" +" --lowest-speed-limit Close connection if download speed is lower " +"than\n" +" or equal to this value. 0 means aria2 does " +"not\n" +" care lowest speed limit. You can use K or M " +"in\n" +" the same manner as in --min-segment-size " +"option.\n" +" This option does not affect BitTorrent " +"download.\n" +" Default: 0" +msgstr "" + +#: src/main.cc:157 msgid " -T, --torrent-file=TORRENT_FILE The file path to .torrent file." msgstr "" -#: src/main.cc:207 +#: src/main.cc:158 msgid "" " --follow-torrent=true|false Setting this option to false prevents aria2 " "to\n" @@ -546,25 +569,25 @@ msgid "" " Default: true" msgstr "" -#: src/main.cc:211 +#: src/main.cc:162 msgid "" " -S, --show-files Print file listing of .torrent file and exit." msgstr "" -#: src/main.cc:212 +#: src/main.cc:163 msgid "" " --direct-file-mapping=true|false Directly read from and write to each file\n" " mentioned in .torrent file.\n" " Default: true" msgstr "" -#: src/main.cc:215 +#: src/main.cc:166 msgid "" " --listen-port=PORT Set port number to listen to for peer " "connection." msgstr "" -#: src/main.cc:216 +#: src/main.cc:167 msgid "" " --upload-limit=SPEED Set upload speed limit in KB/sec. aria2 tries " "to\n" @@ -572,7 +595,7 @@ msgid "" "unlimited." msgstr "" -#: src/main.cc:218 +#: src/main.cc:169 msgid "" " --select-file=INDEX... Set file to download by specifing its index.\n" " You can know file index through --show-files\n" @@ -584,11 +607,11 @@ msgid "" " ',' and '-' can be used together." msgstr "" -#: src/main.cc:226 +#: src/main.cc:177 msgid " -M, --metalink-file=METALINK_FILE The file path to .metalink file." msgstr "" -#: src/main.cc:227 +#: src/main.cc:178 msgid "" " -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n" " simultaneously. If more than one connection " @@ -597,20 +620,20 @@ msgid "" " Default: 15" msgstr "" -#: src/main.cc:231 +#: src/main.cc:182 msgid " --metalink-version=VERSION The version of file to download." msgstr "" -#: src/main.cc:232 +#: src/main.cc:183 msgid " --metalink-language=LANGUAGE The language of file to download." msgstr "" -#: src/main.cc:233 +#: src/main.cc:184 msgid "" " --metalink-os=OS The operating system the file is targeted." msgstr "" -#: src/main.cc:234 +#: src/main.cc:185 msgid "" " --follow-metalink=true|false Setting this option to false prevents aria2 " "to\n" @@ -619,155 +642,151 @@ msgid "" " Default: true" msgstr "" -#: src/main.cc:239 +#: src/main.cc:190 msgid " -v, --version Print the version number and exit." msgstr "" -#: src/main.cc:240 +#: src/main.cc:191 msgid " -h, --help Print this message and exit." msgstr "" -#: src/main.cc:243 +#: src/main.cc:194 msgid "" " You can specify multiple URLs. All URLs must point to the same file\n" " or downloading fails." msgstr "" -#: src/main.cc:248 +#: src/main.cc:199 msgid "" " Specify files in multi-file torrent to download. Use conjunction with\n" " -T option. This arguments are ignored if you specify --select-file option." msgstr "" -#: src/main.cc:252 +#: src/main.cc:203 msgid "Examples:" msgstr "" -#: src/main.cc:253 +#: src/main.cc:204 msgid " Download a file by 1 connection:" msgstr "" -#: src/main.cc:255 +#: src/main.cc:206 msgid " Download a file by 2 connections:" msgstr "" -#: src/main.cc:257 +#: src/main.cc:208 msgid " Download a file by 2 connections, each connects to a different server:" msgstr "" -#: src/main.cc:259 +#: src/main.cc:210 msgid " You can mix up different protocols:" msgstr "" -#: src/main.cc:263 +#: src/main.cc:214 msgid " Download a torrent:" msgstr "" -#: src/main.cc:265 +#: src/main.cc:216 msgid " Download a torrent using local .torrent file:" msgstr "" -#: src/main.cc:267 +#: src/main.cc:218 msgid " Download only selected files:" msgstr "" -#: src/main.cc:269 +#: src/main.cc:220 msgid " Print file listing of .torrent file:" msgstr "" -#: src/main.cc:274 +#: src/main.cc:225 msgid " Metalink downloading:" msgstr "" -#: src/main.cc:276 +#: src/main.cc:227 msgid " Download a file using local .metalink file:" msgstr "" -#: src/main.cc:278 +#: src/main.cc:229 msgid " Metalink downloading with preferences:" msgstr "" -#: src/main.cc:282 +#: src/main.cc:233 #, c-format msgid "Report bugs to %s" msgstr "" -#: src/main.cc:446 +#: src/main.cc:358 msgid "unrecognized proxy format" msgstr "" -#: src/main.cc:473 +#: src/main.cc:385 msgid "Currently, supported authentication scheme is basic." msgstr "" -#: src/main.cc:482 +#: src/main.cc:394 msgid "retry-wait must be between 0 and 60." msgstr "" -#: src/main.cc:499 +#: src/main.cc:411 msgid "ftp-type must be either 'binary' or 'ascii'." msgstr "" -#: src/main.cc:508 +#: src/main.cc:420 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'." msgstr "" -#: src/main.cc:526 +#: src/main.cc:428 msgid "min-segment-size invalid" msgstr "" -#: src/main.cc:537 +#: src/main.cc:439 msgid "http-proxy-method must be either 'get' or 'tunnel'." msgstr "" -#: src/main.cc:545 +#: src/main.cc:447 msgid "listen-port must be between 1024 and 65535." msgstr "" -#: src/main.cc:556 +#: src/main.cc:460 msgid "follow-torrent must be either 'true' or 'false'." msgstr "" -#: src/main.cc:570 +#: src/main.cc:474 msgid "direct-file-mapping must be either 'true' or 'false'." msgstr "" -#: src/main.cc:578 +#: src/main.cc:482 msgid "upload-limit must be greater than or equal to 0." msgstr "" -#: src/main.cc:603 +#: src/main.cc:507 msgid "follow-metalink must be either 'true' or 'false'." msgstr "" -#: src/main.cc:630 +#: src/main.cc:515 +msgid "lowest-speed-limit must be greater than or equal to 0" +msgstr "" + +#: src/main.cc:544 msgid "split must be between 1 and 5." msgstr "" -#: src/main.cc:640 +#: src/main.cc:556 msgid "timeout must be between 1 and 600" msgstr "" -#: src/main.cc:649 +#: src/main.cc:565 msgid "max-tries invalid" msgstr "" -#: src/main.cc:671 +#: src/main.cc:587 msgid "metalink-servers must be greater than 0." msgstr "" -#: src/main.cc:689 +#: src/main.cc:607 msgid "specify at least one URL" msgstr "" -#: src/main.cc:696 +#: src/main.cc:614 msgid "daemon failed" msgstr "" - -#: src/main.cc:837 -msgid "Files:" -msgstr "" - -#: src/main.cc:868 -msgid "Errors occurred while binding port.\n" -msgstr "" diff --git a/po/de.gmo b/po/de.gmo index 8faf2543..95b6db13 100644 Binary files a/po/de.gmo and b/po/de.gmo differ diff --git a/po/de.po b/po/de.po index 08e04a27..d1a149ce 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: de\n" "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n" -"POT-Creation-Date: 2006-07-21 00:57+0900\n" +"POT-Creation-Date: 2006-08-07 22:15+0900\n" "PO-Revision-Date: 2006-05-05 19:44+0900\n" "Last-Translator: Hermann J. Beckers \n" "Language-Team: deutsch \n" @@ -16,6 +16,23 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.3\n" +#: src/RequestInfo.h:76 +#, c-format +msgid "" +"\n" +"The download was complete. <%s>\n" +msgstr "" +"\n" +"Abruf ist vollständig. <%s>\n" + +#: src/RequestInfo.h:84 +msgid "" +"\n" +"The download was not complete because of errors. Check the log.\n" +msgstr "" +"\n" +"Abruf wegen Fehlern nicht vollständig. Überprüfen Sie die Log-Datei.\n" + #: src/message.h:27 #, c-format msgid "CUID#%d - The download for one segment completed successfully." @@ -338,24 +355,15 @@ msgstr "Konnte Daten nicht erhalten, Ursache: %s" msgid "Failed to peek data, cause: %s" msgstr "Datenermittelung fehlgeschlagen, Ursache: %s" -#: src/main.cc:76 -#, c-format -msgid "" -"\n" -"The download was complete. <%s>\n" -msgstr "" -"\n" -"Abruf ist vollständig. <%s>\n" +#: src/DownloadEngineFactory.cc:102 +msgid "Errors occurred while binding port.\n" +msgstr "Fehler beim Binden an Port aufgetreten.\n" -#: src/main.cc:84 -msgid "" -"\n" -"The download was not complete because of errors. Check the log.\n" -msgstr "" -"\n" -"Abruf wegen Fehlern nicht vollständig. Überprüfen Sie die Log-Datei.\n" +#: src/TorrentRequestInfo.cc:71 +msgid "Files:" +msgstr "Dateien:" -#: src/main.cc:101 +#: src/UrlRequestInfo.cc:57 msgid "" "\n" "stopping application...\n" @@ -363,20 +371,20 @@ msgstr "" "\n" "Anwendung wird gestoppt ...\n" -#: src/main.cc:107 +#: src/UrlRequestInfo.cc:62 msgid "done\n" msgstr "erledigt\n" -#: src/main.cc:123 +#: src/UrlRequestInfo.cc:86 #, c-format msgid "Unrecognized URL or unsupported protocol: %s\n" msgstr "URL nicht erkannt oder nicht unterstütztes Protokoll: %s\n" -#: src/main.cc:129 +#: src/main.cc:71 msgid " version " msgstr " Version " -#: src/main.cc:133 +#: src/main.cc:78 msgid "" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" @@ -406,41 +414,41 @@ msgstr "" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" -#: src/main.cc:147 +#: src/main.cc:92 #, c-format msgid "Contact Info: %s\n" msgstr "Kontakt-Info: %s\n" -#: src/main.cc:153 +#: src/main.cc:98 #, c-format msgid "Usage: %s [options] URL ...\n" msgstr "Aufruf: %s [Optionen] URL ...\n" -#: src/main.cc:155 +#: src/main.cc:100 #, c-format msgid " %s [options] -T TORRENT_FILE FILE ...\n" msgstr " %s [Optionen] -T TORRENT_FILE FILE ...\n" -#: src/main.cc:158 +#: src/main.cc:103 #, fuzzy, c-format msgid " %s [options] -M METALINK_FILE\n" msgstr " %s [Optionen] -T TORRENT_FILE FILE ...\n" -#: src/main.cc:161 +#: src/main.cc:106 msgid "Options:" msgstr "Optionen:" -#: src/main.cc:162 +#: src/main.cc:107 msgid " -d, --dir=DIR The directory to store downloaded file." msgstr "" " -d, --dir=DIR Verzeichnis zum Speichern der abgerufenen " "Datei." -#: src/main.cc:163 +#: src/main.cc:108 msgid " -o, --out=FILE The file name for downloaded file." msgstr " -o, --out=FILE Dateiname für die abgerufene Datei." -#: src/main.cc:164 +#: src/main.cc:109 msgid "" " -l, --log=LOG The file path to store log. If '-' is " "specified,\n" @@ -451,11 +459,11 @@ msgstr "" " wird das Log auf die Standardausgabe " "geschrieben." -#: src/main.cc:166 +#: src/main.cc:111 msgid " -D, --daemon Run as daemon." msgstr " -D, --daemon Start als Daemon-Prozeß." -#: src/main.cc:167 +#: src/main.cc:112 msgid "" " -s, --split=N Download a file using N connections. N must " "be\n" @@ -471,7 +479,7 @@ msgstr "" " Daher verbindet sich aria2 zu jeder URL mit\n" " N Verbindungen." -#: src/main.cc:171 +#: src/main.cc:116 msgid "" " --retry-wait=SEC Set amount of time in second between requests\n" " for errors. Specify a value between 0 and 60.\n" @@ -483,12 +491,12 @@ msgstr "" "und 60 an.\n" " Fehlwert: 5" -#: src/main.cc:174 +#: src/main.cc:119 msgid " -t, --timeout=SEC Set timeout in second. Default: 60" msgstr "" " -t, --timeout=SEC Setzt Wartezeit in Sekunden. Fehlwert: 60" -#: src/main.cc:175 +#: src/main.cc:120 msgid "" " -m, --max-tries=N Set number of tries. 0 means unlimited.\n" " Default: 5" @@ -496,12 +504,13 @@ msgstr "" " -m, --max-tries=N Anzahl Versuche. 0 bedeutet unbegrenzt.\n" " Fehlwert: 5" -#: src/main.cc:177 +#: src/main.cc:122 +#, fuzzy msgid "" " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n" " K or M(1K = 1024, 1M = 1024K). This\n" " value must be greater than or equal to\n" -" 1024." +" 1024. Default: 1M" msgstr "" " --min-segment-size=SIZE[K|M] Setzt die minimale Segment-Größe. Sie können \n" " K oder M(1K = 1024, 1M = 1024K) anhängen. " @@ -509,7 +518,7 @@ msgstr "" " Wert muss größer oder gleich \n" " 1024 sein." -#: src/main.cc:181 +#: src/main.cc:126 msgid "" " --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all\n" " URLs." @@ -517,26 +526,26 @@ msgstr "" " --http-proxy=HOST:PORT HTTP-Proxyserver benutzen. Dies betrifft alle\n" " URLs." -#: src/main.cc:183 +#: src/main.cc:128 msgid " --http-user=USER Set HTTP user. This affects to all URLs." msgstr "" " --http-user=USER HTTP-Anwendername angeben. Dies betrifft alle " "URLs." -#: src/main.cc:184 +#: src/main.cc:129 msgid "" " --http-passwd=PASSWD Set HTTP password. This affects to all URLs." msgstr "" " --http-passwd=PASSWD HTTP-Passwort setzen. Dies betrifft alle URLs." -#: src/main.cc:185 +#: src/main.cc:130 msgid "" " --http-proxy-user=USER Set HTTP proxy user. This affects to all URLs" msgstr "" " --http-proxy-user=USER HTTP-Proxy-Anwender setzen. Dies betrifft alle " "URLs." -#: src/main.cc:186 +#: src/main.cc:131 msgid "" " --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects to all " "URLs." @@ -544,7 +553,7 @@ msgstr "" " --http-proxy-passwd=PASSWD HTTP-Proxy-Passwort setzen. Dies betrifft alle " "URLs." -#: src/main.cc:187 +#: src/main.cc:132 msgid "" " --http-proxy-method=METHOD Set the method to use in proxy request.\n" " METHOD is either 'get' or 'tunnel'.\n" @@ -555,7 +564,7 @@ msgstr "" " METHOD ist entweder 'get' oder 'tunnel'.\n" " Fehlwert: tunnel" -#: src/main.cc:190 +#: src/main.cc:135 msgid "" " --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, " "basic\n" @@ -567,11 +576,11 @@ msgstr "" " das einzig zulässige Schema.\n" " Fehlwert: basic" -#: src/main.cc:193 +#: src/main.cc:138 msgid " --referer=REFERER Set Referer. This affects to all URLs." msgstr " --referer=REFERER Referer setzen. Dies betrifft alle URLs." -#: src/main.cc:194 +#: src/main.cc:139 msgid "" " --ftp-user=USER Set FTP user. This affects to all URLs.\n" " Default: anonymous" @@ -579,7 +588,7 @@ msgstr "" " --ftp-user=USER FTP-Anwender setzen. Dies betrifft alle URLs.\n" " Fehlwert: anonymous" -#: src/main.cc:196 +#: src/main.cc:141 msgid "" " --ftp-passwd=PASSWD Set FTP password. This affects to all URLs.\n" " Default: ARIA2USER@" @@ -587,7 +596,7 @@ msgstr "" " --ftp-passwd=PASSWD FTP-Passwort setzen. Dies betrifft alle URLs.\n" " Fehlwert: ARIA2USER@" -#: src/main.cc:198 +#: src/main.cc:143 msgid "" " --ftp-type=TYPE Set FTP transfer type. TYPE is either " "'binary'\n" @@ -599,11 +608,11 @@ msgstr "" " oder 'ascii'.\n" " Fehlwert: binary" -#: src/main.cc:201 +#: src/main.cc:146 msgid " -p, --ftp-pasv Use passive mode in FTP." msgstr " -p, --ftp-pasv Passiv-Modus für FTP benutzen." -#: src/main.cc:202 +#: src/main.cc:147 msgid "" " --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' " "or\n" @@ -615,11 +624,26 @@ msgstr "" " 'tunnel'.\n" " Fehlwert: tunnel" -#: src/main.cc:206 +#: src/main.cc:150 +msgid "" +" --lowest-speed-limit Close connection if download speed is lower " +"than\n" +" or equal to this value. 0 means aria2 does " +"not\n" +" care lowest speed limit. You can use K or M " +"in\n" +" the same manner as in --min-segment-size " +"option.\n" +" This option does not affect BitTorrent " +"download.\n" +" Default: 0" +msgstr "" + +#: src/main.cc:157 msgid " -T, --torrent-file=TORRENT_FILE The file path to .torrent file." msgstr " -T, --torrent-file=TORRENT_FILE Datenpfad zur torrent-Datei." -#: src/main.cc:207 +#: src/main.cc:158 msgid "" " --follow-torrent=true|false Setting this option to false prevents aria2 " "to\n" @@ -634,14 +658,14 @@ msgstr "" " auf .torrent endet.\n" " Fehlwert: true" -#: src/main.cc:211 +#: src/main.cc:162 msgid "" " -S, --show-files Print file listing of .torrent file and exit." msgstr "" " -S, --show-files Dateiliste der .torrent-Datei ausgeben und " "beenden." -#: src/main.cc:212 +#: src/main.cc:163 msgid "" " --direct-file-mapping=true|false Directly read from and write to each file\n" " mentioned in .torrent file.\n" @@ -651,7 +675,7 @@ msgstr "" " .torrent-Datei erwähnten Datei.\n" " Fehlwert: true" -#: src/main.cc:215 +#: src/main.cc:166 msgid "" " --listen-port=PORT Set port number to listen to for peer " "connection." @@ -659,7 +683,7 @@ msgstr "" " --listen-port=PORT Port-Nummer zum Lauschen auf Peer-Verbindungen " "setzen." -#: src/main.cc:216 +#: src/main.cc:167 msgid "" " --upload-limit=SPEED Set upload speed limit in KB/sec. aria2 tries " "to\n" @@ -671,7 +695,7 @@ msgstr "" " Sendegeschwindigkeit unter SPEED zu halten. 0 " "bedeutet keine Begrenzung." -#: src/main.cc:218 +#: src/main.cc:169 msgid "" " --select-file=INDEX... Set file to download by specifing its index.\n" " You can know file index through --show-files\n" @@ -691,12 +715,12 @@ msgstr "" " Sie können auch '-' verwenden wie in \"1-5\".\n" " ',' und '-' können zusammen benutzt werden." -#: src/main.cc:226 +#: src/main.cc:177 #, fuzzy msgid " -M, --metalink-file=METALINK_FILE The file path to .metalink file." msgstr " -T, --torrent-file=TORRENT_FILE Datenpfad zur torrent-Datei." -#: src/main.cc:227 +#: src/main.cc:178 #, fuzzy msgid "" " -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n" @@ -712,20 +736,20 @@ msgstr "" " auf .torrent endet.\n" " Fehlwert: true" -#: src/main.cc:231 +#: src/main.cc:182 msgid " --metalink-version=VERSION The version of file to download." msgstr "" -#: src/main.cc:232 +#: src/main.cc:183 msgid " --metalink-language=LANGUAGE The language of file to download." msgstr "" -#: src/main.cc:233 +#: src/main.cc:184 msgid "" " --metalink-os=OS The operating system the file is targeted." msgstr "" -#: src/main.cc:234 +#: src/main.cc:185 #, fuzzy msgid "" " --follow-metalink=true|false Setting this option to false prevents aria2 " @@ -741,15 +765,15 @@ msgstr "" " auf .torrent endet.\n" " Fehlwert: true" -#: src/main.cc:239 +#: src/main.cc:190 msgid " -v, --version Print the version number and exit." msgstr " -v, --version Versionsnummer ausgeben und beenden." -#: src/main.cc:240 +#: src/main.cc:191 msgid " -h, --help Print this message and exit." msgstr " -h, --help Diese Anzeige ausgeben und beenden." -#: src/main.cc:243 +#: src/main.cc:194 msgid "" " You can specify multiple URLs. All URLs must point to the same file\n" " or downloading fails." @@ -758,7 +782,7 @@ msgstr "" "verweisen\n" "oder der Abruf schlägt fehl." -#: src/main.cc:248 +#: src/main.cc:199 msgid "" " Specify files in multi-file torrent to download. Use conjunction with\n" " -T option. This arguments are ignored if you specify --select-file option." @@ -768,140 +792,137 @@ msgstr "" " -T-Option. Diese Argumente werden ignoriert, wenn sie die Option --select-" "file angeben." -#: src/main.cc:252 +#: src/main.cc:203 msgid "Examples:" msgstr "Beispiele:" -#: src/main.cc:253 +#: src/main.cc:204 msgid " Download a file by 1 connection:" msgstr " Abruf einer Datei über 1 Verbindung:" -#: src/main.cc:255 +#: src/main.cc:206 msgid " Download a file by 2 connections:" msgstr " Abruf einer Datei mit 2 Verbindungen:" -#: src/main.cc:257 +#: src/main.cc:208 msgid " Download a file by 2 connections, each connects to a different server:" msgstr "" " Abruf einer Datei über 2 Verbindungen, jede verbindet zu einem anderen " "Server:" -#: src/main.cc:259 +#: src/main.cc:210 msgid " You can mix up different protocols:" msgstr " Sie können verschiedene Protokolle mischen:" -#: src/main.cc:263 +#: src/main.cc:214 msgid " Download a torrent:" msgstr " Einen torrent abrufen:" -#: src/main.cc:265 +#: src/main.cc:216 msgid " Download a torrent using local .torrent file:" msgstr " Einen torrent mit einer lokalen .torrent-Datei abrufen:" -#: src/main.cc:267 +#: src/main.cc:218 msgid " Download only selected files:" msgstr " Nur ausgewählte Dateien abrufen:" -#: src/main.cc:269 +#: src/main.cc:220 msgid " Print file listing of .torrent file:" msgstr " Dateiliste einer .torrent-Datei ausgeben:" -#: src/main.cc:274 +#: src/main.cc:225 msgid " Metalink downloading:" msgstr "" -#: src/main.cc:276 +#: src/main.cc:227 #, fuzzy msgid " Download a file using local .metalink file:" msgstr " Einen torrent mit einer lokalen .torrent-Datei abrufen:" -#: src/main.cc:278 +#: src/main.cc:229 msgid " Metalink downloading with preferences:" msgstr "" -#: src/main.cc:282 +#: src/main.cc:233 #, c-format msgid "Report bugs to %s" msgstr "Fehler an %s melden" -#: src/main.cc:446 +#: src/main.cc:358 msgid "unrecognized proxy format" msgstr "nicht erkanntes Proxy-Format" -#: src/main.cc:473 +#: src/main.cc:385 msgid "Currently, supported authentication scheme is basic." msgstr "Derzeit unterstütztes Authentifizierungsschema ist basic." -#: src/main.cc:482 +#: src/main.cc:394 msgid "retry-wait must be between 0 and 60." msgstr "retry-wait muss zwischen 0 und 60 liegen." -#: src/main.cc:499 +#: src/main.cc:411 msgid "ftp-type must be either 'binary' or 'ascii'." msgstr "ftp-type muss entweder 'binary' oder 'ascii' sein." -#: src/main.cc:508 +#: src/main.cc:420 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'." msgstr "ftp-via-http-proxy muss entweder 'get' oder 'tunnel' sein." -#: src/main.cc:526 +#: src/main.cc:428 msgid "min-segment-size invalid" msgstr "min-segment-size ungültig" -#: src/main.cc:537 +#: src/main.cc:439 msgid "http-proxy-method must be either 'get' or 'tunnel'." msgstr "http-proxy-method muss entweder 'get' oder 'tunnel' sein." -#: src/main.cc:545 +#: src/main.cc:447 msgid "listen-port must be between 1024 and 65535." msgstr "listen-port muss zwischen 1024 und 65535 liegen." -#: src/main.cc:556 +#: src/main.cc:460 msgid "follow-torrent must be either 'true' or 'false'." msgstr "follow-torrent muss entweder 'true' oder 'false' sein." -#: src/main.cc:570 +#: src/main.cc:474 msgid "direct-file-mapping must be either 'true' or 'false'." msgstr "direct-file-mapping muss entweder 'true' oder 'false' sein." -#: src/main.cc:578 +#: src/main.cc:482 msgid "upload-limit must be greater than or equal to 0." msgstr "upload-limit muss größer oder gleich 0 sein." -#: src/main.cc:603 +#: src/main.cc:507 #, fuzzy msgid "follow-metalink must be either 'true' or 'false'." msgstr "follow-torrent muss entweder 'true' oder 'false' sein." -#: src/main.cc:630 +#: src/main.cc:515 +#, fuzzy +msgid "lowest-speed-limit must be greater than or equal to 0" +msgstr "upload-limit muss größer oder gleich 0 sein." + +#: src/main.cc:544 msgid "split must be between 1 and 5." msgstr "split muss zwischen 1 und 5 liegen." -#: src/main.cc:640 +#: src/main.cc:556 msgid "timeout must be between 1 and 600" msgstr "timeout muss zwischen 1 und 600 liegen." -#: src/main.cc:649 +#: src/main.cc:565 msgid "max-tries invalid" msgstr "max-tries ungültig" -#: src/main.cc:671 +#: src/main.cc:587 #, fuzzy msgid "metalink-servers must be greater than 0." msgstr "upload-limit muss größer oder gleich 0 sein." -#: src/main.cc:689 +#: src/main.cc:607 msgid "specify at least one URL" msgstr "Geben Sie zumindest eine URL an" -#: src/main.cc:696 +#: src/main.cc:614 msgid "daemon failed" msgstr "Daemon-Start nicht erfolgreich" - -#: src/main.cc:837 -msgid "Files:" -msgstr "Dateien:" - -#: src/main.cc:868 -msgid "Errors occurred while binding port.\n" -msgstr "Fehler beim Binden an Port aufgetreten.\n" diff --git a/po/ja.gmo b/po/ja.gmo index c8293905..65b25055 100644 Binary files a/po/ja.gmo and b/po/ja.gmo differ diff --git a/po/ja.po b/po/ja.po index 4ac87aa9..d9f74590 100644 --- a/po/ja.po +++ b/po/ja.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: aria2c 0.2.1\n" "Report-Msgid-Bugs-To: http://aria2.sourceforge.net/\n" -"POT-Creation-Date: 2006-07-21 00:57+0900\n" +"POT-Creation-Date: 2006-08-07 22:15+0900\n" "PO-Revision-Date: 2006-07-04 01:41+0900\n" "Last-Translator: Tatsuhiro Tsujikawa \n" "Language-Team: Japanese \n" @@ -16,6 +16,23 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +#: src/RequestInfo.h:76 +#, c-format +msgid "" +"\n" +"The download was complete. <%s>\n" +msgstr "" +"\n" +"<%s> ¤Î¥À¥¦¥ó¥í¡¼¥É¤¬´°Î»¤·¤Þ¤·¤¿.\n" + +#: src/RequestInfo.h:84 +msgid "" +"\n" +"The download was not complete because of errors. Check the log.\n" +msgstr "" +"\n" +"¥À¥¦¥ó¥í¡¼¥É¤Ï¥¨¥é¡¼¤Î¤¿¤á´°Î»¤·¤Æ¤¤¤Þ¤»¤ó. ¥í¥°¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤.\n" + #: src/message.h:27 #, c-format msgid "CUID#%d - The download for one segment completed successfully." @@ -341,24 +358,15 @@ msgstr " msgid "Failed to peek data, cause: %s" msgstr "¥Ç¡¼¥¿¤Î peek ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿. ¸¶°ø: %s" -#: src/main.cc:76 -#, c-format -msgid "" -"\n" -"The download was complete. <%s>\n" -msgstr "" -"\n" -"<%s> ¤Î¥À¥¦¥ó¥í¡¼¥É¤¬´°Î»¤·¤Þ¤·¤¿.\n" +#: src/DownloadEngineFactory.cc:102 +msgid "Errors occurred while binding port.\n" +msgstr "¥Ý¡¼¥È¤ò¥Ð¥¤¥ó¥ÉÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿.\n" -#: src/main.cc:84 -msgid "" -"\n" -"The download was not complete because of errors. Check the log.\n" -msgstr "" -"\n" -"¥À¥¦¥ó¥í¡¼¥É¤Ï¥¨¥é¡¼¤Î¤¿¤á´°Î»¤·¤Æ¤¤¤Þ¤»¤ó. ¥í¥°¤ò³Îǧ¤·¤Æ¤¯¤À¤µ¤¤.\n" +#: src/TorrentRequestInfo.cc:71 +msgid "Files:" +msgstr "¥Õ¥¡¥¤¥ë:" -#: src/main.cc:101 +#: src/UrlRequestInfo.cc:57 msgid "" "\n" "stopping application...\n" @@ -366,22 +374,22 @@ msgstr "" "\n" "¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ò½ªÎ»¤·¤Æ¤¤¤Þ¤¹...\n" -#: src/main.cc:107 +#: src/UrlRequestInfo.cc:62 msgid "done\n" msgstr "´°Î»\n" -#: src/main.cc:123 +#: src/UrlRequestInfo.cc:86 #, c-format msgid "Unrecognized URL or unsupported protocol: %s\n" msgstr "" "%s ¤Ï, Íý²ò¤Ç¤­¤Ê¤¤ URL ¥Õ¥©¡¼¥Þ¥Ã¥È, ¤Þ¤¿¤Ï, ¥µ¥Ý¡¼¥È¤µ¤ì¤Ê¤¤¥×¥í¥È¥³¥ë¤Ç" "¤¹.\n" -#: src/main.cc:129 +#: src/main.cc:71 msgid " version " msgstr " ¥Ð¡¼¥¸¥ç¥ó " -#: src/main.cc:133 +#: src/main.cc:78 msgid "" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" @@ -411,41 +419,41 @@ msgstr "" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n" -#: src/main.cc:147 +#: src/main.cc:92 #, c-format msgid "Contact Info: %s\n" msgstr "Ï¢ÍíÀè: %s\n" -#: src/main.cc:153 +#: src/main.cc:98 #, c-format msgid "Usage: %s [options] URL ...\n" msgstr "»È¤¤Êý: %s [¥ª¥×¥·¥ç¥ó] URL ...\n" -#: src/main.cc:155 +#: src/main.cc:100 #, c-format msgid " %s [options] -T TORRENT_FILE FILE ...\n" msgstr " %s [¥ª¥×¥·¥ç¥ó] -T TORRENT_FILE FILE ...\n" -#: src/main.cc:158 +#: src/main.cc:103 #, c-format msgid " %s [options] -M METALINK_FILE\n" msgstr " %s [¥ª¥×¥·¥ç¥ó] -M METALINK_FILE\n" -#: src/main.cc:161 +#: src/main.cc:106 msgid "Options:" msgstr "¥ª¥×¥·¥ç¥ó:" -#: src/main.cc:162 +#: src/main.cc:107 msgid " -d, --dir=DIR The directory to store downloaded file." msgstr "" " -d, --dir=DIR ¥À¥¦¥ó¥í¡¼¥É¤·¤¿¥Õ¥¡¥¤¥ë¤òÊݸ¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê." -#: src/main.cc:163 +#: src/main.cc:108 msgid " -o, --out=FILE The file name for downloaded file." msgstr "" " -o, --out=FILE ¥À¥¦¥ó¥í¡¼¥É¤·¤¿¥Õ¥¡¥¤¥ë¤ÎÊݸÀè¥Õ¥¡¥¤¥ë̾." -#: src/main.cc:164 +#: src/main.cc:109 msgid "" " -l, --log=LOG The file path to store log. If '-' is " "specified,\n" @@ -455,11 +463,11 @@ msgstr "" "ÎÏ\n" " ¤Ë½ÐÎϤ·¤Þ¤¹." -#: src/main.cc:166 +#: src/main.cc:111 msgid " -D, --daemon Run as daemon." msgstr " -D, --daemon ¥Ç¡¼¥â¥ó¤È¤·¤Æµ¯Æ°¤·¤Þ¤¹." -#: src/main.cc:167 +#: src/main.cc:112 msgid "" " -s, --split=N Download a file using N connections. N must " "be\n" @@ -478,7 +486,7 @@ msgstr "" "¥·¥ç\n" " ¥ó¤ò³ÎΩ¤·¤Þ¤¹." -#: src/main.cc:171 +#: src/main.cc:116 msgid "" " --retry-wait=SEC Set amount of time in second between requests\n" " for errors. Specify a value between 0 and 60.\n" @@ -489,13 +497,13 @@ msgstr "" " ¤¹. 0 - 60 ¤ÎÃͤò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: 5" -#: src/main.cc:174 +#: src/main.cc:119 msgid " -t, --timeout=SEC Set timeout in second. Default: 60" msgstr "" " -t, --timeout=SEC ¥¿¥¤¥à¥¢¥¦¥È¤È¤Ê¤ë»þ´Ö¤òÉäǻØÄꤷ¤Þ¤¹.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: 60" -#: src/main.cc:175 +#: src/main.cc:120 msgid "" " -m, --max-tries=N Set number of tries. 0 means unlimited.\n" " Default: 5" @@ -504,12 +512,13 @@ msgstr "" "¹Ô\n" " ¤·¤Þ¤¹. ¥Ç¥Õ¥©¥ë¥ÈÃÍ: 5" -#: src/main.cc:177 +#: src/main.cc:122 +#, fuzzy msgid "" " --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n" " K or M(1K = 1024, 1M = 1024K). This\n" " value must be greater than or equal to\n" -" 1024." +" 1024. Default: 1M" msgstr "" " --min-segment-size=SIZE[K|M] ºÇ¾®¤Î¥»¥°¥á¥ó¥È¡¦¥µ¥¤¥º¤ò»ØÄꤷ¤Þ¤¹. K ¤Þ¤¿¤Ï " "M\n" @@ -517,7 +526,7 @@ msgstr "" "1024K).\n" " 1024 °Ê¾å¤ÎÃͤò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:181 +#: src/main.cc:126 msgid "" " --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all\n" " URLs." @@ -526,14 +535,14 @@ msgstr "" "¥·\n" " ¥ç¥ó¤Ï¤¹¤Ù¤Æ¤Î URL ¤Ë±Æ¶Á¤·¤Þ¤¹." -#: src/main.cc:183 +#: src/main.cc:128 msgid " --http-user=USER Set HTTP user. This affects to all URLs." msgstr "" " --http-user=USER HTTP ¤Ç¤Îǧ¾Ú¥æ¡¼¥¶¡¼¤ò»ØÄꤷ¤Þ¤¹. ¤³¤Î¥ª¥×¥·¥ç" "¥ó\n" " ¤Ï¤¹¤Ù¤Æ¤Î URL ¤Ë±Æ¶Á¤·¤Þ¤¹." -#: src/main.cc:184 +#: src/main.cc:129 msgid "" " --http-passwd=PASSWD Set HTTP password. This affects to all URLs." msgstr "" @@ -541,7 +550,7 @@ msgstr "" "¥·¥ç\n" " ¥ó¤Ï¤¹¤Ù¤Æ¤Î URL ¤Ë±Æ¶Á¤·¤Þ¤¹." -#: src/main.cc:185 +#: src/main.cc:130 msgid "" " --http-proxy-user=USER Set HTTP proxy user. This affects to all URLs" msgstr "" @@ -551,7 +560,7 @@ msgstr "" "¤Þ\n" " ¤¹." -#: src/main.cc:186 +#: src/main.cc:131 msgid "" " --http-proxy-passwd=PASSWD Set HTTP proxy password. This affects to all " "URLs." @@ -562,7 +571,7 @@ msgstr "" "¤·\n" " ¤Þ¤¹." -#: src/main.cc:187 +#: src/main.cc:132 msgid "" " --http-proxy-method=METHOD Set the method to use in proxy request.\n" " METHOD is either 'get' or 'tunnel'.\n" @@ -573,7 +582,7 @@ msgstr "" " ¤¹. 'get' ¤Þ¤¿¤Ï 'tunnel' ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: tunnel" -#: src/main.cc:190 +#: src/main.cc:135 msgid "" " --http-auth-scheme=SCHEME Set HTTP authentication scheme. Currently, " "basic\n" @@ -585,14 +594,14 @@ msgstr "" " ¤¤¤ë¤Î¤Ï basic ¤Ç¤¹. \n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: basic" -#: src/main.cc:193 +#: src/main.cc:138 msgid " --referer=REFERER Set Referer. This affects to all URLs." msgstr "" " --referer=REFERER ¥ê¥Õ¥¡¥é¡¼¤ò»ØÄꤷ¤Þ¤¹. ¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¤¹¤Ù¤Æ" "¤Î\n" " URL ¤Ë±Æ¶Á¤·¤Þ¤¹." -#: src/main.cc:194 +#: src/main.cc:139 msgid "" " --ftp-user=USER Set FTP user. This affects to all URLs.\n" " Default: anonymous" @@ -602,7 +611,7 @@ msgstr "" " ¤Ï¤¹¤Ù¤Æ¤Î URL ¤Ë±Æ¶Á¤·¤Þ¤¹.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: anonymous" -#: src/main.cc:196 +#: src/main.cc:141 msgid "" " --ftp-passwd=PASSWD Set FTP password. This affects to all URLs.\n" " Default: ARIA2USER@" @@ -612,7 +621,7 @@ msgstr "" " ¥ó¤Ï¤¹¤Ù¤Æ¤Î URL ¤Ë±Æ¶Á¤·¤Þ¤¹.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: ARIA2USER@" -#: src/main.cc:198 +#: src/main.cc:143 msgid "" " --ftp-type=TYPE Set FTP transfer type. TYPE is either " "'binary'\n" @@ -623,11 +632,11 @@ msgstr "" " 'ascii' ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤. ¥Ç¥Õ¥©¥ë¥ÈÃÍ: " "binary" -#: src/main.cc:201 +#: src/main.cc:146 msgid " -p, --ftp-pasv Use passive mode in FTP." msgstr " -p, --ftp-pasv FTP ¤Ç passive ¥â¡¼¥É¤ò»ÈÍѤ·¤Þ¤¹." -#: src/main.cc:202 +#: src/main.cc:147 msgid "" " --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' " "or\n" @@ -640,11 +649,26 @@ msgstr "" "¤¯\n" " ¤À¤µ¤¤. ¥Ç¥Õ¥©¥ë¥ÈÃÍ: tunnel" -#: src/main.cc:206 +#: src/main.cc:150 +msgid "" +" --lowest-speed-limit Close connection if download speed is lower " +"than\n" +" or equal to this value. 0 means aria2 does " +"not\n" +" care lowest speed limit. You can use K or M " +"in\n" +" the same manner as in --min-segment-size " +"option.\n" +" This option does not affect BitTorrent " +"download.\n" +" Default: 0" +msgstr "" + +#: src/main.cc:157 msgid " -T, --torrent-file=TORRENT_FILE The file path to .torrent file." msgstr " -T, --torrent-file=TORRENT_FILE .torrent ¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤ò»ØÄê." -#: src/main.cc:207 +#: src/main.cc:158 msgid "" " --follow-torrent=true|false Setting this option to false prevents aria2 " "to\n" @@ -659,7 +683,7 @@ msgstr "" " ¤Ï, BitTorrent ¥â¡¼¥É¤ËÆþ¤ê¤Þ¤»¤ó.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: true" -#: src/main.cc:211 +#: src/main.cc:162 msgid "" " -S, --show-files Print file listing of .torrent file and exit." msgstr "" @@ -667,7 +691,7 @@ msgstr "" "¤·\n" " ½ªÎ»¤·¤Þ¤¹." -#: src/main.cc:212 +#: src/main.cc:163 msgid "" " --direct-file-mapping=true|false Directly read from and write to each file\n" " mentioned in .torrent file.\n" @@ -678,14 +702,14 @@ msgstr "" " ¤·¤Þ¤¹.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: true" -#: src/main.cc:215 +#: src/main.cc:166 msgid "" " --listen-port=PORT Set port number to listen to for peer " "connection." msgstr "" " --listen-port=PORT ¥Ô¥¢¤«¤é¤ÎÀܳ¤ò¼õ¤±ÉÕ¤±¤ë¥Ý¡¼¥ÈÈÖ¹æ¤ò»ØÄê." -#: src/main.cc:216 +#: src/main.cc:167 msgid "" " --upload-limit=SPEED Set upload speed limit in KB/sec. aria2 tries " "to\n" @@ -698,7 +722,7 @@ msgstr "" "¤·\n" " ¤Þ¤¹. 0 ¤Ï®ÅÙ̵À©¸Â¤ò°ÕÌ£¤·¤Þ¤¹." -#: src/main.cc:218 +#: src/main.cc:169 msgid "" " --select-file=INDEX... Set file to download by specifing its index.\n" " You can know file index through --show-files\n" @@ -719,11 +743,11 @@ msgstr "" " ¤Þ¤¿, '-' ¤ò»È¤Ã¤ÆÈÏ°Ï»ØÄê¤â¤Ç¤­¤Þ¤¹: \"1-5\"\n" " ',' ¤È '-' ¤ÏÁȤ߹ç¤ï¤»¤Æ»È¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹." -#: src/main.cc:226 +#: src/main.cc:177 msgid " -M, --metalink-file=METALINK_FILE The file path to .metalink file." msgstr " -M, --metalink-file=METALINK_FILE .metalink ¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹¤ò»ØÄê." -#: src/main.cc:227 +#: src/main.cc:178 msgid "" " -C, --metalink-servers=NUM_SERVERS The number of servers to connect to\n" " simultaneously. If more than one connection " @@ -737,15 +761,15 @@ msgstr "" " »ÈÍѤ·¤Æ¤¯¤À¤µ¤¤.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: 15" -#: src/main.cc:231 +#: src/main.cc:182 msgid " --metalink-version=VERSION The version of file to download." msgstr " --metalink-version=VERSION ¥À¥¦¥ó¥í¡¼¥É¤¹¤ë¥Õ¥¡¥¤¥ë¤Î¥Ð¡¼¥¸¥ç¥ó." -#: src/main.cc:232 +#: src/main.cc:183 msgid " --metalink-language=LANGUAGE The language of file to download." msgstr " --metalink-language=LANGUAGE ¥À¥¦¥ó¥í¡¼¥É¤¹¤ë¥Õ¥¡¥¤¥ë¤Î¸À¸ì." -#: src/main.cc:233 +#: src/main.cc:184 msgid "" " --metalink-os=OS The operating system the file is targeted." msgstr "" @@ -753,7 +777,7 @@ msgstr "" "¥ì¡¼\n" " ¥Æ¥£¥ó¥°¡¦¥·¥¹¥Æ¥à." -#: src/main.cc:234 +#: src/main.cc:185 msgid "" " --follow-metalink=true|false Setting this option to false prevents aria2 " "to\n" @@ -768,16 +792,16 @@ msgstr "" " ¤Ï, Metalink ¥â¡¼¥É¤ËÆþ¤ê¤Þ¤»¤ó.\n" " ¥Ç¥Õ¥©¥ë¥ÈÃÍ: true" -#: src/main.cc:239 +#: src/main.cc:190 msgid " -v, --version Print the version number and exit." msgstr " -v, --version ¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤òɽ¼¨¤·, ½ªÎ»¤·¤Þ¤¹." -#: src/main.cc:240 +#: src/main.cc:191 msgid " -h, --help Print this message and exit." msgstr "" " -h, --help ¤³¤Î¥Ø¥ë¥×¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤·, ½ªÎ»¤·¤Þ¤¹." -#: src/main.cc:243 +#: src/main.cc:194 msgid "" " You can specify multiple URLs. All URLs must point to the same file\n" " or downloading fails." @@ -786,7 +810,7 @@ msgstr "" "¤ì\n" " ¤Ð¤Ê¤ê¤Þ¤»¤ó. ¤µ¤â¤Ê¤¯¤Ð¥À¥¦¥ó¥í¡¼¥É¤Ï¼ºÇÔ¤·¤Þ¤¹." -#: src/main.cc:248 +#: src/main.cc:199 msgid "" " Specify files in multi-file torrent to download. Use conjunction with\n" " -T option. This arguments are ignored if you specify --select-file option." @@ -795,135 +819,132 @@ msgstr "" "¥ó\n" " ¤È¶¦¤Ë»ÈÍѤ·¤Þ¤¹. --select-file ¥ª¥×¥·¥ç¥ó¤ÈÊ»ÍѤϤǤ­¤Þ¤»¤ó." -#: src/main.cc:252 +#: src/main.cc:203 msgid "Examples:" msgstr "Îã:" -#: src/main.cc:253 +#: src/main.cc:204 msgid " Download a file by 1 connection:" msgstr " 1 ¥³¥Í¥¯¥·¥ç¥ó¤Ç¤Î¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:255 +#: src/main.cc:206 msgid " Download a file by 2 connections:" msgstr " 2 ¥³¥Í¥¯¥·¥ç¥ó¤Ç¤Î¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:257 +#: src/main.cc:208 msgid " Download a file by 2 connections, each connects to a different server:" msgstr " Æó¤Ä¤Î°Û¤Ê¤ë¥µ¡¼¥Ð¡¼¤ËÀܳ¤·¤Æ¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:259 +#: src/main.cc:210 msgid " You can mix up different protocols:" msgstr " °Û¤Ê¤ë¥×¥í¥È¥³¥ë¤òº®¹ç¤µ¤»¤Æ¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:263 +#: src/main.cc:214 msgid " Download a torrent:" msgstr " torrent ¤ò¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:265 +#: src/main.cc:216 msgid " Download a torrent using local .torrent file:" msgstr " ¥í¡¼¥«¥ë .torrent ¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:267 +#: src/main.cc:218 msgid " Download only selected files:" msgstr " ¥Õ¥¡¥¤¥ë¤ò»ØÄꤷ¤Æ¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:269 +#: src/main.cc:220 msgid " Print file listing of .torrent file:" msgstr " ¤³¤Î .torrent ¥Õ¥¡¥¤¥ë¤Ë´Þ¤Þ¤ì¤ë¥Õ¥¡¥¤¥ë¥ê¥¹¥È¤òɽ¼¨:" -#: src/main.cc:274 +#: src/main.cc:225 msgid " Metalink downloading:" msgstr " Metalink ¤Ç¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:276 +#: src/main.cc:227 msgid " Download a file using local .metalink file:" msgstr " ¥í¡¼¥«¥ë .metalink ¥Õ¥¡¥¤¥ë¤ò»È¤Ã¤Æ¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:278 +#: src/main.cc:229 msgid " Metalink downloading with preferences:" msgstr " ¥æ¡¼¥¶ÀßÄê¤Ë¤è¤ë Metalink ¥À¥¦¥ó¥í¡¼¥É:" -#: src/main.cc:282 +#: src/main.cc:233 #, c-format msgid "Report bugs to %s" msgstr "¥Ð¥°¥ì¥Ý¡¼¥È¤Ï¤³¤Á¤é¤Ø: %s" -#: src/main.cc:446 +#: src/main.cc:358 msgid "unrecognized proxy format" msgstr "Íý²ò¤Ç¤­¤Ê¤¤Proxy¥Õ¥©¡¼¥Þ¥Ã¥È¤Ç¤¹." -#: src/main.cc:473 +#: src/main.cc:385 msgid "Currently, supported authentication scheme is basic." msgstr "¸½ºß¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ëǧ¾ÚÊýË¡¤Ï basic ¤Ç¤¹." -#: src/main.cc:482 +#: src/main.cc:394 msgid "retry-wait must be between 0 and 60." msgstr "retry-wait ¤Ï 0 ¤«¤é 60 ¤Î´Ö¤Ç»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:499 +#: src/main.cc:411 msgid "ftp-type must be either 'binary' or 'ascii'." msgstr "ftp-type ¤Ï 'binary' ¤Þ¤¿¤Ï 'ascii' ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:508 +#: src/main.cc:420 msgid "ftp-via-http-proxy must be either 'get' or 'tunnel'." msgstr "ftp-via-http-proxy ¤Ï 'get' ¤Þ¤¿¤Ï 'tunnel' ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:526 +#: src/main.cc:428 msgid "min-segment-size invalid" msgstr "min-segment-size ¤¬ÉÔÀµ¤Ç¤¹." -#: src/main.cc:537 +#: src/main.cc:439 msgid "http-proxy-method must be either 'get' or 'tunnel'." msgstr "http-proxy-method ¤Ï 'get' ¤Þ¤¿¤Ï 'tunnel' ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:545 +#: src/main.cc:447 msgid "listen-port must be between 1024 and 65535." msgstr "listen-port ¤Ï 1024 - 65535 ¤ÎÃͤò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:556 +#: src/main.cc:460 msgid "follow-torrent must be either 'true' or 'false'." msgstr "follow-torrent ¤Ï 'true' ¤Þ¤¿¤Ï 'false ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:570 +#: src/main.cc:474 msgid "direct-file-mapping must be either 'true' or 'false'." msgstr "direct-file-mapping ¤Ï 'true' ¤Þ¤¿¤Ï 'false ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:578 +#: src/main.cc:482 msgid "upload-limit must be greater than or equal to 0." msgstr "upload-limit ¤Ï 0 °Ê¾å¤Î¿ô¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:603 +#: src/main.cc:507 msgid "follow-metalink must be either 'true' or 'false'." msgstr "follow-metalink ¤Ï 'true' ¤Þ¤¿¤Ï 'false ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:630 +#: src/main.cc:515 +#, fuzzy +msgid "lowest-speed-limit must be greater than or equal to 0" +msgstr "upload-limit ¤Ï 0 °Ê¾å¤Î¿ô¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." + +#: src/main.cc:544 msgid "split must be between 1 and 5." msgstr "split ¤Ï 1 - 5 ¤ÎÃͤò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:640 +#: src/main.cc:556 msgid "timeout must be between 1 and 600" msgstr "timeout ¤Ï 1 - 600 ¤ÎÃͤò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:649 +#: src/main.cc:565 msgid "max-tries invalid" msgstr "max-tries ¤¬ÉÔÀµ¤Ç¤¹." -#: src/main.cc:671 +#: src/main.cc:587 msgid "metalink-servers must be greater than 0." msgstr "metalink-servers ¤Ï 0 °Ê¾å¤Î¿ô¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:689 +#: src/main.cc:607 msgid "specify at least one URL" msgstr "°ì¸Ä°Ê¾å¤Î URL ¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤." -#: src/main.cc:696 +#: src/main.cc:614 msgid "daemon failed" msgstr "¥Ç¡¼¥â¥óµ¯Æ°¤Ë¼ºÇÔ" - -#: src/main.cc:837 -msgid "Files:" -msgstr "¥Õ¥¡¥¤¥ë:" - -#: src/main.cc:868 -msgid "Errors occurred while binding port.\n" -msgstr "¥Ý¡¼¥È¤ò¥Ð¥¤¥ó¥ÉÃæ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤Þ¤·¤¿.\n" diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index 7f6f85c8..ff56fa57 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -30,17 +30,21 @@ #include #include -AbstractDiskWriter::AbstractDiskWriter():fd(0) { +AbstractDiskWriter::AbstractDiskWriter(): + fd(0) +#ifdef ENABLE_MESSAGE_DIGEST + ,ctx(DIGEST_ALGO_SHA1) +#endif // ENABLE_MESSAGE_DIGEST +{ #ifdef ENABLE_MESSAGE_DIGEST - ctx.setAlgo(MessageDigestContext::ALGO_SHA1); - digestInit(ctx); + ctx.digestInit(); #endif // ENABLE_MESSAGE_DIGEST } AbstractDiskWriter::~AbstractDiskWriter() { closeFile(); #ifdef ENABLE_MESSAGE_DIGEST - digestFree(ctx); + ctx.digestFree(); #endif // ENABLE_MESSAGE_DIGEST } @@ -100,7 +104,7 @@ int AbstractDiskWriter::readDataInternal(char* data, int len) { string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) { #ifdef ENABLE_MESSAGE_DIGEST - digestReset(ctx); + ctx.digestReset(); try { int BUFSIZE = 16*1024; char buf[BUFSIZE]; @@ -108,7 +112,7 @@ string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) { if(BUFSIZE != readData(buf, BUFSIZE, offset)) { throw string("error"); } - digestUpdate(ctx, buf, BUFSIZE); + ctx.digestUpdate(buf, BUFSIZE); offset += BUFSIZE; } int r = length%BUFSIZE; @@ -116,10 +120,10 @@ string AbstractDiskWriter::sha1Sum(long long int offset, long long int length) { if(r != readData(buf, r, offset)) { throw string("error"); } - digestUpdate(ctx, buf, r); + ctx.digestUpdate(buf, r); } unsigned char hashValue[20]; - digestFinal(ctx, hashValue); + ctx.digestFinal(hashValue); return Util::toHex(hashValue, 20); } catch(string ex) { throw new DlAbortEx(EX_FILE_SHA1SUM, filename.c_str(), strerror(errno)); diff --git a/src/Checksum.h b/src/Checksum.h new file mode 100644 index 00000000..220befe7 --- /dev/null +++ b/src/Checksum.h @@ -0,0 +1,64 @@ +/* */ +#ifndef _D_CHECKSUM_H_ +#define _D_CHECKSUM_H_ + +#include "common.h" +#include "messageDigest.h" + +#ifdef ENABLE_MESSAGE_DIGEST +class Checksum { +private: + string md; + MessageDigestContext::DigestAlgo algo; +public: + Checksum(const string& md, MessageDigestContext::DigestAlgo algo): + md(md), + algo(algo) {} + Checksum(): + algo(DIGEST_ALGO_SHA1) {} + ~Checksum() {} + + bool isEmpty() const { + return md.size() == 0; + } + + void setMessageDigest(const string& md) { + this->md = md; + } + const string& getMessageDigest() const { + return md; + } + + void setDigestAlgo(MessageDigestContext::DigestAlgo algo) { + this->algo = algo; + } + const MessageDigestContext::DigestAlgo& getDigestAlgo() const { + return algo; + } +}; +#else +class Checksum { +}; +#endif // ENABLE_MESSAGE_DIGEST + +#endif // _D_CHECKSUM_H_ diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc index 441b00de..4e948f53 100644 --- a/src/DownloadCommand.cc +++ b/src/DownloadCommand.cc @@ -20,12 +20,14 @@ */ /* copyright --> */ #include "DownloadCommand.h" -#include #include "Util.h" #include "DlRetryEx.h" +#include "DlAbortEx.h" #include "HttpInitiateConnectionCommand.h" #include "InitiateConnectionCommandFactory.h" #include "message.h" +#include "prefs.h" +#include DownloadCommand::DownloadCommand(int cuid, Request* req, DownloadEngine* e, const SocketHandle& s): @@ -59,6 +61,13 @@ bool DownloadCommand::executeInternal(Segment seg) { seg.speed = (int)((seg.ds-lastSize)/(diff*1.0)); sw.reset(); lastSize = seg.ds; + int lowestLimit = e->option->getAsInt(PREF_LOWEST_SPEED_LIMIT); + if(lowestLimit > 0 && seg.speed <= lowestLimit) { + throw new DlAbortEx("CUID#%d - Too slow Downloading speed: %d <= %d(B/s)", + cuid, + seg.speed, + lowestLimit); + } } if(e->segmentMan->totalSize != 0 && bufSize == 0) { throw new DlRetryEx(EX_GOT_EOF); diff --git a/src/DownloadEngine.cc b/src/DownloadEngine.cc index 0f6f36af..ab75c7f9 100644 --- a/src/DownloadEngine.cc +++ b/src/DownloadEngine.cc @@ -32,14 +32,13 @@ using namespace std; -DownloadEngine::DownloadEngine():noWait(false), segmentMan(NULL) { +DownloadEngine::DownloadEngine():noWait(false), segmentMan(0) { logger = LogFactory::getInstance(); } DownloadEngine::~DownloadEngine() { - if(segmentMan != NULL) { - delete segmentMan; - } + delete segmentMan; + cleanQueue(); } void DownloadEngine::cleanQueue() { @@ -66,7 +65,7 @@ public: void DownloadEngine::run() { initStatistics(); Time cp; - CommandUuids activeCommandUuids; + CommandUuids activeUuids; while(!commands.empty()) { if(cp.elapsed(1)) { cp.reset(); @@ -79,8 +78,8 @@ void DownloadEngine::run() { } } } else { - for(CommandUuids::iterator itr = activeCommandUuids.begin(); - itr != activeCommandUuids.end(); itr++) { + for(CommandUuids::iterator itr = activeUuids.begin(); + itr != activeUuids.end(); itr++) { Commands::iterator comItr = find_if(commands.begin(), commands.end(), FindCommand(*itr)); assert(comItr != commands.end()); @@ -92,9 +91,9 @@ void DownloadEngine::run() { } } afterEachIteration(); - activeCommandUuids.clear(); + activeUuids.clear(); if(!noWait && !commands.empty()) { - waitData(activeCommandUuids); + waitData(activeUuids); } noWait = false; calculateStatistics(); @@ -113,63 +112,86 @@ void DownloadEngine::shortSleep() const { class SetDescriptor { private: - fd_set* fds_ptr; int* max_ptr; + fd_set* rfds_ptr; + fd_set* wfds_ptr; public: - SetDescriptor(int* max_ptr, fd_set* fds_ptr) - :fds_ptr(fds_ptr), max_ptr(max_ptr) {} + SetDescriptor(int* max_ptr, fd_set* rfds_ptr, fd_set* wfds_ptr): + max_ptr(max_ptr), + rfds_ptr(rfds_ptr), + wfds_ptr(wfds_ptr) {} - void operator()(const SockCmdMap::value_type& pa) { - int fd = pa.first->getSockfd(); - FD_SET(fd, fds_ptr); + void operator()(const SocketEntry& entry) { + int fd = entry.socket->getSockfd(); + switch(entry.type) { + case SocketEntry::TYPE_RD: + FD_SET(fd, rfds_ptr); + break; + case SocketEntry::TYPE_WR: + FD_SET(fd, wfds_ptr); + break; + } if(*max_ptr < fd) { *max_ptr = fd; } } }; -class AccumulateActiveCommandUuid { +class AccumulateActiveUuid { private: - CommandUuids* activeCommandUuids_ptr; - fd_set* fds_ptr; + CommandUuids* activeUuids_ptr; + fd_set* rfds_ptr; + fd_set* wfds_ptr; public: - AccumulateActiveCommandUuid(CommandUuids* activeCommandUuids_ptr, - fd_set* fds_ptr) - :activeCommandUuids_ptr(activeCommandUuids_ptr), fds_ptr(fds_ptr) {} + AccumulateActiveUuid(CommandUuids* activeUuids_ptr, + fd_set* rfds_ptr, + fd_set* wfds_ptr): + activeUuids_ptr(activeUuids_ptr), + rfds_ptr(rfds_ptr), + wfds_ptr(wfds_ptr) {} - void operator()(const SockCmdMap::value_type& pa) { - if(FD_ISSET(pa.first->getSockfd(), fds_ptr)) { - activeCommandUuids_ptr->push_back(pa.second); + void operator()(const SocketEntry& entry) { + if(FD_ISSET(entry.socket->getSockfd(), rfds_ptr) || + FD_ISSET(entry.socket->getSockfd(), wfds_ptr)) { + activeUuids_ptr->push_back(entry.commandUuid); } + /* + switch(entry.type) { + case SocketEntry::TYPE_RD: + if(FD_ISSET(entry.socket->getSockfd(), rfds_ptr)) { + activeUuids_ptr->push_back(entry.commandUuid); + } + break; + case SocketEntry::TYPE_WR: + if(FD_ISSET(entry.socket->getSockfd(), wfds_ptr)) { + activeUuids_ptr->push_back(entry.commandUuid); + } + break; + } + */ } }; -void DownloadEngine::waitData(CommandUuids& activeCommandUuids) { +void DownloadEngine::waitData(CommandUuids& activeUuids) { fd_set rfds; fd_set wfds; int retval = 0; - while(1) { - struct timeval tv; - - memcpy(&rfds, &rfdset, sizeof(fd_set)); - memcpy(&wfds, &wfdset, sizeof(fd_set)); - - tv.tv_sec = 1; - tv.tv_usec = 0; - retval = select(fdmax+1, &rfds, &wfds, NULL, &tv); - if(retval != -1 || errno != EINTR) { - break; - } - } + struct timeval tv; + + memcpy(&rfds, &rfdset, sizeof(fd_set)); + memcpy(&wfds, &wfdset, sizeof(fd_set)); + + tv.tv_sec = 1; + tv.tv_usec = 0; + retval = select(fdmax+1, &rfds, &wfds, NULL, &tv); if(retval > 0) { - for_each(rsockmap.begin(), rsockmap.end(), - AccumulateActiveCommandUuid(&activeCommandUuids, &rfds)); - for_each(wsockmap.begin(), wsockmap.end(), - AccumulateActiveCommandUuid(&activeCommandUuids, &wfds)); - sort(activeCommandUuids.begin(), activeCommandUuids.end()); - activeCommandUuids.erase(unique(activeCommandUuids.begin(), - activeCommandUuids.end()), - activeCommandUuids.end()); + for_each(socketEntries.begin(), socketEntries.end(), + AccumulateActiveUuid(&activeUuids, &rfds, &wfds)); + + sort(activeUuids.begin(), activeUuids.end()); + activeUuids.erase(unique(activeUuids.begin(), + activeUuids.end()), + activeUuids.end()); } } @@ -177,18 +199,15 @@ void DownloadEngine::updateFdSet() { fdmax = 0; FD_ZERO(&rfdset); FD_ZERO(&wfdset); - for_each(rsockmap.begin(), rsockmap.end(), SetDescriptor(&fdmax, &rfdset)); - for_each(wsockmap.begin(), wsockmap.end(), SetDescriptor(&fdmax, &wfdset)); + for_each(socketEntries.begin(), socketEntries.end(), + SetDescriptor(&fdmax, &rfdset, &wfdset)); } -bool DownloadEngine::addSocket(SockCmdMap& sockmap, - const SocketHandle& socket, - const CommandUuid& commandUuid) { - SockCmdMap::iterator itr = find_if(sockmap.begin(), sockmap.end(), - PairFind(socket, commandUuid)); - if(itr == sockmap.end()) { - SockCmdMap::value_type vt(socket, commandUuid); - sockmap.insert(vt); +bool DownloadEngine::addSocket(const SocketEntry& entry) { + SocketEntries::iterator itr = + find(socketEntries.begin(), socketEntries.end(), entry); + if(itr == socketEntries.end()) { + socketEntries.push_back(entry); updateFdSet(); return true; } else { @@ -196,15 +215,13 @@ bool DownloadEngine::addSocket(SockCmdMap& sockmap, } } -bool DownloadEngine::deleteSocket(SockCmdMap& sockmap, - const SocketHandle& socket, - const CommandUuid& commandUuid) { - SockCmdMap::iterator itr = find_if(sockmap.begin(), sockmap.end(), - PairFind(socket, commandUuid)); - if(itr == sockmap.end()) { +bool DownloadEngine::deleteSocket(const SocketEntry& entry) { + SocketEntries::iterator itr = + find(socketEntries.begin(), socketEntries.end(), entry); + if(itr == socketEntries.end()) { return false; } else { - sockmap.erase(itr); + socketEntries.erase(itr); updateFdSet(); return true; } @@ -212,20 +229,24 @@ bool DownloadEngine::deleteSocket(SockCmdMap& sockmap, bool DownloadEngine::addSocketForReadCheck(const SocketHandle& socket, const CommandUuid& commandUuid) { - return addSocket(rsockmap, socket, commandUuid); + SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_RD); + return addSocket(entry); } bool DownloadEngine::deleteSocketForReadCheck(const SocketHandle& socket, const CommandUuid& commandUuid) { - return deleteSocket(rsockmap, socket, commandUuid); + SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_RD); + return deleteSocket(entry); } bool DownloadEngine::addSocketForWriteCheck(const SocketHandle& socket, const CommandUuid& commandUuid) { - return addSocket(wsockmap, socket, commandUuid); + SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_WR); + return addSocket(entry); } bool DownloadEngine::deleteSocketForWriteCheck(const SocketHandle& socket, const CommandUuid& commandUuid) { - return deleteSocket(wsockmap, socket, commandUuid); + SocketEntry entry(socket, commandUuid, SocketEntry::TYPE_WR); + return deleteSocket(entry); } diff --git a/src/DownloadEngine.h b/src/DownloadEngine.h index d2dd0521..aa118ac7 100644 --- a/src/DownloadEngine.h +++ b/src/DownloadEngine.h @@ -32,22 +32,44 @@ typedef deque Sockets; typedef deque Commands; typedef deque CommandUuids; -typedef multimap SockCmdMap; + +class SocketEntry { +public: + enum TYPE { + TYPE_RD, + TYPE_WR, + }; + + SocketHandle socket; + CommandUuid commandUuid; + TYPE type; +public: + SocketEntry(const SocketHandle& socket, + const CommandUuid& commandUuid, + TYPE type): + socket(socket), commandUuid(commandUuid), type(type) {} + ~SocketEntry() {} + + bool operator==(const SocketEntry& entry) { + return socket == entry.socket && + commandUuid == entry.commandUuid && + type == entry.type; + } +}; + +typedef deque SocketEntries; class DownloadEngine { private: - void waitData(CommandUuids& activeCommandUuids); - SockCmdMap rsockmap; - SockCmdMap wsockmap; + void waitData(CommandUuids& activeUuids); + SocketEntries socketEntries; fd_set rfdset; fd_set wfdset; int fdmax; void shortSleep() const; - bool addSocket(SockCmdMap& sockmap, const SocketHandle& socket, - const CommandUuid& commandUuid); - bool deleteSocket(SockCmdMap& sockmap, const SocketHandle& socket, - const CommandUuid& commandUuid); + bool addSocket(const SocketEntry& socketEntry); + bool deleteSocket(const SocketEntry& socketEntry); protected: const Logger* logger; virtual void initStatistics() = 0; @@ -80,22 +102,5 @@ public: }; -template -class PairFind { -private: - T1 first; - T2 second; -public: - PairFind(T1 t1, T2 t2):first(t1), second(t2) {} - - bool operator()(const pair& pa) { - if(pa.first == first && pa.second == second) { - return true; - } else { - return false; - } - } -}; - #endif // _D_DOWNLOAD_ENGINE_H_ diff --git a/src/DownloadEngineFactory.cc b/src/DownloadEngineFactory.cc new file mode 100644 index 00000000..52da662c --- /dev/null +++ b/src/DownloadEngineFactory.cc @@ -0,0 +1,123 @@ +/* */ +#include "DownloadEngineFactory.h" +#include "prefs.h" +#include "DefaultDiskWriter.h" +#include "SplitSlowestSegmentSplitter.h" +#include "InitiateConnectionCommandFactory.h" +#include "ByteArrayDiskWriter.h" +#include "Util.h" +#ifdef ENABLE_BITTORRENT +# include "PeerListenCommand.h" +# include "TrackerWatcherCommand.h" +# include "TrackerUpdateCommand.h" +# include "TorrentAutoSaveCommand.h" +# include "PeerChokeCommand.h" +# include "HaveEraseCommand.h" +#endif // ENABLE_BITTORRENT + +ConsoleDownloadEngine* +DownloadEngineFactory::newConsoleEngine(const Option* op, + const Requests& requests, + const Requests& reserved) +{ + ConsoleDownloadEngine* e = new ConsoleDownloadEngine(); + e->option = op; + e->segmentMan = new SegmentMan(); + e->segmentMan->diskWriter = new DefaultDiskWriter(); + e->segmentMan->dir = op->get(PREF_DIR); + e->segmentMan->ufilename = op->get(PREF_OUT); + 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)); + } + return e; +} + +#ifdef ENABLE_BITTORRENT +TorrentConsoleDownloadEngine* +DownloadEngineFactory::newTorrentConsoleEngine(const Option* op, + const string& torrentFile, + const Strings& targetFiles) +{ + Request* req = new Request(); + req->isTorrent = true; + req->setTrackerEvent(Request::STARTED); + TorrentConsoleDownloadEngine* te = new TorrentConsoleDownloadEngine(); + te->option = op; + ByteArrayDiskWriter* byteArrayDiskWriter = new ByteArrayDiskWriter(); + te->segmentMan = new SegmentMan(); + te->segmentMan->diskWriter = byteArrayDiskWriter; + te->segmentMan->option = op; + te->segmentMan->splitter = new SplitSlowestSegmentSplitter(); + te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE)); + te->torrentMan = new TorrentMan(); + te->torrentMan->setStoreDir(op->get(PREF_DIR)); + te->torrentMan->option = op; + te->torrentMan->req = req; + Integers selectIndexes; + Util::unfoldRange(op->get(PREF_SELECT_FILE), selectIndexes); + if(selectIndexes.size()) { + te->torrentMan->setup(torrentFile, selectIndexes); + } else { + te->torrentMan->setup(torrentFile, targetFiles); + } + + PeerListenCommand* listenCommand = + new PeerListenCommand(te->torrentMan->getNewCuid(), te); + int port; + int listenPort = op->getAsInt(PREF_LISTEN_PORT); + if(listenPort == -1) { + port = listenCommand->bindPort(6881, 6999); + } else { + port = listenCommand->bindPort(listenPort, listenPort); + } + if(port == -1) { + printf(_("Errors occurred while binding port.\n")); + exit(EXIT_FAILURE); + } + te->torrentMan->setPort(port); + te->commands.push_back(listenCommand); + + te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(), + te, + te->torrentMan->minInterval)); + te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(), + te)); + te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(), + te, + op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); + te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(), + te, 10)); + te->commands.push_back(new HaveEraseCommand(te->torrentMan->getNewCuid(), + te, 10)); + + return te; +} +#endif // ENABLE_BITTORRENT diff --git a/src/DownloadEngineFactory.h b/src/DownloadEngineFactory.h new file mode 100644 index 00000000..10108fbc --- /dev/null +++ b/src/DownloadEngineFactory.h @@ -0,0 +1,46 @@ +/* */ +#ifndef _D_DOWNLOAD_ENGINE_FACTORY_H_ +#define _D_DOWNLOAD_ENGINE_FACTORY_H_ + +#include "common.h" +#include "ConsoleDownloadEngine.h" +#ifdef ENABLE_BITTORRENT +# include "TorrentConsoleDownloadEngine.h" +#endif // ENABLE_BITTORRENT + +class DownloadEngineFactory { +public: + static ConsoleDownloadEngine* + newConsoleEngine(const Option* option, + const Requests& requests, + const Requests& reserved); + +#ifdef ENABLE_BITTORRENT + static TorrentConsoleDownloadEngine* + newTorrentConsoleEngine(const Option* option, + const string& torrentFile, + const Strings& targetFiles); +#endif // ENABLE_BITTORRENT +}; + +#endif // _D_DOWNLOAD_ENGINE_FACTORY_H_ diff --git a/src/FtpNegotiationCommand.cc b/src/FtpNegotiationCommand.cc index 67b08f6b..efca2c2d 100644 --- a/src/FtpNegotiationCommand.cc +++ b/src/FtpNegotiationCommand.cc @@ -57,6 +57,9 @@ bool FtpNegotiationCommand::executeInternal(Segment segment) { bool FtpNegotiationCommand::recvGreeting() { socket->setBlockingMode(); + disableWriteCheckSocket(); + setReadCheckSocket(socket); + int status = ftp->receiveResponse(); if(status == 0) { return false; @@ -66,9 +69,6 @@ bool FtpNegotiationCommand::recvGreeting() { } sequence = SEQ_SEND_USER; - setReadCheckSocket(socket); - disableWriteCheckSocket(); - return true; } diff --git a/src/Makefile.am b/src/Makefile.am index 1cfbac55..9e61a607 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,7 +52,10 @@ SRCS = Socket.h\ NullLogger.h\ Time.cc Time.h\ SharedHandle.h\ - FeatureConfig.cc FeatureConfig.h + FeatureConfig.cc FeatureConfig.h\ + DownloadEngineFactory.cc DownloadEngineFactory.h\ + RequestInfo.h\ + UrlRequestInfo.cc UrlRequestInfo.h if ENABLE_BITTORRENT SRCS += MetaEntry.h\ @@ -108,7 +111,8 @@ SRCS += MetaEntry.h\ SuggestPieceMessage.cc SuggestPieceMessage.h\ SimplePeerMessage.cc SimplePeerMessage.h\ PeerMessageFactory.cc PeerMessageFactory.h\ - HaveEraseCommand.cc HaveEraseCommand.h + HaveEraseCommand.cc HaveEraseCommand.h\ + TorrentRequestInfo.cc TorrentRequestInfo.h endif # ENABLE_BITTORRENT if ENABLE_METALINK @@ -116,15 +120,16 @@ SRCS += Metalinker.cc Metalinker.h\ MetalinkEntry.cc MetalinkEntry.h\ MetalinkResource.cc MetalinkResource.h\ MetalinkProcessor.h\ - Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h + Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h\ + MetalinkRequestInfo.cc MetalinkRequestInfo.h endif # ENABLE_METALINK noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ -aria2c_LDFLAGS = -pg +#aria2c_LDFLAGS = -pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ - -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg \ No newline at end of file + -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg \ No newline at end of file diff --git a/src/Makefile.in b/src/Makefile.in index 12f65d27..752c58b1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -91,13 +91,15 @@ bin_PROGRAMS = aria2c$(EXEEXT) @ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.cc SuggestPieceMessage.h\ @ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.cc SimplePeerMessage.h\ @ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.cc PeerMessageFactory.h\ -@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.cc HaveEraseCommand.h +@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.cc HaveEraseCommand.h\ +@ENABLE_BITTORRENT_TRUE@ TorrentRequestInfo.cc TorrentRequestInfo.h @ENABLE_METALINK_TRUE@am__append_2 = Metalinker.cc Metalinker.h\ @ENABLE_METALINK_TRUE@ MetalinkEntry.cc MetalinkEntry.h\ @ENABLE_METALINK_TRUE@ MetalinkResource.cc MetalinkResource.h\ @ENABLE_METALINK_TRUE@ MetalinkProcessor.h\ -@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h +@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h\ +@ENABLE_METALINK_TRUE@ MetalinkRequestInfo.cc MetalinkRequestInfo.h subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in alloca.c @@ -155,13 +157,14 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ AbstractDiskWriter.h File.cc File.h Option.cc Option.h \ Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \ LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \ - SharedHandle.h FeatureConfig.cc FeatureConfig.h MetaEntry.h \ - Data.cc Data.h Dictionary.cc Dictionary.h List.cc List.h \ - MetaFileUtil.cc MetaFileUtil.h MetaEntryVisitor.h \ - ShaVisitor.cc ShaVisitor.h TorrentMan.cc TorrentMan.h \ - PeerConnection.cc PeerConnection.h PeerMessageUtil.cc \ - PeerMessageUtil.h PeerAbstractCommand.cc PeerAbstractCommand.h \ - PeerInitiateConnectionCommand.cc \ + SharedHandle.h FeatureConfig.cc FeatureConfig.h \ + DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \ + UrlRequestInfo.cc UrlRequestInfo.h MetaEntry.h Data.cc Data.h \ + Dictionary.cc Dictionary.h List.cc List.h MetaFileUtil.cc \ + MetaFileUtil.h MetaEntryVisitor.h ShaVisitor.cc ShaVisitor.h \ + TorrentMan.cc TorrentMan.h PeerConnection.cc PeerConnection.h \ + PeerMessageUtil.cc PeerMessageUtil.h PeerAbstractCommand.cc \ + PeerAbstractCommand.h PeerInitiateConnectionCommand.cc \ PeerInitiateConnectionCommand.h PeerInteractionCommand.cc \ PeerInteractionCommand.h Peer.cc Peer.h BitfieldMan.cc \ BitfieldMan.h TorrentDownloadEngine.cc TorrentDownloadEngine.h \ @@ -191,9 +194,11 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ SuggestPieceMessage.cc SuggestPieceMessage.h \ SimplePeerMessage.cc SimplePeerMessage.h PeerMessageFactory.cc \ PeerMessageFactory.h HaveEraseCommand.cc HaveEraseCommand.h \ - Metalinker.cc Metalinker.h MetalinkEntry.cc MetalinkEntry.h \ + TorrentRequestInfo.cc TorrentRequestInfo.h Metalinker.cc \ + Metalinker.h MetalinkEntry.cc MetalinkEntry.h \ MetalinkResource.cc MetalinkResource.h MetalinkProcessor.h \ - Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h + Xml2MetalinkProcessor.cc Xml2MetalinkProcessor.h \ + MetalinkRequestInfo.cc MetalinkRequestInfo.h @ENABLE_BITTORRENT_TRUE@am__objects_1 = Data.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ Dictionary.$(OBJEXT) List.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ MetaFileUtil.$(OBJEXT) \ @@ -241,11 +246,13 @@ am__libaria2c_a_SOURCES_DIST = Socket.h SocketCore.cc SocketCore.h \ @ENABLE_BITTORRENT_TRUE@ SuggestPieceMessage.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ SimplePeerMessage.$(OBJEXT) \ @ENABLE_BITTORRENT_TRUE@ PeerMessageFactory.$(OBJEXT) \ -@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.$(OBJEXT) +@ENABLE_BITTORRENT_TRUE@ HaveEraseCommand.$(OBJEXT) \ +@ENABLE_BITTORRENT_TRUE@ TorrentRequestInfo.$(OBJEXT) @ENABLE_METALINK_TRUE@am__objects_2 = Metalinker.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkEntry.$(OBJEXT) \ @ENABLE_METALINK_TRUE@ MetalinkResource.$(OBJEXT) \ -@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.$(OBJEXT) +@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessor.$(OBJEXT) \ +@ENABLE_METALINK_TRUE@ MetalinkRequestInfo.$(OBJEXT) am__objects_3 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ AbstractCommand.$(OBJEXT) \ InitiateConnectionCommandFactory.$(OBJEXT) \ @@ -269,7 +276,8 @@ am__objects_3 = SocketCore.$(OBJEXT) Command.$(OBJEXT) \ PreAllocationDiskWriter.$(OBJEXT) AbstractDiskWriter.$(OBJEXT) \ File.$(OBJEXT) Option.$(OBJEXT) Base64.$(OBJEXT) \ CookieBox.$(OBJEXT) LogFactory.$(OBJEXT) Time.$(OBJEXT) \ - FeatureConfig.$(OBJEXT) $(am__objects_1) $(am__objects_2) + FeatureConfig.$(OBJEXT) DownloadEngineFactory.$(OBJEXT) \ + UrlRequestInfo.$(OBJEXT) $(am__objects_1) $(am__objects_2) am_libaria2c_a_OBJECTS = $(am__objects_3) libaria2c_a_OBJECTS = $(am_libaria2c_a_OBJECTS) am__installdirs = "$(DESTDIR)$(bindir)" @@ -459,17 +467,19 @@ SRCS = Socket.h SocketCore.cc SocketCore.h Command.cc Command.h \ Base64.cc Base64.h CookieBox.cc CookieBox.h messageDigest.h \ LogFactory.cc LogFactory.h NullLogger.h Time.cc Time.h \ SharedHandle.h FeatureConfig.cc FeatureConfig.h \ - $(am__append_1) $(am__append_2) + DownloadEngineFactory.cc DownloadEngineFactory.h RequestInfo.h \ + UrlRequestInfo.cc UrlRequestInfo.h $(am__append_1) \ + $(am__append_2) noinst_LIBRARIES = libaria2c.a libaria2c_a_SOURCES = $(SRCS) aria2c_LDADD = libaria2c.a @LIBINTL@ @ALLOCA@ @LIBGNUTLS_LIBS@\ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ -aria2c_LDFLAGS = -pg +#aria2c_LDFLAGS = -pg AM_CPPFLAGS = -Wall\ -I../lib -I../intl -I$(top_srcdir)/intl\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ - -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -pg + -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@# -pg all: all-am @@ -567,6 +577,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DiskAdaptor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadCommand.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngine.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DownloadEngineFactory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FeatureConfig.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/File.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FtpConnection.Po@am__quote@ @@ -595,6 +606,7 @@ distclean-compile: @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)/MetalinkRequestInfo.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@ @@ -635,9 +647,11 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentConsoleDownloadEngine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentDownloadEngine.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentMan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentRequestInfo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerUpdateCommand.Po@am__quote@ @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)/UrlRequestInfo.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@ diff --git a/src/MetalinkEntry.cc b/src/MetalinkEntry.cc index 6eb86f50..4a4327a8 100644 --- a/src/MetalinkEntry.cc +++ b/src/MetalinkEntry.cc @@ -29,30 +29,6 @@ MetalinkEntry::~MetalinkEntry() { for_each(resources.begin(), resources.end(), Deleter()); } -bool MetalinkEntry::check(const string& filename) const { -#ifdef ENABLE_MESSAGE_DIGEST - 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); -#else - return true; -#endif //ENABLE_MESSAGE_DIGEST -} - class PrefOrder { public: bool operator()(const MetalinkResource* res1, const MetalinkResource* res2) { @@ -71,6 +47,10 @@ public: switch(res->type) { case MetalinkResource::TYPE_FTP: case MetalinkResource::TYPE_HTTP: + case MetalinkResource::TYPE_HTTPS: +#ifdef ENABLE_BITTORRENT + case MetalinkResource::TYPE_BITTORRENT: +#endif // ENABLE_BITTORRENT return true; default: return false; @@ -81,5 +61,6 @@ public: void MetalinkEntry::dropUnsupportedResource() { MetalinkResources::iterator split = partition(resources.begin(), resources.end(), Supported()); + for_each(split, resources.end(), Deleter()); resources.erase(split, resources.end()); } diff --git a/src/MetalinkEntry.h b/src/MetalinkEntry.h index 8e1f98e8..2d6c3a96 100644 --- a/src/MetalinkEntry.h +++ b/src/MetalinkEntry.h @@ -24,6 +24,7 @@ #include "common.h" #include "MetalinkResource.h" +#include "Checksum.h" #include typedef deque MetalinkResources; @@ -35,8 +36,7 @@ public: string language; string os; long long int size; - string md5; - string sha1; + Checksum checksum; public: MetalinkResources resources; public: @@ -50,14 +50,11 @@ public: this->language = metalinkEntry.language; this->os = metalinkEntry.os; this->size = metalinkEntry.size; - this->md5 = metalinkEntry.md5; - this->sha1 = metalinkEntry.sha1; + this->checksum = metalinkEntry.checksum; } return *this; } - bool check(const string& filename) const; - void dropUnsupportedResource(); void reorderResourcesByPreference(); diff --git a/src/MetalinkRequestInfo.cc b/src/MetalinkRequestInfo.cc new file mode 100644 index 00000000..6b58c102 --- /dev/null +++ b/src/MetalinkRequestInfo.cc @@ -0,0 +1,111 @@ +/* */ +#include "MetalinkRequestInfo.h" +#include "Xml2MetalinkProcessor.h" +#include "prefs.h" +#include "DlAbortEx.h" +#include "UrlRequestInfo.h" + +class AccumulateNonP2PUrl { +private: + Strings* urlsPtr; + int split; +public: + AccumulateNonP2PUrl(Strings* urlsPtr, + int split) + :urlsPtr(urlsPtr), + split(split) {} + + void operator()(const MetalinkResource* resource) { + switch(resource->type) { + case MetalinkResource::TYPE_HTTP: + case MetalinkResource::TYPE_HTTPS: + case MetalinkResource::TYPE_FTP: + for(int s = 1; s <= split; s++) { + urlsPtr->push_back(resource->url); + } + break; + } + } +}; + +class FindBitTorrentUrl { +public: + FindBitTorrentUrl() {} + + bool operator()(const MetalinkResource* resource) { + if(resource->type == MetalinkResource::TYPE_BITTORRENT) { + return true; + } else { + return false; + } + } +}; + +RequestInfo* MetalinkRequestInfo::execute() { + RequestInfo* next = 0; + Xml2MetalinkProcessor proc; + Metalinker* metalinker = 0; + try { + metalinker = proc.parseFile(metalinkFile); + + MetalinkEntry* entry = + metalinker->queryEntry(op->get(PREF_METALINK_VERSION), + op->get(PREF_METALINK_LANGUAGE), + op->get(PREF_METALINK_OS)); + if(entry == 0) { + printf("No file matched with your preference.\n"); + throw new DlAbortEx("No file matched with your preference."); + } + entry->dropUnsupportedResource(); + MetalinkResources::iterator itr = + find_if(entry->resources.begin(), + entry->resources.end(), + FindBitTorrentUrl()); + Strings urls; + int maxConnection = 0; + Checksum checksum; + if(itr == entry->resources.end()) { + entry->reorderResourcesByPreference(); + + for_each(entry->resources.begin(), entry->resources.end(), + AccumulateNonP2PUrl(&urls, op->getAsInt(PREF_SPLIT))); + maxConnection = + op->getAsInt(PREF_METALINK_SERVERS)*op->getAsInt(PREF_SPLIT); + + // TODO + // set checksum + checksum = entry->checksum; + } else { + // BitTorrent downloading + urls.push_back((*itr)->url); + } + next = new UrlRequestInfo(urls, maxConnection, op); + next->setChecksum(checksum); + } catch(Exception* e) { + logger->error("Exception caught", e); + delete e; + fail = true; + } + delete metalinker; + return next; +} diff --git a/src/MetalinkRequestInfo.h b/src/MetalinkRequestInfo.h new file mode 100644 index 00000000..763537d5 --- /dev/null +++ b/src/MetalinkRequestInfo.h @@ -0,0 +1,41 @@ +/* */ +#ifndef _D_METALINK_REQUEST_INFO_H_ +#define _D_METALINK_REQUEST_INFO_H_ + +#include "RequestInfo.h" + +class MetalinkRequestInfo : public RequestInfo { +private: + string metalinkFile; +public: + MetalinkRequestInfo(const string& metalinkFile, const Option* op): + RequestInfo(op), + metalinkFile(metalinkFile) {} + virtual ~MetalinkRequestInfo() {} + + virtual RequestInfo* execute(); + + virtual DownloadEngine* getDownloadEngine() { return 0; } +}; + +#endif // _D_METALINK_REQUEST_INFO_H_ diff --git a/src/MetalinkResource.h b/src/MetalinkResource.h index 497e65c8..44ddc23b 100644 --- a/src/MetalinkResource.h +++ b/src/MetalinkResource.h @@ -29,6 +29,7 @@ public: enum TYPE { TYPE_FTP, TYPE_HTTP, + TYPE_HTTPS, TYPE_BITTORRENT, TYPE_NOT_SUPPORTED }; diff --git a/src/MultiDiskWriter.cc b/src/MultiDiskWriter.cc index f40f6da0..d0a13776 100644 --- a/src/MultiDiskWriter.cc +++ b/src/MultiDiskWriter.cc @@ -25,18 +25,15 @@ #include "message.h" #include -MultiDiskWriter::MultiDiskWriter(int pieceLength):pieceLength(pieceLength) { -#ifdef ENABLE_MESSAGE_DIGEST - ctx.setAlgo(MessageDigestContext::ALGO_SHA1); - digestInit(ctx); -#endif // ENABLE_MESSAGE_DIGEST +MultiDiskWriter::MultiDiskWriter(int pieceLength): + pieceLength(pieceLength), + ctx(DIGEST_ALGO_SHA1) { + ctx.digestInit(); } MultiDiskWriter::~MultiDiskWriter() { clearEntries(); -#ifdef ENABLE_MESSAGE_DIGEST - digestFree(ctx); -#endif // ENABLE_MESSAGE_DIGEST + ctx.digestFree(); } void MultiDiskWriter::clearEntries() { @@ -143,7 +140,6 @@ int MultiDiskWriter::readData(char* data, int len, long long int offset) { return totalReadLength; } -#ifdef ENABLE_MESSAGE_DIGEST void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, long long int length) { int BUFSIZE = 16*1024; char buf[BUFSIZE]; @@ -151,7 +147,7 @@ void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, l if(BUFSIZE != entry->diskWriter->readData(buf, BUFSIZE, offset)) { throw string("error"); } - digestUpdate(ctx, buf, BUFSIZE); + ctx.digestUpdate(buf, BUFSIZE); offset += BUFSIZE; } int r = length%BUFSIZE; @@ -159,17 +155,15 @@ void MultiDiskWriter::hashUpdate(DiskWriterEntry* entry, long long int offset, l if(r != entry->diskWriter->readData(buf, r, offset)) { throw string("error"); } - digestUpdate(ctx, buf, r); + ctx.digestUpdate(buf, r); } } -#endif // ENABLE_MESSAGE_DIGEST string MultiDiskWriter::sha1Sum(long long int offset, long long int length) { -#ifdef ENABLE_MESSAGE_DIGEST long long int fileOffset = offset; bool reading = false; int rem = length; - digestReset(ctx); + ctx.digestReset(); try { for(DiskWriterEntries::iterator itr = diskWriterEntries.begin(); itr != diskWriterEntries.end() && rem != 0; itr++) { @@ -187,13 +181,10 @@ 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]; - digestFinal(ctx, hashValue); + ctx.digestFinal(hashValue); return Util::toHex(hashValue, 20); } catch(string ex) { throw new DlAbortEx(EX_FILE_SHA1SUM, "", strerror(errno)); } -#else - return ""; -#endif // ENABLE_MESSAGE_DIGEST } diff --git a/src/MultiDiskWriter.h b/src/MultiDiskWriter.h index 0cd18cb5..a903424d 100644 --- a/src/MultiDiskWriter.h +++ b/src/MultiDiskWriter.h @@ -48,10 +48,8 @@ private: bool isInRange(const DiskWriterEntry* entry, long long int offset) const; int calculateLength(const DiskWriterEntry* entry, long long int fileOffset, int rem) const; void clearEntries(); -#ifdef ENABLE_MESSAGE_DIGEST MessageDigestContext ctx; void hashUpdate(DiskWriterEntry* entry, long long int offset, long long int length); -#endif // ENABLE_MESSAGE_DIGEST public: MultiDiskWriter(int pieceLength); diff --git a/src/PeerChokeCommand.cc b/src/PeerChokeCommand.cc index 7a32e6da..8fdb44fa 100644 --- a/src/PeerChokeCommand.cc +++ b/src/PeerChokeCommand.cc @@ -22,7 +22,7 @@ #include "PeerChokeCommand.h" #include "Util.h" -PeerChokeCommand::PeerChokeCommand(int cuid, int interval, TorrentDownloadEngine* e):Command(cuid), interval(interval), e(e), rotate(0) {} +PeerChokeCommand::PeerChokeCommand(int cuid, TorrentDownloadEngine* e, int interval):Command(cuid), interval(interval), e(e), rotate(0) {} PeerChokeCommand::~PeerChokeCommand() {} diff --git a/src/PeerChokeCommand.h b/src/PeerChokeCommand.h index c0019bf6..c31a9f9b 100644 --- a/src/PeerChokeCommand.h +++ b/src/PeerChokeCommand.h @@ -38,7 +38,7 @@ private: void optUnchokingPeer(Peers& peers) const; public: - PeerChokeCommand(int cuid, int interval, TorrentDownloadEngine* e); + PeerChokeCommand(int cuid, TorrentDownloadEngine* e, int interval); virtual ~PeerChokeCommand(); bool execute(); diff --git a/src/RequestInfo.h b/src/RequestInfo.h new file mode 100644 index 00000000..b8a6bdf0 --- /dev/null +++ b/src/RequestInfo.h @@ -0,0 +1,116 @@ +/* */ +#ifndef _D_REQUEST_INFO_H_ +#define _D_REQUEST_INFO_H_ + +#include "common.h" +#include "LogFactory.h" +#include "Option.h" +#include "DownloadEngine.h" +#include "Util.h" +#include "Checksum.h" +#include + +class FileInfo { +public: + string filename; + long long int length; + Checksum checksum; +public: + FileInfo():length(0) {} + ~FileInfo() {} + + bool isEmpty() const { + return filename.size() == 0 && length == 0; + } + + bool checkReady() const { +#ifdef ENABLE_MESSAGE_DIGEST + return !isEmpty() && !checksum.isEmpty(); +#else + return false; +#endif // ENABLE_MESSAGE_DIGEST + } + + bool check() const { +#ifdef ENABLE_MESSAGE_DIGEST + unsigned char md[MAX_MD_LENGTH]; + Util::fileChecksum(filename, md, checksum.getDigestAlgo()); + return Util::toHex(md, + MessageDigestContext::digestLength(checksum.getDigestAlgo())) + == checksum.getMessageDigest(); +#else + return false; +#endif // ENABLE_MESSAGE_DIGEST + } + + bool isTorrentFile() const { + return Util::endsWith(filename, ".torrent"); + } + + bool isMetalinkFile() const { + return Util::endsWith(filename, ".metalink"); + } +}; + +class RequestInfo { +protected: + const Option* op; + const Logger* logger; + Checksum checksum; + FileInfo fileInfo; + bool fail; + + void printDownloadCompeleteMessage(const string& filename) { + printf(_("\nThe download was complete. <%s>\n"), filename.c_str()); + } + + void printDownloadCompeleteMessage() { + printf("\nThe download was complete.\n"); + } + + void printDownloadAbortMessage() { + printf(_("\nThe download was not complete because of errors. Check the log.\n")); + } +public: + RequestInfo(const Option* op): + op(op), + fail(false) + { + logger = LogFactory::getInstance(); + } + virtual ~RequestInfo() {} + + virtual RequestInfo* execute() = 0; + + virtual DownloadEngine* getDownloadEngine() = 0; + + bool isFail() const { return fail; } + + void setChecksum(const Checksum& checksum) { + this->checksum = checksum; + } + const Checksum& getChecksum() const { return checksum; } + const FileInfo& getFileInfo() const { return fileInfo; } +}; + +#endif // _D_REQUEST_INFO_H_ diff --git a/src/ShaVisitor.cc b/src/ShaVisitor.cc index 6807e7c2..e1cbc2c3 100644 --- a/src/ShaVisitor.cc +++ b/src/ShaVisitor.cc @@ -22,60 +22,49 @@ #include "ShaVisitor.h" #include "Util.h" -ShaVisitor::ShaVisitor() { -#ifdef ENABLE_MESSAGE_DIGEST - ctx.setAlgo(MessageDigestContext::ALGO_SHA1); - digestInit(ctx); - digestReset(ctx); -#endif // ENABLE_MESSAGE_DIGEST +ShaVisitor::ShaVisitor(): + ctx(DIGEST_ALGO_SHA1) { + ctx.digestInit(); } ShaVisitor::~ShaVisitor() { -#ifdef ENABLE_MESSAGE_DIGEST - digestFree(ctx); -#endif // ENABLE_MESSAGE_DIGEST + ctx.digestFree(); } void ShaVisitor::visit(const Data* d) { -#ifdef ENABLE_MESSAGE_DIGEST if(d->isNumber()) { - digestUpdate(ctx, "i", 1); + ctx.digestUpdate("i", 1); } else { string lenStr = Util::llitos(d->getLen()); - digestUpdate(ctx, lenStr.c_str(), lenStr.size()); - digestUpdate(ctx, ":", 1); + ctx.digestUpdate(lenStr.c_str(), lenStr.size()); + ctx.digestUpdate(":", 1); } - digestUpdate(ctx, d->getData(), d->getLen()); + ctx.digestUpdate(d->getData(), d->getLen()); if(d->isNumber()) { - digestUpdate(ctx, "e", 1); + ctx.digestUpdate("e", 1); } -#endif // ENABLE_MESSAGE_DIGEST } void ShaVisitor::visit(const Dictionary* d) { -#ifdef ENABLE_MESSAGE_DIGEST - digestUpdate(ctx, "d", 1); + ctx.digestUpdate("d", 1); const Order& v = d->getOrder(); for(Order::const_iterator itr = v.begin(); itr != v.end(); itr++) { string lenStr = Util::llitos(itr->size()); - digestUpdate(ctx, lenStr.c_str(), lenStr.size()); - digestUpdate(ctx, ":", 1); - digestUpdate(ctx, itr->c_str(), itr->size()); + ctx.digestUpdate(lenStr.c_str(), lenStr.size()); + ctx.digestUpdate(":", 1); + ctx.digestUpdate(itr->c_str(), itr->size()); const MetaEntry* e = d->get(*itr); this->visit(e); } - digestUpdate(ctx, "e", 1); -#endif // ENABLE_MESSAGE_DIGEST + ctx.digestUpdate("e", 1); } void ShaVisitor::visit(const List* l) { -#ifdef ENABLE_MESSAGE_DIGEST - digestUpdate(ctx, "l", 1); + ctx.digestUpdate("l", 1); for(MetaList::const_iterator itr = l->getList().begin(); itr != l->getList().end(); itr++) { this->visit(*itr); } - digestUpdate(ctx, "e", 1); -#endif // ENABLE_MESSAGE_DIGEST + ctx.digestUpdate("e", 1); } void ShaVisitor::visit(const MetaEntry* e) { @@ -89,8 +78,6 @@ void ShaVisitor::visit(const MetaEntry* e) { } void ShaVisitor::getHash(unsigned char* hashValue, int& len) { -#ifdef ENABLE_MESSAGE_DIGEST - digestFinal(ctx, hashValue); - len = 20; -#endif // ENABLE_MESSAGE_DIGEST + len = ctx.digestLength(); + ctx.digestFinal(hashValue); } diff --git a/src/ShaVisitor.h b/src/ShaVisitor.h index 87f98d9a..cecced65 100644 --- a/src/ShaVisitor.h +++ b/src/ShaVisitor.h @@ -27,15 +27,11 @@ #include "Dictionary.h" #include "List.h" #include "common.h" -#ifdef ENABLE_MESSAGE_DIGEST #include "messageDigest.h" -#endif // ENABLE_MESSAGE_DIGEST class ShaVisitor : public MetaEntryVisitor { private: -#ifdef ENABLE_MESSAGE_DIGEST MessageDigestContext ctx; -#endif // ENABLE_MESSAGE_DIGEST public: ShaVisitor(); ~ShaVisitor(); diff --git a/src/TorrentMan.cc b/src/TorrentMan.cc index 0e97453e..5704bdd5 100644 --- a/src/TorrentMan.cc +++ b/src/TorrentMan.cc @@ -43,7 +43,7 @@ extern PeerHandle nullPeer; -TorrentMan::TorrentMan():bitfield(NULL), +TorrentMan::TorrentMan():bitfield(0), peerEntryIdCounter(0), cuidCounter(0), downloadLength(0), @@ -61,18 +61,16 @@ TorrentMan::TorrentMan():bitfield(NULL), incomplete(0), connections(0), trackers(0), - diskAdaptor(NULL) + req(0), + diskAdaptor(0) { logger = LogFactory::getInstance(); } TorrentMan::~TorrentMan() { - if(bitfield != NULL) { - delete bitfield; - } - if(diskAdaptor != NULL) { - delete diskAdaptor; - } + delete bitfield; + delete diskAdaptor; + delete req; } // TODO do not use this method in application code diff --git a/src/TorrentRequestInfo.cc b/src/TorrentRequestInfo.cc new file mode 100644 index 00000000..bfc2945c --- /dev/null +++ b/src/TorrentRequestInfo.cc @@ -0,0 +1,81 @@ +/* */ +#include "TorrentRequestInfo.h" +#include "DownloadEngineFactory.h" +#include "prefs.h" +#include "Util.h" + +extern RequestInfo* requestInfo; +extern void setSignalHander(int signal, void (*handler)(int), int flags); + +void torrentHandler(int signal) { + ((TorrentDownloadEngine*)requestInfo->getDownloadEngine())-> + torrentMan->setHalt(true); +} + +RequestInfo* TorrentRequestInfo::execute() { + if(op->get(PREF_SHOW_FILES) == V_TRUE) { + showFileEntry(); + return 0; + } + e = DownloadEngineFactory::newTorrentConsoleEngine(op, + torrentFile, + targetFiles); + setSignalHander(SIGINT, torrentHandler, SA_RESETHAND); + setSignalHander(SIGTERM, torrentHandler, SA_RESETHAND); + + try { + e->run(); + if(e->torrentMan->downloadComplete()) { + printDownloadCompeleteMessage(); + } + } catch(Exception* e) { + logger->error("Exception caught", e); + delete e; + fail = true; + } + setSignalHander(SIGINT, SIG_DFL, 0); + setSignalHander(SIGTERM, SIG_DFL, 0); + delete e; + + return 0; +} + +// TODO should be const TorrentMan* torrentMan +void TorrentRequestInfo::showFileEntry() +{ + TorrentMan torrentMan; + torrentMan.option = op; + + FileEntries fileEntries = + torrentMan.readFileEntryFromMetaInfoFile(torrentFile); + cout << _("Files:") << endl; + cout << "idx|path/length" << endl; + cout << "===+===========================================================================" << endl; + int count = 1; + for(FileEntries::const_iterator itr = fileEntries.begin(); + itr != fileEntries.end(); count++, itr++) { + printf("%3d|%s\n |%s Bytes\n", count, itr->path.c_str(), + Util::llitos(itr->length, true).c_str()); + cout << "---+---------------------------------------------------------------------------" << endl; + } +} diff --git a/src/TorrentRequestInfo.h b/src/TorrentRequestInfo.h new file mode 100644 index 00000000..f9e61d22 --- /dev/null +++ b/src/TorrentRequestInfo.h @@ -0,0 +1,51 @@ +/* */ +#ifndef _D_TORRENT_REQUEST_INFO_H_ +#define _D_TORRENT_REQUEST_INFO_H_ + +#include "RequestInfo.h" +#include "TorrentDownloadEngine.h" + +class TorrentRequestInfo : public RequestInfo { +private: + string torrentFile; + TorrentDownloadEngine* e; + Strings targetFiles; + + void showFileEntry(); +public: + TorrentRequestInfo(const string& torrentFile, const Option* op): + RequestInfo(op), + torrentFile(torrentFile), + e(0) {} + virtual ~TorrentRequestInfo() {} + + virtual RequestInfo* execute(); + + void setTargetFiles(const Strings& targetFiles) { + this->targetFiles = targetFiles; + } + virtual DownloadEngine* getDownloadEngine() { return e; } + +}; + +#endif // _D_TORRENT_REQUEST_INFO_H_ diff --git a/src/UrlRequestInfo.cc b/src/UrlRequestInfo.cc new file mode 100644 index 00000000..986dbc97 --- /dev/null +++ b/src/UrlRequestInfo.cc @@ -0,0 +1,146 @@ +/* */ +#include "UrlRequestInfo.h" +#include "TorrentRequestInfo.h" +#include "MetalinkRequestInfo.h" +#include "prefs.h" +#include "DownloadEngineFactory.h" + +extern RequestInfo* requestInfo; +extern void setSignalHander(int signal, void (*handler)(int), int flags); + +void UrlRequestInfo::adjustRequestSize(Requests& requests, + Requests& reserved, + int maxConnections) const +{ + if(maxConnections > 0 && (int)requests.size() > maxConnections) { + copy(requests.begin()+maxConnections, requests.end(), + back_inserter(reserved)); + //insert_iterator(reserved, reserved.end())); + requests.erase(requests.begin()+maxConnections, requests.end()); + } +} + +RequestInfo* UrlRequestInfo::createNextRequestInfo() const +{ +#ifdef ENABLE_BITTORRENT + if(op->getAsBool(PREF_FOLLOW_TORRENT) && + Util::endsWith(fileInfo.filename, ".torrent")) { + return new TorrentRequestInfo(fileInfo.filename, op); + } else +#endif // ENABLE_BITTORRENT +#ifdef ENABLE_METALINK + if(op->getAsBool(PREF_FOLLOW_METALINK) && + Util::endsWith(fileInfo.filename, ".metalink")) { + return new MetalinkRequestInfo(fileInfo.filename, op); + } else +#endif // ENABLE_METALINK + { + return 0; + } +} + +void handler(int signal) { + printf(_("\nstopping application...\n")); + fflush(stdout); + requestInfo->getDownloadEngine()->segmentMan->save(); + requestInfo->getDownloadEngine()->segmentMan->diskWriter->closeFile(); + delete requestInfo->getDownloadEngine(); + printf(_("done\n")); + exit(EXIT_SUCCESS); +} + +class CreateRequest { +private: + Requests* requestsPtr; + string referer; + int split; +public: + CreateRequest(Requests* requestsPtr, + const string& referer, + int split) + :requestsPtr(requestsPtr), + referer(referer), + split(split) {} + + void operator()(const string& url) { + for(int s = 1; s <= split; s++) { + Request* req = new Request(); + req->setReferer(referer); + if(req->setUrl(url)) { + requestsPtr->push_back(req); + } else { + fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"), + req->getUrl().c_str()); + delete req; + } + } + } +}; + +RequestInfo* UrlRequestInfo::execute() { + Requests requests; + Requests reserved; + for_each(urls.begin(), urls.end(), + CreateRequest(&requests, + op->get(PREF_REFERER), + op->getAsInt(PREF_SPLIT))); + + adjustRequestSize(requests, reserved, maxConnections); + + e = DownloadEngineFactory::newConsoleEngine(op, requests, reserved); + + setSignalHander(SIGINT, handler, 0); + setSignalHander(SIGTERM, handler, 0); + + RequestInfo* next = 0; + try { + e->run(); + + if(e->segmentMan->finished()) { + printDownloadCompeleteMessage(e->segmentMan->getFilePath()); + fileInfo.filename = e->segmentMan->getFilePath(); + fileInfo.length = e->segmentMan->totalSize; + fileInfo.checksum = checksum; + + next = createNextRequestInfo(); + } else { + e->segmentMan->save(); + e->segmentMan->diskWriter->closeFile(); + printDownloadAbortMessage(); + } + } catch(Exception *e) { + logger->error("Exception caught", e); + delete e; + fail = true; + } + for_each(requests.begin(), requests.end(), Deleter()); + for_each(reserved.begin(), reserved.end(), Deleter()); + + setSignalHander(SIGINT, SIG_DFL, 0); + setSignalHander(SIGTERM, SIG_DFL, 0); + + delete e; + e = 0; + + return next; +} diff --git a/src/UrlRequestInfo.h b/src/UrlRequestInfo.h new file mode 100644 index 00000000..85172b29 --- /dev/null +++ b/src/UrlRequestInfo.h @@ -0,0 +1,52 @@ +/* */ +#ifndef _D_URL_REQUEST_INFO_H_ +#define _D_URL_REQUEST_INFO_H_ + +#include "RequestInfo.h" + +class UrlRequestInfo : public RequestInfo { +private: + Strings urls; + int maxConnections; + DownloadEngine* e; + + RequestInfo* createNextRequestInfo() const; + void adjustRequestSize(Requests& requests, + Requests& reserved, + int maxConnections) const; +public: + UrlRequestInfo(const Strings& urls, int maxConnections, const Option* op): + RequestInfo(op), + urls(urls), + maxConnections(maxConnections), + e(0) {} + virtual ~UrlRequestInfo() {} + + virtual RequestInfo* execute(); + + virtual DownloadEngine* getDownloadEngine() { + return e; + } +}; + +#endif // _D_URL_REQUEST_INFO_H_ diff --git a/src/Util.cc b/src/Util.cc index 5780889d..846e8976 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -363,21 +363,20 @@ string Util::getContentDispositionFilename(const string& header) { #ifdef ENABLE_MESSAGE_DIGEST void Util::sha1Sum(unsigned char* digest, const void* data, int dataLength) { - MessageDigestContext ctx(MessageDigestContext::ALGO_SHA1); - digestInit(ctx); - digestReset(ctx); - digestUpdate(ctx, data, dataLength); - digestFinal(ctx, digest); - digestFree(ctx); + MessageDigestContext ctx(DIGEST_ALGO_SHA1); + ctx.digestInit(); + ctx.digestUpdate(data, dataLength); + ctx.digestFinal(digest); + ctx.digestFree(); } #endif // ENABLE_MESSAGE_DIGEST #ifdef ENABLE_MESSAGE_DIGEST void Util::fileChecksum(const string& filename, unsigned char* digest, - MessageDigestContext::HashAlgo algo) { + MessageDigestContext::DigestAlgo algo) { MessageDigestContext ctx(algo); - digestInit(ctx); - digestReset(ctx); + ctx.digestInit(); + ctx.digestReset(); int BUFLEN = 4096; char buf[BUFLEN]; @@ -396,14 +395,14 @@ void Util::fileChecksum(const string& filename, unsigned char* digest, throw new DlAbortEx(EX_FILE_READ, filename.c_str(), strerror(errno)); } } else if(size > 0) { - digestUpdate(ctx, buf, size); + ctx.digestUpdate(buf, size); } if(size < BUFLEN) { break; } } - digestFinal(ctx, digest); - digestFree(ctx); + ctx.digestFinal(digest); + ctx.digestFree(); } #endif // ENABLE_MESSAGE_DIGEST diff --git a/src/Util.h b/src/Util.h index 98536864..9a01da8b 100644 --- a/src/Util.h +++ b/src/Util.h @@ -92,7 +92,7 @@ public: // For sha1, you need 20 bytes. For md5, 16 bytes. #ifdef ENABLE_MESSAGE_DIGEST static void fileChecksum(const string& filename, unsigned char* digest, - MessageDigestContext::HashAlgo algo); + MessageDigestContext::DigestAlgo algo); #endif // ENABLE_MESSAGE_DIGEST #ifdef ENABLE_BITTORRENT diff --git a/src/Xml2MetalinkProcessor.cc b/src/Xml2MetalinkProcessor.cc index bb3281a9..f68f2da2 100644 --- a/src/Xml2MetalinkProcessor.cc +++ b/src/Xml2MetalinkProcessor.cc @@ -88,8 +88,20 @@ MetalinkEntry* Xml2MetalinkProcessor::getEntry(const string& xpath) { 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::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]"))); - entry->sha1 = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]"))); +#ifdef ENABLE_MESSAGE_DIGEST + string md; + md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"sha1\"]"))); + if(md.size() > 0) { + entry->checksum.setMessageDigest(md); + entry->checksum.setDigestAlgo(DIGEST_ALGO_SHA1); + } else { + md = Util::toLower(Util::trim(xpathContent(xpath+"/m:verification/m:hash[@type=\"md5\"]"))); + if(md.size() > 0) { + entry->checksum.setMessageDigest(md); + entry->checksum.setDigestAlgo(DIGEST_ALGO_MD5); + } + } +#endif // ENABLE_MESSAGE_DIGEST for(int index = 1; 1; index++) { MetalinkResource* resource = getResource(xpath+"/m:resources/m:url["+Util::itos(index)+"]"); @@ -121,6 +133,8 @@ MetalinkResource* Xml2MetalinkProcessor::getResource(const string& xpath) { resource->type = MetalinkResource::TYPE_FTP; } else if(type == "http") { resource->type = MetalinkResource::TYPE_HTTP; + } else if(type == "https") { + resource->type = MetalinkResource::TYPE_HTTPS; } else if(type == "bittorrent") { resource->type = MetalinkResource::TYPE_BITTORRENT; } else { diff --git a/src/main.cc b/src/main.cc index 943a54db..09543542 100644 --- a/src/main.cc +++ b/src/main.cc @@ -30,23 +30,11 @@ #include "InitiateConnectionCommandFactory.h" #include "prefs.h" #include "FeatureConfig.h" - -#ifdef ENABLE_BITTORRENT -# include "TorrentConsoleDownloadEngine.h" -# include "TorrentMan.h" -# include "PeerListenCommand.h" -# include "TorrentAutoSaveCommand.h" -# include "TrackerWatcherCommand.h" -# include "TrackerUpdateCommand.h" -# include "HaveEraseCommand.h" -# include "ByteArrayDiskWriter.h" -# include "PeerChokeCommand.h" -#endif // ENABLE_BITTORRENT - -#ifdef ENABLE_METALINK -# include "Xml2MetalinkProcessor.h" -#endif // ENABLE_METALINK - +#include "DownloadEngineFactory.h" +#include "UrlRequestInfo.h" +#include "TorrentRequestInfo.h" +#include "MetalinkRequestInfo.h" +#include "Xml2MetalinkProcessor.h" #include #include #include @@ -69,22 +57,7 @@ extern int optind, opterr, optopt; using namespace std; -bool readyToTorrentMode = false; -string downloadedTorrentFile; -bool readyToMetalinkMode = false; -string downloadedMetalinkFile; - -void printDownloadCompeleteMessage(string filename) { - printf(_("\nThe download was complete. <%s>\n"), filename.c_str()); -} - -void printDownloadCompeleteMessage() { - printf("\nThe download was complete.\n"); -} - -void printDownloadAbortMessage() { - printf(_("\nThe download was not complete because of errors. Check the log.\n")); -} +RequestInfo* requestInfo; void setSignalHander(int signal, void (*handler)(int), int flags) { struct sigaction sigact; @@ -94,39 +67,6 @@ void setSignalHander(int signal, void (*handler)(int), int flags) { sigaction(signal, &sigact, NULL); } -DownloadEngine* e; -#ifdef ENABLE_BITTORRENT -TorrentDownloadEngine* te; -#endif // ENABLE_BITTORRENT - -void handler(int signal) { - printf(_("\nstopping application...\n")); - fflush(stdout); - e->segmentMan->save(); - e->segmentMan->diskWriter->closeFile(); - e->cleanQueue(); - delete e; - printf(_("done\n")); - exit(EXIT_SUCCESS); -} - -#ifdef ENABLE_BITTORRENT -void torrentHandler(int signal) { - te->torrentMan->setHalt(true); -} -#endif // ENABLE_BITTORRENT - -void createRequest(int cuid, const string& url, string referer, Requests& requests) { - Request* req = new Request(); - req->setReferer(referer); - if(req->setUrl(url)) { - requests.push_back(req); - } else { - fprintf(stderr, _("Unrecognized URL or unsupported protocol: %s\n"), req->getUrl().c_str()); - delete(req); - } -} - void showVersion() { cout << PACKAGE << _(" version ") << PACKAGE_VERSION << endl; cout << "Copyright (C) 2006 Tatsuhiro Tsujikawa" << endl; @@ -182,7 +122,7 @@ void showUsage() { cout << _(" --min-segment-size=SIZE[K|M] Set minimum segment size. You can append\n" " K or M(1K = 1024, 1M = 1024K). This\n" " value must be greater than or equal to\n" - " 1024.") << endl; + " 1024. Default: 1M") << endl; cout << _(" --http-proxy=HOST:PORT Use HTTP proxy server. This affects to all\n" " URLs.") << endl; cout << _(" --http-user=USER Set HTTP user. This affects to all URLs.") << endl; @@ -207,6 +147,12 @@ void showUsage() { cout << _(" --ftp-via-http-proxy=METHOD Use HTTP proxy in FTP. METHOD is either 'get' or\n" " 'tunnel'.\n" " Default: tunnel") << endl; + cout << _(" --lowest-speed-limit Close connection if download speed is lower than\n" + " or equal to this value. 0 means aria2 does not\n" + " care lowest speed limit. You can use K or M in\n" + " the same manner as in --min-segment-size option.\n" + " This option does not affect BitTorrent download.\n" + " Default: 0") << endl; #ifdef ENABLE_BITTORRENT cout << _(" -T, --torrent-file=TORRENT_FILE The file path to .torrent file.") << endl; cout << _(" --follow-torrent=true|false Setting this option to false prevents aria2 to\n" @@ -288,52 +234,19 @@ void showUsage() { cout << endl; } -bool normalDownload(const Requests& requests, - const Requests& reserved, - Option* op, - 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 = op->get(PREF_DIR); - e->segmentMan->ufilename = op->get(PREF_OUT); - 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; +long long int getRealSize(char* optarg) { + string::size_type p = string(optarg).find_first_of("KM"); + int mult = 1; + if(p != string::npos) { + if(optarg[p] == 'K') { + mult = 1024; + } else if(optarg[p] == 'M') { + mult = 1024*1024; } - downloadedFilename = e->segmentMan->getFilePath(); - success = true; - } else { - e->segmentMan->save(); - e->segmentMan->diskWriter->closeFile(); - printDownloadAbortMessage(); + optarg[p] = '\0'; } - e->cleanQueue(); - delete e; - - return success; + long long int size = strtoll(optarg, NULL, 10)*mult; + return size; } int main(int argc, char* argv[]) { @@ -343,18 +256,6 @@ int main(int argc, char* argv[]) { bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif // ENABLE_NLS - 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(); op->put(PREF_STDOUT_LOG, V_FALSE); @@ -363,6 +264,20 @@ int main(int argc, char* argv[]) { op->put(PREF_DAEMON, V_FALSE); op->put(PREF_LISTEN_PORT, "-1"); op->put(PREF_METALINK_SERVERS, "15"); + op->put(PREF_FOLLOW_TORRENT, +#ifdef ENABLE_BITTORRENT + V_TRUE +#else + V_FALSE +#endif // ENABLE_BITTORRENT + ); + op->put(PREF_FOLLOW_METALINK, +#ifdef ENABLE_METALINK + V_TRUE +#else + V_FALSE +#endif // ENABLE_METALINK + ); op->put(PREF_RETRY_WAIT, "5"); op->put(PREF_TIMEOUT, "60"); op->put(PREF_PEER_CONNECTION_TIMEOUT, "60"); @@ -377,6 +292,7 @@ int main(int argc, char* argv[]) { op->put(PREF_AUTO_SAVE_INTERVAL, "60"); op->put(PREF_DIRECT_FILE_MAPPING, V_TRUE); op->put(PREF_UPLOAD_LIMIT, "0"); + op->put(PREF_LOWEST_SPEED_LIMIT, "4000"); while(1) { int optIndex = 0; int lopt; @@ -403,6 +319,7 @@ int main(int argc, char* argv[]) { { "ftp-via-http-proxy", required_argument, &lopt, 12 }, { "min-segment-size", required_argument, &lopt, 13 }, { "http-proxy-method", required_argument, &lopt, 14 }, + { "lowest-speed-limit", required_argument, &lopt, 200 }, #ifdef ENABLE_BITTORRENT { "torrent-file", required_argument, NULL, 'T' }, { "listen-port", required_argument, &lopt, 15 }, @@ -506,17 +423,7 @@ int main(int argc, char* argv[]) { } break; case 13: { - string::size_type p = string(optarg).find_first_of("KM"); - int mult = 1; - if(p != string::npos) { - if(optarg[p] == 'K') { - mult = 1024; - } else if(optarg[p] == 'M') { - mult = 1024*1024; - } - optarg[p] = '\0'; - } - long long int size = strtoll(optarg, NULL, 10)*mult; + long long int size = getRealSize(optarg); if(size < 1024) { cerr << _("min-segment-size invalid") << endl; showUsage(); @@ -546,9 +453,9 @@ int main(int argc, char* argv[]) { } case 16: if(string(optarg) == "true") { - followTorrent = true; + op->put(PREF_FOLLOW_TORRENT, V_TRUE); } else if(string(optarg) == "false") { - followTorrent = false; + op->put(PREF_FOLLOW_TORRENT, V_FALSE); } else { cerr << _("follow-torrent must be either 'true' or 'false'.") << endl; showUsage(); @@ -580,7 +487,7 @@ int main(int argc, char* argv[]) { break; } case 21: - Util::unfoldRange(optarg, selectFileIndexes); + op->put(PREF_SELECT_FILE, optarg); break; case 100: op->put(PREF_METALINK_VERSION, optarg); @@ -593,15 +500,25 @@ int main(int argc, char* argv[]) { break; case 103: if(string(optarg) == "true") { - followMetalink = true; + op->put(PREF_FOLLOW_METALINK, V_TRUE); } else if(string(optarg) == "false") { - followMetalink = false; + op->put(PREF_FOLLOW_METALINK, V_FALSE); } else { cerr << _("follow-metalink must be either 'true' or 'false'.") << endl; showUsage(); exit(EXIT_FAILURE); } break; + case 200: { + int limit = getRealSize(optarg); + if(limit < 0) { + cerr << _("lowest-speed-limit must be greater than or equal to 0") << endl; + showUsage(); + exit(EXIT_FAILURE); + } + op->put(PREF_LOWEST_SPEED_LIMIT, Util::itos(limit)); + break; + } } break; } @@ -720,190 +637,58 @@ int main(int argc, char* argv[]) { } // make sure logger is configured properly. try { - LogFactory::getInstance(); + Logger* logger = LogFactory::getInstance(); + logger->info("%s %s", PACKAGE, PACKAGE_VERSION); + logger->info("Logging started."); + + setSignalHander(SIGPIPE, SIG_IGN, 0); + + requestInfo = 0; +#ifdef ENABLE_BITTORRENT + if(op->defined(PREF_TORRENT_FILE)) { + requestInfo = new TorrentRequestInfo(op->get(PREF_TORRENT_FILE), + op); + Strings targetFiles; + if(op->defined(PREF_TORRENT_FILE) && !args.empty()) { + targetFiles = args; + } + ((TorrentRequestInfo*)requestInfo)->setTargetFiles(targetFiles); + } + else +#endif // ENABLE_BITTORRENT +#ifdef ENABLE_METALINK + if(op->defined(PREF_METALINK_FILE)) { + requestInfo = new MetalinkRequestInfo(op->get(PREF_METALINK_FILE), + op); + } else +#endif // ENABLE_METALINK + { + requestInfo = new UrlRequestInfo(args, 0, op); + } + + while(requestInfo) { + RequestInfo* next = requestInfo->execute(); + if(requestInfo->isFail()) { + delete requestInfo; + exit(EXIT_FAILURE); + } + if(requestInfo->getFileInfo().checkReady()) { + if(requestInfo->getFileInfo().check()) { + printf("checksum OK.\n"); + } else { + // TODO + printf("checksum ERROR.\n"); + exit(EXIT_FAILURE); + } + } + delete requestInfo; + requestInfo = next; + } } catch(Exception* ex) { cerr << ex->getMsg() << endl; delete ex; exit(EXIT_FAILURE); } - - setSignalHander(SIGPIPE, SIG_IGN, 0); - - if(!op->defined(PREF_TORRENT_FILE) && !op->defined(PREF_METALINK_FILE)) { - Requests requests; - int cuidCounter = 1; - for(Strings::const_iterator itr = args.begin(); itr != args.end(); itr++) { - for(int s = 1; s <= op->getAsInt(PREF_SPLIT); s++) { - createRequest(cuidCounter, *itr, op->get(PREF_REFERER), requests); - cuidCounter++; - } - } - setSignalHander(SIGINT, handler, 0); - setSignalHander(SIGTERM, handler, 0); - - Requests reserved; - string downloadedFilename; - normalDownload(requests, reserved, op, downloadedFilename); - - for_each(requests.begin(), requests.end(), Deleter()); - for_each(reserved.begin(), reserved.end(), Deleter()); - requests.clear(); - } -#ifdef ENABLE_METALINK - if(op->defined(PREF_METALINK_FILE) || - followMetalink && readyToMetalinkMode) { - string targetMetalinkFile = op->defined(PREF_METALINK_FILE) ? - op->get(PREF_METALINK_FILE) : downloadedMetalinkFile; - Xml2MetalinkProcessor proc; - Metalinker* metalinker = proc.parseFile(targetMetalinkFile); - - MetalinkEntry* entry = - metalinker->queryEntry(op->get(PREF_METALINK_VERSION), - op->get(PREF_METALINK_LANGUAGE), - op->get(PREF_METALINK_OS)); - if(entry == NULL) { - printf("No file matched with your preference.\n"); - exit(EXIT_FAILURE); - } - 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; - for(int s = 1; s <= op->getAsInt(PREF_SPLIT); s++) { - createRequest(cuidCounter, resource->url, - op->get(PREF_REFERER), requests); - cuidCounter++; - } - } - Requests reserved; - int maxConnection = - op->getAsInt(PREF_METALINK_SERVERS)*op->getAsInt(PREF_SPLIT); - if((int)requests.size() > maxConnection) { - copy(requests.begin()+maxConnection, requests.end(), - insert_iterator(reserved, reserved.end())); - requests.erase(requests.begin()+maxConnection, requests.end()); - } - - setSignalHander(SIGINT, handler, 0); - setSignalHander(SIGTERM, handler, 0); - - string downloadedFilename; - bool success = normalDownload(requests, reserved, op, downloadedFilename); - - for_each(requests.begin(), requests.end(), Deleter()); - for_each(reserved.begin(), reserved.end(), Deleter()); - requests.clear(); - - if(success) { -#ifdef ENABLE_MESSAGE_DIGEST - if(entry->check(downloadedFilename)) { - printf("checksum OK.\n"); - } else { - printf("checksum ERROR.\n"); - exit(EXIT_FAILURE); - } -#endif // ENABLE_MESSAGE_DIGEST - } - - delete metalinker; - } -#endif // ENABLE_METALINK -#ifdef ENABLE_BITTORRENT - if(op->defined(PREF_TORRENT_FILE) || - followTorrent && readyToTorrentMode) { - try { - //op->put(PREF_MAX_TRIES, "0"); - setSignalHander(SIGINT, torrentHandler, SA_RESETHAND); - setSignalHander(SIGTERM, torrentHandler, SA_RESETHAND); - - Request* req = new Request(); - req->isTorrent = true; - req->setTrackerEvent(Request::STARTED); - te = new TorrentConsoleDownloadEngine(); - te->option = op; - ByteArrayDiskWriter* byteArrayDiskWriter = new ByteArrayDiskWriter(); - te->segmentMan = new SegmentMan(); - te->segmentMan->diskWriter = byteArrayDiskWriter; - te->segmentMan->option = op; - te->segmentMan->splitter = new SplitSlowestSegmentSplitter(); - te->segmentMan->splitter->setMinSegmentSize(op->getAsLLInt(PREF_MIN_SEGMENT_SIZE)); - te->torrentMan = new TorrentMan(); - te->torrentMan->setStoreDir(op->get(PREF_DIR)); - te->torrentMan->option = op; - te->torrentMan->req = req; - string targetTorrentFile = op->defined(PREF_TORRENT_FILE) ? - op->get(PREF_TORRENT_FILE) : downloadedTorrentFile; - if(op->get(PREF_SHOW_FILES) == V_TRUE) { - FileEntries fileEntries = - te->torrentMan->readFileEntryFromMetaInfoFile(targetTorrentFile); - cout << _("Files:") << endl; - cout << "idx|path/length" << endl; - cout << "===+===========================================================================" << endl; - int count = 1; - for(FileEntries::const_iterator itr = fileEntries.begin(); - itr != fileEntries.end(); count++, itr++) { - printf("%3d|%s\n |%s Bytes\n", count, itr->path.c_str(), - Util::llitos(itr->length, true).c_str()); - cout << "---+---------------------------------------------------------------------------" << endl; - } - exit(EXIT_SUCCESS); - } else { - if(selectFileIndexes.empty()) { - Strings targetFiles; - if(op->defined(PREF_TORRENT_FILE) && !args.empty()) { - targetFiles = args; - } - te->torrentMan->setup(targetTorrentFile, targetFiles); - } else { - te->torrentMan->setup(targetTorrentFile, selectFileIndexes); - } - } - PeerListenCommand* listenCommand = - new PeerListenCommand(te->torrentMan->getNewCuid(), te); - int port; - int listenPort = op->getAsInt(PREF_LISTEN_PORT); - if(listenPort == -1) { - port = listenCommand->bindPort(6881, 6999); - } else { - port = listenCommand->bindPort(listenPort, listenPort); - } - if(port == -1) { - printf(_("Errors occurred while binding port.\n")); - exit(EXIT_FAILURE); - } - te->torrentMan->setPort(port); - te->commands.push_back(listenCommand); - - te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(), - te, - te->torrentMan->minInterval)); - te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(), - te)); - te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(), - te, - op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); - te->commands.push_back(new PeerChokeCommand(te->torrentMan->getNewCuid(), - 10, te)); - te->commands.push_back(new HaveEraseCommand(te->torrentMan->getNewCuid(), - te, 10)); - te->run(); - - if(te->torrentMan->downloadComplete()) { - printDownloadCompeleteMessage(); - } - delete req; - te->cleanQueue(); - delete te; - } catch(Exception* ex) { - cerr << ex->getMsg() << endl; - delete ex; - exit(EXIT_FAILURE); - } - } -#endif // ENABLE_BITTORRENT delete op; LogFactory::release(); #ifdef HAVE_LIBGNUTLS diff --git a/src/messageDigest.h b/src/messageDigest.h index b084f07b..c14c4600 100644 --- a/src/messageDigest.h +++ b/src/messageDigest.h @@ -26,6 +26,8 @@ #ifdef ENABLE_SSL +#define MAX_MD_LENGTH (16+20) + #ifdef HAVE_LIBSSL #include #endif // HAVE_LIBSSL @@ -36,73 +38,80 @@ class MessageDigestContext { public: - enum HashAlgo { - ALGO_MD5, - ALGO_SHA1 - }; +#ifdef HAVE_LIBSSL + typedef const EVP_MD* DigestAlgo; +# define DIGEST_ALGO_MD5 EVP_md5() +# define DIGEST_ALGO_SHA1 EVP_sha1() +#endif // HAVE_LIBSSL +#ifdef HAVE_LIBGCRYPT + typedef int DigestAlgo; +# define DIGEST_ALGO_MD5 GCRY_MD_MD5 +# define DIGEST_ALGO_SHA1 GCRY_MD_SHA1 +#endif // HAVE_LIBGCRYPT +private: #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 +#endif // HAVE_LIBGCRYPT + DigestAlgo algo; +public: + MessageDigestContext(): + algo(DIGEST_ALGO_SHA1) {} + MessageDigestContext(DigestAlgo algo): + algo(algo) {} - MessageDigestContext() {} - MessageDigestContext(HashAlgo algo) { - setAlgo(algo); +#ifdef HAVE_LIBSSL + void digestInit() { + EVP_MD_CTX_init(&ctx); + digestReset(); } + void digestReset() { + EVP_DigestInit_ex(&ctx, algo, 0); + } + void digestUpdate(const void* data, int length) { + EVP_DigestUpdate(&ctx, data, length); + } + void digestFinal(unsigned char* md) { + int len; + EVP_DigestFinal_ex(&ctx, md, (unsigned int*)&len); + } + void digestFree() { + EVP_MD_CTX_cleanup(&ctx); + } + int digestLength() const { + return digestLength(algo); + } + static int digestLength(DigestAlgo algo) { + return EVP_MD_size(algo); + } +#endif // HAVE_LIBSSL - 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; - } + void digestInit() { + gcry_md_open(&ctx, algo, 0); } + void digestReset() { + gcry_md_reset(ctx); + } + void digestUpdate(const void* data, int length) { + gcry_md_write(ctx, data, length); + } + void digestFinal(unsigned char* md) { + gcry_md_final(ctx); + memcpy(md, gcry_md_read(ctx, 0), gcry_md_get_algo_dlen(algo)); + } + void digestFree() { + gcry_md_close(ctx); + } + int digestLength() const { + return digestLength(algo); + } + static int digestLength(DigestAlgo algo) { + return gcry_md_get_algo_dlen(algo); + } +#endif // HAVE_LIBGCRYPT }; - -#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) \ -{\ -int len;\ -EVP_DigestFinal_ex(&CTX.ctx, HASH, (unsigned int*)&len);\ -} -#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_SSL - #endif // _D_MESSAGE_DIGEST_H_ diff --git a/src/prefs.h b/src/prefs.h index 6b48cb63..83fcaba7 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -57,6 +57,8 @@ #define PREF_DAEMON "daemon" // value: a string #define PREF_REFERER "referer" +// value' 1*digit +#define PREF_LOWEST_SPEED_LIMIT "lowest_speed_limit" /** * FTP related preferences @@ -116,6 +118,10 @@ #define PREF_TORRENT_FILE "torrent_file" // values: 1*digit #define PREF_LISTEN_PORT "listen_port" +// values: true | false +#define PREF_FOLLOW_TORRENT "follow_torrent" +// values: 1*digit *( (,|-) 1*digit) +#define PREF_SELECT_FILE "select_file" /** * Metalink related preferences @@ -130,5 +136,7 @@ #define PREF_METALINK_OS "metalink_os" // values: 1*digit #define PREF_METALINK_SERVERS "metalink_servers" +// values: true | false +#define PREF_FOLLOW_METALINK "follow_metalink" #endif // _D_PREFS_H_ diff --git a/test/MetalinkEntryTest.cc b/test/MetalinkEntryTest.cc index 99b47fc2..58612f78 100644 --- a/test/MetalinkEntryTest.cc +++ b/test/MetalinkEntryTest.cc @@ -48,11 +48,17 @@ MetalinkEntry* createTestEntry() { res4->type = MetalinkResource::TYPE_NOT_SUPPORTED; res4->location = "ad"; res4->preference = 10; + MetalinkResource* res5 = new MetalinkResource(); + res5->url = "https://myhost/aria2.tar.bz2"; + res5->type = MetalinkResource::TYPE_HTTPS; + res5->location = "jp"; + res5->preference = 90; entry->resources.push_back(res1); entry->resources.push_back(res2); entry->resources.push_back(res3); entry->resources.push_back(res4); + entry->resources.push_back(res5); return entry; } @@ -61,12 +67,16 @@ void MetalinkEntryTest::testDropUnsupportedResource() { entry->dropUnsupportedResource(); - CPPUNIT_ASSERT_EQUAL(2, (int)entry->resources.size()); + CPPUNIT_ASSERT_EQUAL(4, (int)entry->resources.size()); CPPUNIT_ASSERT_EQUAL((int)MetalinkResource::TYPE_FTP, entry->resources.at(0)->type); CPPUNIT_ASSERT_EQUAL((int)MetalinkResource::TYPE_HTTP, entry->resources.at(1)->type); + CPPUNIT_ASSERT_EQUAL((int)MetalinkResource::TYPE_BITTORRENT, + entry->resources.at(2)->type); + CPPUNIT_ASSERT_EQUAL((int)MetalinkResource::TYPE_HTTPS, + entry->resources.at(3)->type); } void MetalinkEntryTest::testReorderResourcesByPreference() { @@ -75,9 +85,10 @@ void MetalinkEntryTest::testReorderResourcesByPreference() { entry->reorderResourcesByPreference(); CPPUNIT_ASSERT_EQUAL(100, entry->resources.at(0)->preference); - CPPUNIT_ASSERT_EQUAL(60, entry->resources.at(1)->preference); - CPPUNIT_ASSERT_EQUAL(50, entry->resources.at(2)->preference); - CPPUNIT_ASSERT_EQUAL(10, entry->resources.at(3)->preference); + CPPUNIT_ASSERT_EQUAL(90, entry->resources.at(1)->preference); + CPPUNIT_ASSERT_EQUAL(60, entry->resources.at(2)->preference); + CPPUNIT_ASSERT_EQUAL(50, entry->resources.at(3)->preference); + CPPUNIT_ASSERT_EQUAL(10, entry->resources.at(4)->preference); } void MetalinkEntryTest::testCheck() { diff --git a/test/UtilTest.cc b/test/UtilTest.cc index 150c8f68..a7255f8f 100644 --- a/test/UtilTest.cc +++ b/test/UtilTest.cc @@ -224,12 +224,12 @@ void UtilTest::testRandomAlpha() { void UtilTest::testFileChecksum() { unsigned char buf[20]; string filename = "4096chunk.txt"; - Util::fileChecksum(filename, buf, MessageDigestContext::ALGO_SHA1); + Util::fileChecksum(filename, buf, DIGEST_ALGO_SHA1); string sha1 = Util::toHex(buf, 20); CPPUNIT_ASSERT_EQUAL(string("608cabc0f2fa18c260cafd974516865c772363d5"), sha1); - Util::fileChecksum(filename, buf, MessageDigestContext::ALGO_MD5); + Util::fileChecksum(filename, buf, DIGEST_ALGO_MD5); string md5 = Util::toHex(buf, 16); CPPUNIT_ASSERT_EQUAL(string("82a7348c2e03731109d0cf45a7325b88"), md5);