Browse Source

Merge branch 'master' into random-webseeding

Tatsuhiro Tsujikawa 10 years ago
parent
commit
c81b132112
100 changed files with 1217 additions and 1132 deletions
  1. 36 0
      .travis.yml
  2. 17 3
      Dockerfile.mingw
  3. 101 0
      Dockerfile.raspberrypi
  4. 1 0
      Makefile.am
  5. 101 647
      NEWS
  6. 14 4
      README.android
  7. 5 4
      README.mingw
  8. 36 22
      README.rst
  9. 6 12
      android-config
  10. 22 0
      android/zlib-config
  11. 6 0
      build_test.sh
  12. 62 29
      configure.ac
  13. 0 0
      doc/bash_completion/aria2c
  14. 109 54
      doc/manual-src/en/aria2c.rst
  15. 46 24
      doc/manual-src/en/mkapiref.py
  16. 4 2
      doc/manual-src/en/technical-notes.rst
  17. 6 0
      doc/manual-src/pt/aria2c.rst
  18. 6 0
      doc/manual-src/pt/index.rst
  19. 1 0
      doc/manual-src/ru/Makefile.am
  20. 99 40
      doc/manual-src/ru/aria2c.rst
  21. 1 1
      doc/sphinx_themes/sphinx_rtd_theme/__init__.py
  22. 23 15
      doc/sphinx_themes/sphinx_rtd_theme/breadcrumbs.html
  23. 20 14
      doc/sphinx_themes/sphinx_rtd_theme/footer.html
  24. 75 32
      doc/sphinx_themes/sphinx_rtd_theme/layout.html
  25. 1 1
      doc/sphinx_themes/sphinx_rtd_theme/search.html
  26. 9 5
      doc/sphinx_themes/sphinx_rtd_theme/searchbox.html
  27. 0 0
      doc/sphinx_themes/sphinx_rtd_theme/static/css/badge_only.css
  28. 2 0
      doc/sphinx_themes/sphinx_rtd_theme/static/css/badge_only.css.map
  29. 0 0
      doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css
  30. 2 0
      doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css.map
  31. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.eot
  32. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.woff
  33. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
  34. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf
  35. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf
  36. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf
  37. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf
  38. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf
  39. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf
  40. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
  41. 23 8
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
  42. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
  43. BIN
      doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
  44. 3 0
      doc/sphinx_themes/sphinx_rtd_theme/static/js/modernizr.min.js
  45. 112 15
      doc/sphinx_themes/sphinx_rtd_theme/static/js/theme.js
  46. 2 0
      doc/sphinx_themes/sphinx_rtd_theme/theme.conf
  47. 4 4
      doc/sphinx_themes/sphinx_rtd_theme/versions.html
  48. 3 3
      makerelease-osx.mk
  49. 17 0
      mingw-build-memo
  50. 2 0
      mingw-config
  51. 17 21
      src/AbstractCommand.cc
  52. 4 4
      src/AbstractCommand.h
  53. 1 1
      src/AbstractHttpServerResponseCommand.cc
  54. 1 1
      src/AbstractProxyRequestCommand.cc
  55. 1 1
      src/AbstractSingleDiskAdaptor.cc
  56. 2 2
      src/ActivePeerConnectionCommand.cc
  57. 2 2
      src/ActivePeerConnectionCommand.h
  58. 2 2
      src/AdaptiveFileAllocationIterator.cc
  59. 18 14
      src/AdaptiveURISelector.cc
  60. 1 2
      src/AdaptiveURISelector.h
  61. 2 2
      src/AnnounceList.cc
  62. 8 6
      src/AppleTLSContext.cc
  63. 2 1
      src/AppleTLSSession.cc
  64. 2 4
      src/AsyncNameResolver.cc
  65. 2 1
      src/AuthConfigFactory.cc
  66. 3 3
      src/AutoSaveCommand.cc
  67. 2 1
      src/AutoSaveCommand.h
  68. 2 1
      src/BackupIPv4ConnectCommand.cc
  69. 1 1
      src/BackupIPv4ConnectCommand.h
  70. 2 0
      src/BtAnnounce.cc
  71. 3 2
      src/BtAnnounce.h
  72. 10 2
      src/BtCheckIntegrityEntry.cc
  73. 15 15
      src/BtConstants.h
  74. 8 8
      src/BtDependency.cc
  75. 1 1
      src/BtFileAllocationEntry.cc
  76. 23 20
      src/BtLeecherStateChoke.cc
  77. 1 1
      src/BtPieceMessage.cc
  78. 3 3
      src/BtPostDownloadHandler.cc
  79. 11 9
      src/BtSeederStateChoke.cc
  80. 0 1
      src/BtSeederStateChoke.h
  81. 6 6
      src/BtSetup.cc
  82. 4 4
      src/BtStopDownloadCommand.cc
  83. 2 2
      src/BtStopDownloadCommand.h
  84. 3 1
      src/ByteArrayDiskWriter.h
  85. 4 0
      src/ChecksumCheckIntegrityEntry.cc
  86. 1 1
      src/ConnectCommand.cc
  87. 7 6
      src/ConsoleStatCalc.cc
  88. 2 2
      src/ConsoleStatCalc.h
  89. 5 0
      src/Context.cc
  90. 8 0
      src/CreateRequestCommand.cc
  91. 2 2
      src/DHTAutoSaveCommand.cc
  92. 1 1
      src/DHTAutoSaveCommand.h
  93. 2 2
      src/DHTBucketRefreshCommand.cc
  94. 2 1
      src/DHTBucketRefreshCommand.h
  95. 1 2
      src/DHTConnectionImpl.cc
  96. 19 13
      src/DHTConstants.h
  97. 6 6
      src/DHTGetPeersCommand.cc
  98. 10 7
      src/DHTInteractionCommand.cc
  99. 1 1
      src/DHTMessageDispatcher.h
  100. 4 4
      src/DHTMessageDispatcherImpl.cc

+ 36 - 0
.travis.yml

@@ -0,0 +1,36 @@
+language: cpp
+compiler:
+  - clang
+  - gcc
+sudo: false
+addons:
+  apt:
+    sources:
+    - ubuntu-toolchain-r-test
+    packages:
+    - g++-4.9
+    - libstdc++-4.9-dev
+    - autoconf
+    - automake
+    - autotools-dev
+    - autopoint
+    - libtool
+    - pkg-config
+    - libssl-dev
+    - libc-ares-dev
+    - libxml2-dev
+    - zlib1g-dev
+    - libsqlite3-dev
+    - libssh2-1-dev
+    - libcppunit-dev
+before_install:
+  - $CC --version
+  - if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi
+  - $CC --version
+before_script:
+  - autoreconf -i
+  - automake
+  - autoconf
+  - ./configure
+script:
+  - make check

+ 17 - 3
Dockerfile.mingw

@@ -26,9 +26,10 @@ RUN apt-get install -y make binutils autoconf automake autotools-dev libtool \
 
 RUN curl -L -O https://gmplib.org/download/gmp/gmp-6.0.0a.tar.lz
 RUN curl -L -O http://downloads.sourceforge.net/project/expat/expat/2.1.0/expat-2.1.0.tar.gz
-RUN curl -L -O http://www.sqlite.org/2015/sqlite-autoconf-3080802.tar.gz
+RUN curl -L -O http://www.sqlite.org/2015/sqlite-autoconf-3080803.tar.gz
 RUN curl -L -O http://zlib.net/zlib-1.2.8.tar.xz
 RUN curl -L -O http://c-ares.haxx.se/download/c-ares-1.10.0.tar.gz
+RUN curl -L -O http://libssh2.org/download/libssh2-1.5.0.tar.gz
 
 RUN tar xf gmp-6.0.0a.tar.lz
 RUN cd gmp-6.0.0 && \
@@ -52,8 +53,8 @@ RUN cd expat-2.1.0 && \
     --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` && \
     make install
 
-RUN tar xf sqlite-autoconf-3080700.tar.gz
-RUN cd sqlite-autoconf-3080700 && \
+RUN tar xf sqlite-autoconf-3080803.tar.gz
+RUN cd sqlite-autoconf-3080803 && \
     ./configure \
     --disable-shared \
     --enable-static \
@@ -88,6 +89,19 @@ RUN cd c-ares-1.10.0 && \
     LIBS="-lws2_32" && \
     make install
 
+RUN tar xf libssh2-1.5.0.tar.gz
+RUN cd libssh2-1.5.0 && \
+    ./configure \
+    --disable-shared \
+    --enable-static \
+    --prefix=/usr/local/$HOST \
+    --host=$HOST \
+    --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
+    --without-openssl \
+    --with-wincng \
+    LIBS="-lws2_32" && \
+    make install
+
 RUN git clone https://github.com/tatsuhiro-t/aria2
 RUN cd aria2 && autoreconf -i && ./mingw-config && make && \
     $HOST-strip src/aria2c.exe

+ 101 - 0
Dockerfile.raspberrypi

@@ -0,0 +1,101 @@
+FROM ubuntu:trusty
+
+MAINTAINER Igor Khomyakov
+
+RUN apt-get update && \
+    apt-get install -y make binutils autoconf automake autotools-dev libtool \
+    pkg-config git curl dpkg-dev autopoint libcppunit-dev libxml2-dev \
+    libgcrypt11-dev lzip
+
+RUN git clone https://github.com/raspberrypi/tools.git --depth=1 /tools
+
+ENV ARCH armhf
+ENV HOST arm-linux-gnueabihf
+ENV LOCAL_DIR /local
+
+ENV TOOL_BIN_DIR /tools/arm-bcm2708/gcc-linaro-$HOST-raspbian-x64/bin
+ENV PATH ${TOOL_BIN_DIR}:$PATH
+
+RUN mkdir $LOCAL_DIR && mkdir zlib && cd zlib && \
+   curl -Ls -o - 'http://prdownloads.sourceforge.net/libpng/zlib-1.2.8.tar.gz?download'  | \
+        tar xzf - --strip-components=1 && \
+   prefix=${LOCAL_DIR} \
+   CC=$HOST-gcc \
+   STRIP=$HOST-strip \
+   RANLIB=$HOST-ranlib \
+   AR=$HOST-ar \
+   LD=$HOST-ld \
+   ./configure --static \
+        --libdir=$LOCAL_DIR/lib && \
+   make -s && \
+   make -s install
+
+RUN mkdir -p expat && cd expat && \
+    curl -Ls -o - 'http://sourceforge.net/projects/expat/files/latest/download' | \
+        tar xzf - --strip-components=1 && \
+    ./configure \
+        --host=$HOST \
+        --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
+        --enable-shared=no \
+        --enable-static=yes \
+        --prefix=${LOCAL_DIR} && \
+    make -s && \
+    make -s install
+
+RUN mkdir c-ares && cd c-ares && \
+    curl -Ls -o -  http://c-ares.haxx.se/download/c-ares-1.10.0.tar.gz | \
+        tar xzf - --strip-components=1 && \
+    ./configure \
+        --host=$HOST \
+        --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
+        --enable-shared=no \
+        --enable-static=yes \
+        --prefix=${LOCAL_DIR} && \
+    make -s && \
+    make -s install
+
+RUN mkdir gmp && cd gmp && \
+    curl -Ls -o - 'https://gmplib.org/download/gmp/gmp-6.0.0a.tar.lz' | \
+        lzip -d | tar xf - --strip-components=1 && \
+    ./configure \
+        --disable-shared \
+        --enable-static \
+        --prefix=$LOCAL_DIR \
+        --host=$HOST \
+        --disable-cxx \
+        --enable-fat && \
+    make -s && \
+    make -s install
+
+RUN mkdir sqlite && cd sqlite && \
+    curl -Ls -o - https://www.sqlite.org/2015/sqlite-autoconf-3080900.tar.gz | \
+        tar xzf - --strip-components=1 && \
+    ./configure \
+        --disable-shared \
+        --enable-static \
+        --prefix=$LOCAL_DIR \
+        --host=$HOST \
+        --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` && \
+    make -s && \
+    make -s install
+   
+RUN mkdir aria && cd aria && \
+    curl -Ls -o - http://sourceforge.net/projects/aria2/files/latest/download | \
+        tar xjf - --strip-components=1 && \
+    ./configure \
+        --host=$HOST \
+        --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
+        --disable-nls \
+        --disable-ssl \
+        --without-gnutls \
+        --without-libxml2 \
+        --with-libz     --with-libz-prefix=${LOCAL_DIR} \
+        --with-libexpat --with-libexpat-prefix=${LOCAL_DIR} \
+        --with-slite3   --with-sqlite3-prefix=${LOCAL_DIR} \
+        --with-libcares --with-libcares-prefix=${LOCAL_DIR} \
+        --prefix=${LOCAL_DIR} \
+        LDFLAGS="-L$LOCAL_DIR/lib" \
+        PKG_CONFIG_PATH="$LOCAL_DIR/lib/pkgconfig" \
+        ARIA2_STATIC=yes && \
+    make -s && \
+    make -s install-strip

+ 1 - 0
Makefile.am

@@ -10,6 +10,7 @@ EXTRA_DIST = config.rpath \
 	     android-config android-make \
 	     makerelease-osx.mk osx-package/DS_Store osx-package/etc/paths.d/aria2c osx-package/etc/manpaths.d/aria2 \
 	     Dockerfile.mingw \
+	     Dockerfile.raspberrypi \
 	     examples/libaria2ex.cc examples/libaria2wx.cc
 
 dist_doc_DATA = README README.rst README.html

+ 101 - 647
NEWS

@@ -1,716 +1,170 @@
-aria2 1.18.9
+aria2 1.19.1
 ============
 
 Release Note
 ------------
 
-This releases fixes memory leak with OpenSSL and crash on OSX when
-proxy is used.  We added several new features.  Adler32 checksum is
-now available in --checksum option and hash element in Metalink files.
-We added --bt-detach-seed-only option, which excludes seed-only
-downloads when counting concurrent active downloads (-j option).  We
-disabled SSLv3 by default.  If you ever want to enable it or further
-tune the TLS protocols to enable, use new --min-tls-version option.
---bt-force-encryption option was added to make requiring BitTorrent
-full encryption easier.  From this release, we build Android binary
-using API level 16.
+This release fixes TLS handshake error with servers which only support
+RSA-SHA1 signature algorithm.  We removed RSA-SHA1 for enchanced
+security, but many users reported there were servers which could not
+talk aria2 1.19.0, so added it again for compatibility reasons.  For
+Windows build, we fixed potential infinite loop bug when TLS is used.
+
+We changed the location where dht.dat and aria2.conf are looked up.
+The aria2 manual page described details.  Basically we now follow XDG
+specification (http://standards.freedesktop.org/basedir-spec/latest/).
+For dht.dat, the default location is $XDG_CACHE_HOME/aria2/ directory.
+For aria2.conf, the default location is $XDG_CONFIG_HOME/aria2/
+directory.  To keep the current user configuration working, if aria2
+detects dht.dat under $HOME/.aria2/ directory, it is used instead.
+Similarly, if aria2.conf exists under $HOME/.aria2/ directory, it is
+used instead.
+
+Previously, we return 500 HTTP status if RPC method execution
+encountered error.  Now it returns with 400 HTTP status with error
+code.  This is more natural because server processed request and found
+an error, and returned error reply correctly.  This is not something
+server crashed or something.  Also, there is RPC libraries which
+throws exception if it sees 5XX status code, where 400 is better
+because we can examine the error.
 
 Changes
 -------
 
-* Support HTTP date ending "+0000" as well as "GMT".
+* Update README.android
 
-  Closes GH-330
+  Providing some workarounds about CA certificates and standard output
 
-* Revise getRandom facilities
+  Patch from amtlib-dot-dll
 
-  Use one of the following to provide random bytes:
-  - Windows CryptGenRandom
-  - Linux getrandom (syscall interface to urandom, without nasty
-    corner cases such as file descriptor exhaustion or re-linked
-    /dev/urandom)
-  - std::device_random (C++ random device, which usually will be
-    urandom)
+* Return 400 HTTP status code if exception was caught while executing
+  RPC method
 
-  This also equalizes util::getRandom and SimpleRandomizer (the former
-  will now use the latter) instead of having essentially two different
-  PRNG interfaces with potentially different quality.
+  Previously, we returned 500 HTTP status code.  I think the found in
+  RPC level, not in HTTP protocol, so 500 is not appropriate.
 
-  Closes GH-320
+* WinTLS: Fix potential infinite loop
 
-* Added debug log of all Metalink URLs with final priorities
+* Fix on-download-error is executed even if download succeeded
 
-  Patch from Dan Fandrich
+* Update Dockerfile.mingw
 
-* Use gcc-4.9 and android-16 API level for android build
+  Patch from Adam Baxter
 
-* Add --bt-force-encryption option
+* Increase --select-file upper bound to 1m for torrent containing lots
+  of files
 
-  This option requires BitTorrent message payload encryption with
-  arc4. This is a shorthand of --bt-requre-crypto
-  --bt-min-crypto-level=arc4.  If true is given, deny legacy
-  BitTorrent handshake and only use Obfuscation handshake and always
-  encrypt message payload. This option defaults to false.
+* Fix busy loop with --dry-run and 4xx response for URI listed in
+  metalink
 
-* TLS: Fix memory leak with OpenSSL
+  See GH-430
 
-  Based on the patch submitted by midnight2k
+* Update sqlite in OSX build to 3.8.10.2
 
-* Warn about insecure SSL connections.
+* Make LibuvEventPoll compatible with the latest libuv again
 
-  Fixed GH-313
+* gnutls: Allow SIGN-RSA-SHA1 for compatibility reason
 
-* Add --min-tls-version option
+* Make script compatible with both Python 2 and 3
 
-  The --min-tls-version option specifies minimum SSL/TLS version to
-  enable. Possible Values: SSLv3, TLSv1, TLSv1.1, TLSv1.2 Default:
-  TLSv1
+  Patch from Vasilij Schneidermann
 
-* LibsslTLSContext: Disable SSLv3 and enable ECDHE cipher suites
+* Make config and cache files conform to XDG
 
-* Add Dockerfile.mingw
+  See http://standards.freedesktop.org/basedir-spec/latest/ for
+  further details.  This implementation decides the default based on
+  whether a file exists at the legacy location, if it doesn't, it
+  picks the XDG-conforming location instead.
 
-  Dockerfile.mingw builds aria2 Windows binary.  It is probably the
-  easiest way to build the Windows binary.
+  Patch from Vasilij Schneidermann
 
-* Fix crash when JSON batch response vector is empty
+* ftp, sftp: Fix heap-after-free bug on exception
 
-* Fix doc: Wrong rpc secret token prefix
+* ftp: Fix timeout when reusing FTP connection
 
-* Add --bt-detach-seed-only option
+* Various MinGW-w64 build improvements
 
-  This option excludes seed only downloads when counting concurrent
-  active downloads (-j option).  This means that if -j3 is given and
-  this option is turned on and 3 downloads are active and one of those
-  enters seed mode, then it is excluded from active download count
-  (thus it becomes 2), and the next download waiting in queue gets
-  started.  But be aware that seeding item is still recognized as
-  active download in RPC method.
-
-* mingw: Use MoveFileExW for better atomic move
-
-* Work around libintl's vprintf macro messing with OutputFile::vprintf
-
-  Patch from David Macek
-
-* Fix crash on OSX when proxy is used
-
-  See GH-275
-
-* Support Adler32 checksum
-
-  Adler32 checksum is available for --checksum option and hash element
-  in Metalink files.  Currently, we use Adler32 implementation in
-  Zlib.
-
-
-
-aria2 1.18.8
-============
-
-Release Note
-------------
-
-This releases fixes the bug that aria2 cannot read piped stdin on
-mingw32.  It also fixes busy loop on mingw32 when SSL/TLS is used.  We
-also fixed 2 crashes which can occur on all platforms.
-
-Changes
--------
-
-* WinTLS: Fix abrupt connection closing and closing in general.
-
-  Fixes GH-277
-
-* LibsslTLSSession: Treat 0 from readData as EOF
-
-* Enable dynamicbase and nxcompat in Windows binaries
-
-* Fix crash in OpenedFileCounter::ensureMaxOpenFileLimit()
-
-  The crash happens if PieceStorage and/or DiskAdaptor are not
-  initialized in one of active RequestGroups.
-
-* mingw32: Fix bug that aria2 does not read piped stdin
-
-* Fix std::length_error when no_proxy is used
-
-  This is regression introduced in 8cada497.
-
-* Try to set sane limits for RLIMIT_NO_FILE
-
-  E.g. on OSX the default is 256, which isn't exactly compatible with
-  torrent downloads.
-
-  Closes GH-257
-
-* Delay auth failures instead of PBKDF2
-
-  Closes GH-256
-
-
-
-aria2 1.18.7
-============
-
-Release Note
-------------
-
-This release fixes regression which makes 100% CPU utilization in
-multi-file torrent download with -V option.  It also fixes build error
-on big endian platforms.
-
-Changes
--------
-
-* Fixed segfault unsupported encodings
-
-  Patch from diadistis
-
-* Fix regression 100% CPU utility when -V is used and download is
-  multi-file bittorrent downloads.
-
-  This is regression of a3426821c8a7f9cf8d80a81726157d4eb844f661
-
-* Fix compile error on big endian platform
-
-
-
-aria2 1.18.6
-============
-
-Release Note
-------------
-
-This release fixes several bugs reported in github issues and adds a
-feature to make RPC authentication more resilient to certain attacks.
-New option --pause-metadata is added.  The explanation is a bit log,
-so check the changelog and manual.  The session is now only saved if
-there are changes from the last saved state.
-
-From this release, MinGW32 build uses Windows native TLS
-implementation and no longer use OpenSSL library.
-
-Changes
--------
-
-* Disard cache when checking checksum
-
-  This will slow down checksum checking but does not thrash cache.
-
-* Compat with libuv 0.11 (Unstable)
-
-  Fixes #241
-
-* Drop WinMessageDigestImpl.
-
-  The algorithms the `CryptProv` on Windows supports does not
-  currently include SHA-224, so there is a "dark spot" in this
-  implementation. Also on Win XP < SP3, most of the SHA-2 family is
-  not actually supported.  All other implementation provide support
-  for MD5, SHA-1 and all of the SHA-2 family, hence drop the
-  incomplete WinMessageDigest implementation in favor of any other
-  supported implementation (at least the internal implementation is
-  always available at compile-time).
-
-* Add --pause-metadata option
-
-  This option pauses downloads created as a result of metadata
-  download. There are 3 types of metadata downloads in aria2: (1)
-  downloading .torrent file. (2) downloading torrent metadata using
-  magnet link. (3) downloading metalink file.  These metadata
-  downloads will generate downloads using their metadata. This option
-  pauses these subsequent downloads.
-
-* Improve compiler/platform/libs information in logs
-
-  Add and use usedCompilerAndPlatform().  This adds compiler
-  information to INFO logs and the --version output, and may be
-  helpful when trying to diagnose/reproduce user-reported problems.
-
-  Also make INFO logs include usedLibs() output.
-
-  Closes #235
-
-* Fix use-after-free on exit with multi-file torrent download + DHT
-
-  DefaultPieceStorage may be referenced by one of DHT task (e.g.,
-  DHTPeerLookupTask), after RequestGroup was deleted, and even after
-  RequestGroupMan was deleted.  DefaultPieceStorage has a reference to
-  MultiDiskAdaptor which calls RequestGroupMan object on destruction.
-  So when DHT task is destroyed, DefaultPieceStorage is destroyed,
-  which in turn destroys MultiDiskAdaptor.  DHT task is destroyed
-  after RequestGroupMan was destroyed, MultiDiskAdaptor will use now
-  freed RequestGroupMan object, this is use-after-free.
-
-* Fix bug that zero length file is not opened when flushing cache
-
-  This bug was only seen when MultiDiskAdaptor was used.
-
-* Support PREF_DIR change for Metalink files
-
-  Reworked previous commit adeead6f0396e2f8551d1182972e277728fd6c8b,
-  and now support changing PREF_DIR for Metalink downloads.
-
-* Fix assertion failure when dir option of paused HTTP/FTP download is
-  changed
-
-  When the directory is changed via aria2.changeOption RPC method, we
-  directly change first FileEntry's path using FileEntry::setPath().
-  If there is no PREF_OUT option is given, basically file name is
-  unknown, so we just set empty string and let the next run determine
-  the correct file name and new directory is applied there.  But
-  previous code does not reset length property of FileEntry, so the
-  unexpected code path is taken when unpaused and its path expects
-  path is not empty string.  This commit fixes this issue by setting
-  length to 0 using FileEntry::setLength().
-
-* Save session only when there is change since the last serialization
-
-  This is a slight optimization not to cause useless disk access.
-  This only applies to saving session automatically (see
-  --save-session-interval).  aria2.saveSession and serialization at
-  the end of the session are always performed as before.
-
-  When serialization, we first check that whether there is any change
-  since the last serialization.  To do this, we first calculate hash
-  value of serialized content without writing into file.  Then compare
-  this value to the value of last serialization.  If they do not
-  match, perform serialization.
-
-* Fix (unknown length) downloads larger than 2GiB
-
-  Closes #215
-
-* Fix F_PREALLOC based allocation on some OSX versions
-
-* Use index.html as filename for conditional-get when file is missing
-  in URI
-
-  Previously we disabled conditional-get if file part is missing in
-  URI.  But we use constant string "index.html" in this case, so we
-  can do the same to determine the modification time.  In this patch,
-  if we have file part in URI, we are not going to set absolute file
-  path in FileEntry, since it prevents content-disposition from
-  working.
-
-* Always add README.html to dist_doc_DATA
-
-  rst2html is required to produce README.html from README.rst.  We
-  include generated README.html to distribution.  And rst2html is not
-  required when compiling sources in distribution and always
-  README.html is available.
-
-* Validate token using PBKDF2-HMAC-SHA1.
-
-  This change should make token validation more resilient to:
-  - timing attacks (constant time array compare)
-  - brute-force/dictionary attacks (PBKDF2)
-
-  Closes #220
-
-* Add --disable-websocket configure option
-
-* mingw32: Enable wintls and compile with GMP
-
-  By enabling wintls, we can use Windows certificate store to validate
-  server's certificate.  Previously, we built windows build using
-  openssl and since we don't bundle CA certificates, aria2 fails to
-  validate server's certificate unless user setups their CA
-  certificates.  GMP provides fast big integer calculations, whic is
-  used in BitTorrent encryption.
-
-* AppleTLS: Enable BEAST mitigations in ST
-
-  Only available in 10.9+, but since we might be building on a
-  previous version but running on 10.9+, always try to set the option.
-
-* WinTLS: Accept chains with no revocation information.
-
-  This is kind what browser do anyway (IE, Firefox, Chrome tested),
-  what AppleTLS does, what GnuTLS does and what OpenSSL
-  does. Actually, most browsers will also be OK with the CRL/OCSP
-  provider being offline.  WinTLS will still fail in that case.
-
-  Should revocation information be available in the trust chain (CRL
-  or OCSP) the certificate still will be checked!
-
-  "Real" CAs, aka. those provided by the OS or system CA bundle,
-  usually provide revocation information and are thus still checked.
-  It should be mostly (only?) custom (organization) CAs that lack
-  revocation information, but those users might want to use aria2 in
-  their intranets and VPNs anyway ;)
-
-  See #217
-
-* Fix GnuTLS 2.x compatiblity
-
-  Closes GH-216
-
-* AppleTLS: Use newer, non-deprecated API in 10.8+
-
-
-
-aria2 1.18.5
-============
-
-Release Note
-------------
-
-This release fixes BitTorrent download failure on Mingw build.
-
-Changes
--------
-
-* Ignore error when setting DSCP value
-
-  Setting DSCP is additional feature and failure to enable it should
-  not abort download entirely.  This change fixes the bug that windows
-  build does not perform bittorrent downloads.
-
-
-
-aria2 1.18.4
-============
-
-Release Note
-------------
-
-This release adds new RPC authorization mechanism using --rpc-secret
-option.  The existing --rpc-user and --rpc-passwd options are now
-deprecated, and all applications using RPC API is strongly encouraged
-to migrate to the new mechanism.  See RPC INTERFACE section in aria2
-manual page for the details.  The new RPC method, aria2.saveSession,
-was added, which tells aria2 server to save session file immediately.
-There are several enhancements and bug fixes.  See the changes for the
-details.
-
-Changes
--------
-
-* Added support for RPC channel encryption in aria2rpc
+  - Fix detection of localtime_r and asctime_r on MinGW-w64
+  - Fix linking with libintl on MinGW-w64
 
   Patch from David Macek
 
