metalink: remove

Warning: this will make existing curl command lines that use metalink to
stop working.

Reasons for removal:

1. We've found several security problems and issues involving the
   metalink support in curl. The issues are not detailed here. When
   working on those, it become apparent to the team that several of the
   problems are due to the system design, metalink library API and what
   the metalink RFC says. They are very hard to fix on the curl side
   only.

2. The metalink usage with curl was only very briefly documented and was
   not following the "normal" curl usage pattern in several ways, making
   it surprising and non-intuitive which could lead to further security
   issues.

3. The metalink library was last updated 6 years ago and wasn't so
   active the years before that either. An unmaintained library means
   there's a security problem waiting to happen. This is probably reason
   enough.

4. Metalink requires an XML parsing library, which is complex code (even
   the smaller alternatives) and to this day often gets security
   updates.

5. Metalink is not a widely used curl feature. In the 2020 curl user
   survey, only 1.4% of the responders said that they'd are using it. In
   2021 that number was 1.2%. Searching the web also show very few
   traces of it being used, even with other tools.

6. The torrent format and associated technology clearly won for
   downloading large files from multiple sources in parallel.

Cloes #7176
This commit is contained in:
Daniel Stenberg 2021-06-01 16:24:00 +02:00
parent 9cf516adc6
commit 265b14d6b3
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
48 changed files with 65 additions and 3154 deletions

View File

@ -41,7 +41,7 @@ freebsd_task:
pkginstall_script:
- pkg update -f
- pkg install -y autoconf automake libtool pkgconf brotli openldap-client heimdal libpsl libmetalink libssh2 openssh-portable libidn2 librtmp libnghttp2 nghttp2 stunnel
- pkg install -y autoconf automake libtool pkgconf brotli openldap-client heimdal libpsl libssh2 openssh-portable libidn2 librtmp libnghttp2 nghttp2 stunnel
- case `python -V` in
Python?3.7*) pkg install -y py37-impacket ;;
Python?2.7*) pkg install -y py27-impacket ;;
@ -56,7 +56,7 @@ freebsd_task:
export CXXFLAGS="-fsanitize=address,undefined -fno-sanitize-recover=undefined,integer -Wformat -Werror=format-security -Werror=array-bounds -g";
export LDFLAGS="-fsanitize=address,undefined -fno-sanitize-recover=undefined,integer" ;;
esac
- ./configure --prefix="${HOME}"/install --enable-debug --with-openssl --with-libssh2 --with-brotli --with-gssapi --with-libidn2 --enable-manual --enable-ldap --enable-ldaps --with-librtmp --with-libmetalink --with-libpsl --with-nghttp2 || { tail -300 config.log; false; }
- ./configure --prefix="${HOME}"/install --enable-debug --with-openssl --with-libssh2 --with-brotli --with-gssapi --with-libidn2 --enable-manual --enable-ldap --enable-ldaps --with-librtmp --with-libpsl --with-nghttp2 || { tail -300 config.log; false; }
compile_script:
- make V=1 && cd tests && make V=1
test_script:

View File

@ -38,19 +38,19 @@ jobs:
macosx-version-min: 10.9
- name: HTTP only
install: nghttp2
configure: --enable-debug --enable-maintainer-mode --disable-dict --disable-file --disable-ftp --disable-gopher --disable-imap --disable-ldap --disable-pop3 --disable-rtmp --disable-rtsp --disable-scp --disable-sftp --disable-smb --disable-smtp --disable-telnet --disable-tftp --disable-unix-sockets --disable-shared --without-brotli --without-gssapi --without-libidn2 --without-libmetalink --without-libpsl --without-librtmp --without-libssh2 --without-nghttp2 --without-ntlm-auth --without-ssl --without-zlib
configure: --enable-debug --enable-maintainer-mode --disable-dict --disable-file --disable-ftp --disable-gopher --disable-imap --disable-ldap --disable-pop3 --disable-rtmp --disable-rtsp --disable-scp --disable-sftp --disable-smb --disable-smtp --disable-telnet --disable-tftp --disable-unix-sockets --disable-shared --without-brotli --without-gssapi --without-libidn2 --without-libpsl --without-librtmp --without-libssh2 --without-nghttp2 --without-ntlm-auth --without-ssl --without-zlib
macosx-version-min: 10.15
- name: SecureTransport metalink
install: nghttp2 libmetalink
configure: --enable-debug --with-secure-transport --with-libmetalink
- name: SecureTransport http2
install: nghttp2
configure: --enable-debug --with-secure-transport
macosx-version-min: 10.8
- name: OpenSSL metalink
install: nghttp2 openssl libmetalink
configure: --enable-debug --with-openssl=/usr/local/opt/openssl --with-libmetalink
- name: OpenSSL http2
install: nghttp2 openssl
configure: --enable-debug --with-openssl=/usr/local/opt/openssl
macosx-version-min: 10.9
- name: LibreSSL metalink
install: nghttp2 libressl libmetalink
configure: --enable-debug --with-openssl=/usr/local/opt/libressl --with-libmetalink
- name: LibreSSL http2
install: nghttp2 libressl
configure: --enable-debug --with-openssl=/usr/local/opt/libressl
macosx-version-min: 10.9
- name: torture
install: nghttp2 openssl
@ -63,7 +63,7 @@ jobs:
tflags: -n -t --shallow=20 FTP
macosx-version-min: 10.9
- name: macOS 10.15
install: nghttp2 libmetalink libssh2 openssl
install: nghttp2 libssh2 openssl
configure: --enable-debug --disable-ldap --with-openssl=/usr/local/opt/openssl
macosx-version-min: 10.15
steps:

View File

@ -28,4 +28,4 @@ extraction:
- rm -f CMakeLists.txt
- ./buildconf
configure: # enable as many optional features as possible
command: ./configure --enable-ares --with-libssh2 --with-gssapi --with-librtmp --with-libmetalink --with-openssl
command: ./configure --enable-ares --with-libssh2 --with-gssapi --with-librtmp --with-openssl

View File

@ -163,7 +163,6 @@ curl_verbose_msg="enabled (--disable-verbose)"
curl_ldaps_msg="no (--enable-ldaps)"
curl_rtsp_msg="no (--enable-rtsp)"
curl_rtmp_msg="no (--with-librtmp)"
curl_mtlnk_msg="no (--with-libmetalink)"
curl_psl_msg="no (--with-libpsl)"
curl_altsvc_msg="enabled (--disable-alt-svc)"
curl_hsts_msg="enabled (--disable-hsts)"
@ -1853,99 +1852,8 @@ if test $with_libgsasl != "no"; then
fi
AM_CONDITIONAL([USE_GSASL], [test "$curl_gsasl_msg" = "enabled"])
dnl **********************************************************************
dnl Check for libmetalink
dnl **********************************************************************
OPT_LIBMETALINK=no
AC_ARG_WITH(libmetalink,dnl
AS_HELP_STRING([--with-libmetalink=PATH],[where to look for libmetalink, PATH points to the installation root])
AS_HELP_STRING([--without-libmetalink], [disable libmetalink detection]),
OPT_LIBMETALINK=$withval)
if test X"$OPT_LIBMETALINK" != Xno; then
addld=""
addlib=""
addcflags=""
version=""
libmetalinklib=""
PKGTEST="no"
if test "x$OPT_LIBMETALINK" = "xyes"; then
dnl this is with no partiular path given
PKGTEST="yes"
CURL_CHECK_PKGCONFIG(libmetalink)
else
dnl When particular path is given, set PKG_CONFIG_LIBDIR using the path.
LIBMETALINK_PCDIR="$OPT_LIBMETALINK/lib/pkgconfig"
AC_MSG_NOTICE([PKG_CONFIG_LIBDIR will be set to "$LIBMETALINK_PCDIR"])
if test -f "$LIBMETALINK_PCDIR/libmetalink.pc"; then
PKGTEST="yes"
fi
if test "$PKGTEST" = "yes"; then
CURL_CHECK_PKGCONFIG(libmetalink, [$LIBMETALINK_PCDIR])
fi
fi
if test "$PKGTEST" = "yes" && test "$PKGCONFIG" != "no"; then
addlib=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl
$PKGCONFIG --libs-only-l libmetalink`
addld=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl
$PKGCONFIG --libs-only-L libmetalink`
addcflags=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl
$PKGCONFIG --cflags-only-I libmetalink`
version=`CURL_EXPORT_PCDIR([$LIBMETALINK_PCDIR]) dnl
$PKGCONFIG --modversion libmetalink`
libmetalinklib=`echo $addld | $SED -e 's/^-L//'`
fi
if test -n "$addlib"; then
clean_CPPFLAGS="$CPPFLAGS"
clean_LDFLAGS="$LDFLAGS"
clean_LIBS="$LIBS"
CPPFLAGS="$clean_CPPFLAGS $addcflags"
LDFLAGS="$clean_LDFLAGS $addld"
LIBS="$addlib $clean_LIBS"
AC_MSG_CHECKING([if libmetalink is recent enough])
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
# include <metalink/metalink.h>
]],[[
if(0 != metalink_strerror(0)) /* added in 0.1.0 */
return 1;
]])
],[
AC_MSG_RESULT([yes ($version)])
want_metalink="yes"
],[
AC_MSG_RESULT([no ($version)])
AC_MSG_NOTICE([libmetalink library defective or too old])
want_metalink="no"
])
if test "x$OPENSSL_ENABLED" != "x1" -a "x$USE_WINDOWS_SSPI" != "x1" \
-a "x$GNUTLS_ENABLED" != "x1" -a "x$NSS_ENABLED" != "x1" \
-a "x$SECURETRANSPORT_ENABLED" != "x1"; then
AC_MSG_WARN([metalink support requires a compatible SSL/TLS backend])
want_metalink="no"
fi
CPPFLAGS="$clean_CPPFLAGS"
LDFLAGS="$clean_LDFLAGS"
LIBS="$clean_LIBS"
if test "$want_metalink" = "yes"; then
dnl finally libmetalink will be used
AC_DEFINE(USE_METALINK, 1, [Define to enable metalink support])
LIBMETALINK_LIBS=$addlib
LIBMETALINK_LDFLAGS=$addld
LIBMETALINK_CPPFLAGS=$addcflags
AC_SUBST([LIBMETALINK_LIBS])
AC_SUBST([LIBMETALINK_LDFLAGS])
AC_SUBST([LIBMETALINK_CPPFLAGS])
curl_mtlnk_msg="enabled"
fi
fi
fi
AC_ARG_WITH(libmetalink,,
AC_MSG_ERROR([--with-libmetalink no longer works!]))
dnl **********************************************************************
dnl Check for the presence of LIBSSH2 libraries and headers
@ -4342,7 +4250,6 @@ AC_MSG_NOTICE([Configured to build curl/libcurl:
LDAPS: ${curl_ldaps_msg}
RTSP: ${curl_rtsp_msg}
RTMP: ${curl_rtmp_msg}
Metalink: ${curl_mtlnk_msg}
PSL: ${curl_psl_msg}
Alt-svc: ${curl_altsvc_msg}
HSTS: ${curl_hsts_msg}

View File

@ -8,7 +8,6 @@
- multiple file upload on a single command line
- custom maximum transfer rate
- redirectable stderr
- metalink support (13)
- parallel transfers
## libcurl
@ -79,7 +78,7 @@
- download
- authentication
- Kerberos 5 (14)
- Kerberos 5 (13)
- active/passive using PORT, EPRT, PASV or EPSV
- single file size information (compare to HTTP HEAD)
- 'type=' URL support
@ -218,6 +217,4 @@
10. -
11. requires libidn2 or Windows
12. requires libz, brotli and/or zstd
13. requires libmetalink, and either an Apple or Microsoft operating
system, or OpenSSL, or GnuTLS, or NSS
14. requires a GSS-API implementation (such as Heimdal or MIT Kerberos)
13. requires a GSS-API implementation (such as Heimdal or MIT Kerberos)

View File

@ -952,31 +952,6 @@ previous example in an SFTP URL might look like:
IPv6 addresses provided other than in URLs (e.g. to the `--proxy`,
`--interface` or `--ftp-port` options) should not be URL encoded.
## Metalink
Curl supports Metalink (both version 3 and 4 (RFC 5854) are supported), a way
to list multiple URIs and hashes for a file. Curl will make use of the mirrors
listed within for failover if there are errors (such as the file or server not
being available). It will also verify the hash of the file after the download
completes. The Metalink file itself is downloaded and processed in memory and
not stored in the local file system.
Example to use a remote Metalink file:
curl --metalink http://www.example.com/example.metalink
To use a Metalink file in the local file system, use FILE protocol
(`file://`):
curl --metalink file:///example.metalink
Please note that if FILE protocol is disabled, there is no way to use a local
Metalink file at the time of this writing. Also note that if `--metalink` and
`--include` are used together, `--include` will be ignored. This is because
including headers in the response will break Metalink parser and if the
headers are included in the file described in Metalink file, hash check will
fail.
## Mailing Lists
For your convenience, we have several open mailing lists to discuss curl, its

View File

@ -1,27 +1,8 @@
Long: metalink
Help: Process given URLs as metalink XML file
Added: 7.27.0
Requires: metalink
Category: misc
---
This option can tell curl to parse and process a given URI as Metalink file
(both version 3 and 4 (RFC 5854) are supported) and make use of the mirrors
listed within for failover if there are errors (such as the file or server not
being available). It will also verify the hash of the file after the download
completes. The Metalink file itself is downloaded and processed in memory and
not stored in the local file system.
Example to use a remote Metalink file:
curl --metalink http://www.example.com/example.metalink
To use a Metalink file in the local file system, use FILE protocol (file://):
curl --metalink file:///example.metalink
Please note that if FILE protocol is disabled, there is no way to use a local
Metalink file at the time of this writing. Also note that if --metalink and
--include are used together, --include will be ignored. This is because
including headers in the response will break Metalink parser and if the
headers are included in the file described in Metalink file, hash check will
fail.
This option was previously used to specify a metalink resource. Metalink
support has unfortunately been disabled in curl since 7.78.0 due to security
reasons.

View File

@ -37,8 +37,8 @@ interaction.
curl offers a busload of useful tricks like proxy support, user
authentication, FTP upload, HTTP post, SSL connections, cookies, file transfer
resume, Metalink, and more. As you will see below, the number of features will
make your head spin!
resume and more. As you will see below, the number of features will make your
head spin!
curl is powered by libcurl for all transfer-related features. See
*libcurl(3)* for details.

View File

@ -50,8 +50,6 @@ This curl supports transfers of large files, files larger than 2GB.
.IP "libz"
Automatic decompression (via gzip, deflate) of compressed files over HTTP is
supported.
.IP "Metalink"
This curl supports Metalink.
.IP "MultiSSL"
This curl supports multiple TLS backends.
.IP "NTLM"

View File

@ -59,10 +59,6 @@ endif
ifndef LIBRTMP_PATH
LIBRTMP_PATH = ../../../librtmp-2.4
endif
# Edit the path below to point to the base of your libmetalink package.
ifndef LIBMETALINK_PATH
LIBMETALINK_PATH = ../../../libmetalink-0.1.3
endif
# Edit the path below to point to the base of your libexpat package.
ifndef LIBEXPAT_PATH
LIBEXPAT_PATH = ../../../expat-2.1.0
@ -220,9 +216,6 @@ endif
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
IPV6 = 1
endif
ifeq ($(findstring -metalink,$(CFG)),-metalink)
METALINK = 1
endif
ifeq ($(findstring -winssl,$(CFG)),-winssl)
WINSSL = 1
SSPI = 1
@ -354,18 +347,6 @@ ifdef WINIDN
curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz
endif
endif
ifdef METALINK
INCLUDES += -I"$(LIBMETALINK_PATH)/include"
CFLAGS += -DUSE_METALINK
curl_LDADD += -L"$(LIBMETALINK_PATH)/lib" -lmetalink
ifndef DYN
ifeq ($(findstring libexpat_metalink_parser.o,$(shell $(AR) t "$(LIBMETALINK_PATH)/lib/libmetalink.a")),libexpat_metalink_parser.o)
curl_LDADD += -L"$(LIBEXPAT_PATH)/lib" -lexpat
else
curl_LDADD += -L"$(LIBXML2_PATH)/lib" -lxml2
endif
endif
endif
ifdef SSPI
CFLAGS += -DUSE_WINDOWS_SSPI
endif

View File

@ -4,7 +4,7 @@ $! $Id$
$!
$! File to build images using gnv$libcurl.exe
$!
$! Copyright 2009 - 2020, John Malmberg
$! Copyright 2009 - 2021, John Malmberg
$!
$! Permission to use, copy, modify, and/or distribute this software for any
$! purpose with or without fee is hereby granted, provided that the above
@ -408,7 +408,7 @@ $ link'ldebug'/exe=[.src]curl.exe/dsf=[.src]curl.dsf -
[.src]curl-tool_getpass.o, [.src]curl-tool_help.o, -
[.src]curl-tool_helpers.o, [.src]curl-tool_homedir.o, -
[.src]curl-tool_hugehelp.o, [.src]curl-tool_libinfo.o, -
[.src]curl-tool_metalink.o, [.src]curl-tool_mfiles.o, -
[.src]curl-tool_mfiles.o, -
[.src]curl-tool_msgs.o, [.src]curl-tool_operate.o, -
[.src]curl-tool_operhlp.o, [.src]curl-tool_panykey.o, -
[.src]curl-tool_paramhlp.o, [.src]curl-tool_parsecfg.o, -

View File

@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@ -61,18 +61,15 @@ CFLAGS += @CURL_CFLAG_EXTRAS@
LIBS = $(BLANK_AT_MAKETIME)
if USE_EXPLICIT_LIB_DEPS
curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @LIBCURL_LIBS@
curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
else
curl_LDADD = $(top_builddir)/lib/libcurl.la @LIBMETALINK_LIBS@ @NSS_LIBS@ @SSL_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
curl_LDADD = $(top_builddir)/lib/libcurl.la @NSS_LIBS@ @SSL_LIBS@ @ZLIB_LIBS@ @CURL_NETWORK_AND_TIME_LIBS@
endif
curl_LDFLAGS = @LIBMETALINK_LDFLAGS@
curl_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMETALINK_CPPFLAGS)
# if unit tests are enabled, build a static library to link them with
if BUILD_UNITTESTS
noinst_LTLIBRARIES = libcurltool.la
libcurltool_la_CPPFLAGS = $(LIBMETALINK_CPPFLAGS) $(AM_CPPFLAGS) \
libcurltool_la_CPPFLAGS = $(AM_CPPFLAGS) \
-DCURL_STATICLIB -DUNITTESTS
libcurltool_la_CFLAGS =
libcurltool_la_LDFLAGS = -static $(LINKFLAGS)

View File

@ -5,7 +5,7 @@
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@ -74,7 +74,6 @@ CURL_CFILES = \
tool_hugehelp.c \
tool_libinfo.c \
tool_main.c \
tool_metalink.c \
tool_msgs.c \
tool_operate.c \
tool_operhlp.c \
@ -117,7 +116,6 @@ CURL_HFILES = \
tool_hugehelp.h \
tool_libinfo.h \
tool_main.h \
tool_metalink.h \
tool_msgs.h \
tool_operate.h \
tool_operhlp.h \

View File