-* Add aria2.saveSession RPC method
-
-  This method saves the current session to a file specified by
-  --save-session option. This method returns "OK" if it succeeds.
-
-* Add numStoppedTotal key to aria2.getGlobalStat() RPC method response
-
-  It shows the number of stopped downloads in the current session and
-  not capped by --max-download-result option. On the other hand, the
-  existing numStopped key also shows the number of stopped downloads,
-  but it is capped by --max-download-result option.
-
-* Better handling of 30x HTTP status codes
-
-  Reference: http://greenbytes.de/tech/tc/httpredirects/
-
-* Implement new RPC authorization using --rpc-secret option
-
-  Add future deprecation warning to --rpc-user and --rpc-passwd.  Warn
-  if neither --rpc-secret nor a combination of --rpc-user/rpc-passwd
-  is set.
-
-* Add --enable-color option to enable/disable terminal color output
-
-* Add DSCP support
-
-* gnutls: Don't fail handshake if returned error is not fatal
-
-* Add workaround GnuTLS bug with OCSP status extension and
-  non-blocking socket
-
-  GnuTLS version 3.1.3 - 3.1.18 and 3.2.0 - 3.2.8, inclusive, has this
-  bug. For these versions, we disable OCSP status extension.
-
-* Make GnuTLS log level dependent on the aria2 ones
-
 
 
-aria2 1.18.3
+aria2 1.19.0
 ============
 
 Release Note
 ------------
 
-This release fixes the bug which may cause assertion failure after
-multi-file downloads (e.g., multi-file metalink or torrent) are
-performed several times due to the bad handling of --bt-max-open-files
-option.
+This releases adds SFTP support, and fixes several bugs.  SFTP support
+has been implemented using libssh2.  We added several new options.
+--multiple-interface option is like --interface option, but can take
+several interfaces.  They are used in round-robin manner, and it works
+like link aggregation.  Previously, .netrc search path is fixed under
+$HOME directory, and cannot be changed.  In this release, --netrc-path
+option has been added to override the search path.  The runtime bug
+concerning getrandom has been fixed in this release.  Previously if
+download failed because checksum error, aria2 exited with error code 1
+(unknown error).  Now it exits with dedicated error code 32.  We fixed
+long outstanding bug that aria2 crashes when downloading multi-file
+torrent.
 
 Changes
 -------
 