@ -59,10 +59,6 @@ endif
ifndef LIBRTMP_PATH
LIBRTMP_PATH = ../../librtmp-2.4
endif
# Edit the path below to point to the base of your libmetalink package.
ifndef LIBMETALINK_PATH
LIBMETALINK_PATH = ../../libmetalink-0.1.3
endif
# Edit the path below to point to the base of your libexpat package.
ifndef LIBEXPAT_PATH
LIBEXPAT_PATH = ../../expat-2.1.0
@ -229,9 +225,6 @@ endif
ifeq ($(findstring -ipv6,$(CFG)),-ipv6)
IPV6 = 1
endif
ifeq ($(findstring -metalink,$(CFG)),-metalink)
METALINK = 1
endif
ifeq ($(findstring -winssl,$(CFG)),-winssl)
WINSSL = 1
SSPI = 1
@ -379,18 +372,6 @@ ifdef WINIDN
curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz
endif
endif
ifdef METALINK
INCLUDES += -I"$(LIBMETALINK_PATH)/include"
CFLAGS += -DUSE_METALINK
curl_LDADD += -L"$(LIBMETALINK_PATH)/lib" -lmetalink
ifndef DYN
ifeq ($(findstring libexpat_metalink_parser.o,$(shell $(AR) t "$(LIBMETALINK_PATH)/lib/libmetalink.a")),libexpat_metalink_parser.o)
curl_LDADD += -L"$(LIBEXPAT_PATH)/lib" -lexpat
else
curl_LDADD += -L"$(LIBXML2_PATH)/lib" -lxml2
endif
endif
endif
ifdef SSPI
CFLAGS += -DUSE_WINDOWS_SSPI
endif

View File

@ -6,7 +6,7 @@
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2004 - 2014, Guenter Knauf
# Copyright (C) 2001 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
# Copyright (C) 2001 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
@ -69,11 +69,6 @@ ifndef FBOPENSSL_PATH
FBOPENSSL_PATH = ../../fbopenssl-0.4
endif
# Edit the path below to point to the base of your libmetalink package.
ifndef LIBMETALINK_PATH
LIBMETALINK_PATH = ../../libmetalink-0.1.2
endif
# Edit the path below to point to the base of your libexpat package.
ifndef LIBEXPAT_PATH
LIBEXPAT_PATH = ../../expat-2.1.0
@ -243,10 +238,6 @@ endif
ifeq ($(findstring -idn,$(CFG)),-idn)
WITH_IDN = 1
endif
ifeq ($(findstring -metalink,$(CFG)),-metalink)
WITH_METALINK = 1
WITH_SSL = 1
endif
ifeq ($(findstring -nghttp2,$(CFG)),-nghttp2)
WITH_NGHTTP2 = 1
endif
@ -301,25 +292,6 @@ ifdef WITH_NGHTTP2
INCLUDES += -I$(NGHTTP2_PATH)/include
LDLIBS += $(NGHTTP2_PATH)/lib/libnghttp2.$(LIBEXT)
endif
ifdef WITH_METALINK
CFLAGS += -DUSE_METALINK
INCLUDES += -I$(OPENSSL_PATH)/outinc_nw_$(LIBARCH_L)
INCLUDES += -I$(LIBMETALINK_PATH)/include
LDLIBS += $(LIBMETALINK_PATH)/lib/libmetalink.$(LIBEXT)
ifdef WITH_LIBEXPAT
ifeq ($(LIBARCH),LIBC)
IMPORTS += @$(LIBEXPAT_PATH)/imports/expatlbc.imp
MODULES += expatlbc
else
IMPORTS += @$(LIBEXPAT_PATH)/imports/expatlib.imp
MODULES += expatlib
endif
else
ifdef WITH_LIBXML2
IMPORTS += @$(LIBXML2_PATH)/lib/libxml2.imp
MODULES += libxml2
endif
endif
endif
ifeq ($(LIBARCH),LIBC)

View File

@ -23,7 +23,6 @@
***************************************************************************/
#include "tool_setup.h"
#include "tool_sdecls.h"
#include "tool_metalink.h"
#include "tool_urlglob.h"
#include "tool_formparse.h"
@ -270,10 +269,6 @@ struct OperationConfig {
bool ssl_auto_client_cert; /* automatically locate and use a client
certificate for authentication (Schannel) */
bool proxy_ssl_auto_client_cert; /* proxy version of ssl_auto_client_cert */
bool use_metalink; /* process given URLs as metalink XML file */
struct metalinkfile *metalinkfile_list; /* point to the first node */
struct metalinkfile *metalinkfile_last; /* point to the last/current node */
char *oauth_bearer; /* OAuth 2.0 bearer token */
bool nonpn; /* enable/disable TLS NPN extension */
bool noalpn; /* enable/disable TLS ALPN extension */

View File

@ -36,7 +36,6 @@
#include "tool_getparam.h"
#include "tool_helpers.h"
#include "tool_libinfo.h"
#include "tool_metalink.h"
#include "tool_msgs.h"
#include "tool_paramhlp.h"
#include "tool_parsecfg.h"
@ -1140,29 +1139,8 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
GetStr(&config->mail_auth, nextarg);
break;
case 'J': /* --metalink */
{
#ifdef USE_METALINK
int mlmaj, mlmin, mlpatch;
metalink_get_version(&mlmaj, &mlmin, &mlpatch);
if((mlmaj*10000)+(mlmin*100) + mlpatch < CURL_REQ_LIBMETALINK_VERS) {
warnf(global,
"--metalink option cannot be used because the version of "
"the linked libmetalink library is too old. "
"Required: %d.%d.%d, found %d.%d.%d\n",
CURL_REQ_LIBMETALINK_MAJOR,
CURL_REQ_LIBMETALINK_MINOR,
CURL_REQ_LIBMETALINK_PATCH,
mlmaj, mlmin, mlpatch);
return PARAM_BAD_USE;
}
else
config->use_metalink = toggle;
#else
warnf(global, "--metalink option is ignored because the binary is "
"built without the Metalink support.\n");
#endif
break;
}
errorf(global, "--metalink is disabled\n");
return PARAM_BAD_USE;
case '6': /* --sasl-authzid */
GetStr(&config->sasl_authzid, nextarg);
break;

View File

@ -30,7 +30,6 @@
#include "tool_panykey.h"
#include "tool_help.h"
#include "tool_libinfo.h"
#include "tool_metalink.h"
#include "tool_version.h"
#include "memdebug.h" /* keep this as LAST include */
@ -967,27 +966,11 @@ featcomp(const void *p1, const void *p2)
#endif
}
#ifdef USE_METALINK
static const char *metalnk_version(void)
{
static char version[25];
int major = 0;
int minor = 0;
int patch = 0;
metalink_get_version(&major, &minor, &patch);
msnprintf(version, sizeof(version), " libmetalink/%u.%u.%u",
major, minor, patch);
return version;
}
#else
#define metalnk_version() ""
#endif
void tool_version_info(void)
{
const char *const *proto;
printf(CURL_ID "%s%s\n", curl_version(), metalnk_version());
printf(CURL_ID "%s\n", curl_version());
#ifdef CURL_PATCHSTAMP
printf("Release-Date: %s, security patched: %s\n",
LIBCURL_TIMESTAMP, CURL_PATCHSTAMP);
@ -1010,9 +993,6 @@ void tool_version_info(void)
if(curlinfo->features & feats[i].bitmask)
featp[numfeat++] = (char *)feats[i].name;
}
#ifdef USE_METALINK
featp[numfeat++] = (char *)"Metalink";
#endif
qsort(&featp[0], numfeat, sizeof(char *), featcomp);
for(i = 0; i< numfeat; i++)
printf(" %s", featp[i]);

View File

@ -212,7 +212,6 @@ static void main_free(struct GlobalConfig *config)
/* Main cleanup */
curl_global_cleanup();
convert_cleanup();
metalink_cleanup();
#ifdef USE_NSS
if(PR_Initialized()) {
/* prevent valgrind from reporting still reachable mem from NSRP arenas */

View File

@ -1,873 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "tool_setup.h"
#ifdef USE_METALINK
#include <sys/stat.h>
#include <stdlib.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#undef HAVE_NSS_CONTEXT
#ifdef USE_OPENSSL
# include <openssl/md5.h>
# include <openssl/sha.h>
#elif defined(USE_GNUTLS)
# include <nettle/md5.h>
# include <nettle/sha.h>
# define MD5_CTX struct md5_ctx
# define SHA_CTX struct sha1_ctx
# define SHA256_CTX struct sha256_ctx
#elif defined(USE_NSS)
# include <nss.h>
# include <pk11pub.h>
# define MD5_CTX void *
# define SHA_CTX void *
# define SHA256_CTX void *
# define HAVE_NSS_CONTEXT
static NSSInitContext *nss_context;
#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
(__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \
(defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
(__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
/* For Apple operating systems: CommonCrypto has the functions we need.
The library's headers are even backward-compatible with OpenSSL's
headers as long as we define COMMON_DIGEST_FOR_OPENSSL first.
These functions are available on Tiger and later, as well as iOS 2.0
and later. If you're building for an older cat, well, sorry. */
# define COMMON_DIGEST_FOR_OPENSSL
# include <CommonCrypto/CommonDigest.h>
#elif defined(USE_WIN32_CRYPTO)
/* For Windows: If no other crypto library is provided, we fallback
to the hash functions provided within the Microsoft Windows CryptoAPI */
# include <wincrypt.h>
/* Custom structure in order to store the required provider and hash handle */
struct win32_crypto_hash {
HCRYPTPROV hCryptProv;
HCRYPTHASH hHash;
};
/* Custom Microsoft AES Cryptographic Provider defines required for MinGW */
# ifndef ALG_SID_SHA_256
# define ALG_SID_SHA_256 12
# endif
# ifndef CALG_SHA_256
# define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256)
# endif
# define MD5_CTX struct win32_crypto_hash
# define SHA_CTX struct win32_crypto_hash
# define SHA256_CTX struct win32_crypto_hash
#else
# error "Can't compile METALINK support without a crypto library."
#endif
#define ENABLE_CURLX_PRINTF
/* use our own printf() functions */
#include "curlx.h"
#include "tool_getparam.h"
#include "tool_paramhlp.h"
#include "tool_cfgable.h"
#include "tool_metalink.h"
#include "tool_operate.h"
#include "tool_msgs.h"
#include "memdebug.h" /* keep this as LAST include */
/* Copied from tool_getparam.c */
#define GetStr(str,val) do { \
if(*(str)) { \
free(*(str)); \
*(str) = NULL; \
} \
if((val)) \
*(str) = strdup((val)); \
if(!(val)) \
return PARAM_NO_MEM; \
} while(0)
#if defined(USE_OPENSSL)
/* Functions are already defined */
#elif defined(USE_GNUTLS)
static int MD5_Init(MD5_CTX *ctx)
{
md5_init(ctx);
return 1;
}
static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
md5_update(ctx, inputLen, input);
}
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
{
md5_digest(ctx, 16, digest);
}
static int SHA1_Init(SHA_CTX *ctx)
{
sha1_init(ctx);
return 1;
}
static void SHA1_Update(SHA_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
sha1_update(ctx, inputLen, input);
}
static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
{
sha1_digest(ctx, 20, digest);
}
static int SHA256_Init(SHA256_CTX *ctx)
{
sha256_init(ctx);
return 1;
}
static void SHA256_Update(SHA256_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
sha256_update(ctx, inputLen, input);
}
static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
{
sha256_digest(ctx, 32, digest);
}
#elif defined(USE_NSS)
static int nss_hash_init(void **pctx, SECOidTag hash_alg)
{
PK11Context *ctx;
/* we have to initialize NSS if not initialized already */
if(!NSS_IsInitialized() && !nss_context) {
static NSSInitParameters params;
params.length = sizeof(params);
nss_context = NSS_InitContext("", "", "", "", &params, NSS_INIT_READONLY
| NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN
| NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD);
}
ctx = PK11_CreateDigestContext(hash_alg);
if(!ctx)
return /* failure */ 0;
if(PK11_DigestBegin(ctx) != SECSuccess) {
PK11_DestroyContext(ctx, PR_TRUE);
return /* failure */ 0;
}
*pctx = ctx;
return /* success */ 1;
}
static void nss_hash_final(void **pctx, unsigned char *out, unsigned int len)
{
PK11Context *ctx = *pctx;
unsigned int outlen;
PK11_DigestFinal(ctx, out, &outlen, len);
PK11_DestroyContext(ctx, PR_TRUE);
}
static int MD5_Init(MD5_CTX *pctx)
{
return nss_hash_init(pctx, SEC_OID_MD5);
}
static void MD5_Update(MD5_CTX *pctx,
const unsigned char *input,
unsigned int input_len)
{
PK11_DigestOp(*pctx, input, input_len);
}
static void MD5_Final(unsigned char digest[16], MD5_CTX *pctx)
{
nss_hash_final(pctx, digest, 16);
}
static int SHA1_Init(SHA_CTX *pctx)
{
return nss_hash_init(pctx, SEC_OID_SHA1);
}
static void SHA1_Update(SHA_CTX *pctx,
const unsigned char *input,
unsigned int input_len)
{
PK11_DigestOp(*pctx, input, input_len);
}
static void SHA1_Final(unsigned char digest[20], SHA_CTX *pctx)
{
nss_hash_final(pctx, digest, 20);
}
static int SHA256_Init(SHA256_CTX *pctx)
{
return nss_hash_init(pctx, SEC_OID_SHA256);
}
static void SHA256_Update(SHA256_CTX *pctx,
const unsigned char *input,
unsigned int input_len)
{
PK11_DigestOp(*pctx, input, input_len);
}
static void SHA256_Final(unsigned char digest[32], SHA256_CTX *pctx)
{
nss_hash_final(pctx, digest, 32);
}
#elif defined(USE_WIN32_CRYPTO)
static void win32_crypto_final(struct win32_crypto_hash *ctx,
unsigned char *digest,
unsigned int digestLen)
{
unsigned long length;
CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
if(length == digestLen)
CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
if(ctx->hHash)
CryptDestroyHash(ctx->hHash);
if(ctx->hCryptProv)
CryptReleaseContext(ctx->hCryptProv, 0);
}
static int MD5_Init(MD5_CTX *ctx)
{
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
}
return 1;
}
static void MD5_Update(MD5_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
}
static void MD5_Final(unsigned char digest[16], MD5_CTX *ctx)
{
win32_crypto_final(ctx, digest, 16);
}
static int SHA1_Init(SHA_CTX *ctx)
{
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
CryptCreateHash(ctx->hCryptProv, CALG_SHA1, 0, 0, &ctx->hHash);
}
return 1;
}
static void SHA1_Update(SHA_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
}
static void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx)
{
win32_crypto_final(ctx, digest, 20);
}
static int SHA256_Init(SHA256_CTX *ctx)
{
if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_AES,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash);
}
return 1;
}
static void SHA256_Update(SHA256_CTX *ctx,
const unsigned char *input,
unsigned int inputLen)
{
CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
}
static void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx)
{
win32_crypto_final(ctx, digest, 32);
}
#endif /* CRYPTO LIBS */
const struct digest_params MD5_DIGEST_PARAMS[] = {
{
CURLX_FUNCTION_CAST(digest_init_func, MD5_Init),
CURLX_FUNCTION_CAST(digest_update_func, MD5_Update),
CURLX_FUNCTION_CAST(digest_final_func, MD5_Final),
sizeof(MD5_CTX),
16
}
};
const struct digest_params SHA1_DIGEST_PARAMS[] = {
{
CURLX_FUNCTION_CAST(digest_init_func, SHA1_Init),
CURLX_FUNCTION_CAST(digest_update_func, SHA1_Update),
CURLX_FUNCTION_CAST(digest_final_func, SHA1_Final),
sizeof(SHA_CTX),
20
}
};
const struct digest_params SHA256_DIGEST_PARAMS[] = {
{
CURLX_FUNCTION_CAST(digest_init_func, SHA256_Init),
CURLX_FUNCTION_CAST(digest_update_func, SHA256_Update),
CURLX_FUNCTION_CAST(digest_final_func, SHA256_Final),
sizeof(SHA256_CTX),
32
}
};
static const struct metalink_digest_def SHA256_DIGEST_DEF[] = {
{"sha-256", SHA256_DIGEST_PARAMS}
};
static const struct metalink_digest_def SHA1_DIGEST_DEF[] = {
{"sha-1", SHA1_DIGEST_PARAMS}
};
static const struct metalink_digest_def MD5_DIGEST_DEF[] = {
{"md5", MD5_DIGEST_PARAMS}
};
/*
* The alias of supported hash functions in the order by preference
* (basically stronger hash comes first). We included "sha-256" and
* "sha256". The former is the name defined in the IANA registry named
* "Hash Function Textual Names". The latter is widely (and
* historically) used in Metalink version 3.
*/
static const struct metalink_digest_alias digest_aliases[] = {
{"sha-256", SHA256_DIGEST_DEF},
{"sha256", SHA256_DIGEST_DEF},
{"sha-1", SHA1_DIGEST_DEF},
{"sha1", SHA1_DIGEST_DEF},
{"md5", MD5_DIGEST_DEF},
{NULL, NULL}
};
static struct digest_context *digest_init(const struct digest_params *dparams)
{
struct digest_context *ctxt = malloc(sizeof(*ctxt));
if(!ctxt)
return ctxt;
ctxt->digest_hashctx = malloc(dparams->digest_ctxtsize);
if(!ctxt->digest_hashctx) {
free(ctxt);
return NULL;
}
ctxt->digest_hash = dparams;
if(dparams->digest_init(ctxt->digest_hashctx) != 1) {
free(ctxt->digest_hashctx);
free(ctxt);
return NULL;
}
return ctxt;
}
static int digest_update(struct digest_context *context,
const unsigned char *data,
unsigned int len)
{
(*context->digest_hash->digest_update)(context->digest_hashctx, data, len);
return 0;
}
static int digest_final(struct digest_context *context, unsigned char *result)
{
if(result)
(*context->digest_hash->digest_final)(result, context->digest_hashctx);
free(context->digest_hashctx);
free(context);
return 0;
}
static unsigned char hex_to_uint(const char *s)
{
char buf[3];
unsigned long val;
buf[0] = s[0];
buf[1] = s[1];
buf[2] = 0;
val = strtoul(buf, NULL, 16);
return (unsigned char)(val&0xff);
}
/*
* Check checksum of file denoted by filename. The expected hash value
* is given in hex_hash which is hex-encoded string.
*
* This function returns 1 if it succeeds or one of the following
* integers:
*
* 0:
* Checksum didn't match.
* -1:
* Could not open file; or could not read data from file.
* -2:
* Hash algorithm not available.
*/
static int check_hash(const char *filename,
const struct metalink_digest_def *digest_def,
const unsigned char *digest, FILE *error)
{
unsigned char *result;
struct digest_context *dctx;
int check_ok, flags, fd;
flags = O_RDONLY;
#ifdef O_BINARY
/* O_BINARY is required in order to avoid binary EOF in text mode */
flags |= O_BINARY;
#endif
fd = open(filename, flags);
if(fd == -1) {
fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
digest_def->hash_name, strerror(errno));
return -1;
}
dctx = digest_init(digest_def->dparams);
if(!dctx) {
fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
digest_def->hash_name, "failed to initialize hash algorithm");
close(fd);
return -2;
}
result = malloc(digest_def->dparams->digest_resultlen);
if(!result) {
close(fd);
digest_final(dctx, NULL);
return -1;
}
while(1) {
unsigned char buf[4096];
ssize_t len = read(fd, buf, sizeof(buf));
if(len == 0) {
break;
}
else if(len == -1) {
fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename,
digest_def->hash_name, strerror(errno));
digest_final(dctx, result);
close(fd);
return -1;
}
digest_update(dctx, buf, (unsigned int)len);
}
digest_final(dctx, result);
check_ok = memcmp(result, digest,
digest_def->dparams->digest_resultlen) == 0;
/* sha*sum style verdict output */
if(check_ok)
fprintf(error, "Metalink: validating (%s) [%s] OK\n", filename,
digest_def->hash_name);
else
fprintf(error, "Metalink: validating (%s) [%s] FAILED (digest mismatch)\n",
filename, digest_def->hash_name);
free(result);
close(fd);
return check_ok;
}
int metalink_check_hash(struct GlobalConfig *config,
struct metalinkfile *mlfile,
const char *filename)
{
int rv;
fprintf(config->errors, "Metalink: validating (%s)...\n", filename);
if(!mlfile->checksum) {
fprintf(config->errors,
"Metalink: validating (%s) FAILED (digest missing)\n", filename);
return -2;
}
rv = check_hash(filename, mlfile->checksum->digest_def,
mlfile->checksum->digest, config->errors);
return rv;
}
static struct metalink_checksum *
checksum_from_hex_digest(const struct metalink_digest_def *digest_def,
const char *hex_digest)
{
struct metalink_checksum *chksum;
unsigned char *digest;
size_t i;
size_t len = strlen(hex_digest);
digest = malloc(len/2);
if(!digest)
return 0;
for(i = 0; i < len; i += 2) {
digest[i/2] = hex_to_uint(hex_digest + i);
}
chksum = malloc(sizeof(struct metalink_checksum));
if(chksum) {
chksum->digest_def = digest_def;
chksum->digest = digest;
}
else
free(digest);
return chksum;
}
static struct metalink_resource *new_metalink_resource(const char *url)
{
struct metalink_resource *res = malloc(sizeof(struct metalink_resource));
if(res) {
res->next = NULL;
res->url = strdup(url);
if(!res->url) {
free(res);
return NULL;
}
}
return res;
}
/* Returns nonzero if hex_digest is properly formatted; that is each
letter is in [0-9A-Za-z] and the length of the string equals to the
result length of digest * 2. */
static int check_hex_digest(const char *hex_digest,
const struct metalink_digest_def *digest_def)
{
size_t i;
for(i = 0; hex_digest[i]; ++i) {
char c = hex_digest[i];
if(!(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') ||
('A' <= c && c <= 'Z'))) {
return 0;
}
}
return digest_def->dparams->digest_resultlen * 2 == i;
}
static struct metalinkfile *new_metalinkfile(metalink_file_t *fileinfo)
{
struct metalinkfile *f = malloc(sizeof(struct metalinkfile));
if(!f)
return NULL;
f->next = NULL;
f->filename = strdup(fileinfo->name);
if(!f->filename) {
free(f);
return NULL;
}
f->checksum = NULL;
f->resource = NULL;
if(fileinfo->checksums) {
const struct metalink_digest_alias *digest_alias;
for(digest_alias = digest_aliases; digest_alias->alias_name;
++digest_alias) {
metalink_checksum_t **p;
for(p = fileinfo->checksums; *p; ++p) {
if(curl_strequal(digest_alias->alias_name, (*p)->type) &&
check_hex_digest((*p)->hash, digest_alias->digest_def)) {
f->checksum =
checksum_from_hex_digest(digest_alias->digest_def,
(*p)->hash);
break;
}
}
if(f->checksum) {
break;
}
}
}
if(fileinfo->resources) {
metalink_resource_t **p;
struct metalink_resource root, *tail;
root.next = NULL;
tail = &root;
for(p = fileinfo->resources; *p; ++p) {
struct metalink_resource *res;
/* Filter by type if it is non-NULL. In Metalink v3, type
includes the type of the resource. In curl, we are only
interested in HTTP, HTTPS and FTP. In addition to them,
Metalink v3 file may contain bittorrent type URL, which
points to the BitTorrent metainfo file. We ignore it here.
In Metalink v4, type was deprecated and all
fileinfo->resources point to the target file. BitTorrent
metainfo file URL may be appeared in fileinfo->metaurls.
*/
if(!(*p)->type ||
curl_strequal((*p)->type, "http") ||
curl_strequal((*p)->type, "https") ||
curl_strequal((*p)->type, "ftp") ||
curl_strequal((*p)->type, "ftps")) {
res = new_metalink_resource((*p)->url);
if(res) {
tail->next = res;
tail = res;
}
else {
tail = root.next;
/* clean up the linked list */
while(tail) {
res = tail->next;
free(tail->url);
free(tail);
tail = res;
}
free(f->filename);
free(f);
return NULL;
}
}
}
f->resource = root.next;
}
return f;
}
int parse_metalink(struct OperationConfig *config, struct OutStruct *outs,
const char *metalink_url)
{
metalink_error_t r;
metalink_t* metalink;
metalink_file_t **files;
bool warnings = FALSE;
/* metlaink_parse_final deletes outs->metalink_parser */
r = metalink_parse_final(outs->metalink_parser, NULL, 0, &metalink);
outs->metalink_parser = NULL;
if(r) {
return -1;
}
if(!metalink->files) {
fprintf(config->global->errors, "Metalink: parsing (%s) WARNING "
"(missing or invalid file name)\n",
metalink_url);
metalink_delete(metalink);
return -1;
}
for(files = metalink->files; *files; ++files) {
struct getout *url;
/* Skip an entry which has no resource. */
if(!(*files)->resources) {
fprintf(config->global->errors, "Metalink: parsing (%s) WARNING "
"(missing or invalid resource)\n",
metalink_url);
continue;
}
if(config->url_get ||
((config->url_get = config->url_list) != NULL)) {
/* there's a node here, if it already is filled-in continue to
find an "empty" node */
while(config->url_get && (config->url_get->flags & GETOUT_URL))
config->url_get = config->url_get->next;
}
/* now there might or might not be an available node to fill in! */
if(config->url_get)
/* existing node */
url = config->url_get;
else
/* there was no free node, create one! */
url = new_getout(config);
if(url) {
struct metalinkfile *mlfile = new_metalinkfile(*files);
if(!mlfile)
break;
if(!mlfile->checksum) {
warnings = TRUE;
fprintf(config->global->errors,
"Metalink: parsing (%s) WARNING (digest missing)\n",
metalink_url);
}
/* Set name as url */
GetStr(&url->url, mlfile->filename);
/* set flag metalink here */
url->flags |= GETOUT_URL | GETOUT_METALINK;
if(config->metalinkfile_list) {
config->metalinkfile_last->next = mlfile;
config->metalinkfile_last = mlfile;
}
else {
config->metalinkfile_list = config->metalinkfile_last = mlfile;
}
}
}
metalink_delete(metalink);
return (warnings) ? -2 : 0;
}
size_t metalink_write_cb(void *buffer, size_t sz, size_t nmemb,
void *userdata)
{
struct per_transfer *per = userdata;
struct OutStruct *outs = &per->outs;
struct OperationConfig *config = per->config;
int rv;
/*
* Once that libcurl has called back tool_write_cb() the returned value
* is checked against the amount that was intended to be written, if
* it does not match then it fails with CURLE_WRITE_ERROR. So at this
* point returning a value different from sz*nmemb indicates failure.
*/
const size_t failure = (sz && nmemb) ? 0 : 1;
if(!config)
return failure;
rv = metalink_parse_update(outs->metalink_parser, buffer, sz * nmemb);
if(rv == 0)
return sz * nmemb;
else {
fprintf(config->global->errors, "Metalink: parsing FAILED\n");
return failure;
}
}
/*
* Returns nonzero if content_type includes mediatype.
*/
static int check_content_type(const char *content_type, const char *media_type)
{
const char *ptr = content_type;
size_t media_type_len = strlen(media_type);
for(; *ptr && (*ptr == ' ' || *ptr == '\t'); ++ptr);
if(!*ptr) {
return 0;
}
return curl_strnequal(ptr, media_type, media_type_len) &&
(*(ptr + media_type_len) == '\0' || *(ptr + media_type_len) == ' ' ||
*(ptr + media_type_len) == '\t' || *(ptr + media_type_len) == ';');
}
int check_metalink_content_type(const char *content_type)
{
return check_content_type(content_type, "application/metalink+xml");
}
int count_next_metalink_resource(struct metalinkfile *mlfile)
{
int count = 0;
struct metalink_resource *res;
for(res = mlfile->resource; res; res = res->next, ++count);
return count;
}
static void delete_metalink_checksum(struct metalink_checksum *chksum)
{
if(!chksum)
return;
Curl_safefree(chksum->digest);
Curl_safefree(chksum);
}
static void delete_metalink_resource(struct metalink_resource *res)
{
if(!res) {
return;
}
Curl_safefree(res->url);
Curl_safefree(res);
}
void delete_metalinkfile(struct metalinkfile *mlfile)
{
struct metalink_resource *res;
if(!mlfile) {
return;
}
Curl_safefree(mlfile->filename);
delete_metalink_checksum(mlfile->checksum);
for(res = mlfile->resource; res;) {
struct metalink_resource *next;
next = res->next;
delete_metalink_resource(res);
res = next;
}
Curl_safefree(mlfile);
}
void clean_metalink(struct OperationConfig *config)
{
if(config) {
while(config->metalinkfile_list) {
struct metalinkfile *mlfile = config->metalinkfile_list;
config->metalinkfile_list = config->metalinkfile_list->next;
delete_metalinkfile(mlfile);
}
config->metalinkfile_last = 0;
}
}
void metalink_cleanup(void)
{
#ifdef HAVE_NSS_CONTEXT
if(nss_context) {
NSS_ShutdownContext(nss_context);
nss_context = NULL;
}
#endif
}
#endif /* USE_METALINK */