-* Fix crash if unpause failed before assigning BtProgressInfoFile
-  object
-
-* Enable and check PIE in makerelease-osx
-
-* Fix bug that numOpenFile_ is not reduced when MultiDiskAdaptor is
-  deleted
-
-  This bug caused assertion error in
-  RequestGroupMan::ensureMaxOpenFileLimit
-
-
-
-aria2 1.18.2
-============
-
-Release Note
-------------
-
-This release fixes the wrong handling of return value of fork(), which
-leads to high CPU usage. The progress readout has some color output.
-Mingw32 build now receives colorized output. Mingw32 build now can
-read unicode command-line arguments. The build script of OSX was
-rewritten. The --bt-max-open-files now limits the number of opened
-file globally for multi-file downloads instead of per download basis.
-
-Changes
--------
-
-* Remove the outdated, broken build_osx_release.sh
-
-* Initial revision of the a new OSX release Makefile
-
-* Allow using libgmp with AppleTLS/WinTLS
-
-* Fix crash when metaurl contains unsupported URI or text
-
-* Fix bad fork() return value handling
-
-* Use some colors in progress reports (where available)
-
-* Implement basic color support for the Windows console
-
-  Only \033[*m (SGR) is supported, with a 16+16 color terminal.
-
-* AppleTLS: Implement PKCS12 loading.
-
-* Limit number of opened file globally with --bt-max-open-files option
-
-  This change changes the behavior of --bt-max-open-files. Previously,
-  it specifies the maximum number of opened files for each multi-file
-  download. Since it is more useful to limit the number globally, the
-  option now specifies the global limit. This change suggests that
-  aria2.changeOption() method now ignores --bt-max-open-files and
-  aria2.changeGlobalOption now reads it and dynamically change the
-  limit.
-
-* Don't fail multiple concurrent dl same file if auto-file-renaming is
-  enabled
-
-* mingw32: Use CommandLineToArgvW() and GetCommandLineW() to read
-  cmd-line args
-
-  This change enables aria2 to read unicode characters in
-  command-line.
-
-
-
-aria2 1.18.1
-============
-
-Release Note
-------------
-
-This release fixes the percent-encoding bug which affects file name
-encodings. It adds PKCS12 support in certificate import. It also adds
-experimental internal implementation of message digest functions, ARC4
-cipher and bignum. It means that no external libraries are required to
-build BitTorrent support, but this feature is still marked as
-experimental. This release also fixes the android build with NDK r9.
-
-Changes
--------
-
-* LibsslTLSContext: Remove weak cipher suite
-
-* AppleTLS: Enable --certificate
-
-* util::percentEncodeMini: Fix regression bug removed unsignedness
-
-  srange-based for around std::string is convenient but several
-  functions depend unsigned char for correctness and readability.
-
-* Log exception; throw error if loading private key and/or certificate
-  failed
-
-* Provide internal ARC4 implementation
-
-  Now you can build bittorrent support without without external
-  libraries, meaning you can skip libnettle, libgmp, libgcrypt, GnuTLS
-  and OpenSSL on OSX (for now).
-
-* Internal implementation of DHKeyExchange
-
-  Reusing a bignum (well, unsigned very-long) implementation I had
-  lying around for years and just cleaned up a bit and brought to
-  C++11 land.
-
-  It might not be the most performant implementation, but it shoud be
-  fast enough for our purposes and will go a long way of removing
-  gcrypt, nettle, gmp, openssl dependencies when using AppleTLS and
-  WinTLS (upcoming).
-
-* PKCS12 support in --certificate and --rpc-certificate options.
-
-* Add --disable-ssl configure option
-
-* Add internal md5 and sha1 message digests
-
-* Fix AppleMessageDigestImpl use with large data
-
-* Set old cookie's creation-time to new cookie on replacement
-
-  As described in http://tools.ietf.org/html/rfc6265#section-5.3
-
-* Fix link error with Android NDK r9
-
-  Since Android ndk r9, __set_errno is deprecated. It is now defined
-  as inline function in errno.h. The syscall assembly calls
-  __set_errno, but since libc.so does not export it, the link
-  fails. To workaround this, replace all occurrences of __set_errno
-  with a2_set_errno and define it as normal C function.
-
-
-
-aria2 1.18.0
-============
-
-Release Note
-------------
-
-This release changes the default disk cache size to 16 MiB. To change
-the default size, --with-disk-cache configure option was added.  Now
-used URIs are also saved by --save-session option. The control file is
-now always saved if --force-save is given. The ctrl-c handling on
-Mingw build was improved. The internal intl library is no longer
-supplied. From this release, C++11 compiler is required to build aria2
-executable. For gcc, at least 4.6.3 is required.
-
-Changes
--------
-
-* Use AM subdir-objects
-
-  Doing so in AM_INIT_AUTOMAKE seems to be the most compatible way of
-  doing so.
-
-  Closes GH-120
-
-* AM_SILENT_RULES([yes]) with backwards-compatiblity
-
-  Supported since automake-1.11. There is no point in having the very
-  verbose compile stuff running about, which cannot even silenced
-  properly with `make -s` by default. Otherwise, `make V=1` or
-  `--disable-silent-rules` are your friends
-
-* Fix automake-1.14 am_aux_dir
-
-  AC_USE_SYSTEM_EXTENSIONS will cause AC_PROG_CC, which is overridden
-  by automake-1.14, which will then init (part) of automake, in
-  particular am_aux_dir expansion, which in turn relies on ac_aux-dir,
-  which is not initialized at this point, and thus: certain doom (or
-  fun, depending on your POV and mood :p)
-
-  Hence call AC_USE_SYSTEM_EXTENSIONS only after
-  AM_INIT_AUTOMAKE. This, of course, caused a lot of related macro
-  shuffling.
-
-  Tested against automake-1.10 (OSX Lion/XCode version) and
-  automake-1.14 (homebrew version)
-
-* Require external gettext for --enable-nls
-
-  And stop using the internal flavor with ./intl
-
-* Make AX_CXX_COMPILE_STDCXX_11 test for -stdlib=libc++ via std::shared_ptr
-
-  The clang shipped with OSX XCode and clangs not build enabling
-  libcpp, will default to the libstdc++ headers and lib installed on
-  the system.  In the OSX case, that libstdc++ is the one bundles with
-  gcc-4.2, which is far too old to provide all required C++11 types,
-  such as std::shared_ptr.  Hence, the C++11 check should try to
-  compile a program with a C++11 type and try -stdlib=libc++ if the
-  default lib fails to compile said program.
-
-* Make the configure check for C++11 compiler mandatory
-
-  Remove stray "dnl", so that mandatory actually works with (my)
-  autoreconf.
-
-* Always build doc/manual-src
-
-  Should sphinx-build be not available AND the man file not be prsent,
-  then just "touch" it into existence (and warn about that)
-
-* Win: Use SetConsoleCtrlHandler for SIGINT/SIGTERM
-
-* Implement a simple resource lock (threading)
-
-  In this initial implementation Locks are no-ops on platforms other
-  than Windows.
+* android: Build and link with zlib
 
-* Check for sphinx-build during configure
+  Previously, we linked with zlib shipped with NDK, but it seems this
+  is not part of NDK API, and thus could break our app.
 
-* Add --with-disk-cache configure option
+* Allow netrc-path to be specified in the config file
 
-  Enables packagers more fine grained control over the default value
-  without having to mess with config files.
+  Adds --netrc-path to override default .netrc search path.  Patch
+  from Ryan Steinmetz
 
-  See GH-115
+* Exit with 32 status code if checksum verification failed
 
-* Change defaults: Enable 16M disk cache by default.
+* Add SFTP support using libssh2
 
-* Always save control file if --force-save is given
+  aria2 can now download files via sftp protocol: aria2c sftp://....
+  --ssh-host-key-md option is added to specify expected server's
+  fingerprint.
 
-* Set log level DEBUG for unittests
+* Added Dockerfile to cross complile aria2 for RaspberryPI (armhf)
 
-* Check that C++ compiler supports override keyword
+  Patch from Igor Khomyakov
 
-  If the compiler supports override, define CXX11_OVERRIDE as
-  override, otherwise define it as empty. Use CXX11_OVERRIDE instead
-  of override.
+* multiple interface support for link aggregation
 
-* AppleTLS: Fix MessageDigestImpl
+  Adds --multiple-interface option.  Patch from Sarim Khan
 
-* AppleTLS: Fix session CFRelease stuff
+* Run on-bt-download-complete command when -V reports download finished
 
-* Use AX_CXX_COMPILE_STDCXX_11 macro to detect C++0x/C++11 support in
-  compiler
+  Fixes GH-355
 
-* Require -std=c++11 and use std::shared_ptr instead of SharedHandle
+* Use dedicated DiskWriter in MultiDiskFileAllocationIterator
 
-* Join URI on redirect
+  We have to use dedicated DiskWriter instead of
+  (*entryItr_)->getDiskWriter().  This is because
+  SingleFileAllocationIterator cannot reopen file if file is closed by
+  OpenedFileCounter.  Fixes GH-350
 
-* Send HAVE message to the peer which the piece is downloaded from
+* Fix getrandom for system with libc not including errno or systems
 
-  Historically, aria2 did not send HAVE message to the peer which the
-  piece is coming from, thinking it is obvious that the peer knows we
-  have the piece. But it is not obvious if one piece is download from
-  more than 1 peers (e.g., end game mode). So it is better to send
-  HAVE to all peers connected.
+  not supporting ENOSYS in the first place.  Fixes GH-347
 
-* Improvements to --follow-torrent=false documentation.
+* Don't send back rpc-secret option value in aria2.getGlobalOption RPC
+  method
 
-  Patch from gt
+* Make libuv default off
 
-* SessionSerializer: Truly unique URIs
+  See GH-241 for discussion
 
-  Before, only spent uris where sanitized not to be contained within
-  remaining uris. Change this so that each uri in the
-  union(remaining,spent) get saved once at most.  The order of the
-  uris will won't be changed, with remaining uris going first followed
-  by spent uris.
+* Fixed slow RPC response
 
-  Also avoid copying the uri std::strings around during dupe checking,
-  usually resulting in better performance regarding CPU and space.
+  Fxies GH-345
 
-* Make getOption RPC method return option for stopped downloads
+* Fix getrandom interface detection
 
-* SessionSerializer: Save spent URIs as well as remaining ones
+  Fixes GH-346

+ 14 - 4
README.android

@@ -38,13 +38,14 @@ See `the online manual
 Notes
 -----
 
-aria2c executable was generated using android-ndk-r10b.
+aria2c executable was generated using android-ndk-r10d.
 
 The following libraries were statically linked.
 
- * openssl 1.0.2
- * expat 2.1.0
- * c-ares 1.10.0
+* openssl 1.0.2d
+* expat 2.1.0
+* c-ares 1.10.0
+* libssh2 1.6.0
 
 Since Android does not have ``/etc/resolv.conf``, c-ares (asynchronous
 DNS resolver) is disabled by default. But name resolution is sometimes
@@ -54,11 +55,19 @@ using ``--async-dns`` and specify DNS servers using
 
   --async-dns --async-dns-server=`getprop net.dns1`,`getprop net.dns2`
 
+Additionally, the CA certificates shipped with Android don't locate in
+the same place as those of normal Unix-like systems do, so this
+workaround might be useful to securely download files via HTTPS::
+
+   cat /etc/security/cacerts/* | aria2c --ca-certificate=/proc/self/fd/0 $@
+
 Because it is tedious to type these long parameters every time you use
 aria2c, the following wrapper shell script would be handy::
 
     #!/system/bin/sh
+    cat /etc/security/cacerts/* | \
     /data/data/jackpal.androidterm/aria2c \
+      --ca-certificate=/proc/self/fd/0 \
       --async-dns \
       --async-dns-server=`getprop net.dns1`,`getprop net.dns2` \
       "$@"
@@ -70,6 +79,7 @@ Known Issues
 ------------
 
 * Since Android does not have ``/dev/stdout``, ``-l-`` does not work.
+  ``/proc/self/fd/0`` is a workaround for Android.
 
 * Android Terminal Emulator sometimes stops updating console. It looks
   like aria2c hangs, but aria2c continues to run.

+ 5 - 4
README.mingw

@@ -5,18 +5,19 @@ aria2 Windows build is provided in 2 flavors: 32bit version and 64bit
 version. The executable was compiled using mingw-w64 cross compiler on
 Debian Linux.
 
-* gcc-mingw-w64               4.9.0-2+13
-* binutils-mingw-w64-i686     2.24-2+3+b1
-* binutils-mingw-w64-x86-64   2.24-2+3+b1
+* gcc-mingw-w64               4.9.2-21+15.4
+* binutils-mingw-w64-i686     2.25-8+6.2
+* binutils-mingw-w64-x86-64   2.25-8+6.2
 
 The executable is statically linked, so no extra DLLs are
 necessary. The linked libraries are:
 
 * gmp 6.0.0
 * expat 2.1.0
-* sqlite 3.8.8.2
+* sqlite 3.8.11.1
 * zlib 1.2.8
 * c-ares 1.10.0 with the dns.patch [1] applied
+* libssh2 1.6.0
 
 [1] http://c-ares.haxx.se/mail/c-ares-archive-2014-05/0008.shtml
 

+ 36 - 22
README.rst

@@ -10,14 +10,15 @@ You must use this program at your own risk.
 
 Introduction
 ------------
+
 aria2 is a utility for downloading files. The supported protocols are
-HTTP(S), FTP, BitTorrent, and Metalink. aria2 can download a file from
-multiple sources/protocols and tries to utilize your maximum download
-bandwidth. It supports downloading a file from HTTP(S)/FTP and
-BitTorrent at the same time, while the data downloaded from
-HTTP(S)/FTP is uploaded to the BitTorrent swarm. Using Metalink's
-chunk checksums, aria2 automatically validates chunks of data while
-downloading a file like BitTorrent.
+HTTP(S), FTP, SFTP, BitTorrent, and Metalink. aria2 can download a
+file from multiple sources/protocols and tries to utilize your maximum
+download bandwidth. It supports downloading a file from
+HTTP(S)/FTP/SFTP and BitTorrent at the same time, while the data
+downloaded from HTTP(S)/FTP/SFTP is uploaded to the BitTorrent
+swarm. Using Metalink's chunk checksums, aria2 automatically validates
+chunks of data while downloading a file like BitTorrent.
 
 The project page is located at http://aria2.sourceforge.net/.
 
@@ -33,10 +34,10 @@ Features
 Here is a list of features:
 
 * Command-line interface
-* Download files through HTTP(S)/FTP/BitTorrent
+* Download files through HTTP(S)/FTP/SFTP/BitTorrent
 * Segmented downloading
-* Metalink version 4 (RFC 5854) support(HTTP/FTP/BitTorrent)
-* Metalink version 3.0 support(HTTP/FTP/BitTorrent)
+* Metalink version 4 (RFC 5854) support(HTTP/FTP/SFTP/BitTorrent)
+* Metalink version 3.0 support(HTTP/FTP/SFTP/BitTorrent)
 * Metalink/HTTP (RFC 6249) support
 * HTTP/1.1 implementation
 * HTTP Proxy support
@@ -54,7 +55,7 @@ Here is a list of features:
 * Save Cookies in the Mozilla/Firefox (1.x/2.x)/Netscape format.
 * Custom HTTP Header support
 * Persistent Connections support
-* FTP through HTTP Proxy
+* FTP/SFTP through HTTP Proxy
 * Download/Upload speed throttling
 * BitTorrent extensions: Fast extension, DHT, PEX, MSE/PSE,
   Multi-Tracker, UDP tracker
@@ -98,6 +99,7 @@ Dependency
 features                  dependency
 ======================== ========================================
 HTTPS                    OSX or GnuTLS or OpenSSL or Windows
+SFTP                     libssh2
 BitTorrent               None. Optional: libnettle+libgmp or libgcrypt
                          or OpenSSL (see note)
 Metalink                 libxml2 or Expat.
@@ -183,6 +185,7 @@ distribution you use):
 * libgnutls-dev    (Required for HTTPS, BitTorrent, Checksum support)
 * nettle-dev       (Required for BitTorrent, Checksum support)
 * libgmp-dev       (Required for BitTorrent)
+* libssh2-1-dev    (Required for SFTP support)
 * libc-ares-dev    (Required for async DNS support)
 * libxml2-dev      (Required for Metalink support)
 * zlib1g-dev       (Required for gzip, deflate decoding support in HTTP)
@@ -206,8 +209,13 @@ You can use libexpat1-dev instead of libxml2-dev:
 On Fedora you need the following packages: gcc, gcc-c++, kernel-devel,
 libgcrypt-devel, libxml2-devel, openssl-devel, gettext-devel, cppunit
 
-If you downloaded source code from git repository, you have to run
-following command to generate configure script and other files
+If you downloaded source code from git repository, you have to install
+following packages to get autoconf macros:
+
+* libxml2-dev
+* libcppunit-dev
+
+And run following command to generate configure script and other files
 necessary to build the program::
 
     $ autoreconf -i
@@ -301,6 +309,7 @@ following libraries have been built for cross-compile:
 * expat
 * sqlite3
 * zlib
+* libssh2
 * cppunit
 
 Some environment variables can be adjusted to change build settings:
@@ -341,6 +350,8 @@ assumes the following libraries have been built for cross-compile:
 * c-ares
 * openssl
 * expat
+* zlib
+* libssh2
 
 When building the above libraries, make sure that disable shared
 library and enable only static library. We are going to link those
@@ -419,9 +430,11 @@ DHT
 ~~~
 
 aria2 supports mainline compatible DHT. By default, the routing table
-for IPv4 DHT is saved to ``$HOME/.aria2/dht.dat`` and the routing
-table for IPv6 DHT is saved to ``$HOME/.aria2/dht6.dat``. aria2 uses
-same port number to listen on for both IPv4 and IPv6 DHT.
+for IPv4 DHT is saved to ``$XDG_CACHE_HOME/aria2/dht.dat`` and the
+routing table for IPv6 DHT is saved to
+``$XDG_CACHE_HOME/aria2/dht6.dat`` unless files exist at
+``$HOME/.aria2/dht.dat`` or ``$HOME/.aria2/dht6.dat``. aria2 uses same
+port number to listen on for both IPv4 and IPv6 DHT.
 
 UDP tracker
 ~~~~~~~~~~~
@@ -449,9 +462,9 @@ Other things should be noted
 Metalink
 --------
 
-The current implementation supports HTTP(S)/FTP/BitTorrent.  The other
-P2P protocols are ignored. Both Metalink4 (RFC 5854) and Metalink
-version 3.0 documents are supported.
+The current implementation supports HTTP(S)/FTP/SFTP/BitTorrent.  The
+other P2P protocols are ignored. Both Metalink4 (RFC 5854) and
+Metalink version 3.0 documents are supported.
 
 For checksum verification, md5, sha-1, sha-224, sha-256, sha-384 and
 sha-512 are supported. If multiple hash algorithms are provided, aria2
@@ -497,9 +510,10 @@ which location you prefer, you can use ``--metalink-location`` option.
 
 netrc
 -----
-netrc support is enabled by default for HTTP(S)/FTP.  To disable netrc
-support, specify -n command-line option.  Your .netrc file should have
-correct permissions(600).
+
+netrc support is enabled by default for HTTP(S)/FTP/SFTP.  To disable
+netrc support, specify -n command-line option.  Your .netrc file
+should have correct permissions(600).
 
 WebSocket
 ---------

+ 6 - 12
android-config

@@ -44,21 +44,15 @@ PATH=$TOOLCHAIN/bin:$PATH
     --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
     --disable-nls \
     --without-gnutls \
-    --with-openssl --with-openssl-prefix=$PREFIX \
+    --with-openssl \
     --without-sqlite3 \
     --without-libxml2 \
-    --with-libexpat --with-libexpat-prefix=$PREFIX \
-    --with-libcares --with-libcares-prefix=$PREFIX \
-    --with-libz --with-libz-prefix=$PREFIX \
+    --with-libexpat \
+    --with-libcares \
+    --with-libz \
+    --with-libssh2 \
     CXXFLAGS="-Os -g" \
     CFLAGS="-Os -g" \
     CPPFLAGS="-fPIE" \
     LDFLAGS="-fPIE -pie -L$PREFIX/lib" \
-    PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig" \
-    ZLIB_LIBS="-lz" \
-    ZLIB_CFLAGS="-I$TOOLCHAIN/sysroot/usr/include"
-
-# ZLIB_LIBS and ZLIB_CFLAGS are needed because aria2 configure script
-# checks zlib availability using pkg-config, but android toochain does
-# not provide pkg-config file. We need to specify these variables
-# manually.
+    PKG_CONFIG_LIBDIR="$PREFIX/lib/pkgconfig"

+ 22 - 0
android/zlib-config

@@ -0,0 +1,22 @@
+#!/bin/sh -e
+
+if [ -z "$ANDROID_HOME" ]; then
+    echo 'No $ANDROID_HOME specified.'
+    exit 1
+fi
+PREFIX=$ANDROID_HOME/usr/local
+TOOLCHAIN=$ANDROID_HOME/toolchain
+PATH=$TOOLCHAIN/bin:$PATH
+
+HOST=arm-linux-androideabi
+
+CC=$HOST-gcc \
+AR=$HOST-ar \
+LD=$HOST-ld \
+RANLIB=$HOST-ranlib \
+STRIP=$HOST-strip \
+./configure \
+    --prefix=$PREFIX \
+    --libdir=$PREFIX/lib \
+    --includedir=$PREFIX/include \
+    --static

+ 6 - 0
build_test.sh

@@ -28,6 +28,10 @@ build()
 	&& LANG=C make clean \
 	&& LANG=C make -j2 check 2>&1 |tee "$BUILDDIR/aria2c_$2.log" \
 	&& cp src/aria2c "$BUILDDIR/aria2c_$2"
+
+    if [ -f "test/aria2c.log" ]; then
+	cat "test/aria2c.log" >> "$BUILDDIR/aria2c_$2.log"
+    fi
 }
 
 clear()
@@ -53,11 +57,13 @@ case "$1" in
 	build "--without-libxml2 --without-libexpat" "noxml"
 	build "--without-libz" "nozlib"
 	build "--without-sqlite3" "nosqlite3"
+	build "--without-libssh2" "nolibssh2"
 	# Feature combinations
 	build "--disable-bittorrent" "nobt"
 	build "--disable-metalink" "noml"
 	build "--disable-bittorrent --disable-metalink" "nobt_noml"
 	build "--disable-epoll" "noepoll"
 	build "--disable-epoll --without-libcares" "noepoll_nocares"
+	build "--enable-libaria2" "libaria2"
 	;;
 esac

+ 62 - 29
configure.ac

@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 #
 AC_PREREQ([2.67])
-AC_INIT([aria2],[1.18.9],[https://github.com/tatsuhiro-t/aria2/issues],[aria2],[http://aria2.sourceforge.net/])
+AC_INIT([aria2],[1.19.1],[https://github.com/tatsuhiro-t/aria2/issues],[aria2],[http://aria2.sourceforge.net/])
 
 AC_CANONICAL_HOST
 AC_CANONICAL_TARGET
@@ -29,9 +29,10 @@ case "$host" in
   *mingw*)
     win_build=yes
     LIBS="$LIBS -lws2_32 -lwsock32 -lgdi32 -lwinmm -liphlpapi -lpsapi"
-    # C++ headers defines __USE_MINGW_ANSI_STDIO to 1 unconditionally.
-    # We have to use it as well nonetheless.
-    CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS"
+    # Define _POSIX_C_SOURCE to 1. This makes {asc,local}time_r available
+    # from <time.h> even without (un)helpful interference from <pthread.h>,
+    # and also defines __USE_MINGW_ANSI_STDIO.
+    CPPFLAGS="-D_POSIX_C_SOURCE=1 $CPPFLAGS"
     # Build with ASLR (dynamicbase) and NX compatiblity (nxcompat)
     # Enable pie once upstream/binutils gets fixed to produce correct binaries with it.
     LDFLAGS="$LDFLAGS -Wl,--dynamicbase -Wl,--nxcompat"
@@ -43,7 +44,7 @@ AC_DEFINE_UNQUOTED([HOST], ["$host"], [Define build-type])
 AC_DEFINE_UNQUOTED([TARGET], ["$target"], [Define target-type])
 
 # Checks for arguments.
-ARIA2_ARG_WITHOUT([libuv])
+ARIA2_ARG_WITH([libuv])
 ARIA2_ARG_WITHOUT([appletls])
 ARIA2_ARG_WITHOUT([wintls])
 ARIA2_ARG_WITHOUT([gnutls])
@@ -58,6 +59,7 @@ ARIA2_ARG_WITHOUT([libcares])
 ARIA2_ARG_WITHOUT([libz])
 ARIA2_ARG_WITH([tcmalloc])
 ARIA2_ARG_WITH([jemalloc])
+ARIA2_ARG_WITHOUT([libssh2])
 
 ARIA2_ARG_DISABLE([ssl])
 ARIA2_ARG_DISABLE([bittorrent])
@@ -106,14 +108,6 @@ if test "x$AR" = "x:"; then
 fi
 AC_SUBST([AR])
 
-AC_PATH_PROG([A2X], [a2x])
-AC_SUBST([A2X])
-AM_CONDITIONAL([HAVE_A2X], [ test "x$A2X" != "x" ])
-
-AC_PATH_PROG([ASCIIDOC], [asciidoc])
-AC_SUBST([ASCIIDOC])
-AM_CONDITIONAL([HAVE_ASCIIDOC], [ test "x$ASCIIDOC" != "x" ])
-
 AC_PATH_PROGS([SPHINXBUILD], [sphinx-build])
 AC_SUBST([SPHINXBUILD])
 AM_CONDITIONAL([HAVE_SPHINXBUILD], [ test "x$SPHINXBUILD" != "x" ])
@@ -131,6 +125,16 @@ PKG_PROG_PKG_CONFIG([0.20])
 # Check C++ compiler supports C++0x/C++11 feature
 AX_CXX_COMPILE_STDCXX_11([noext], [mandatory])
 
+# Check C++ compiler actually supports nullptr
+AC_MSG_CHECKING([whether the c++ compiler supports nullptr])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+]],
+[[
+int *a = nullptr;
+]])],
+[],
+[AC_MSG_FAILURE([C++ compiler does not understand nullptr, perhaps C++ compiler is too old.  Try again with new one (gcc >= 4.8.3 or clang >= 3.4)])])
+
 # i686-w64-mingw32-g++ 4.6 does not support override keyword. For
 # those compilers, define CXX11_OVERRIDE to empty string. Otherwise
 # define it as override. Use CXX11_OVERRIDE instead of override.
@@ -470,6 +474,20 @@ if test "x$have_openssl" != "xyes"; then
   fi
 fi
 
+if test "x$with_libssh2" = "xyes"; then
+  PKG_CHECK_MODULES([LIBSSH2], [libssh2], [have_libssh2=yes], [have_libssh2=no])
+  if test "x$have_libssh2" = "xyes"; then
+    AC_DEFINE([HAVE_LIBSSH2], [1], [Define to 1 if you have libssh2.])
+    LIBS="$LIBSSH2_LIBS $LIBS"
+    CPPFLAGS="$LIBSSH2_CFLAGS $CPPFLAGS"
+  else
+    AC_MSG_WARN([$LIBSSH2_PKG_ERRORS])
+    if test "x$with_libssh2_requested" = "xyes"; then
+      ARIA2_DEP_NOT_MET([libssh2])
+    fi
+  fi
+fi
+
 if test "x$with_libcares" = "xyes"; then
   PKG_CHECK_MODULES([LIBCARES], [libcares >= 1.7.0], [have_libcares=yes],
                     [have_libcares=no])
@@ -613,6 +631,9 @@ AM_CONDITIONAL([HAVE_ZLIB], [test "x$have_zlib" = "xyes"])
 # Set conditional for sqlite3
 AM_CONDITIONAL([HAVE_SQLITE3], [test "x$have_sqlite3" = "xyes"])
 
+# Set conditional for libssh2
+AM_CONDITIONAL([HAVE_LIBSSH2], [test "x$have_libssh2" = "xyes"])
+
 AC_SEARCH_LIBS([clock_gettime], [rt])
 
 case "$host" in
@@ -758,10 +779,12 @@ AC_CHECK_FUNCS([__argz_count \
 
 AC_MSG_CHECKING([for getrandom linux syscall interface])
 AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/syscall.h>
 #include <linux/random.h>
 ]],
 [[
 int x = GRND_NONBLOCK;
+int y = (int)SYS_getrandom;
 ]])],
   [have_getrandom_interface=yes
    AC_DEFINE([HAVE_GETRANDOM_INTERFACE], [1], [Define to 1 if getrandom linux syscall interface is available.])],
@@ -839,10 +862,32 @@ AM_CONDITIONAL([HAVE_SOME_FALLOCATE],
   [test "x$have_posix_fallocate" = "xyes" || test "x$have_fallocate" = "xyes" \
   || test "x$have_osx" = "xyes" || test "x$win_build" = "xyes"])
 
+AC_MSG_CHECKING([for asctime_r])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+    #include <time.h>
+  ]], [[
+    struct tm r; char *c;
+    asctime_r(&r, c);
+  ]])],
+  [AM_CONDITIONAL([HAVE_ASCTIME_R], true)
+   AC_MSG_RESULT([yes])
+   AC_DEFINE([HAVE_ASCTIME_R], [1], [Define to 1 if you have the `asctime_r' function or macro.])],
+  [AC_MSG_RESULT([no])
+   AM_CONDITIONAL([HAVE_ASCTIME_R], false)])
+
+AC_MSG_CHECKING([for localtime_r])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+    #include <time.h>
+  ]], [[
+    time_t t; struct tm r;
+    localtime_r(&t, &r);
+  ]])],
+  [AM_CONDITIONAL([HAVE_LOCALTIME_R], true)
+   AC_MSG_RESULT([yes])
+   AC_DEFINE([HAVE_LOCALTIME_R], [1], [Define to 1 if you have the `localtime_r' function or macro.])],
+  [AC_MSG_RESULT([no])
+   AM_CONDITIONAL([HAVE_LOCALTIME_R], false)])
 
-AC_CHECK_FUNCS([asctime_r],
-	[AM_CONDITIONAL([HAVE_ASCTIME_R], true)],
-	[AM_CONDITIONAL([HAVE_ASCTIME_R], false)])
 AC_CHECK_FUNCS([basename],
 	[AM_CONDITIONAL([HAVE_BASENAME], true)],
 	[AM_CONDITIONAL([HAVE_BASENAME], false)])
@@ -855,9 +900,6 @@ AC_CHECK_FUNCS([getaddrinfo],
 AC_CHECK_FUNCS([gettimeofday],
 	[AM_CONDITIONAL([HAVE_GETTIMEOFDAY], true)],
 	[AM_CONDITIONAL([HAVE_GETTIMEOFDAY], false)])
-AC_CHECK_FUNCS([localtime_r],
-	[AM_CONDITIONAL([HAVE_LOCALTIME_R], true)],
-	[AM_CONDITIONAL([HAVE_LOCALTIME_R], false)])
 AC_CHECK_FUNCS([strptime],
 	[AM_CONDITIONAL([HAVE_STRPTIME], true)],
 	[AM_CONDITIONAL([HAVE_STRPTIME], false)])
@@ -867,14 +909,6 @@ AC_CHECK_FUNCS([timegm],
 AC_CHECK_FUNCS([daemon], [have_daemon=yes])
 AM_CONDITIONAL([HAVE_DAEMON], [test "x$have_daemon" = "xyes"])
 
-AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes])
-
-if test "x$have_clock_gettime" != "xyes"; then
-   AC_CHECK_FUNCS([mach_absolute_time], [have_mach_absolute_time=yes])
-fi
-AM_CONDITIONAL([HAVE_MACH_ABSOLUTE_TIME],
-		[test "x$have_mach_absolute_time" = "xyes"])
-
 AC_CHECK_FUNCS([poll], [have_poll=yes])
 AM_CONDITIONAL([HAVE_POLL], [test "x$have_poll" = "xyes"])
 
@@ -885,11 +919,9 @@ case "$host" in
     AM_CONDITIONAL([HAVE_GETADDRINFO], true)
     dnl defined in ws2tcpip.h, but missing in C:\mingw\lib\libws2_32.a
     AM_CONDITIONAL([HAVE_GAI_STRERROR], false)
-    AM_CONDITIONAL([HAVE_TIMEGETTIME], [test "x$have_clock_gettime" != "xyes"])
     ;;
   *)
     AM_CONDITIONAL([MINGW_BUILD], false)
-    AM_CONDITIONAL([HAVE_TIMEGETTIME], false)
     ;;
 esac
 
@@ -1060,6 +1092,7 @@ echo "LibXML2:        $have_libxml2"
 echo "LibExpat:       $have_libexpat"
 echo "LibCares:       $have_libcares"
 echo "Zlib:           $have_zlib"
+echo "Libssh2:        $have_libssh2"
 echo "Epoll:          $have_epoll"
 echo "Bittorrent:     $enable_bittorrent"
 echo "Metalink:       $enable_metalink"

File diff suppressed because it is too large
+ 0 - 0
doc/bash_completion/aria2c


+ 109 - 54
doc/manual-src/en/aria2c.rst

@@ -9,17 +9,22 @@ DESCRIPTION
 -----------
 
 aria2 is a utility for downloading files. The supported protocols are
-HTTP(S), FTP, BitTorrent, and Metalink. aria2 can download a file from
-multiple sources/protocols and tries to utilize your maximum download
-bandwidth. It supports downloading a file from HTTP(S)/FTP and
-BitTorrent at the same time, while the data downloaded from
-HTTP(S)/FTP is uploaded to the BitTorrent swarm. Using Metalink
+HTTP(S), FTP, SFTP, BitTorrent, and Metalink. aria2 can download a
+file from multiple sources/protocols and tries to utilize your maximum
+download bandwidth. It supports downloading a file from HTTP(S)/FTP
+/SFTP and BitTorrent at the same time, while the data downloaded from
+HTTP(S)/FTP/SFTP is uploaded to the BitTorrent swarm. Using Metalink
 chunk checksums, aria2 automatically validates chunks of data while
 downloading a file.
 
 OPTIONS
 -------
 
+.. note::
+
+  Most FTP related options are applicable to SFTP as well.
+  Some options are not effective against SFTP (e.g., :option:`--ftp-pasv`)
+
 Basic Options
 ~~~~~~~~~~~~~
 .. option:: -d, --dir=<DIR>
@@ -84,8 +89,9 @@ Basic Options
    ``#checksum``, ``#experimental``, ``#deprecated``, ``#help``, ``#all``
    Default: ``#basic``
 
-HTTP/FTP Options
-~~~~~~~~~~~~~~~~
+HTTP/FTP/SFTP Options
+~~~~~~~~~~~~~~~~~~~~~
+
 .. option:: --all-proxy=<PROXY>
 
   Use a proxy server for all protocols.  To override a previously
@@ -184,6 +190,17 @@ HTTP/FTP Options
   1 source.  You can append ``K`` or ``M`` (1K = 1024, 1M = 1024K).
   Possible Values: ``1M`` -``1024M`` Default: ``20M``
 
+
+.. option:: --netrc-path=<FILE>
+
+   Specify the path to the netrc file.
+   Default: ``$(HOME)/.netrc``
+
+   .. note::
+
+       Permission of the .netrc file must be 600.  Otherwise, the file
+       will be ignored.
+
 .. option:: -n, --no-netrc[=true|false]
 
   Disables netrc support. netrc support is enabled by default.
@@ -520,8 +537,8 @@ HTTP Specific Options
   Set user agent for HTTP(S) downloads.
   Default: ``aria2/$VERSION``, $VERSION is replaced by package version.
 
-FTP Specific Options
-~~~~~~~~~~~~~~~~~~~~
+FTP/SFTP Specific Options
+~~~~~~~~~~~~~~~~~~~~~~~~~
 .. option:: --ftp-user=<USER>
 
   Set FTP user. This affects all URIs.
@@ -542,6 +559,10 @@ FTP Specific Options
   If ``false`` is given, the active mode will be used.
   Default: ``true``
 
+  .. note::
+
+    This option is ignored for SFTP transfer.
+
 .. option:: --ftp-proxy=<PROXY>
 
   Use a proxy server for FTP.  To override a previously defined proxy,
@@ -562,11 +583,24 @@ FTP Specific Options
   Set FTP transfer type. TYPE is either ``binary`` or ``ascii``.
   Default: ``binary``
 
+  .. note::
+
+    This option is ignored for SFTP transfer.
+
 .. option:: --ftp-reuse-connection[=true|false]
 
   Reuse connection in FTP.
   Default: ``true``
 
+.. option:: --ssh-host-key-md=<TYPE>=<DIGEST>
+
+  Set checksum for SSH host public key. TYPE is hash type. The
+  supported hash type is ``sha-1`` or ``md5``. DIGEST is hex
+  digest. For example:
+  ``sha-1=b030503d4de4539dc7885e6f0f5e256704edf4c3``.  This option can
+  be used to validate server's public key when SFTP is used. If this
+  option is not set, which is default, no validation takes place.
+
 BitTorrent/Metalink Options
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .. option:: --select-file=<INDEX>...
@@ -767,12 +801,14 @@ BitTorrent Specific Options
 .. option:: --dht-file-path=<PATH>
 
   Change the IPv4 DHT routing table file to PATH.
-  Default: ``$HOME/.aria2/dht.dat``
+  Default: ``$HOME/.aria2/dht.dat`` if present, otherwise
+  ``$XDG_CACHE_HOME/aria2/dht.dat``.
 
 .. option:: --dht-file-path6=<PATH>
 
   Change the IPv6 DHT routing table file to PATH.
-  Default: ``$HOME/.aria2/dht6.dat``
+  Default: ``$HOME/.aria2/dht6.dat`` if present, otherwise
+  ``$XDG_CACHE_HOME/aria2/dht6.dat``.
 
 .. option:: --dht-listen-addr6=<ADDR>
 
@@ -1147,7 +1183,8 @@ Advanced Options
 .. option:: --conf-path=<PATH>
 
   Change the configuration file path to PATH.
-  Default: ``$HOME/.aria2/aria2.conf``
+  Default: ``$HOME/.aria2/aria2.conf`` if present, otherwise
+  ``$XDG_CONFIG_HOME/aria2/aria2.conf``.
 
 .. option:: --console-log-level=<LEVEL>
 
@@ -1336,6 +1373,14 @@ Advanced Options
   Possible Values: ``SSLv3``, ``TLSv1``, ``TLSv1.1``, ``TLSv1.2``
   Default: ``TLSv1``
 
+.. option:: --multiple-interface=<INTERFACES>
+
+  Comma separated list of interfaces to bind sockets to. Requests will
+  be splited among the interfaces to achieve link aggregation. You can
+  specify interface name, IP address and hostname. If
+  :option:`--interface` is used, this option will be ignored.
+  Possible Values: interface, IP address, hostname
+
 .. option:: --log-level=<LEVEL>
 
   Set log level to output.
@@ -1579,12 +1624,12 @@ treated as a separate download. Both Metalink4 and Metalink version
 3.0 are supported.
 
 You can specify both torrent file with -T option and URIs. By doing
-this, you can download a file from both torrent swarm and HTTP(S)/FTP
-server at the same time, while the data from HTTP(S)/FTP are uploaded
-to the torrent swarm.  For single file torrents, URI can be a complete
-URI pointing to the resource or if URI ends with /, name in torrent
-file in torrent is added. For multi-file torrents, name and path are
-added to form a URI for each file.
+this, you can download a file from both torrent swarm and
+HTTP(S)/FTP/SFTP server at the same time, while the data from
+HTTP(S)/FTP/SFTP are uploaded to the torrent swarm.  For single file
+torrents, URI can be a complete URI pointing to the resource or if URI
+ends with /, name in torrent file in torrent is added. For multi-file
+torrents, name and path are added to form a URI for each file.
 
 .. note::
 
@@ -1615,15 +1660,14 @@ occurred. Currently following options are available:
 
 aria2 passes 3 arguments to specified command when it is executed.
 These arguments are: GID, the number of files and file path.  For
-HTTP, FTP downloads, usually the number of files is 1.  BitTorrent
-download can contain multiple files.
-If number of files is more than one, file path is first one.  In
-other words, this is the value of path key of first struct whose
-selected key is true in the response of :func:`aria2.getFiles`
-RPC method.
-If you want to get all file paths, consider to use JSON-RPC/XML-RPC.  Please
-note that file path may change during download in HTTP because of
-redirection or Content-Disposition header.
+HTTP, FTP, and SFTP downloads, usually the number of files is 1.
+BitTorrent download can contain multiple files.  If number of files is
+more than one, file path is first one.  In other words, this is the
+value of path key of first struct whose selected key is true in the
+response of :func:`aria2.getFiles` RPC method.  If you want to get all
+file paths, consider to use JSON-RPC/XML-RPC.  Please note that file
+path may change during download in HTTP because of redirection or
+Content-Disposition header.
 
 Let's see an example of how arguments are passed to command:
 
@@ -1746,6 +1790,12 @@ based on the last error encountered.
 30
   If aria2 could not parse JSON-RPC request.
 
+31
+  Reserved.  Not used.
+
+32
+  If checksum validation failed.
+
 .. note::
 
   An error occurred in a finished download will not be reported
@@ -1792,10 +1842,12 @@ FILES
 aria2.conf
 ~~~~~~~~~~
 
-By default, aria2 parses ``$HOME/.aria2/aria2.conf`` as a
-configuration file. You can specify the path to configuration file
-using :option:`--conf-path` option.  If you don't want to use the
-configuration file, use :option:`--no-conf` option.
+By default, aria2 checks whether the legacy path
+``$HOME/.aria2/aria2.conf`` is present, otherwise it parses
+``$XDG_CONFIG_HOME/aria2/aria2.conf`` as its configuration file.  You
+can specify the path to configuration file using :option:`--conf-path`
+option.  If you don't want to use the configuration file, use
+:option:`--no-conf` option.
 
 The configuration file is a text file and has 1 option per each
 line. In each line, you can specify name-value pair in the format:
@@ -1820,16 +1872,18 @@ lines beginning ``#`` are treated as comments::
 dht.dat
 ~~~~~~~~
 
-By default, the routing table of IPv4 DHT is saved to the path
-``$HOME/.aria2/dht.dat`` and the routing table of IPv6 DHT is saved to
-the path ``$HOME/.aria2/dht6.dat``.
+Unless the legacy file paths ``$HOME/.aria2/dht.dat`` and
+``$HOME/.aria2/dht6.dat`` are pointing to existing files, the routing
+table of IPv4 DHT is saved to the path
+``$XDG_CACHE_HOME/aria2/dht.dat`` and the routing table of IPv6 DHT is
+saved to the path ``$XDG_CACHE_HOME/aria2/dht6.dat``.
 
 Netrc
 ~~~~~
 
-Netrc support is enabled by default for HTTP(S)/FTP.  To disable netrc
-support, specify :option:`--no-netrc <-n>` option.  Your .netrc file should have correct
-permissions(600).
+Netrc support is enabled by default for HTTP(S)/FTP/SFTP.  To disable
+netrc support, specify :option:`--no-netrc <-n>` option.  Your .netrc
+file should have correct permissions(600).
 
 If machine name starts ``.``, aria2 performs domain-match instead of
 exact match. This is an extension of aria2. For example of domain
@@ -1992,6 +2046,7 @@ of URIs. These optional lines must start with white space(s).
   * :option:`seed-time <--seed-time>`
   * :option:`select-file <--select-file>`
   * :option:`split <-s>`
+  * :option:`ssh-host-key-md <--ssh-host-key-md>`
   * :option:`stream-piece-selector <--stream-piece-selector>`
   * :option:`timeout <-t>`
   * :option:`uri-selector <--uri-selector>`
@@ -2156,19 +2211,19 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
 
 .. function:: aria2.addUri([secret], uris[, options[, position]])
 
-  This method adds a new download. *uris* is an array of HTTP/FTP/BitTorrent
-  URIs (strings) pointing to the same resource.  If you mix URIs pointing to
-  different resources, then the download may fail or be corrupted without aria2
-  complaining.
-  When adding BitTorrent Magnet URIs, *uris* must have only one element and it
-  should be BitTorrent Magnet URI.
-  *options* is a struct and its members are pairs of option name and value.
-  See :ref:`rpc_options` below for more details.
-  If *position* is given, it must be an integer starting from 0. The new
-  download will be inserted at *position* in the waiting queue. If
-  *position* is omitted or *position* is larger than the current size of the
-  queue, the new download is appended to the end of the queue.
-  This method returns the GID of the newly registered download.
+  This method adds a new download. *uris* is an array of
+  HTTP/FTP/SFTP/BitTorrent URIs (strings) pointing to the same
+  resource.  If you mix URIs pointing to different resources, then the
+  download may fail or be corrupted without aria2 complaining.  When
+  adding BitTorrent Magnet URIs, *uris* must have only one element and
+  it should be BitTorrent Magnet URI.  *options* is a struct and its
+  members are pairs of option name and value.  See :ref:`rpc_options`
+  below for more details.  If *position* is given, it must be an
+  integer starting from 0. The new download will be inserted at
+  *position* in the waiting queue. If *position* is omitted or
+  *position* is larger than the current size of the queue, the new
+  download is appended to the end of the queue.  This method returns
+  the GID of the newly registered download.
 
   **JSON-RPC Example**
 
@@ -2775,9 +2830,9 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
 
 .. function:: aria2.getServers([secret], gid)
 
-  This method returns currently connected HTTP(S)/FTP servers of the download
-  denoted by *gid* (string). The response is an array of structs and contains
-  the following keys. Values are strings.
+  This method returns currently connected HTTP(S)/FTP/SFTP servers of
+  the download denoted by *gid* (string). The response is an array of
+  structs and contains the following keys. Values are strings.
 
   ``index``
     Index of the file, starting at 1, in the same order as files appear in the
@@ -4107,7 +4162,7 @@ The Metalink Download Description Format: :rfc:`5854`
 
 COPYRIGHT
 ---------
-Copyright (C) 2006, 2014 Tatsuhiro Tsujikawa
+Copyright (C) 2006, 2015 Tatsuhiro Tsujikawa
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by

+ 46 - 24
doc/manual-src/en/mkapiref.py

@@ -32,6 +32,7 @@
 # files in the program, then also delete it here.
 #
 # Generates API reference from C++ source code.
+from __future__ import print_function
 import re, sys, argparse
 
 class FunctionDoc:
@@ -41,10 +42,10 @@ class FunctionDoc:
         self.domain = domain
 
     def write(self, out):
-        print '''.. {}:: {}'''.format(self.domain, self.name)
-        print ''
+        print('''.. {}:: {}'''.format(self.domain, self.name))
+        print()
         for line in self.content:
-            print '    {}'.format(line)
+            print('    {}'.format(line))
 
 class TypedefDoc:
     def __init__(self, name, content):
@@ -52,10 +53,10 @@ class TypedefDoc:
         self.content = content
 
     def write(self, out):
-        print '''.. type:: {}'''.format(self.name)
-        print ''
+        print('''.. type:: {}'''.format(self.name))
+        print()
         for line in self.content:
-            print '    {}'.format(line)
+            print('    {}'.format(line))
 
 class StructDoc:
     def __init__(self, name, content, domain, members, member_domain):
@@ -67,19 +68,40 @@ class StructDoc:
 
     def write(self, out):
         if self.name:
-            print '''.. {}:: {}'''.format(self.domain, self.name)
-            print ''
+            print('''.. {}:: {}'''.format(self.domain, self.name))
+            print()
             for line in self.content:
-                print '    {}'.format(line)
-            print ''
+                print('    {}'.format(line))
+            print()
             for name, content in self.members:
-                print '''    .. {}:: {}'''.format(\
-                    'function' if name.endswith(')') else self.member_domain,
-                    name)
-                print ''
+                name = name.strip()
+                # For function (e.g., int foo())
+                m = re.match(r'(.+)\s+([^ ]+\(.*)', name)
+                if not m:
+                    # For variable (e.g., bool a)
+                    m = re.match(r'(.+)\s+([^ ]+)', name)
+                if m:
+                    print('''    .. {}:: {} {}::{}'''.format(
+                        'function' if name.endswith(')') else self.member_domain,
+                        m.group(1),
+                        self.name,
+                        m.group(2)))
+                else:
+                    if name.endswith(')'):
+                        # For function, without return type, like
+                        # constructor
+                        print('''    .. {}:: {}::{}'''.format(
+                            'function' if name.endswith(')') else self.member_domain,
+                            self.name, name))
+                    else:
+                        # enum
+                        print('''    .. {}:: {}'''.format(
+                            'function' if name.endswith(')') else self.member_domain,
+                            name))
+                print()
                 for line in content:
-                    print '''        {}'''.format(line)
-            print ''
+                    print('''        {}'''.format(line))
+            print()
 
 class MacroDoc:
     def __init__(self, name, content):
@@ -87,10 +109,10 @@ class MacroDoc:
         self.content = content
 
     def write(self, out):
-        print '''.. macro:: {}'''.format(self.name)
-        print ''
+        print('''.. macro:: {}'''.format(self.name))
+        print()
         for line in self.content:
-            print '    {}'.format(line)
+            print('    {}'.format(line))
 
 def make_api_ref(infiles):
     macros = []
@@ -124,12 +146,12 @@ def make_api_ref(infiles):
     for title, docs in alldocs:
         if not docs:
             continue
-        print title
-        print '-'*len(title)
+        print(title)
+        print('-'*len(title))
         for doc in docs:
             doc.write(sys.stdout)
-            print ''
-        print ''
+            print()
+        print()
 
 def process_macro(infile):
     content = read_content(infile)
@@ -263,6 +285,6 @@ if __name__ == '__main__':
                         help='source file')
     args = parser.parse_args()
     if args.header:
-        print args.header.read()
+        print(args.header.read())
     for infile in args.files:
         make_api_ref(args.files)

+ 4 - 2
doc/manual-src/en/technical-notes.rst

@@ -96,8 +96,10 @@ times.
 DHT routing table file format
 -----------------------------
 
-aria2 saves IPv4 DHT routing table in ``${HOME}/.aria2/dht.dat`` and
-IPv6 DHT routing table in ``${HOME}/.aria2/dht6.dat`` by default.
+aria2 saves IPv4 DHT routing table in
+``${XDG_CACHE_HOME}/aria2/dht.dat`` and IPv6 DHT routing table in
+``${XDG_CACHE_HOME}/aria2/dht6.dat`` by default unless
+``${HOME}/.aria2/dht.dat`` and ``${HOME}/.aria2/dht.dat`` are present.
 
 ``dht.dat`` and ``dht6.dat`` files use same binary encoding and have
 following fields. All multi byte integers are in network byte

+ 6 - 0
doc/manual-src/pt/aria2c.rst

@@ -16,6 +16,12 @@ SINOPSE
 DESCRIÇÃO
 ---------
 
+.. warning::
+
+   This translation has been outdated quite sometime now, and lacks
+   many recent changes.  Please consult English version manual for
+   updated information.
+
 Observação: Para executar o aria2 em um terminal ou no prompt da
 linha de comando do windows, utilize o comando aria2c.
 

+ 6 - 0
doc/manual-src/pt/index.rst

@@ -17,6 +17,12 @@
 Manual Aria2
 ============
 
+.. warning::
+
+   This translation has been outdated quite sometime now, and lacks
+   many recent changes.  Please consult English version manual for
+   updated information.
+
 aria2 é um utilitário para download de arquivos, que utiliza protocolos HTTP,
 HTTPS, FTP, BitTorrent e Metalink. Pode efetuar download de um ou vários 
 arquivos, a partir de uma ou múltiplas fontes e protocolos, com ou sem 

+ 1 - 0
doc/manual-src/ru/Makefile.am

@@ -126,6 +126,7 @@ text:
 
 man:
 	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	sed -i -e '1i .\\" -*- mode: troff; coding: utf-8 -*-' $(BUILDDIR)/man/aria2c.1
 	@echo
 	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
 

+ 99 - 40
doc/manual-src/ru/aria2c.rst

@@ -9,17 +9,22 @@ aria2c(1)
 --------
 
 aria2 - это утилита для загрузки файлов. Поддерживаемые протоколы: HTTP(S),
-FTP, BitTorrent и Metalink. aria2 может загрузить файл с разных
+FTP, SFTP, BitTorrent и Metalink. aria2 может загрузить файл с разных
 источников/протоколов и пытается максимально использовать пропускную
-способность канала. Есть поддержка загрузки файла по протоколам HTTP(S)/FTP
-и BitTorrent одновременно, пока данные загружаются по HTTP(S)/FTP, они тут
-же могут выгружаться в BitTorrent-рой. Используя контрольные суммы блока
-данных для Metalink, aria2 автоматически проверяет части данных во время
-загрузки файла.
+способность канала. Есть поддержка загрузки файла по протоколам
+HTTP(S)/FTP/SFTP и BitTorrent одновременно, пока данные загружаются по
+HTTP(S)/FTP, они тут же могут выгружаться в BitTorrent-рой. Используя
+контрольные суммы блока данных для Metalink, aria2 автоматически проверяет
+части данных во время загрузки файла.
 
 ПАРАМЕТРЫ
 ---------
 
+.. note::
+
+  Большинство связанных с FTP параметров применимы также к SFTP.
+  Некоторые параметры не являются эффективными по отношению к SFTP (например, :option:`--ftp-pasv`)
+
 Основные параметры
 ~~~~~~~~~~~~~~~~~~
 .. option:: -d, --dir=<DIR>
@@ -89,8 +94,9 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
    ``#deprecated``, ``#help``, ``#all``.
    По умолчанию: ``#basic``
 
-Параметры HTTP/FTP
-~~~~~~~~~~~~~~~~~~
+Параметры HTTP/FTP/SFTP
+~~~~~~~~~~~~~~~~~~~~~~~
+
 .. option:: --all-proxy=<PROXY>
 
   Использовать указанный прокси-сервер для всех протоколов. Для отмены
@@ -197,6 +203,17 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
   ``1M`` -``1024M``.
   По умолчанию: ``20M``
 
+
+.. option:: --netrc-path=<FILE>
+
+   Указать путь к файлу .netrc.
+   По умолчанию: ``$(HOME)/.netrc``
+
+   .. note::
+
+       Права доступа к файлу .netrc должны быть равны 600. Иначе, файл
+       будет проигнорирован.
+
 .. option:: -n, --no-netrc[=true|false]
 
   Отключить поддержку netrc. Поддержка netrc по умолчанию
@@ -544,8 +561,8 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
   Задать клиентское приложение для HTTP(S)-загрузок.
   По умолчанию: ``aria2/$VERSION``, $VERSION заменяется на версию пакета.
 
-Специфические параметры FTP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Специфические параметры FTP/SFTP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .. option:: --ftp-user=<USER>
 
   Задать пользователя для FTP.
@@ -566,6 +583,10 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
   то будет использован активный режим.
   По умолчанию: ``true``
 
+  .. note::
+
+    Этот параметр игнорируется для SFTP-передачи.
+
 .. option:: --ftp-proxy=<PROXY>
 
   Использовать указанный прокси-сервер для FTP. Для отмены
@@ -587,11 +608,25 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
   двух: ``binary`` или ``ascii``.
   По умолчанию: ``binary``
 
+  .. note::
+
+    Этот параметр игнорируется для SFTP-передачи.
+
 .. option:: --ftp-reuse-connection[=true|false]
 
   Повторно использовать FTP соединение.
   По умолчанию: ``true``
 
+.. option:: --ssh-host-key-md=<TYPE>=<DIGEST>
+
+  Задать контрольную сумму для публичного SSH-ключа хоста. TYPE - тип хэша.
+  Поддерживаемые типы хэшей - ``sha-1`` или ``md5``.
+  DIGEST - шестнадцатеричное значение хэша.
+  Например: ``sha-1=b030503d4de4539dc7885e6f0f5e256704edf4c3``.
+  Этот параметр может быть использован для проверки публичного ключа сервера
+  при использовании SFTP. Если параметр не задан (по умолчанию), то никакой
+  проверки не происходит.
+
 Параметры BitTorrent/Metalink
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 .. option:: --select-file=<INDEX>...
@@ -812,13 +847,15 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
 
 .. option:: --dht-file-path=<PATH>
 
-  Заменять файл таблицы маршрутизации IPv4 DHT на PATH.
-  По умолчанию: ``$HOME/.aria2/dht.dat``
+  Сменить путь к файлу таблицы маршрутизации IPv4 DHT на PATH.
+  По умолчанию: ``$HOME/.aria2/dht.dat`` если существует,
+  иначе ``$XDG_CACHE_HOME/aria2/dht.dat``.
 
 .. option:: --dht-file-path6=<PATH>
 
-  Заменять файл таблицы маршрутизации IPv6 DHT на PATH.
-  По умолчанию: ``$HOME/.aria2/dht.dat``
+  Сменить путь к файлу таблицы маршрутизации IPv6 DHT на PATH.
+  По умолчанию: ``$HOME/.aria2/dht6.dat`` если существует,
+  иначе ``$XDG_CACHE_HOME/aria2/dht6.dat``.
 
 .. option:: --dht-listen-addr6=<ADDR>
 
@@ -1220,7 +1257,8 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
 .. option:: --conf-path=<PATH>
 
   Сменить путь к файлу конфигурации на PATH.
-  По умолчанию: ``$HOME/.aria2/aria2.conf``
+  По умолчанию: ``$HOME/.aria2/aria2.conf`` если существует,
+  иначе ``$XDG_CACHE_HOME/aria2/aria2.conf``.
 
 .. option:: --console-log-level=<LEVEL>
 
@@ -1420,6 +1458,15 @@ FTP, BitTorrent и Metalink. aria2 может загрузить файл с р
   Возможные значения: ``SSLv3``, ``TLSv1``, ``TLSv1.1``, ``TLSv1.2``
   По умолчанию: ``TLSv1``
 
+.. option:: --multiple-interface=<INTERFACES>
+
+  Разделенный запятыми список интерфейсов для привязки сокетов.
+  Запросы будут разделяться между интерфейсами для достижения объединения
+  каналов. Вы можете указать имя интерфейса (например, eth0),
+  IP-адрес (например, 192.168.0.12) и имя хоста (например, myhost). Если
+  используется :option:`--interface`, то этот параметр будет проигнорирован.
+  Возможные значения: интерфейс, IP-адрес, имя хоста.
+
 .. option:: --log-level=<LEVEL>
 
   Задать уровень вывода журнала событий. LEVEL может
@@ -1677,13 +1724,14 @@ Metalink-документов, которые хранятся на локаль
 что они всегда будут обрабатываться как отдельная загрузка. Поддерживаются
 оба формата: Metalink4 и Metalink версии 3.0.
 
-Вы можете указать вместе, torrent-файл с параметром -T и URI. Сделав это, вы
-можете загружать файл, используя torrent-рой и HTTP(S)/FTP-сервер
-одновременно, пока данные из HTTP(S)/FTP выгружаются в torrent-рой. Для
-однофайловых торрентов, URI может быть завершенным, который указывает на
-ресурс, или же если заканчиваться символом /, тогда name (имя) в
-torrent-файле будет добавлено. Для многофайловых торрентов, name (имя) и
-path (путь) в torrent-файле будут добавлены из URI для каждого файла.
+Вы можете указать вместе, torrent-файл с параметром :option:`--torrent-file
+<-T>` и URI. Сделав это, вы можете загружать файл, используя torrent-рой и
+HTTP(S)/FTP/SFTP-сервер одновременно, пока данные из HTTP(S)/FTP/SFTP
+выгружаются в torrent-рой. Для однофайловых торрентов, URI может быть
+завершенным, который указывает на ресурс, или же если заканчиваться символом
+/, тогда name (имя) в torrent-файле будет добавлено. Для многофайловых
+торрентов, name (имя) и path (путь) в torrent-файле будут добавлены из URI
+для каждого файла.
 
 .. note::
 
@@ -1715,15 +1763,16 @@ aria2 предоставляет параметры, в которых указ
 :option:`--on-download-stop`.
 
 aria2 передает 3 аргумента указанной команды, которая выполняется. Это
-аргументы: GID, количество файлов и путь к файлу. Для HTTP-, FTP-загрузок,
-обычно количество файлов - 1. BitTorrent загрузка может содержать множество
-файлов. Если число файлов больше чем один, то путь к файлу будет для
-первого. Другими словами, это значение параметра path в первой структуре,
-определенный параметр которой имеет значение true (истина), в ответе
-RPC-метода :func:`aria2.getFiles`. Если вы хотите получить все пути к
-файлам, то рассмотрите использование JSON-RPC/XML-RPC. Обратите внимание,
-что путь к файлу может меняться в процессе загрузки по HTTP из-за
-перенаправления или заголовка Content-Disposition.
+аргументы: GID, количество файлов и путь к файлу. Для HTTP-, FTP- и
+SFTP-загрузок, обычно количество файлов - 1. BitTorrent загрузка может
+содержать множество файлов. Если число файлов больше чем один, то путь к
+файлу будет для первого. Другими словами, это значение параметра path в
+первой структуре, определенный параметр которой имеет значение true
+(истина), в ответе RPC-метода :func:`aria2.getFiles`. Если вы хотите
+получить все пути к файлам, то рассмотрите использование
+JSON-RPC/XML-RPC. Обратите внимание, что путь к файлу может меняться в
+процессе загрузки по HTTP из-за перенаправления или заголовка
+Content-Disposition.
 
 Посмотрите пример, как аргументы передаются команде:
 
@@ -1848,6 +1897,12 @@ RPC-метода :func:`aria2.getFiles`. Если вы хотите получи
 30
   Если aria2 не смогла проанализировать JSON-RPC-запрос.
 
+31
+  Зарезервировано. Не используется.
+
+32
+  Если проверка контрольной суммы не удалась.
+
 .. note::
 
   Ошибка, произошедшая в завершенной загрузке, не будет передана как код
@@ -1895,9 +1950,10 @@ aria2 распознает следующие переменные окруже
 aria2.conf
 ~~~~~~~~~~
 
-По умолчанию, aria2 анализирует ``$HOME/.aria2/aria2.conf`` как
-конфигурационный файл. Вы можете указать путь к конфигурационному файлу в
-параметре :option:`--conf-path`. Если вы не хотите использовать
+По умолчанию, aria2 проверяет наличие ``$HOME/.aria2/aria2.conf`` по
+устаревшему пути, иначе анализируется ``$XDG_CONFIG_HOME/aria2/aria2.conf``
+как конфигурационный файл. Вы можете указать путь к конфигурационному файлу
+в параметре :option:`--conf-path`. Если вы не хотите использовать
 конфигурационный файл, используйте параметр :option:`--no-conf`.
 
 Конфигурационный файл - это текстовый файл, содержащий один параметр в
@@ -1924,14 +1980,16 @@ aria2.conf
 dht.dat
 ~~~~~~~
 
-By default, the routing table of IPv4 DHT is saved to the path
-``$HOME/.aria2/dht.dat`` and the routing table of IPv6 DHT is saved to the
-path ``$HOME/.aria2/dht6.dat``.
+Если устаревшие пути к файлам ``$HOME/.aria2/dht.dat`` и
+``$HOME/.aria2/dht6.dat`` указывают на несуществующие файлы, то таблица
+маршрутизации IPv4 DHT сохраняется в ``$XDG_CACHE_HOME/aria2/dht.dat``, а
+таблица маршрутизации IPv6 DHT  сохраняется в
+``$XDG_CACHE_HOME/aria2/dht6.dat``.
 
 Netrc
 ~~~~~
 
-Поддержка Netrc включена по умолчанию для HTTP(S)/FTP. Для отключения
+Поддержка Netrc включена по умолчанию для HTTP(S)/FTP/SFTP. Для отключения
 поддержки netrc, укажите параметр :option:`--no-netrc <-n>`. Ваш файл .netrc
 должен иметь соответствующие права (600).
 
@@ -2098,6 +2156,7 @@ URI. Эти дополнительные строки должны начина
   * :option:`seed-time <--seed-time>`
   * :option:`select-file <--select-file>`
   * :option:`split <-s>`
+  * :option:`ssh-host-key-md <--ssh-host-key-md>`
   * :option:`stream-piece-selector <--stream-piece-selector>`
   * :option:`timeout <-t>`
   * :option:`uri-selector <--uri-selector>`
@@ -2263,7 +2322,7 @@ RPC-метод `system.multicall` обрабатывается особым об
 .. function:: aria2.addUri([secret], uris[, options[, position]])
 
   Этот метод добавляет новую загрузку. Параметр *uris* - это массив
-  HTTP(S)/FTP/BitTorrent Magnet URI (строки), указывающие на один и тот же
+  HTTP(S)/FTP/SFTP/BitTorrent Magnet URI (строки), указывающие на один и тот же
   ресурс. Если вы смешивайте URI, указывающие на разные ресурсы, то загрузка
   может неудачно завершиться или быть повреждена без жалоб со стороны aria2.
   При добавлении BitTorrent Magnet URI, *uris* должен содержать только один
@@ -2878,7 +2937,7 @@ RPC-метод `system.multicall` обрабатывается особым об
 
 .. function:: aria2.getServers([secret], gid)
 
-  Этот метод возвращает текущие подключенные HTTP(S)/FTP-серверы загрузки,
+  Этот метод возвращает текущие подключенные HTTP(S)/FTP/SFTP-серверы загрузки,
   которая обозначена *gid* (строка). Ответ - это массив структур, которые содержат
   следующие ключи. Значения являются строками.
 

+ 1 - 1
doc/sphinx_themes/sphinx_rtd_theme/__init__.py

@@ -5,7 +5,7 @@ From https://github.com/ryan-roemer/sphinx-bootstrap-theme.
 """
 import os
 
-VERSION = (0, 1, 5)
+VERSION = (0, 1, 8)
 
 __version__ = ".".join(str(v) for v in VERSION)
 __version_full__ = __version__

+ 23 - 15
doc/sphinx_themes/sphinx_rtd_theme/breadcrumbs.html

@@ -1,15 +1,23 @@
-<ul class="wy-breadcrumbs">
-  <li><a href="{{ pathto(master_doc) }}">Docs</a> &raquo;</li>
-  <li><a href="">{{ title }}</a></li>
-    <li class="wy-breadcrumbs-aside">
-      {% if display_github %}
-        <a href="https://github.com/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}.rst" class="icon icon-github"> Edit on GitHub</a>
-      {% elif display_bitbucket %}
-        <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}.rst'" class="icon icon-bitbucket"> Edit on Bitbucket</a>
-      {% elif show_source and has_source and sourcename %}
-        <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
-      {% endif %}
-    </li>
-</ul>
-<hr/>
-
+<div role="navigation" aria-label="breadcrumbs navigation">
+  <ul class="wy-breadcrumbs">
+    <li><a href="{{ pathto(master_doc) }}">Docs</a> &raquo;</li>
+      {% for doc in parents %}
+          <li><a href="{{ doc.link|e }}">{{ doc.title }}</a> &raquo;</li>
+      {% endfor %}
+    <li>{{ title }}</li>
+      <li class="wy-breadcrumbs-aside">
+        {% if pagename != "search" %}
+          {% if display_github %}
+            <a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ source_suffix }}" class="fa fa-github"> Edit on GitHub</a>
+          {% elif display_bitbucket %}
+            <a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ source_suffix }}" class="fa fa-bitbucket"> Edit on Bitbucket</a>
+          {% elif show_source and source_url_prefix %}
+            <a href="{{ source_url_prefix }}{{ pagename }}{{ source_suffix }}">View page source</a>
+          {% elif show_source and has_source and sourcename %}
+            <a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
+          {% endif %}
+        {% endif %}
+      </li>
+  </ul>
+  <hr/>
+</div>

+ 20 - 14
doc/sphinx_themes/sphinx_rtd_theme/footer.html

@@ -1,30 +1,36 @@
 <footer>
   {% if next or prev %}
-    <div class="rst-footer-buttons">
+    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
       {% if next %}
-        <a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}"/>Next <span class="icon icon-circle-arrow-right"></span></a>
+        <a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a>
       {% endif %}
       {% if prev %}
-        <a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}"><span class="icon icon-circle-arrow-left"></span> Previous</a>
+        <a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a>
       {% endif %}
     </div>
   {% endif %}
 
   <hr/>
 
-  <p>
-  {%- if show_copyright %}
-    {%- if hasdoc('copyright') %}
-      {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
-    {%- else %}
-      {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+  <div role="contentinfo">
+    <p>
+    {%- if show_copyright %}
+      {%- if hasdoc('copyright') %}
+        {% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
+      {%- else %}
+        {% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
+      {%- endif %}
     {%- endif %}
-  {%- endif %}
 
-  {%- if last_updated %}
-    {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {%- if last_updated %}
+      {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
+    {%- endif %}
+    </p>
+  </div>
+
+  {%- if show_sphinx %}
+  {% trans %}Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}.
   {%- endif %}
-  </p>
 
-  {% trans %}<a href="https://www.github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="http://readthedocs.org">Read the Docs</a>{% endtrans %}
 </footer>
+

+ 75 - 32
doc/sphinx_themes/sphinx_rtd_theme/layout.html

@@ -12,6 +12,7 @@
 <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
 <head>
   <meta charset="utf-8">
+  {{ metatags }}
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   {% block htmltitle %}
   <title>{{ title|striptags|e }}{{ titlesuffix }}</title>
@@ -23,40 +24,28 @@
   {% endif %}
 
   {# CSS #}
-  <link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
 
-  {# JS #}
+  {# OPENSEARCH #}
   {% if not embedded %}
-
-    <script type="text/javascript">
-      var DOCUMENTATION_OPTIONS = {
-        URL_ROOT:'{{ url_root }}',
-        VERSION:'{{ release|e }}',
-        COLLAPSE_INDEX:false,
-        FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
-        HAS_SOURCE:  {{ has_source|lower }}
-      };
-    </script>
-    {%- for scriptfile in script_files %}
-      <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
-    {%- endfor %}
-
     {% if use_opensearch %}
       <link rel="search" type="application/opensearchdescription+xml" title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}" href="{{ pathto('_static/opensearch.xml', 1) }}"/>
     {% endif %}
 
   {% endif %}
 
-  {# RTD hosts these file themselves, so just load on non RTD builds #}
+  {# RTD hosts this file, so just load on non RTD builds #}
   {% if not READTHEDOCS %}
     <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
-    <script type="text/javascript" src="_static/js/theme.js"></script>
   {% endif %}
 
   {% for cssfile in css_files %}
     <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
   {% endfor %}
 
+  {% for cssfile in extra_css_files %}
+    <link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
+  {% endfor %}
+
   {%- block linktags %}
     {%- if hasdoc('about') %}
         <link rel="author" title="{{ _('About these documents') }}"
@@ -85,29 +74,47 @@
   {%- endblock %}
   {%- block extrahead %} {% endblock %}
 
-  <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
+  {# Keep modernizr in head - http://modernizr.com/docs/#installing #}
+  <script src="_static/js/modernizr.min.js"></script>
 
 </head>
 
-<body class="wy-body-for-nav">
+<body class="wy-body-for-nav" role="document">
 
   <div class="wy-grid-for-nav">
 
     {# SIDE NAV, TOGGLES ON MOBILE #}
     <nav data-toggle="wy-nav-shift" class="wy-nav-side">
       <div class="wy-side-nav-search">
-        <a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}</a>
-        {% include "searchbox.html" %}
-      </div>
+        {% block sidebartitle %}
 
-      <div class="wy-menu wy-menu-vertical" data-spy="affix">
-        {% set toctree = toctree(maxdepth=2, collapse=False, includehidden=True) %}
-        {% if toctree %}
-            {{ toctree }}
+        {% if logo and theme_logo_only %}
+          <a href="{{ pathto(master_doc) }}">
         {% else %}
-            <!-- Local TOC -->
-            <div class="local-toc">{{ toc }}</div>
+          <a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}
+        {% endif %}
+
+        {% if logo %}
+          {# Not strictly valid HTML, but it's the only way to display/scale it properly, without weird scripting or heaps of work #}
+          <img src="{{ pathto('_static/' + logo, 1) }}" class="logo" />
         {% endif %}
+        </a>
+
+        {% include "searchbox.html" %}
+
+        {% endblock %}
+      </div>
+
+      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
+        {% block menu %}
+          {% set toctree = toctree(maxdepth=4, collapse=False, includehidden=True) %}
+          {% if toctree %}
+              {{ toctree }}
+          {% else %}
+              <!-- Local TOC -->
+              <div class="local-toc">{{ toc }}</div>
+          {% endif %}
+        {% endblock %}
       </div>
       &nbsp;
     </nav>
@@ -115,8 +122,8 @@
     <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
 
       {# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
-      <nav class="wy-nav-top">
-        <i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
+      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
+        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
         <a href="{{ pathto(master_doc) }}">{{ project }}</a>
       </nav>
 
@@ -125,7 +132,9 @@
       <div class="wy-nav-content">
         <div class="rst-content">
           {% include "breadcrumbs.html" %}
-          {% block body %}{% endblock %}
+          <div role="main" class="document">
+            {% block body %}{% endblock %}
+          </div>
           {% include "footer.html" %}
         </div>
       </div>
@@ -134,5 +143,39 @@
 
   </div>
   {% include "versions.html" %}
+
+  {% if not embedded %}
+
+    <script type="text/javascript">
+        var DOCUMENTATION_OPTIONS = {
+            URL_ROOT:'{{ url_root }}',
+            VERSION:'{{ release|e }}',
+            COLLAPSE_INDEX:false,
+            FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
+            HAS_SOURCE:  {{ has_source|lower }}
+        };
+    </script>
+    {%- for scriptfile in script_files %}
+      <script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
+    {%- endfor %}
+
+  {% endif %}
+
+  {# RTD hosts this file, so just load on non RTD builds #}
+  {% if not READTHEDOCS %}
+    <script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
+  {% endif %}
+
+  {# STICKY NAVIGATION #}
+  {% if theme_sticky_navigation %}
+  <script type="text/javascript">
+      jQuery(function () {
+          SphinxRtdTheme.StickyNav.enable();
+      });
+  </script>
+  {% endif %}
+
+  {%- block footer %} {% endblock %}
+
 </body>
 </html>

+ 1 - 1
doc/sphinx_themes/sphinx_rtd_theme/search.html

@@ -10,7 +10,7 @@
 {%- extends "layout.html" %}
 {% set title = _('Search') %}
 {% set script_files = script_files + ['_static/searchtools.js'] %}
-{% block extrahead %}
+{% block footer %}
   <script type="text/javascript">
     jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
   </script>

+ 9 - 5
doc/sphinx_themes/sphinx_rtd_theme/searchbox.html

@@ -1,5 +1,9 @@
-<form id ="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
-  <input type="text" name="q" placeholder="Search docs" />
-  <input type="hidden" name="check_keywords" value="yes" />
-  <input type="hidden" name="area" value="default" />
-</form>
+{%- if builder != 'singlehtml' %}
+<div role="search">
+  <form id="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
+    <input type="text" name="q" placeholder="Search docs" />
+    <input type="hidden" name="check_keywords" value="yes" />
+    <input type="hidden" name="area" value="default" />
+  </form>
+</div>
+{%- endif %}

File diff suppressed because it is too large
+ 0 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/css/badge_only.css


File diff suppressed because it is too large
+ 2 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/css/badge_only.css.map


File diff suppressed because it is too large
+ 0 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css


File diff suppressed because it is too large
+ 2 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/css/theme.css.map


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.eot


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.woff


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot


+ 23 - 8
doc/sphinx_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.svg → doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg

@@ -280,8 +280,8 @@
 <glyph unicode="&#xf113;" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
 <glyph unicode="&#xf114;" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
 <glyph unicode="&#xf115;" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " />
-<glyph unicode="&#xf116;" horiz-adv-x="1152" d="M896 608v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h224q14 0 23 -9t9 -23zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28 t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68zM1152 928v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704q93 0 158.5 -65.5t65.5 -158.5z" />
-<glyph unicode="&#xf117;" horiz-adv-x="1152" d="M928 1152q93 0 158.5 -65.5t65.5 -158.5v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68z M864 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576z" />
+<glyph unicode="&#xf116;" horiz-adv-x="1792" />
+<glyph unicode="&#xf117;" horiz-adv-x="1792" />
 <glyph unicode="&#xf118;" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
 <glyph unicode="&#xf119;" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
 <glyph unicode="&#xf11a;" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
@@ -310,7 +310,7 @@
 <glyph unicode="&#xf133;" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
 <glyph unicode="&#xf134;" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
 <glyph unicode="&#xf135;" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
-<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M1708 881l-188 -881h-304l181 849q4 21 1 43q-4 20 -16 35q-10 14 -28 24q-18 9 -40 9h-197l-205 -960h-303l204 960h-304l-205 -960h-304l272 1280h1139q157 0 245 -118q86 -116 52 -281z" />
+<glyph unicode="&#xf136;" horiz-adv-x="1792" d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
 <glyph unicode="&#xf137;" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
 <glyph unicode="&#xf138;" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
 <glyph unicode="&#xf139;" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
@@ -342,7 +342,7 @@
 <glyph unicode="&#xf155;" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" />
 <glyph unicode="&#xf156;" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
 <glyph unicode="&#xf157;" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
-<glyph unicode="&#xf158;" horiz-adv-x="1664" d="M1664 352v-32q0 -132 -94 -226t-226 -94h-128q-132 0 -226 94t-94 226v480h-224q-2 -102 -14.5 -190.5t-30.5 -156t-48.5 -126.5t-57 -99.5t-67.5 -77.5t-69.5 -58.5t-74 -44t-69 -32t-65.5 -25.5q-4 -2 -32 -13q-8 -2 -12 -2q-22 0 -30 20l-71 178q-5 13 0 25t17 17 q7 3 20 7.5t18 6.5q31 12 46.5 18.5t44.5 20t45.5 26t42 32.5t40.5 42.5t34.5 53.5t30.5 68.5t22.5 83.5t17 103t6.5 123h-256q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h1216q14 0 23 -9t9 -23v-160q0 -14 -9 -23t-23 -9h-224v-512q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v64q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1280 1376v-160q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h960q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf158;" horiz-adv-x="1280" d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
 <glyph unicode="&#xf159;" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
 <glyph unicode="&#xf15a;" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
 <glyph unicode="&#xf15b;" horiz-adv-x="1280" d="M1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" />
@@ -390,10 +390,25 @@
 <glyph unicode="&#xf188;" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
 <glyph unicode="&#xf189;" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" />
 <glyph unicode="&#xf18a;" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
-<glyph unicode="&#xf18b;" horiz-adv-x="1920" d="M805 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM453 1176v-344q0 -179 -89.5 -326t-234.5 -217q-129 152 -129 351q0 200 129.5 352t323.5 184zM958 991q-128 -152 -128 -351q0 -201 128 -351q-145 70 -234.5 218t-89.5 328 v341q196 -33 324 -185zM1638 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM1286 1176v-344q0 -179 -91 -326t-237 -217v0q133 154 133 351q0 195 -133 351q129 151 328 185zM1920 640q0 -201 -129 -351q-145 70 -234.5 218 t-89.5 328v341q194 -32 323.5 -184t129.5 -352z" />
-<glyph unicode="&#xf18c;" horiz-adv-x="1792" />
-<glyph unicode="&#xf18d;" horiz-adv-x="1792" />
-<glyph unicode="&#xf18e;" horiz-adv-x="1792" />
+<glyph unicode="&#xf18b;" d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
+<glyph unicode="&#xf18c;" horiz-adv-x="1408" d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
+<glyph unicode="&#xf18d;" horiz-adv-x="1280" d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z " />
+<glyph unicode="&#xf18e;" d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf190;" d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf191;" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf192;" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
+<glyph unicode="&#xf193;" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
+<glyph unicode="&#xf194;" d="M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf195;" horiz-adv-x="1152" d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
+<glyph unicode="&#xf196;" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
+<glyph unicode="&#xf197;" horiz-adv-x="1792" />
+<glyph unicode="&#xf198;" horiz-adv-x="1792" />
+<glyph unicode="&#xf199;" horiz-adv-x="1792" />
+<glyph unicode="&#xf19a;" horiz-adv-x="1792" />
+<glyph unicode="&#xf19b;" horiz-adv-x="1792" />
+<glyph unicode="&#xf19c;" horiz-adv-x="1792" />
+<glyph unicode="&#xf19d;" horiz-adv-x="1792" />
+<glyph unicode="&#xf19e;" horiz-adv-x="1792" />
 <glyph unicode="&#xf500;" horiz-adv-x="1792" />
 </font>
 </defs></svg> 

BIN
doc/sphinx_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.ttf → doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf


BIN
doc/sphinx_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff


File diff suppressed because it is too large
+ 3 - 0
doc/sphinx_themes/sphinx_rtd_theme/static/js/modernizr.min.js


+ 112 - 15
doc/sphinx_themes/sphinx_rtd_theme/static/js/theme.js

@@ -1,16 +1,113 @@
-$( document ).ready(function() {
-  // Shift nav in mobile when clicking the menu.
-  $("[data-toggle='wy-nav-top']").click(function() {
-    $("[data-toggle='wy-nav-shift']").toggleClass("shift");
-    $("[data-toggle='rst-versions']").toggleClass("shift");
-  });
-  // Close menu when you click a link.
-  $(".wy-menu-vertical .current ul li a").click(function() {
-    $("[data-toggle='wy-nav-shift']").removeClass("shift");
-    $("[data-toggle='rst-versions']").toggleClass("shift");
-  });
-  $("[data-toggle='rst-current-version']").click(function() {
-    $("[data-toggle='rst-versions']").toggleClass("shift-up");
-  });
-  $("table.docutils:not(.field-list").wrap("<div class='wy-table-responsive'></div>");
+function toggleCurrent (elem) {
+    var parent_li = elem.closest('li');
+    parent_li.siblings('li.current').removeClass('current');
+    parent_li.siblings().find('li.current').removeClass('current');
+    parent_li.find('> ul li.current').removeClass('current');
+    parent_li.toggleClass('current');
+}
+
+$(document).ready(function() {
+    // Shift nav in mobile when clicking the menu.
+    $(document).on('click', "[data-toggle='wy-nav-top']", function() {
+        $("[data-toggle='wy-nav-shift']").toggleClass("shift");
+        $("[data-toggle='rst-versions']").toggleClass("shift");
+    });
+    // Nav menu link click operations
+    $(document).on('click', ".wy-menu-vertical .current ul li a", function() {
+        var target = $(this);
+        // Close menu when you click a link.
+        $("[data-toggle='wy-nav-shift']").removeClass("shift");
+        $("[data-toggle='rst-versions']").toggleClass("shift");
+        // Handle dynamic display of l3 and l4 nav lists
+        toggleCurrent(target);
+        if (typeof(window.SphinxRtdTheme) != 'undefined') {
+            window.SphinxRtdTheme.StickyNav.hashChange();
+        }
+    });
+    $(document).on('click', "[data-toggle='rst-current-version']", function() {
+        $("[data-toggle='rst-versions']").toggleClass("shift-up");
+    });
+    // Make tables responsive
+    $("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
+
+    // Add expand links to all parents of nested ul
+    $('.wy-menu-vertical ul').siblings('a').each(function () {
+        var link = $(this);
+            expand = $('<span class="toctree-expand"></span>');
+        expand.on('click', function (ev) {
+            toggleCurrent(link);
+            ev.stopPropagation();
+            return false;
+        });
+        link.prepend(expand);
+    });
 });
+
+// Sphinx theme state
+window.SphinxRtdTheme = (function (jquery) {
+    var stickyNav = (function () {
+        var navBar,
+            win,
+            winScroll = false,
+            linkScroll = false,
+            winPosition = 0,
+            enable = function () {
+                init();
+                reset();
+                win.on('hashchange', reset);
+
+                // Set scrolling
+                win.on('scroll', function () {
+                    if (!linkScroll) {
+                        winScroll = true;
+                    }
+                });
+                setInterval(function () {
+                    if (winScroll) {
+                        winScroll = false;
+                        var newWinPosition = win.scrollTop(),
+                            navPosition = navBar.scrollTop(),
+                            newNavPosition = navPosition + (newWinPosition - winPosition);
+                        navBar.scrollTop(newNavPosition);
+                        winPosition = newWinPosition;
+                    }
+                }, 25);
+            },
+            init = function () {
+                navBar = jquery('nav.wy-nav-side:first');
+                win = jquery(window);
+            },
+            reset = function () {
+                // Get anchor from URL and open up nested nav
+                var anchor = encodeURI(window.location.hash);
+                if (anchor) {
+                    try {
+                        var link = $('.wy-menu-vertical')
+                            .find('[href="' + anchor + '"]');
+                        $('.wy-menu-vertical li.toctree-l1 li.current')
+                            .removeClass('current');
+                        link.closest('li.toctree-l2').addClass('current');
+                        link.closest('li.toctree-l3').addClass('current');
+                        link.closest('li.toctree-l4').addClass('current');
+                    }
+                    catch (err) {
+                        console.log("Error expanding nav for anchor", err);
+                    }
+                }
+            },
+            hashChange = function () {
+                linkScroll = true;
+                win.one('hashchange', function () {
+                    linkScroll = false;
+                });
+            };
+        jquery(init);
+        return {
+            enable: enable,
+            hashChange: hashChange
+        };
+    }());
+    return {
+        StickyNav: stickyNav
+    };
+}($));

+ 2 - 0
doc/sphinx_themes/sphinx_rtd_theme/theme.conf

@@ -5,3 +5,5 @@ stylesheet = css/theme.css
 [options]
 typekit_id = hiw1hhg
 analytics_id = 
+sticky_navigation = False
+logo_only =

+ 4 - 4
doc/sphinx_themes/sphinx_rtd_theme/versions.html

@@ -1,10 +1,10 @@
 {% if READTHEDOCS %}
 {# Add rst-badge after rst-versions for small badge style. #}
-  <div class="rst-versions" data-toggle="rst-versions">
+  <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
     <span class="rst-current-version" data-toggle="rst-current-version">
-      <span class="icon icon-book"> Read the Docs</span>
-      v: {{ current_version }} 
-      <span class="icon icon-caret-down"></span>
+      <span class="fa fa-book"> Read the Docs</span>
+      v: {{ current_version }}
+      <span class="fa fa-caret-down"></span>
     </span>
     <div class="rst-other-versions">
       <dl>

+ 3 - 3
makerelease-osx.mk

@@ -123,9 +123,9 @@ cares_confflags = "--enable-optimize=$(OPTFLAGS)"
 cares_cflags=$(LTO_FLAGS)
 cares_ldflags=$(CFLAGS) $(LTO_FLAGS)
 
-sqlite_version = autoconf-3080500
-sqlite_hash = 7f667e10ccebc26ab2086b8a30cb0a600ca0acae
-sqlite_url = http://sqlite.org/2014/sqlite-$(sqlite_version).tar.gz
+sqlite_version = autoconf-3081002
+sqlite_hash = c2f2c17d3dc4c4e179d35cc04e4420636d48a152
+sqlite_url = http://sqlite.org/2015/sqlite-$(sqlite_version).tar.gz
 sqlite_cflags=$(LTO_FLAGS)
 sqlite_ldflags=$(CFLAGS) $(LTO_FLAGS)
 

+ 17 - 0
mingw-build-memo

@@ -53,6 +53,23 @@ HOST=i686-w64-mingw32
 HOST=x86_64-w64-mingw32
 The configure command-line is the same as i686 version.
 
+libssh2
+-------
+
+HOST=i686-w64-mingw32
+./configure \
+    --disable-shared \
+    --enable-static \
+    --prefix=/usr/local/$HOST \
+    --host=$HOST \
+    --build=`dpkg-architecture -qDEB_BUILD_GNU_TYPE` \
+    --without-openssl \
+    --with-wincng \
+    LIBS="-lws2_32"
+
+HOST=x86_64-w64-mingw32
+The configure command-line is the same as i686 version.
+
 Zlib
 ----
 

+ 2 - 0
mingw-config

@@ -52,6 +52,7 @@
 # * expat
 # * sqlite3
 # * zlib
+# * libssh2
 # * cppunit
 
 test -z "$HOST" && HOST=i686-w64-mingw32
@@ -70,6 +71,7 @@ test -z "$PREFIX" && PREFIX=/usr/local/$HOST
     --with-libexpat \
     --with-libz \
     --with-libgmp \
+    --with-libssh2 \
     --without-libgcrypt \
     --without-libnettle \
     --with-cppunit-prefix=$PREFIX \

+ 17 - 21
src/AbstractCommand.cc

@@ -237,7 +237,7 @@ bool AbstractCommand::execute()
       if (req_ && fileEntry_->getLength() > 0 &&
           e_->getRequestGroupMan()->getMaxOverallDownloadSpeedLimit() == 0 &&
           requestGroup_->getMaxDownloadSpeedLimit() == 0 &&
-          serverStatTimer_.difference(global::wallclock()) >= 10) {
+          serverStatTimer_.difference(global::wallclock()) >= 10_s) {
         serverStatTimer_ = global::wallclock();
         std::vector<std::pair<size_t, std::string>> usedHosts;
         if (getOption()->getAsBool(PREF_SELECT_LEAST_USED_HOST)) {
@@ -284,7 +284,7 @@ bool AbstractCommand::execute()
             A2_LOG_DEBUG("All segments are ignored.");
             // This will execute other idle Commands and let them
             // finish quickly.
-            e_->setRefreshInterval(0);
+            e_->setRefreshInterval(std::chrono::milliseconds(0));
             return true;
           }
 
@@ -386,7 +386,8 @@ bool AbstractCommand::execute()
     }
 
     Timer wakeTime(global::wallclock());
-    wakeTime.advance(getOption()->getAsInt(PREF_RETRY_WAIT));
+    wakeTime.advance(
+        std::chrono::seconds(getOption()->getAsInt(PREF_RETRY_WAIT)));
     req_->setWakeTime(wakeTime);
     return prepareForRetry(0);
   }
@@ -401,7 +402,7 @@ bool AbstractCommand::execute()
       A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, err);
     }
     requestGroup_->setHaltRequested(true);
-    getDownloadEngine()->setRefreshInterval(0);
+    getDownloadEngine()->setRefreshInterval(std::chrono::milliseconds(0));
     return true;
   }
 }
@@ -457,7 +458,7 @@ bool AbstractCommand::prepareForRetry(time_t wait)
   }
   else {
     // We don't use wait so that Command can be executed by
-    // DownloadEngine::setRefreshInterval(0).
+    // DownloadEngine::setRefreshInterval(std::chrono::milliseconds(0)).
     command->setStatus(Command::STATUS_INACTIVE);
   }
   e_->addCommand(std::move(command));
@@ -515,14 +516,12 @@ void AbstractCommand::onAbort()
   getPieceStorage()->markPiecesDone(0);
   std::vector<std::string> uris;
   uris.reserve(res.size());
-  std::transform(res.begin(),
-                 res.end(),
-                 std::back_inserter(uris),
+  std::transform(std::begin(res), std::end(res), std::back_inserter(uris),
                  std::mem_fn(&URIResult::getURI));
   A2_LOG_DEBUG(fmt("CUID#%" PRId64 " - %lu URIs found.",
                    getCuid(),
                    static_cast<unsigned long int>(uris.size())));
-  fileEntry_->addUris(uris.begin(), uris.end());
+  fileEntry_->addUris(std::begin(uris), std::end(uris));
   getSegmentMan()->recognizeSegmentFor(fileEntry_);
 }
 
@@ -677,7 +676,7 @@ std::string getProxyUri(const std::string& protocol, const Option* option)
                              option);
   }
 
-  if (protocol == "ftp") {
+  if (protocol == "ftp" || protocol == "sftp") {
     return getProxyOptionFor
       (PREF_FTP_PROXY, PREF_FTP_PROXY_USER, PREF_FTP_PROXY_PASSWD, option);
   }
@@ -700,8 +699,8 @@ namespace {
 bool inNoProxy(const std::shared_ptr<Request>& req, const std::string& noProxy)
 {
   std::vector<Scip> entries;
-  util::splitIter
-    (noProxy.begin(), noProxy.end(), std::back_inserter(entries), ',', true);
+  util::splitIter(std::begin(noProxy), std::end(noProxy),
+                  std::back_inserter(entries), ',', true);
   if (entries.empty()) {
     return false;
   }
@@ -773,10 +772,8 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
   e_->findAllCachedIPAddresses(std::back_inserter(addrs), hostname, port);
   if (!addrs.empty()) {
     auto ipaddr = addrs.front();
-    A2_LOG_INFO(fmt(MSG_DNS_CACHE_HIT,
-                    getCuid(),
-                    hostname.c_str(),
-                    strjoin(addrs.begin(), addrs.end(), ", ").c_str()));
+    A2_LOG_INFO(fmt(MSG_DNS_CACHE_HIT, getCuid(), hostname.c_str(),
+                    strjoin(std::begin(addrs), std::end(addrs), ", ").c_str()));
     return ipaddr;
   }
 
@@ -823,10 +820,8 @@ std::string AbstractCommand::resolveHostname(std::vector<std::string>& addrs,
     }
     res.resolve(addrs, hostname);
   }
-  A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE,
-                  getCuid(),
-                  hostname.c_str(),
-                  strjoin(addrs.begin(), addrs.end(), ", ").c_str()));
+  A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE, getCuid(), hostname.c_str(),
+                  strjoin(std::begin(addrs), std::end(addrs), ", ").c_str()));
   for (const auto& addr : addrs) {
     e_->cacheIPAddress(hostname, addr, port);
   }
@@ -883,7 +878,8 @@ bool AbstractCommand::checkIfConnectionEstablished
 const std::string&
 AbstractCommand::resolveProxyMethod(const std::string& protocol) const
 {
-  if (getOption()->get(PREF_PROXY_METHOD) == V_TUNNEL || protocol == "https") {
+  if (getOption()->get(PREF_PROXY_METHOD) == V_TUNNEL || protocol == "https" ||
+      protocol == "sftp") {
     return V_TUNNEL;
   }
   return V_GET;

+ 4 - 4
src/AbstractCommand.h

@@ -83,7 +83,7 @@ private:
 
   Timer checkPoint_;
   Timer serverStatTimer_;
-  time_t timeout_;
+  std::chrono::seconds timeout_;
 
   bool checkSocketIsReadable_;
   bool checkSocketIsWritable_;
@@ -185,14 +185,14 @@ public:
   // check.
   void swapSocket(std::shared_ptr<SocketCore>& socket);
 
-  time_t getTimeout() const
+  std::chrono::seconds getTimeout() const
   {
     return timeout_;
   }
 
-  void setTimeout(time_t timeout)
+  void setTimeout(std::chrono::seconds timeout)
   {
-    timeout_ = timeout;
+    timeout_ = std::move(timeout);
   }
 
   void prepareForNextAction(std::unique_ptr<CheckIntegrityEntry> checkEntry);

+ 1 - 1
src/AbstractHttpServerResponseCommand.cc

@@ -119,7 +119,7 @@ bool AbstractHttpServerResponseCommand::execute()
     afterSend(httpServer_, e_);
     return true;
   } else {
-    if(timeoutTimer_.difference(global::wallclock()) >= 30) {
+    if (timeoutTimer_.difference(global::wallclock()) >= 30_s) {
       A2_LOG_INFO(fmt("CUID#%" PRId64
                       " - HttpServer: Timeout while trasmitting response.",
                       getCuid()));

+ 1 - 1
src/AbstractProxyRequestCommand.cc

@@ -64,7 +64,7 @@ AbstractProxyRequestCommand::AbstractProxyRequestCommand
   (std::make_shared<HttpConnection>
    (cuid, s, std::make_shared<SocketRecvBuffer>(s)))
 {
-  setTimeout(getOption()->getAsInt(PREF_CONNECT_TIMEOUT));
+  setTimeout(std::chrono::seconds(getOption()->getAsInt(PREF_CONNECT_TIMEOUT)));
   disableReadCheckSocket();
   setWriteCheckSocket(getSocket());
 }

+ 1 - 1
src/AbstractSingleDiskAdaptor.cc

@@ -101,7 +101,7 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
   // activity especially on Windows 7 NTFS. In this code, we assume
   // that maximum length of DataCell data is 16KiB to simplify the
   // code.
-  unsigned char buf[16*1024];
+  unsigned char buf[16_k];
   int64_t start = 0;
   size_t buflen = 0;
   size_t buffoffset = 0;

+ 2 - 2
src/ActivePeerConnectionCommand.cc

@@ -60,10 +60,10 @@ ActivePeerConnectionCommand::ActivePeerConnectionCommand
 (cuid_t cuid,
  RequestGroup* requestGroup,
  DownloadEngine* e,
- time_t interval)
+ std::chrono::seconds interval)
   : Command(cuid),
     requestGroup_(requestGroup),
-    interval_(interval),
+    interval_(std::move(interval)),
     e_(e),
     numNewConnection_(5)
 {

+ 2 - 2
src/ActivePeerConnectionCommand.h

@@ -59,7 +59,7 @@ private:
   std::shared_ptr<PeerStorage> peerStorage_;
   std::shared_ptr<BtAnnounce> btAnnounce_;
 
-  time_t interval_; // UNIT: sec
+  std::chrono::seconds interval_;
   DownloadEngine* e_;
   Timer checkPoint_;
   int numNewConnection_; // the number of the connection to establish.
@@ -67,7 +67,7 @@ public:
   ActivePeerConnectionCommand(cuid_t cuid,
                               RequestGroup* requestGroup,
                               DownloadEngine* e,
-                              time_t interval);
+                              std::chrono::seconds interval);
 
   virtual ~ActivePeerConnectionCommand();
 

+ 2 - 2
src/AdaptiveFileAllocationIterator.cc

@@ -61,8 +61,8 @@ void AdaptiveFileAllocationIterator::allocateChunk()
     try {
       A2_LOG_DEBUG("Testing file system supports fallocate.");
       if(offset_ < totalLength_) {
-        int64_t len = std::min(totalLength_-offset_,
-                               static_cast<int64_t>(4096));
+        int64_t len =
+            std::min(totalLength_ - offset_, static_cast<int64_t>(4_k));
         stream_->allocate(offset_, len, false);
         offset_ += len;
       }

+ 18 - 14
src/AdaptiveURISelector.cc

@@ -90,12 +90,16 @@ std::string AdaptiveURISelector::select
 
   std::string selected = selectOne(uris);
 
-  if(selected != A2STR::NIL)
-    uris.erase(std::find(uris.begin(), uris.end(), selected));
-
+  if(selected != A2STR::NIL) {
+    uris.erase(std::find(std::begin(uris), std::end(uris), selected));
+  }
   return selected;
 }
 
+namespace {
+constexpr auto MAX_TIMEOUT = 60_s;
+} // namespace
+
 void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
 {
   if (requestGroup_->getTimeout()*2 >= MAX_TIMEOUT) return;
@@ -105,16 +109,16 @@ void AdaptiveURISelector::mayRetryWithIncreasedTimeout(FileEntry* fileEntry)
   // looking for retries
   std::deque<URIResult> timeouts;
   fileEntry->extractURIResult(timeouts, error_code::TIME_OUT);
-  std::transform(timeouts.begin(), timeouts.end(), std::back_inserter(uris),
-                 std::mem_fn(&URIResult::getURI));
+  std::transform(std::begin(timeouts), std::end(timeouts),
+                 std::back_inserter(uris), std::mem_fn(&URIResult::getURI));
 
   if(A2_LOG_DEBUG_ENABLED) {
-    for(std::deque<std::string>::const_iterator i = uris.begin(),
-          eoi = uris.end(); i != eoi; ++i) {
-      A2_LOG_DEBUG(fmt("AdaptiveURISelector: will retry server with increased"
-                       " timeout (%ld s): %s",
-                       static_cast<long int>(requestGroup_->getTimeout()),
-                       (*i).c_str()));
+    for (const auto& uri : uris) {
+      A2_LOG_DEBUG(
+          fmt("AdaptiveURISelector: will retry server with increased"
+              " timeout (%ld s): %s",
+              static_cast<long int>(requestGroup_->getTimeout().count()),
+              uri.c_str()));
     }
   }
 }
@@ -222,7 +226,7 @@ void AdaptiveURISelector::adjustLowestSpeedLimit
   int lowest =
     requestGroup_->getOption()->getAsInt(PREF_LOWEST_SPEED_LIMIT);
   if (lowest > 0) {
-    int low_lowest = 4 * 1024;
+    int low_lowest = 4_k;
     int max = getMaxDownloadSpeed(uris);
     if (max > 0 && lowest > max / 4) {
       A2_LOG_NOTICE(fmt(_("Lowering lowest-speed-limit since known max speed is"
@@ -300,7 +304,7 @@ std::string AdaptiveURISelector::selectRandomUri
 (const std::deque<std::string>& uris) const
 {
   int pos = SimpleRandomizer::getInstance()->getRandomNumber(uris.size());
-  auto i = uris.begin();
+  auto i = std::begin(uris);
   i = i+pos;
   return *i;
 }
@@ -331,7 +335,7 @@ std::string AdaptiveURISelector::getFirstToTestUri
     power = (int)pow(2.0, (float)counter);
     /* We test the mirror another time if it has not been
      * tested since 2^counter days */
-    if(ss->getLastUpdated().difference() > power*24*60*60) {
+    if(ss->getLastUpdated().difference() > std::chrono::hours(power * 24)) {
       return u;
     }
   }

+ 1 - 2
src/AdaptiveURISelector.h

@@ -38,6 +38,7 @@
 #include "URISelector.h"
 
 #include <memory>
+#include <chrono>
 
 namespace aria2 {
 
@@ -53,8 +54,6 @@ private:
   int nbServerToEvaluate_;
   int nbConnections_;
 
-  static const time_t MAX_TIMEOUT = 60;
-
   void mayRetryWithIncreasedTimeout(FileEntry* fileEntry);
 
   std::string selectOne(const std::deque<std::string>& uris);

+ 2 - 2
src/AnnounceList.cc

@@ -222,8 +222,8 @@ void AnnounceList::moveToCompletedAllowedTier() {
 void AnnounceList::shuffle() {
   for (const auto& tier: tiers_) {
     auto& urls = tier->urls;
-    std::random_shuffle(std::begin(urls), std::end(urls),
-                        *SimpleRandomizer::getInstance());
+    std::shuffle(std::begin(urls), std::end(urls),
+                 *SimpleRandomizer::getInstance());
   }
 }
 

+ 8 - 6
src/AppleTLSContext.cc

@@ -111,7 +111,8 @@ static inline bool isWhitespace(char c)
 
 static inline std::string stripWhitespace(std::string str)
 {
-  str.erase(std::remove_if(str.begin(), str.end(), isWhitespace), str.end());
+  str.erase(std::remove_if(std::begin(str), std::end(str), isWhitespace),
+            std::end(str));
   return str;
 }
 
@@ -185,9 +186,9 @@ bool checkIdentity(const SecIdentityRef id,
   // future-proof. Also "usually" doesn't cut it; there is already software
   // using SHA-2 class algos, and SHA-3 is standardized and potential users
   // cannot be far.
-  return std::find_if(supported.begin(),
-                      supported.end(),
-                      hash_finder(data.get(), fingerPrint)) != supported.end();
+  return std::find_if(std::begin(supported), std::end(supported),
+                      hash_finder(data.get(), fingerPrint)) !=
+         std::end(supported);
 }
 
 #endif // defined(__MAC_10_6)
@@ -243,11 +244,12 @@ bool AppleTLSContext::tryAsFingerprint(const std::string& fingerprint)
 {
   auto fp = stripWhitespace(fingerprint);
   // Verify this is a valid hex representation and normalize.
-  fp = util::toHex(util::fromHex(fp.begin(), fp.end()));
+  fp = util::toHex(util::fromHex(std::begin(fp), std::end(fp)));
 
   // Verify this can represent a hash
   auto ht = MessageDigest::getSupportedHashTypes();
-  if (std::find_if(ht.begin(), ht.end(), hash_validator(fp)) == ht.end()) {
+  if (std::find_if(std::begin(ht), std::end(ht), hash_validator(fp)) ==
+      std::end(ht)) {
     A2_LOG_INFO(fmt("%s is not a fingerprint, invalid hash representation",
                     fingerprint.c_str()));
     return false;

+ 2 - 1
src/AppleTLSSession.cc

@@ -330,7 +330,8 @@ static SSLCipherSuiteList constructEnabledSuites(SSLContextRef ctx)
     return rv;
   }
 
-  rv.erase(std::remove_if(rv.begin(), rv.end(), isBlockedSuite), rv.end());
+  rv.erase(std::remove_if(std::begin(rv), std::end(rv), isBlockedSuite),
+           std::end(rv));
   return rv;
 }
 

+ 2 - 4
src/AsyncNameResolver.cc

@@ -143,10 +143,8 @@ void AsyncNameResolver::reset()
 ares_addr_node* parseAsyncDNSServers(const std::string& serversOpt)
 {
   std::vector<std::string> servers;
-  util::split(serversOpt.begin(), serversOpt.end(),
-              std::back_inserter(servers),
-              ',',
-              true /* doStrip */);
+  util::split(std::begin(serversOpt), std::end(serversOpt),
+              std::back_inserter(servers), ',', true /* doStrip */);
   ares_addr_node root;
   root.next = nullptr;
   ares_addr_node* tail = &root;

+ 2 - 1
src/AuthConfigFactory.cc

@@ -87,7 +87,8 @@ AuthConfigFactory::createAuthConfig
           createHttpAuthResolver(op)->resolveAuthConfig(request->getHost());
       }
     }
-  } else if(request->getProtocol() == "ftp") {
+  } else if(request->getProtocol() == "ftp" ||
+            request->getProtocol() == "sftp") {
     if(!request->getUsername().empty()) {
       if(request->hasPassword()) {
         return AuthConfig::create(request->getUsername(),

+ 3 - 3
src/AutoSaveCommand.cc

@@ -38,9 +38,9 @@
 
 namespace aria2 {
 
-AutoSaveCommand::AutoSaveCommand
-(cuid_t cuid, DownloadEngine* e, time_t interval)
-  : TimeBasedCommand(cuid, e, interval, true)
+AutoSaveCommand::AutoSaveCommand(cuid_t cuid, DownloadEngine* e,
+                                 std::chrono::seconds interval)
+  : TimeBasedCommand(cuid, e, std::move(interval), true)
 {}
 
 AutoSaveCommand::~AutoSaveCommand() {}

+ 2 - 1
src/AutoSaveCommand.h

@@ -42,7 +42,8 @@ namespace aria2 {
 class AutoSaveCommand : public TimeBasedCommand
 {
 public:
-  AutoSaveCommand(cuid_t cuid, DownloadEngine* e, time_t interval);
+  AutoSaveCommand(cuid_t cuid, DownloadEngine* e,
+                  std::chrono::seconds interval);
 
   virtual ~AutoSaveCommand();
 

+ 2 - 1
src/BackupIPv4ConnectCommand.cc

@@ -114,7 +114,8 @@ bool BackupIPv4ConnectCommand::execute()
     // TODO Although we check 300ms initial timeout as described in
     // RFC 6555, the interval will be much longer and around 1 second
     // due to the refresh interval mechanism in DownloadEngine.
-    if(startTime_.differenceInMillis(global::wallclock()) >= 300) {
+    if(startTime_.difference(global::wallclock()) >=
+       std::chrono::milliseconds(300)) {
       socket_ = std::make_shared<SocketCore>();
       try {
         socket_->establishConnection(ipaddr_, port_);

+ 1 - 1
src/BackupIPv4ConnectCommand.h

@@ -81,7 +81,7 @@ private:
   DownloadEngine* e_;
   Timer startTime_;
   Timer timeoutCheck_;
-  time_t timeout_;
+  std::chrono::seconds timeout_;
 };
 
 } // namespace aria2

+ 2 - 0
src/BtAnnounce.cc

@@ -54,4 +54,6 @@ const std::string BtAnnounce::PEERS("peers");
 
 const std::string BtAnnounce::PEERS6("peers6");
 
+constexpr std::chrono::minutes BtAnnounce::DEFAULT_ANNOUNCE_INTERVAL;
+
 } // namespace aria2

+ 3 - 2
src/BtAnnounce.h

@@ -41,6 +41,7 @@
 #include <memory>
 
 #include "a2time.h"
+#include "a2functional.h"
 
 namespace aria2 {
 
@@ -116,7 +117,7 @@ public:
    */
   virtual void shuffleAnnounce() = 0;
 
-  virtual void overrideMinInterval(time_t interval) = 0;
+  virtual void overrideMinInterval(std::chrono::seconds interval) = 0;
 
   virtual void setTcpPort(uint16_t port) = 0;
 
@@ -138,7 +139,7 @@ public:
 
   static const std::string PEERS6;
 
-  static const time_t DEFAULT_ANNOUNCE_INTERVAL = 120;
+  constexpr static auto DEFAULT_ANNOUNCE_INTERVAL = 2_min;
 };
 
 } // namespace aria2

+ 10 - 2
src/BtCheckIntegrityEntry.cc

@@ -40,6 +40,9 @@
 #include "DiskAdaptor.h"
 #include "prefs.h"
 #include "Option.h"
+#include "util.h"
+#include "SingletonHolder.h"
+#include "Notifier.h"
 
 namespace aria2 {
 
@@ -72,12 +75,17 @@ void BtCheckIntegrityEntry::onDownloadIncomplete
 void BtCheckIntegrityEntry::onDownloadFinished
 (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
 {
+  auto group = getRequestGroup();
+  const auto& option = group->getOption();
+  util::executeHookByOptName(group, option.get(), PREF_ON_BT_DOWNLOAD_COMPLETE);
+  SingletonHolder<Notifier>::instance()->notifyDownloadEvent
+    (EVENT_ON_BT_DOWNLOAD_COMPLETE, group);
   // TODO Currently,when all the checksums
   // are valid, then aria2 goes to seeding mode. Sometimes it is better
   // to exit rather than doing seeding. So, it would be good to toggle this
   // behavior.
-  if(!getRequestGroup()->getOption()->getAsBool(PREF_HASH_CHECK_ONLY) &&
-     getRequestGroup()->getOption()->getAsBool(PREF_BT_HASH_CHECK_SEED)) {
+  if(!option->getAsBool(PREF_HASH_CHECK_ONLY) &&
+     option->getAsBool(PREF_BT_HASH_CHECK_SEED)) {
     proceedFileAllocation(commands,
                           make_unique<BtFileAllocationEntry>
                           (getRequestGroup()),

+ 15 - 15
src/BtConstants.h

@@ -36,33 +36,33 @@
 #define D_BT_CONSTANTS_H
 
 #include "common.h"
-#include <vector>
+#include "a2functional.h"
 
-#define INFO_HASH_LENGTH 20
+namespace aria2 {
 
-#define PIECE_HASH_LENGTH 20
+constexpr size_t INFO_HASH_LENGTH = 20;
 
-#define PEER_ID_LENGTH 20
+constexpr size_t PIECE_HASH_LENGTH = 20;
 
-#define INFO_HASH_LENGTH 20
+constexpr size_t PEER_ID_LENGTH = 20;
 
-#define MAX_BLOCK_LENGTH (16*1024)
+constexpr size_t MAX_BLOCK_LENGTH = 16_k;
 
-#define DEFAULT_MAX_OUTSTANDING_REQUEST 6
-
-#define OUTSTANDING_REQUEST_STEP 6
+constexpr size_t DEFAULT_MAX_OUTSTANDING_REQUEST = 6;
 
 // Upper Bound of the number of outstanding request
-#define UB_MAX_OUTSTANDING_REQUEST 256
+constexpr size_t UB_MAX_OUTSTANDING_REQUEST = 256;
+
+constexpr size_t METADATA_PIECE_SIZE = 16_k;
 
-#define METADATA_PIECE_SIZE (16*1024)
+constexpr const char LPD_MULTICAST_ADDR[] = "239.192.152.143";
 
-#define LPD_MULTICAST_ADDR "239.192.152.143"
+constexpr uint16_t LPD_MULTICAST_PORT = 6771;
 
-#define LPD_MULTICAST_PORT 6771
+constexpr size_t COMPACT_LEN_IPV4 = 6;
 
-#define COMPACT_LEN_IPV4 6
+constexpr size_t COMPACT_LEN_IPV6 = 18;
 
-#define COMPACT_LEN_IPV6 18
+} // namespace aria2
 
 #endif // D_BT_CONSTANTS_H

+ 8 - 8
src/BtDependency.cc

@@ -68,8 +68,8 @@ void copyValues(const std::shared_ptr<FileEntry>& d,
 {
   d->setRequested(true);
   d->setPath(s->getPath());
-  d->addUris(s->getRemainingUris().begin(),
-             s->getRemainingUris().end());
+  d->addUris(std::begin(s->getRemainingUris()),
+             std::end(s->getRemainingUris()));
   d->setMaxConnectionPerServer(s->getMaxConnectionPerServer());
   d->setUniqueProtocol(s->isUniqueProtocol());
 }
@@ -120,8 +120,8 @@ bool BtDependency::resolve()
         context->getFileEntries();
       for (auto &fe : fileEntries) {
         auto &uri = fe->getRemainingUris();
-        std::random_shuffle(std::begin(uri), std::end(uri),
-                            *SimpleRandomizer::getInstance());
+        std::shuffle(std::begin(uri), std::end(uri),
+                     *SimpleRandomizer::getInstance());
       }
       const std::vector<std::shared_ptr<FileEntry> >& dependantFileEntries =
         dependant_->getDownloadContext()->getFileEntries();
@@ -138,14 +138,14 @@ bool BtDependency::resolve()
           e->setRequested(false);
           destFiles.push_back(e);
         }
-        std::sort(destFiles.begin(), destFiles.end(), EntryCmp());
+        std::sort(std::begin(destFiles), std::end(destFiles), EntryCmp());
         // Copy file path in dependant_'s FileEntries to newly created
         // context's FileEntries to endorse the path structure of
         // dependant_.  URIs and singleHostMultiConnection are also copied.
         for(const auto& e: dependantFileEntries){
-          const auto d = std::lower_bound(destFiles.begin(), destFiles.end(), e,
-                                          EntryCmp());
-          if(d == destFiles.end() ||
+          const auto d = std::lower_bound(std::begin(destFiles),
+                                          std::end(destFiles), e, EntryCmp());
+          if(d == std::end(destFiles) ||
              (*d)->getOriginalName() != e->getOriginalName()) {
             throw DL_ABORT_EX
               (fmt("No entry %s in torrent file", e->getOriginalName().c_str()));

+ 1 - 1
src/BtFileAllocationEntry.cc

@@ -70,7 +70,7 @@ void BtFileAllocationEntry::prepareForNextAction
     const std::vector<std::shared_ptr<FileEntry> >& fileEntries =
       getRequestGroup()->getDownloadContext()->getFileEntries();
     if(isUriSuppliedForRequsetFileEntry
-       (fileEntries.begin(), fileEntries.end())) {
+       (std::begin(fileEntries), std::end(fileEntries))) {
       getRequestGroup()->createNextCommandWithAdj(commands, e, 0);
     }
   } else {

+ 23 - 20
src/BtLeecherStateChoke.cc

@@ -47,17 +47,20 @@ namespace aria2 {
 
 BtLeecherStateChoke::BtLeecherStateChoke()
   : round_(0),
-    lastRound_(0)
+    lastRound_(Timer::zero())
 {}
 
 BtLeecherStateChoke::~BtLeecherStateChoke() {}
 
-BtLeecherStateChoke::PeerEntry::PeerEntry(const std::shared_ptr<Peer>& peer):
-  peer_(peer), downloadSpeed_(peer->calculateDownloadSpeed()),
-  // peer must be interested to us and sent block in the last 30 seconds
-  regularUnchoker_
-  (peer->peerInterested() &&
-   peer->getLastDownloadUpdate().difference(global::wallclock()) < 30) {}
+BtLeecherStateChoke::PeerEntry::PeerEntry(const std::shared_ptr<Peer>& peer)
+  : peer_(peer),
+    downloadSpeed_(peer->calculateDownloadSpeed()),
+    // peer must be interested to us and sent block in the last 30 seconds
+    regularUnchoker_(
+        peer->peerInterested() &&
+        peer->getLastDownloadUpdate().difference(global::wallclock()) < 30_s)
+{
+}
 
 BtLeecherStateChoke::PeerEntry::PeerEntry(const PeerEntry& c)
   : peer_(c.peer_),
@@ -143,32 +146,32 @@ bool BtLeecherStateChoke::PeerFilter::operator()
 void BtLeecherStateChoke::plannedOptimisticUnchoke
 (std::vector<PeerEntry>& peerEntries)
 {
-  std::for_each(peerEntries.begin(), peerEntries.end(),
+  std::for_each(std::begin(peerEntries), std::end(peerEntries),
                 std::mem_fn(&PeerEntry::disableOptUnchoking));
 
-  auto i = std::partition(peerEntries.begin(), peerEntries.end(),
+  auto i = std::partition(std::begin(peerEntries), std::end(peerEntries),
                           PeerFilter(true, true));
-  if(i != peerEntries.begin()) {
-    std::random_shuffle(peerEntries.begin(), i,
-                        *SimpleRandomizer::getInstance());
-    (*peerEntries.begin()).enableOptUnchoking();
-    A2_LOG_INFO(fmt("POU: %s",
-                    (*peerEntries.begin()).getPeer()->getIPAddress().c_str()));
+  if(i != std::begin(peerEntries)) {
+    std::shuffle(std::begin(peerEntries), i, *SimpleRandomizer::getInstance());
+    (*std::begin(peerEntries)).enableOptUnchoking();
+    A2_LOG_INFO(
+        fmt("POU: %s",
+            (*std::begin(peerEntries)).getPeer()->getIPAddress().c_str()));
   }
 }
 
 void BtLeecherStateChoke::regularUnchoke(std::vector<PeerEntry>& peerEntries)
 {
-  auto rest = std::partition(peerEntries.begin(), peerEntries.end(),
+  auto rest = std::partition(std::begin(peerEntries), std::end(peerEntries),
                              std::mem_fn(&PeerEntry::isRegularUnchoker));
 
-  std::sort(peerEntries.begin(), rest);
+  std::sort(std::begin(peerEntries), rest);
 
   // the number of regular unchokers
   int count = 3;
 
   bool fastOptUnchoker = false;
-  auto peerIter = peerEntries.begin();
+  auto peerIter = std::begin(peerEntries);
   for(;peerIter != rest && count; ++peerIter, --count) {
     peerIter->disableChokingRequired();
     A2_LOG_INFO(fmt("RU: %s, dlspd=%d",
@@ -180,8 +183,8 @@ void BtLeecherStateChoke::regularUnchoke(std::vector<PeerEntry>& peerEntries)
     }
   }
   if(fastOptUnchoker) {
-    std::random_shuffle(peerIter, peerEntries.end(),
-                        *SimpleRandomizer::getInstance());
+    std::shuffle(peerIter, std::end(peerEntries),
+                 *SimpleRandomizer::getInstance());
     for (auto& p : peerEntries) {
       if(p.getPeer()->peerInterested()) {
         p.enableOptUnchoking();

+ 1 - 1
src/BtPieceMessage.cc

@@ -213,7 +213,7 @@ void BtPieceMessage::send()
 
 void BtPieceMessage::pushPieceData(int64_t offset, int32_t length) const
 {
-  assert(length <= 16*1024);
+  assert(length <= static_cast<int32_t>(16_k));
   auto buf = make_unique<unsigned char[]>(length+MESSAGE_HEADER_LENGTH);
   createMessageHeader(buf.get());
   ssize_t r;

+ 3 - 3
src/BtPostDownloadHandler.cc

@@ -102,12 +102,12 @@ void BtPostDownloadHandler::getNextRequestGroups
                                   std::vector<std::string>(),
                                   "",
                                   torrent.get());
-  requestGroup->followedBy(newRgs.begin(), newRgs.end());
+  requestGroup->followedBy(std::begin(newRgs), std::end(newRgs));
   auto mi =
     createMetadataInfoFromFirstFileEntry(requestGroup->getGroupId(),
                                          requestGroup->getDownloadContext());
   if(mi) {
-    setMetadataInfo(newRgs.begin(), newRgs.end(), mi);
+    setMetadataInfo(std::begin(newRgs), std::end(newRgs), mi);
   }
 
   auto rgman = requestGroup->getRequestGroupMan();
@@ -119,7 +119,7 @@ void BtPostDownloadHandler::getNextRequestGroups
     }
   }
 
-  groups.insert(groups.end(), newRgs.begin(), newRgs.end());
+  groups.insert(std::end(groups), std::begin(newRgs), std::end(newRgs));
 }
 
 } // namespace aria2

+ 11 - 9
src/BtSeederStateChoke.cc

@@ -47,11 +47,15 @@ namespace aria2 {
 
 BtSeederStateChoke::BtSeederStateChoke()
   : round_(0),
-    lastRound_(0)
+    lastRound_(Timer::zero())
 {}
 
 BtSeederStateChoke::~BtSeederStateChoke() {}
 
+namespace {
+constexpr auto TIME_FRAME = 20_s;
+} // namespace
+
 BtSeederStateChoke::PeerEntry::PeerEntry
 (const std::shared_ptr<Peer>& peer):
   peer_(peer),
@@ -122,11 +126,10 @@ void BtSeederStateChoke::unchoke
 {
   int count = (round_ == 2) ? 4 : 3;
 
-  std::sort(peers.begin(), peers.end());
+  std::sort(std::begin(peers), std::end(peers));
 
-  auto r = peers.begin();
-  for(auto eoi = peers.end();
-      r != eoi && count; ++r, --count) {
+  auto r = std::begin(peers);
+  for(; r != std::end(peers) && count; ++r, --count) {
     (*r).getPeer()->chokingRequired(false);
     A2_LOG_INFO(fmt("RU: %s, ulspd=%d",
                     (*r).getPeer()->getIPAddress().c_str(),
@@ -134,11 +137,10 @@ void BtSeederStateChoke::unchoke
   }
 
   if(round_ < 2) {
-    std::for_each(peers.begin(), peers.end(),
+    std::for_each(std::begin(peers), std::end(peers),
                   std::mem_fn(&PeerEntry::disableOptUnchoking));
-    if(r != peers.end()) {
-      std::random_shuffle(r, peers.end(),
-                          *SimpleRandomizer::getInstance());
+    if(r != std::end(peers)) {
+      std::shuffle(r, std::end(peers), *SimpleRandomizer::getInstance());
       (*r).getPeer()->optUnchoking(true);
       A2_LOG_INFO(fmt("POU: %s", (*r).getPeer()->getIPAddress().c_str()));
     }

+ 0 - 1
src/BtSeederStateChoke.h

@@ -61,7 +61,6 @@ private:
     bool recentUnchoking_;
     int uploadSpeed_;
 
-    const static time_t TIME_FRAME = 20;
   public:
     PeerEntry(const std::shared_ptr<Peer>& peer);
     PeerEntry(const PeerEntry& c);

+ 6 - 6
src/BtSetup.cc

@@ -125,8 +125,8 @@ void BtSetup::setup(std::vector<std::unique_ptr<Command>>& commands,
     commands.push_back(std::move(c));
   }
   {
-    auto c = make_unique<ActivePeerConnectionCommand>
-      (e->newCUID(), requestGroup, e, metadataGetMode?2:10);
+    auto c = make_unique<ActivePeerConnectionCommand>(
+        e->newCUID(), requestGroup, e, metadataGetMode ? 2_s : 10_s);
     c->setBtRuntime(btRuntime);
     c->setPieceStorage(pieceStorage);
     c->setPeerStorage(peerStorage);
@@ -158,8 +158,8 @@ void BtSetup::setup(std::vector<std::unique_ptr<Command>>& commands,
   if(!metadataGetMode) {
     auto unionCri = make_unique<UnionSeedCriteria>();
     if(option->defined(PREF_SEED_TIME)) {
-      unionCri->addSeedCriteria(make_unique<TimeSeedCriteria>
-                                (option->getAsInt(PREF_SEED_TIME)*60));
+      unionCri->addSeedCriteria(make_unique<TimeSeedCriteria>(
+          std::chrono::seconds(option->getAsInt(PREF_SEED_TIME) * 60)));
     }
     {
       double ratio = option->getAsDouble(PREF_SEED_RATIO);
@@ -271,10 +271,10 @@ void BtSetup::setup(std::vector<std::unique_ptr<Command>>& commands,
       }
     }
   }
-  time_t btStopTimeout = option->getAsInt(PREF_BT_STOP_TIMEOUT);
+  auto btStopTimeout = option->getAsInt(PREF_BT_STOP_TIMEOUT);
   if(btStopTimeout > 0) {
     auto stopDownloadCommand = make_unique<BtStopDownloadCommand>
-      (e->newCUID(), requestGroup, e, btStopTimeout);
+      (e->newCUID(), requestGroup, e, std::chrono::seconds(btStopTimeout));
     stopDownloadCommand->setBtRuntime(btRuntime);
     stopDownloadCommand->setPieceStorage(pieceStorage);
     commands.push_back(std::move(stopDownloadCommand));

+ 4 - 4
src/BtStopDownloadCommand.cc

@@ -50,10 +50,10 @@ BtStopDownloadCommand::BtStopDownloadCommand
 (cuid_t cuid,
  RequestGroup* requestGroup,
  DownloadEngine* e,
- time_t timeout)
-  : TimeBasedCommand(cuid, e, 1),
+ std::chrono::seconds timeout)
+  : TimeBasedCommand(cuid, e, 1_s),
     requestGroup_(requestGroup),
-    timeout_(timeout)
+    timeout_(std::move(timeout))
 {}
 
 void BtStopDownloadCommand::preProcess()
@@ -66,7 +66,7 @@ void BtStopDownloadCommand::preProcess()
                         " --bt-stop-timeout option."),
                       GroupId::toHex(requestGroup_->getGID()).c_str()));
     requestGroup_->setForceHaltRequested(true);
-    getDownloadEngine()->setRefreshInterval(0);
+    getDownloadEngine()->setRefreshInterval(std::chrono::milliseconds(0));
     enableExit();
   }
 }

+ 2 - 2
src/BtStopDownloadCommand.h

@@ -51,7 +51,7 @@ class BtStopDownloadCommand:public TimeBasedCommand {
 private:
   RequestGroup* requestGroup_;
 
-  time_t timeout_;
+  std::chrono::seconds timeout_;
 
   Timer checkPoint_;
 
@@ -63,7 +63,7 @@ public:
   (cuid_t cuid,
    RequestGroup* requestGroup,
    DownloadEngine* e,
-   time_t timeout);
+   std::chrono::seconds timeout);
 
   virtual void preProcess() CXX11_OVERRIDE;
 

+ 3 - 1
src/ByteArrayDiskWriter.h

@@ -38,6 +38,8 @@
 #include "DiskWriter.h"
 #include <sstream>
 
+#include "a2functional.h"
+
 namespace aria2 {
 
 class ByteArrayDiskWriter : public DiskWriter {
@@ -46,7 +48,7 @@ private:
   size_t maxLength_;
   void clear();
 public:
-  ByteArrayDiskWriter(size_t maxLength = 5*1024*1024);
+  ByteArrayDiskWriter(size_t maxLength = 5_m);
   virtual ~ByteArrayDiskWriter();
 
   virtual void initAndOpenFile(int64_t totalLength = 0) CXX11_OVERRIDE;

+ 4 - 0
src/ChecksumCheckIntegrityEntry.cc

@@ -82,7 +82,11 @@ ChecksumCheckIntegrityEntry::onDownloadIncomplete
                           make_unique<StreamFileAllocationEntry>
                           (getRequestGroup(), popNextCommand()),
                           e);
+    return;
   }
+
+  // If we don't redownload, set error code to indicate checksum error
+  getRequestGroup()->setLastErrorCode(error_code::CHECKSUM_ERROR);
 }
 
 } // namespace aria2

+ 1 - 1
src/ConnectCommand.cc

@@ -57,7 +57,7 @@ ConnectCommand::ConnectCommand(cuid_t cuid,
   : AbstractCommand(cuid, req, fileEntry, requestGroup, e, s),
     proxyRequest_(proxyRequest)
 {
-  setTimeout(getOption()->getAsInt(PREF_CONNECT_TIMEOUT));
+  setTimeout(std::chrono::seconds(getOption()->getAsInt(PREF_CONNECT_TIMEOUT)));
   disableReadCheckSocket();
   setWriteCheckSocket(getSocket());
 }

+ 7 - 6
src/ConsoleStatCalc.cc

@@ -265,10 +265,10 @@ void printProgressSummary(const RequestGroupList& groups, size_t cols,
 }
 } // namespace
 
-ConsoleStatCalc::ConsoleStatCalc(time_t summaryInterval,
+ConsoleStatCalc::ConsoleStatCalc(std::chrono::seconds summaryInterval,
                                  bool colorOutput,
                                  bool humanReadable):
-  summaryInterval_(summaryInterval),
+  summaryInterval_(std::move(summaryInterval)),
   readoutVisibility_(true),
   truncate_(true),
 #ifdef __MINGW32__
@@ -288,7 +288,8 @@ ConsoleStatCalc::ConsoleStatCalc(time_t summaryInterval,
 void
 ConsoleStatCalc::calculateStat(const DownloadEngine* e)
 {
-  if(cp_.differenceInMillis(global::wallclock())+A2_DELTA_MILLIS < 1000) {
+  if(cp_.difference(global::wallclock()) + A2_DELTA_MILLIS <
+     std::chrono::milliseconds(1000)) {
     return;
   }
   cp_ = global::wallclock();
@@ -317,9 +318,9 @@ ConsoleStatCalc::calculateStat(const DownloadEngine* e)
   }
   ColorizedStream o;
   if(e->getRequestGroupMan()->countRequestGroup() > 0) {
-    if((summaryInterval_ > 0) &&
-       lastSummaryNotified_.differenceInMillis(global::wallclock())+
-       A2_DELTA_MILLIS >= summaryInterval_*1000) {
+    if((summaryInterval_ > 0_s) &&
+       lastSummaryNotified_.difference(global::wallclock())+
+       A2_DELTA_MILLIS >= summaryInterval_) {
       lastSummaryNotified_ = global::wallclock();
       printProgressSummary(e->getRequestGroupMan()->getRequestGroups(), cols, e,
                            sizeFormatter);

+ 2 - 2
src/ConsoleStatCalc.h

@@ -61,7 +61,7 @@ private:
 
   Timer lastSummaryNotified_;
 
-  time_t summaryInterval_;
+  std::chrono::seconds summaryInterval_;
 
   std::unique_ptr<SizeFormatter> sizeFormatter_;
   bool readoutVisibility_;
@@ -69,7 +69,7 @@ private:
   bool isTTY_;
   bool colorOutput_;
 public:
-  ConsoleStatCalc(time_t summaryInterval, bool colorOutput = true,
+  ConsoleStatCalc(std::chrono::seconds summaryInterval, bool colorOutput = true,
                   bool humanReadable = true);
 
   virtual ~ConsoleStatCalc() {}

+ 5 - 0
src/Context.cc

@@ -229,6 +229,11 @@ Context::Context(bool standalone,
     std::string iface = op->get(PREF_INTERFACE);
     SocketCore::bindAddress(iface);
   }
+  // Bind multiple interfaces
+  if(!op->get(PREF_MULTIPLE_INTERFACE).empty() && op->get(PREF_INTERFACE).empty()) {
+    std::string ifaces = op->get(PREF_MULTIPLE_INTERFACE);
+    SocketCore::bindAllAddress(ifaces);
+  }
   std::vector<std::shared_ptr<RequestGroup> > requestGroups;
   std::shared_ptr<UriListParser> uriListParser;
 #ifdef ENABLE_BITTORRENT

+ 8 - 0
src/CreateRequestCommand.cc

@@ -48,6 +48,7 @@
 #include "SocketRecvBuffer.h"
 #include "LogFactory.h"
 #include "wallclock.h"
+#include "DownloadFailureException.h"
 
 namespace aria2 {
 
@@ -94,6 +95,13 @@ bool CreateRequestCommand::executeInternal()
     if(getSegmentMan()) {
       getSegmentMan()->ignoreSegmentFor(getFileEntry());
     }
+    if(getOption()->getAsBool(PREF_DRY_RUN)) {
+      // For dry run mode, just throwing DlAbortEx makes infinite
+      // loop, since we don't have SegmentMan, and we cannot tell all
+      // hopes were abandoned.
+      throw DOWNLOAD_FAILURE_EXCEPTION2("No URI available.",
+                                        getRequestGroup()->getLastErrorCode());
+    }
     // In this case, the error might be already set in RequestGroup,
     // so use it here.
     throw DL_ABORT_EX2("No URI available.",

+ 2 - 2
src/DHTAutoSaveCommand.cc

@@ -57,8 +57,8 @@
 namespace aria2 {
 
 DHTAutoSaveCommand::DHTAutoSaveCommand
-(cuid_t cuid, DownloadEngine* e, int family, time_t interval)
-  : TimeBasedCommand{cuid, e, interval},
+(cuid_t cuid, DownloadEngine* e, int family, std::chrono::seconds interval)
+  : TimeBasedCommand{cuid, e, std::move(interval)},
     family_{family},
     routingTable_{nullptr}
 {}

+ 1 - 1
src/DHTAutoSaveCommand.h

@@ -56,7 +56,7 @@ private:
   void save();
 public:
   DHTAutoSaveCommand
-  (cuid_t cuid, DownloadEngine* e, int family, time_t interval);
+  (cuid_t cuid, DownloadEngine* e, int family, std::chrono::seconds interval);
 
   virtual ~DHTAutoSaveCommand();
 

+ 2 - 2
src/DHTBucketRefreshCommand.cc

@@ -43,8 +43,8 @@
 namespace aria2 {
 
 DHTBucketRefreshCommand::DHTBucketRefreshCommand
-(cuid_t cuid, DownloadEngine* e, time_t interval)
-  : TimeBasedCommand{cuid, e, interval},
+(cuid_t cuid, DownloadEngine* e, std::chrono::seconds interval)
+  : TimeBasedCommand{cuid, e, std::move(interval)},
     routingTable_{nullptr},
     taskQueue_{nullptr},
     taskFactory_{nullptr}

+ 2 - 1
src/DHTBucketRefreshCommand.h

@@ -53,7 +53,8 @@ private:
 
   DHTTaskFactory* taskFactory_;
 public:
-  DHTBucketRefreshCommand(cuid_t cuid, DownloadEngine* e, time_t interval);
+  DHTBucketRefreshCommand(cuid_t cuid, DownloadEngine* e,
+                          std::chrono::seconds interval);
 
   virtual ~DHTBucketRefreshCommand();
 

+ 1 - 2
src/DHTConnectionImpl.cc

@@ -61,8 +61,7 @@ bool DHTConnectionImpl::bind
   while(sgl.hasNext()) {
     ports.push_back(sgl.next());
   }
-  std::random_shuffle(ports.begin(), ports.end(),
-                      *SimpleRandomizer::getInstance());
+  std::shuffle(ports.begin(), ports.end(), *SimpleRandomizer::getInstance());
   for (const auto& p : ports) {
     port = p;
     if(bind(port, addr)) {

+ 19 - 13
src/DHTConstants.h

@@ -35,31 +35,37 @@
 #ifndef D_DHT_CONSTANTS_H
 #define D_DHT_CONSTANTS_H
 
+#include "common.h"
+#include "TimerA2.h"
+#include "a2functional.h"
+
+namespace aria2 {
+
 // Increment this if major improvements or bug fixes are made in DHT
 // code. This is 2 bytes unsigned integer.
-#define DHT_VERSION 3U
+constexpr uint16_t DHT_VERSION = 3U;
 
-#define DHT_ID_LENGTH 20
+constexpr size_t DHT_ID_LENGTH = 20;
 
-#define DHT_TRANSACTION_ID_LENGTH 2
-
-#define DHT_TOKEN_LENGTH 4
+constexpr size_t DHT_TRANSACTION_ID_LENGTH = 2;
 
 // See --dht-message-timeout option.
-#define DHT_MESSAGE_TIMEOUT 10
+constexpr auto DHT_MESSAGE_TIMEOUT = 10_s;
+
+constexpr auto DHT_NODE_CONTACT_INTERVAL = 15_min;
 
-#define DHT_NODE_CONTACT_INTERVAL (15*60)
+constexpr auto DHT_BUCKET_REFRESH_INTERVAL = 15_min;
 
-#define DHT_BUCKET_REFRESH_INTERVAL (15*60)
+constexpr auto DHT_BUCKET_REFRESH_CHECK_INTERVAL = 5_min;
 
-#define DHT_BUCKET_REFRESH_CHECK_INTERVAL (5*60)
+constexpr auto DHT_PEER_ANNOUNCE_PURGE_INTERVAL = 30_min;
 
-#define DHT_PEER_ANNOUNCE_PURGE_INTERVAL (30*60)
+constexpr auto DHT_PEER_ANNOUNCE_INTERVAL = 15_min;
 
-#define DHT_PEER_ANNOUNCE_INTERVAL (15*60)
+constexpr auto DHT_PEER_ANNOUNCE_CHECK_INTERVAL = 5_min;
 
-#define DHT_PEER_ANNOUNCE_CHECK_INTERVAL (5*60)
+constexpr auto DHT_TOKEN_UPDATE_INTERVAL = 10_min;
 
-#define DHT_TOKEN_UPDATE_INTERVAL (10*60)
+} // namespace aria2
 
 #endif // D_DHT_CONSTANTS_H

+ 6 - 6
src/DHTGetPeersCommand.cc

@@ -55,13 +55,13 @@ namespace aria2 {
 
 namespace {
 
-const time_t GET_PEER_INTERVAL = (15*60);
+constexpr auto GET_PEER_INTERVAL = 15_min;
 // Interval when the size of peer list is low.
-const time_t GET_PEER_INTERVAL_LOW = (5*60);
+constexpr auto GET_PEER_INTERVAL_LOW = 5_min;
 // Interval when the peer list is empty.
-const time_t GET_PEER_INTERVAL_ZERO = 60;
+constexpr auto GET_PEER_INTERVAL_ZERO = 1_min;
 // Interval for retry.
-const time_t GET_PEER_INTERVAL_RETRY = 5;
+constexpr auto GET_PEER_INTERVAL_RETRY = 5_s;
 // Maximum retries. Try more than 5 to drop bad node.
 const int MAX_RETRIES = 10;
 
@@ -77,7 +77,7 @@ DHTGetPeersCommand::DHTGetPeersCommand
     taskQueue_{nullptr},
     taskFactory_{nullptr},
     numRetry_{0},
-    lastGetPeerTime_{0}
+    lastGetPeerTime_{Timer::zero()}
 {
   requestGroup_->increaseNumCommand();
 }
@@ -92,7 +92,7 @@ bool DHTGetPeersCommand::execute()
   if(btRuntime_->isHalt()) {
     return true;
   }
-  time_t elapsed = lastGetPeerTime_.difference(global::wallclock());
+  auto elapsed = lastGetPeerTime_.difference(global::wallclock());
   if(!task_ &&
      (elapsed >= GET_PEER_INTERVAL ||
       (((btRuntime_->lessThanMinPeers() &&

+ 10 - 7
src/DHTInteractionCommand.cc

@@ -33,6 +33,9 @@
  */
 /* copyright --> */
 #include "DHTInteractionCommand.h"
+
+#include <array>
+
 #include "DownloadEngine.h"
 #include "RecoverableException.h"
 #include "DHTMessageDispatcher.h"
@@ -100,10 +103,10 @@ bool DHTInteractionCommand::execute()
 
   std::string remoteAddr;
   uint16_t remotePort;
-  unsigned char data[64*1024];
+  std::array<unsigned char, 64_k> data;
   try {
     while(1) {
-      ssize_t length = connection_->receiveMessage(data, sizeof(data),
+      ssize_t length = connection_->receiveMessage(data.data(), data.size(),
                                                    remoteAddr, remotePort);
       if(length <= 0) {
         break;
@@ -111,11 +114,11 @@ bool DHTInteractionCommand::execute()
       if(data[0] == 'd') {
         // udp tracker response does not start with 'd', so assume
         // this message belongs to DHT. nothrow.
-        receiver_->receiveMessage(remoteAddr, remotePort, data, length);
+        receiver_->receiveMessage(remoteAddr, remotePort, data.data(), length);
       } else {
         // this may be udp tracker response. nothrow.
-        udpTrackerClient_->receiveReply(data, length, remoteAddr, remotePort,
-                                        global::wallclock());
+        udpTrackerClient_->receiveReply(data.data(), length, remoteAddr,
+                                        remotePort, global::wallclock());
       }
     }
   } catch(RecoverableException& e) {
@@ -126,7 +129,7 @@ bool DHTInteractionCommand::execute()
   dispatcher_->sendMessages();
   while(!udpTrackerClient_->getPendingRequests().empty()) {
     // no throw
-    ssize_t length = udpTrackerClient_->createRequest(data, sizeof(data),
+    ssize_t length = udpTrackerClient_->createRequest(data.data(), data.size(),
                                                       remoteAddr, remotePort,
                                                       global::wallclock());
     if(length == -1) {
@@ -134,7 +137,7 @@ bool DHTInteractionCommand::execute()
     }
     try {
       // throw
-      connection_->sendMessage(data, length, remoteAddr, remotePort);
+      connection_->sendMessage(data.data(), length, remoteAddr, remotePort);
       udpTrackerClient_->requestSent(global::wallclock());
     } catch(RecoverableException& e) {
       A2_LOG_INFO_EX("Exception thrown while sending UDP tracker request.", e);

+ 1 - 1
src/DHTMessageDispatcher.h

@@ -52,7 +52,7 @@ public:
 
   virtual void
   addMessageToQueue(std::unique_ptr<DHTMessage> message,
-                    time_t timeout,
+                    std::chrono::seconds timeout,
                     std::unique_ptr<DHTMessageCallback> callback =
                     std::unique_ptr<DHTMessageCallback>{}) = 0;
 

+ 4 - 4
src/DHTMessageDispatcherImpl.cc

@@ -56,11 +56,11 @@ DHTMessageDispatcherImpl::DHTMessageDispatcherImpl
 void
 DHTMessageDispatcherImpl::addMessageToQueue
 (std::unique_ptr<DHTMessage> message,
- time_t timeout,
+ std::chrono::seconds timeout,
  std::unique_ptr<DHTMessageCallback> callback)
 {
-  messageQueue_.push_back(make_unique<DHTMessageEntry>
-                          (std::move(message), timeout, std::move(callback)));
+  messageQueue_.push_back(make_unique<DHTMessageEntry>(
+      std::move(message), std::move(timeout), std::move(callback)));
 }
 
 void
@@ -92,7 +92,7 @@ bool DHTMessageDispatcherImpl::sendMessage(DHTMessageEntry* entry)
     // DHTTask(such as DHTAbstractNodeLookupTask) don't finish
     // forever.
     if(!entry->message->isReply()) {
-      tracker_->addMessage(entry->message.get(), 0,
+      tracker_->addMessage(entry->message.get(), 0_s,
                            std::move(entry->callback));
     }
   }

Some files were not shown because too many files changed in this diff