View File

@ -1,165 +0,0 @@
#ifndef HEADER_CURL_TOOL_METALINK_H
#define HEADER_CURL_TOOL_METALINK_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#include "tool_setup.h"
#include "tool_sdecls.h"
struct GlobalConfig;
struct OperationConfig;
/* returns 1 for success, 0 otherwise (we use OpenSSL *_Init fncs directly) */
typedef int (*digest_init_func)(void *context);
typedef void (*digest_update_func)(void *context,
const unsigned char *data,
unsigned int len);
typedef void (*digest_final_func)(unsigned char *result, void *context);
struct digest_params {
digest_init_func digest_init; /* Initialize context procedure */
digest_update_func digest_update; /* Update context with data */
digest_final_func digest_final; /* Get final result procedure */
unsigned int digest_ctxtsize; /* Context structure size */
unsigned int digest_resultlen; /* Result length (bytes) */
};
struct digest_context {
const struct digest_params *digest_hash; /* Hash function definition */
void *digest_hashctx; /* Hash function context */
};
struct metalink_digest_def {
const char *hash_name;
const struct digest_params *dparams;
};
struct metalink_digest_alias {
const char *alias_name;
const struct metalink_digest_def *digest_def;
};
struct metalink_checksum {
const struct metalink_digest_def *digest_def;
/* raw digest value, not ascii hex digest */
unsigned char *digest;
};
struct metalink_resource {
struct metalink_resource *next;
char *url;
};
struct metalinkfile {
struct metalinkfile *next;
char *filename;
struct metalink_checksum *checksum;
struct metalink_resource *resource;
};
#ifdef USE_METALINK
/*
* curl requires libmetalink 0.1.0 or newer
*/
#define CURL_REQ_LIBMETALINK_MAJOR 0
#define CURL_REQ_LIBMETALINK_MINOR 1
#define CURL_REQ_LIBMETALINK_PATCH 0
#define CURL_REQ_LIBMETALINK_VERS ((CURL_REQ_LIBMETALINK_MAJOR * 10000) + \
(CURL_REQ_LIBMETALINK_MINOR * 100) + \
CURL_REQ_LIBMETALINK_PATCH)
extern const struct digest_params MD5_DIGEST_PARAMS[1];
extern const struct digest_params SHA1_DIGEST_PARAMS[1];
extern const struct digest_params SHA256_DIGEST_PARAMS[1];
#include <metalink/metalink.h>
/*
* Counts the resource in the metalinkfile.
*/
int count_next_metalink_resource(struct metalinkfile *mlfile);
void delete_metalinkfile(struct metalinkfile *mlfile);
void clean_metalink(struct OperationConfig *config);
/*
* Performs final parse operation and extracts information from
* Metalink and creates metalinkfile structs.
*
* This function returns 0 if it succeeds without warnings, or one of
* the following negative error codes:
*
* -1: Parsing failed; or no file is found
* -2: Parsing succeeded with some warnings.
*/
int parse_metalink(struct OperationConfig *config, struct OutStruct *outs,
const char *metalink_url);
/*
* Callback function for CURLOPT_WRITEFUNCTION
*/
size_t metalink_write_cb(void *buffer, size_t sz, size_t nmemb,
void *userdata);
/*
* Returns nonzero if content_type includes "application/metalink+xml"
* media-type. The check is done in case-insensitive manner.
*/
int check_metalink_content_type(const char *content_type);
/*
* Check checksum of file denoted by filename.
*
* This function returns 1 if the checksum matches or one of the
* following integers:
*
* 0:
* Checksum didn't match.
* -1:
* Could not open file; or could not read data from file.
* -2:
* No checksum in Metalink supported, hash algorithm not available, or
* Metalink does not contain checksum.
*/
int metalink_check_hash(struct GlobalConfig *config,
struct metalinkfile *mlfile,
const char *filename);
/*
* Release resources allocated at global scope.
*/
void metalink_cleanup(void);
#else /* USE_METALINK */
#define count_next_metalink_resource(x) 0
#define delete_metalinkfile(x) (void)x
#define clean_metalink(x) (void)x
/* metalink_cleanup() takes no arguments */
#define metalink_cleanup() Curl_nop_stmt
#endif /* USE_METALINK */
#endif /* HEADER_CURL_TOOL_METALINK_H */

View File

@ -66,7 +66,6 @@
#include "tool_homedir.h"
#include "tool_libinfo.h"
#include "tool_main.h"
#include "tool_metalink.h"
#include "tool_msgs.h"
#include "tool_operate.h"
#include "tool_operhlp.h"
@ -413,35 +412,6 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
}
}
#ifdef USE_METALINK
if(per->metalink && !per->metalink_next_res)
fprintf(global->errors, "Metalink: fetching (%s) from (%s) OK\n",
per->mlfile->filename, per->this_url);
if(!per->metalink && config->use_metalink && result == CURLE_OK) {
int rv = parse_metalink(config, outs, per->this_url);
if(!rv) {
fprintf(config->global->errors, "Metalink: parsing (%s) OK\n",
per->this_url);
}
else if(rv == -1)
fprintf(config->global->errors, "Metalink: parsing (%s) FAILED\n",
per->this_url);
}
else if(per->metalink && result == CURLE_OK && !per->metalink_next_res) {
int rv;
(void)fflush(outs->stream);
rv = metalink_check_hash(global, per->mlfile, outs->filename);
if(!rv)
per->metalink_next_res = 1;
}
#endif /* USE_METALINK */
#ifdef USE_METALINK
if(outs->metalink_parser)
metalink_parser_context_delete(outs->metalink_parser);
#endif /* USE_METALINK */
/* if retry-max-time is non-zero, make sure we haven't exceeded the
time */
if(per->retry_numretries &&
@ -600,36 +570,6 @@ static CURLcode post_per_transfer(struct GlobalConfig *global,
return CURLE_OK;
}
} /* if retry_numretries */
else if(per->metalink) {
/* Metalink: Decide to try the next resource or not. Try the next resource
if download was not successful. */
long response = 0;
if(CURLE_OK == result) {
/* TODO We want to try next resource when download was
not successful. How to know that? */
char *effective_url = NULL;
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &effective_url);
if(effective_url &&
curl_strnequal(effective_url, "http", 4)) {
/* This was HTTP(S) */
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
if(response != 200 && response != 206) {
per->metalink_next_res = 1;
fprintf(global->errors,
"Metalink: fetching (%s) from (%s) FAILED "
"(HTTP status code %ld)\n",
per->mlfile->filename, per->this_url, response);
}
}
}
else {
per->metalink_next_res = 1;
fprintf(global->errors,
"Metalink: fetching (%s) from (%s) FAILED (%s)\n",
per->mlfile->filename, per->this_url,
curl_easy_strerror(result));
}
}
if((global->progressmode == CURL_PROGRESS_BAR) &&
per->progressbar.calls)
@ -715,7 +655,6 @@ static CURLcode single_transfer(struct GlobalConfig *global,
{
CURLcode result = CURLE_OK;
struct getout *urlnode;
struct metalinkfile *mlfile_last = NULL;
bool orig_noprogress = global->noprogress;
bool orig_isatty = global->isatty;
struct State *state = &config->state;
@ -757,24 +696,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
while(config->state.urlnode) {
char *infiles; /* might be a glob pattern */
struct URLGlob *inglob = state->inglob;
bool metalink = FALSE; /* metalink download? */
struct metalinkfile *mlfile;
struct metalink_resource *mlres;
urlnode = config->state.urlnode;
if(urlnode->flags & GETOUT_METALINK) {
metalink = 1;
if(!mlfile_last) {
mlfile_last = config->metalinkfile_list;
}
mlfile = mlfile_last;
mlfile_last = mlfile_last->next;
mlres = mlfile->resource;
}
else {
mlfile = NULL;
mlres = NULL;
}
/* urlnode->url is the full URL (it might be NULL) */
@ -836,12 +758,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
}
if(!state->urlnum) {
if(metalink) {
/* For Metalink download, we don't use glob. Instead we use
the number of resources as urlnum. */
urlnum = count_next_metalink_resource(mlfile);
}
else if(!config->globoff) {
if(!config->globoff) {
/* Unless explicitly shut off, we expand '{...}' and '[...]'
expressions and return total number of URLs in pattern set */
result = glob_url(&state->urls, urlnode->url, &state->urlnum,
@ -997,51 +914,33 @@ static CURLcode single_transfer(struct GlobalConfig *global,
}
}
if(metalink) {
/* For Metalink download, use name in Metalink file as
filename. */
per->outfile = strdup(mlfile->filename);
if(!per->outfile) {
result = CURLE_OUT_OF_MEMORY;
if(state->urls) {
result = glob_next_url(&per->this_url, state->urls);
if(result)
break;
}
per->this_url = strdup(mlres->url);
}
else if(!state->li) {
per->this_url = strdup(urlnode->url);
if(!per->this_url) {
result = CURLE_OUT_OF_MEMORY;
break;
}
per->mlfile = mlfile;
}
else {
if(state->urls) {
result = glob_next_url(&per->this_url, state->urls);
if(result)
break;
}
else if(!state->li) {
per->this_url = strdup(urlnode->url);
if(!per->this_url) {
result = CURLE_OUT_OF_MEMORY;
break;
}
}
else
per->this_url = NULL;
if(!per->this_url)
break;
else
per->this_url = NULL;
if(!per->this_url)
break;
if(state->outfiles) {
per->outfile = strdup(state->outfiles);
if(!per->outfile) {
result = CURLE_OUT_OF_MEMORY;
break;
}
if(state->outfiles) {
per->outfile = strdup(state->outfiles);
if(!per->outfile) {
result = CURLE_OUT_OF_MEMORY;
break;
}
}
if(((urlnode->flags&GETOUT_USEREMOTE) ||
(per->outfile && strcmp("-", per->outfile))) &&
(metalink || !config->use_metalink)) {
(per->outfile && strcmp("-", per->outfile)))) {
/*
* We have specified a file name to store the result in, or we have
@ -1083,7 +982,7 @@ static CURLcode single_transfer(struct GlobalConfig *global,
/* Create the directory hierarchy, if not pre-existent to a multiple
file output call */
if(config->create_dirs || metalink) {
if(config->create_dirs) {
result = create_dir_hierarchy(per->outfile, global->errors);
/* create_dir_hierarchy shows error upon CURLE_WRITE_ERROR */
if(result)
@ -1275,15 +1174,8 @@ static CURLcode single_transfer(struct GlobalConfig *global,
my_setopt(curl, CURLOPT_WRITEDATA, per);
my_setopt(curl, CURLOPT_INTERLEAVEDATA, per);
if(metalink || !config->use_metalink)
/* what call to write */
my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
#ifdef USE_METALINK
else
/* Set Metalink specific write callback function to parse
XML data progressively. */
my_setopt(curl, CURLOPT_WRITEFUNCTION, metalink_write_cb);
#endif /* USE_METALINK */
/* what call to write */
my_setopt(curl, CURLOPT_WRITEFUNCTION, tool_write_cb);
/* for uploads */
input->config = config;
@ -2136,23 +2028,6 @@ static CURLcode single_transfer(struct GlobalConfig *global,
if(config->hsts)
my_setopt_str(curl, CURLOPT_HSTS, config->hsts);
#ifdef USE_METALINK
if(!metalink && config->use_metalink) {
outs->metalink_parser = metalink_parser_context_new();
if(!outs->metalink_parser) {
result = CURLE_OUT_OF_MEMORY;
break;
}
fprintf(global->errors,
"Metalink: parsing (%s) metalink/XML...\n", per->this_url);
}
else if(metalink)
fprintf(global->errors,
"Metalink: fetching (%s) from (%s)...\n",
mlfile->filename, per->this_url);
#endif /* USE_METALINK */
per->metalink = metalink;
/* initialize retry vars for loop below */
per->retry_sleep_default = (config->retry_delay) ?
config->retry_delay*1000L : RETRY_SLEEP_DEFAULT; /* ms */
@ -2410,9 +2285,6 @@ static CURLcode serial_transfers(struct GlobalConfig *global,
bailout = TRUE;
}
/* Release metalink related resources here */
delete_metalinkfile(per->mlfile);
per = del_per_transfer(per);
if(bailout)
@ -2581,8 +2453,6 @@ static CURLcode run_all_transfers(struct GlobalConfig *global,
/* Free list of given URLs */
clean_getout(per->config);
/* Release metalink related resources here */
clean_metalink(per->config);
per = del_per_transfer(per);
}

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -36,10 +36,6 @@ struct per_transfer {
long retry_sleep_default;
long retry_sleep;
struct timeval retrystart;
bool metalink; /* nonzero for metalink download. */
bool metalink_next_res;
struct metalinkfile *mlfile;
struct metalink_resource *mlres;
char *this_url;
unsigned int urlnum; /* the index of the given URL */
char *outfile;

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -31,7 +31,6 @@
#include "tool_convert.h"
#include "tool_doswin.h"
#include "tool_operhlp.h"
#include "tool_metalink.h"
#include "memdebug.h" /* keep this as LAST include */

View File

@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -22,9 +22,6 @@
*
***************************************************************************/
#include "tool_setup.h"
#ifdef USE_METALINK
# include <metalink/metalink.h>
#endif /* USE_METALINK */
/*
* OutStruct variables keep track of information relative to curl's
@ -58,8 +55,6 @@
* 'init' member holds original file size or offset at which truncation is
* taking place. Always zero unless appending to a non-empty regular file.
*
* 'metalink_parser' member is a pointer to Metalink XML parser
* context.
*/
struct OutStruct {
@ -71,9 +66,6 @@ struct OutStruct {
FILE *stream;
curl_off_t bytes;
curl_off_t init;
#ifdef USE_METALINK
metalink_parser_context_t *metalink_parser;
#endif /* USE_METALINK */
};
@ -113,7 +105,6 @@ struct getout {
#define GETOUT_USEREMOTE (1<<2) /* use remote file name locally */
#define GETOUT_UPLOAD (1<<3) /* if set, -T has been used */
#define GETOUT_NOUPLOAD (1<<4) /* if set, -T "" has been used */
#define GETOUT_METALINK (1<<5) /* set when Metalink download */
/*
* 'trace' enumeration represents curl's output look'n feel possibilities.

View File

@ -388,7 +388,6 @@ Features testable here are:
- `ld_preload`
- `libz`
- `manual`
- `Metalink`
- `Mime`
- `netrc`
- `NSS`

View File

@ -215,9 +215,9 @@ test1916 test1917 test1918 \
\
test1933 test1934 test1935 test1936 \
\
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
test2016 test2017 test2018 test2019 test2020 test2021 test2022 test2023 \
test2000 test2001 test2002 test2003 test2004 \
\
test2023 \
test2024 test2025 test2026 test2027 test2028 test2029 test2030 test2031 \
test2032 test2034 test2035 test2036 test2037 test2038 test2039 \
test2040 test2041 test2042 test2043 test2044 test2045 test2046 test2047 \

View File

@ -1,91 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 37
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, HTTP resource
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
<hash type="sha256">a430d26389c69b7a245a9ad692cf20b4dc026fb7c2ff8a2c164c49a77130d6d9</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Data delivered from an HTTP resource
</file1>
<file2 name="log/stdout%TESTNUMBER">
</file2>
<file3 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) OK
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) [sha-256] OK
</file3>
<stripfile3>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile3>
</verify>
</testcase>

View File

@ -1,122 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
FILE
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 14:49:01 GMT
Server: test-server/fake
Content-Length: 42
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Some data delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
# This relies on the debug feature to allow us to set directory to store the
# -O output in, using the CURL_TESTDIR variable. This test might use it upon
# failure only, successful execution won't actually use it.
<features>
debug
file
Metalink
</features>
<server>
http
</server>
<name>
Metalink local XML file, HTTP resource, using -O -D file
</name>
<setenv>
CURL_TESTDIR=%PWD/log
</setenv>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink -O -D log/heads%TESTNUMBER
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
<hash type="md5">we-only-check-the-strongest-hash-provided</hash>
<hash type="sha256">319cb6be756734b7ff689628ca3265580cdae6a0e38f42d4ac612ff4fba143b0</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Some data delivered from an HTTP resource
</file1>
# The Content-Length replace here is to handle with 4/5 digit port number in
# the content
<stripfile2>
s/Last-Modified:.*//
s/Content-Length: 49[67]/Content-Length: yeps/
</stripfile2>
<file2 name="log/heads%TESTNUMBER">
Content-Length: yeps
Accept-ranges: bytes
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 14:49:01 GMT
Server: test-server/fake
Content-Length: 42
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
</file2>
<file3 name="log/stdout%TESTNUMBER">
</file3>
<file4 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) OK
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) [sha-256] OK
</file4>
<stripfile4>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile4>
</verify>
</testcase>

View File

@ -1,122 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
-J
FILE
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 14:50:02 GMT
Server: test-server/fake
Content-Length: 42
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Something delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
# This relies on the debug feature to allow us to set directory to store the
# -O and -J output in, using the CURL_TESTDIR variable. This test might use
# it upon failure only, successful execution won't actually use it.
<features>
debug
file
Metalink
</features>
<server>
http
</server>
<name>
Metalink local XML file, HTTP resource, using -O -J -D file
</name>
<setenv>
CURL_TESTDIR=%PWD/log
</setenv>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink -J -O -D log/heads%TESTNUMBER
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
<hash type="md5">we-only-check-the-strongest-hash-provided</hash>
<hash type="sha256">52899e30f80e3490632d505653204e1fb5b02bda141048704ce9a0ed00b8a3f5</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Something delivered from an HTTP resource
</file1>
# The Content-Length replace here is to handle with 4/5 digit port number in
# the content
<stripfile2>
s/Last-Modified:.*//
s/Content-Length: 49[67]/Content-Length: yeps/
</stripfile2>
<file2 name="log/heads%TESTNUMBER">
Content-Length: yeps
Accept-ranges: bytes
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 14:50:02 GMT
Server: test-server/fake
Content-Length: 42
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
</file2>
<file3 name="log/stdout%TESTNUMBER">
</file3>
<file4 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) OK
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) [sha-256] OK
</file4>
<stripfile4>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile4>
</verify>
</testcase>

View File

@ -1,114 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
FILE
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 15:23:48 GMT
Server: test-server/fake
Content-Length: 43
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Some stuff delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<features>
file
Metalink
</features>
<server>
http
</server>
<name>
Metalink local XML file, HTTP resource, using -o fname -D file
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink -o log/outfile%TESTNUMBER -D log/heads%TESTNUMBER
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
<hash type="md5">we-only-check-the-strongest-hash-provided</hash>
<hash type="sha256">711b1b566b536c5baae9b36f2f5c1830a7c8ff126d1afa2febc5b59f8d0aab54</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/outfile%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Some stuff delivered from an HTTP resource
</file1>
# The Content-Length replace here is to handle with 4/5 digit port number in
# the content
<stripfile2>
s/Last-Modified:.*//
s/Content-Length: 49[67]/Content-Length: yeps/
</stripfile2>
<file2 name="log/heads%TESTNUMBER">
Content-Length: yeps
Accept-ranges: bytes
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 15:23:48 GMT
Server: test-server/fake
Content-Length: 43
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
</file2>
<file3 name="log/stdout%TESTNUMBER">
</file3>
<file4 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) OK
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) [sha-256] OK
</file4>
<stripfile4>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile4>
</verify>
</testcase>

View File

@ -1,115 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
-J
FILE
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 16:27:17 GMT
Server: test-server/fake
Content-Length: 46
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Some contents delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<features>
file
Metalink
</features>
<server>
http
</server>
<name>
Metalink local XML file, HTTP resource, using -o fname -J -D file
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink -J -o log/outfile%TESTNUMBER -D log/heads%TESTNUMBER
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
<hash type="md5">we-only-check-the-strongest-hash-provided</hash>
<hash type="sha256">e4c5b83384ba7d5f8e201d61747a14f29baacd7dfadce0fbd56661db4bba72b2</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/outfile%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Some contents delivered from an HTTP resource
</file1>
# The Content-Length replace here is to handle with 4/5 digit port number in
# the content
<stripfile2>
s/Last-Modified:.*//
s/Content-Length: 49[67]/Content-Length: yeps/
</stripfile2>
<file2 name="log/heads%TESTNUMBER">
Content-Length: yeps
Accept-ranges: bytes
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 16:27:17 GMT
Server: test-server/fake
Content-Length: 46
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
</file2>
<file3 name="log/stdout%TESTNUMBER">
</file3>
<file4 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) OK
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) [sha-256] OK
</file4>
<stripfile4>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile4>
</verify>
</testcase>

View File

@ -1,114 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
FILE
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 17:37:27 GMT
Server: test-server/fake
Content-Length: 41
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Contents delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<features>
file
Metalink
</features>
<server>
http
</server>
<name>
Metalink local XML file, HTTP resource, using -o fname -D file
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink -o log/outfile%TESTNUMBER -D log/heads%TESTNUMBER
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
<hash type="md5">we-only-check-the-strongest-hash-provided</hash>
<hash type="sha256">19dcb4e2a99b9cd02c30b1ed6c55869b7ef8cda9f985648909c48a6dbb54356c</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/outfile%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Contents delivered from an HTTP resource
</file1>
# The Content-Length replace here is to handle with 4/5 digit port number in
# the content
<stripfile2>
s/Last-Modified:.*//
s/Content-Length: 49[67]/Content-Length: yeps/
</stripfile2>
<file2 name="log/heads%TESTNUMBER">
Content-Length: yeps
Accept-ranges: bytes
HTTP/1.1 200 OK
Date: Thu, 21 Jun 2012 17:37:27 GMT
Server: test-server/fake
Content-Length: 41
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
</file2>
<file3 name="log/stdout%TESTNUMBER">
</file3>
<file4 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) OK
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) [sha-256] OK
</file4>
<stripfile4>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile4>
</verify>
</testcase>

View File

@ -1,91 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 37
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, HTTP resource, hash mismatch
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
<hash type="sha256">badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadb</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Data delivered from an HTTP resource
</file1>
<file2 name="log/stdout%TESTNUMBER">
</file2>
<file3 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) OK
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) [sha-256] FAILED (digest mismatch)
</file3>
<stripfile3>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile3>
</verify>
</testcase>

View File

@ -1,90 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun %TESTNUMBER 14:49:00 GMT
Server: test-server/fake
Content-Length: 46
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Some contents delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, HTTP resource, without hash
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER">
<verification>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol>
GET /%TESTNUMBER HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file1 name="log/download%TESTNUMBER">
Some contents delivered from an HTTP resource
</file1>
<file2 name="log/stdout%TESTNUMBER">
</file2>
<file3 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (digest missing)
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER)...
Metalink: fetching (log/download%TESTNUMBER) from (http://%HOSTIP:%HTTPPORT/%TESTNUMBER) OK
Metalink: validating (log/download%TESTNUMBER)...
Metalink: validating (log/download%TESTNUMBER) FAILED (digest missing)
</file3>
<stripfile3>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile3>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix absolute path
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="/tmp/download%TESTNUMBER">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER /tmp/download%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix path relative to current
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="./log/download%TESTNUMBER">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/download%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix path relative to upper
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="../tests/log/download%TESTNUMBER">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/download%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix path traversal
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/../log/download%TESTNUMBER">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/download%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix home path traversal
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="~/download%TESTNUMBER">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix questionable file name I
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/.download%TESTNUMBER">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/.download%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix questionable file name II
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name=".">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix questionable file name III
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="..">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix questionable file name IV
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER >/dev/null">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/download%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -1,78 +0,0 @@
<testcase>
<info>
<keywords>
Metalink
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data nocheck="yes">
HTTP/1.1 200 OK
Date: Wed, 20 Jun 2012 14:49:00 GMT
Server: test-server/fake
Content-Length: 56
Connection: close
Content-Type: text/html
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
Funny-head: yesyes
Data that should not be delivered from an HTTP resource
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<features>
file
Metalink
</features>
<name>
Metalink local XML file, attempt Unix questionable file name V
</name>
<command option="no-output,no-include">
--metalink file://%PWD/log/test%TESTNUMBER.metalink
</command>
# local metalink file written before test command runs
<file name="log/test%TESTNUMBER.metalink">
<?xml version="1.0" encoding="utf-8"?>
<metalink version="3.0" xmlns="http://www.metalinker.org/">
<files>
<file name="log/download%TESTNUMBER |/dev/null">
<verification>
<hash type="sha256">c7d03debe90ca29492203ea921d76941fa98640cf3b744f2a16c9b58465eab82</hash>
</verification>
<resources maxconnections="1">
<url type="http" preference="90">http://%HOSTIP:%HTTPPORT/%TESTNUMBER</url>
</resources>
</file>
</files>
</metalink>
</file>
<postcheck>
perl %SRCDIR/libtest/notexists.pl log/%TESTNUMBER log/name%TESTNUMBER log/download%TESTNUMBER
</postcheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<file1 name="log/stdout%TESTNUMBER">
</file1>
<file2 name="log/stderr%TESTNUMBER" mode="text">
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) metalink/XML...
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) WARNING (missing or invalid file name)
Metalink: parsing (file://%PWD/log/test%TESTNUMBER.metalink) FAILED
</file2>
<stripfile2>
$_ = '' if (($_ !~ /^Metalink: /) && ($_ !~ /error/i) && ($_ !~ /warn/i))
</stripfile2>
</verify>
</testcase>

View File

@ -44,7 +44,7 @@ $curl_protocols =~ /\w+: (.*)$/;
@curl = split / /,$1;
# These features are not supported by curl-config
@curl = grep(!/^(Debug|TrackMemory|Metalink|CharConv)$/i, @curl);
@curl = grep(!/^(Debug|TrackMemory|CharConv)$/i, @curl);
@curl = sort @curl;
# Read the output of curl-config

View File

@ -253,7 +253,6 @@ my $has_kerberos; # set if libcurl is built with Kerberos support
my $has_spnego; # set if libcurl is built with SPNEGO support
my $has_charconv; # set if libcurl is built with CharConv support
my $has_tls_srp; # set if libcurl is built with TLS-SRP support
my $has_metalink; # set if curl is built with Metalink support
my $has_http2; # set if libcurl is built with HTTP2 support
my $has_httpsproxy; # set if libcurl is built with HTTPS-proxy support
my $has_crypto; # set if libcurl is built with cryptographic support
@ -2852,7 +2851,6 @@ sub setupfeatures {
$feature{"ld_preload"} = ($has_ldpreload && !$debug_build);
$feature{"libz"} = $has_libz;
$feature{"manual"} = $has_manual;
$feature{"Metalink"} = $has_metalink;
$feature{"MinGW"} = $has_mingw;
$feature{"MultiSSL"} = $has_multissl;
$feature{"NSS"} = $has_nss;
@ -3103,10 +3101,6 @@ sub checksystem {
# TLS-SRP enabled
$has_tls_srp=1;
}
if($feat =~ /Metalink/i) {
# Metalink enabled
$has_metalink=1;
}
if($feat =~ /PSL/i) {
# PSL enabled
$has_psl=1;

View File

@ -71,9 +71,9 @@ unit1330_SOURCES = unit1330.c $(UNITFILES)
unit1330_CPPFLAGS = $(AM_CPPFLAGS)
unit1394_SOURCES = unit1394.c $(UNITFILES)
unit1394_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMETALINK_CPPFLAGS)
unit1394_LDADD = @LIBMETALINK_LIBS@ $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
unit1394_LDFLAGS = @LIBMETALINK_LDFLAGS@ $(top_builddir)/src/libcurltool.la
unit1394_CPPFLAGS = $(AM_CPPFLAGS)
unit1394_LDADD = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@
unit1394_LDFLAGS = $(top_builddir)/src/libcurltool.la
unit1394_LIBS =
unit1395_SOURCES = unit1395.c $(UNITFILES)
@ -104,7 +104,7 @@ unit1603_SOURCES = unit1603.c $(UNITFILES)
unit1603_CPPFLAGS = $(AM_CPPFLAGS)
unit1604_SOURCES = unit1604.c $(UNITFILES)
unit1604_CPPFLAGS = $(AM_CPPFLAGS) $(LIBMETALINK_CPPFLAGS)
unit1604_CPPFLAGS = $(AM_CPPFLAGS)
unit1605_SOURCES = unit1605.c $(UNITFILES)
unit1605_CPPFLAGS = $(AM_CPPFLAGS)