file(DOWNLOAD|UPLOAD): Add 'NETRC' and 'NETRC_FILE' suboption

This commit is contained in:
Shane Parris 2017-10-18 10:26:55 -04:00 committed by Brad King
parent cb8f26f199
commit 5d67e9025d
8 changed files with 144 additions and 1 deletions

View File

@ -149,7 +149,7 @@ syn keyword cmakeKWexport_library_dependencies contained
\ APPEND EXPORT INCLUDE LINK_INTERFACE_LIBRARIES SET \ APPEND EXPORT INCLUDE LINK_INTERFACE_LIBRARIES SET
syn keyword cmakeKWfile contained syn keyword cmakeKWfile contained
\ ALGO APPEND ASCII CMAKE_TLS_CAINFO CMAKE_TLS_VERIFY CONDITION CONFIG CONTENT COPY CR DESTINATION DIRECTORY_PERMISSIONS DOWNLOAD ENCODING EXCLUDE EXPECTED_HASH FILES_MATCHING FILE_PERMISSIONS FOLLOW_SYMLINKS FUNCTION GENERATE GLOB GLOB_RECURSE GUARD HASH HEX HTTPHEADER INACTIVITY_TIMEOUT INSTALL LENGTH_MAXIMUM LENGTH_MINIMUM LF LIMIT LIMIT_COUNT LIMIT_INPUT LIMIT_OUTPUT LIST_DIRECTORIES LOCK LOG MAKE_DIRECTORY NEWLINE_CONSUME NO_HEX_CONVERSION NO_SOURCE_PERMISSIONS OFFSET OLD PATTERN PROCESS READ REGEX RELATIVE RELATIVE_PATH RELEASE REMOVE REMOVE_RECURSE RENAME RESULT_VARIABLE SHOW_PROGRESS SSL STATUS STRINGS TIMESTAMP TLS_CAINFO TLS_VERIFY TO_CMAKE_PATH TO_NATIVE_PATH UPLOAD USERPWD USE_SOURCE_PERMISSIONS UTC UTF WRITE \ ALGO APPEND ASCII CMAKE_TLS_CAINFO CMAKE_TLS_VERIFY CONDITION CONFIG CONTENT COPY CR DESTINATION DIRECTORY_PERMISSIONS DOWNLOAD ENCODING EXCLUDE EXPECTED_HASH FILES_MATCHING FILE_PERMISSIONS FOLLOW_SYMLINKS FUNCTION GENERATE GLOB GLOB_RECURSE GUARD HASH HEX HTTPHEADER INACTIVITY_TIMEOUT INSTALL LENGTH_MAXIMUM LENGTH_MINIMUM LF LIMIT LIMIT_COUNT LIMIT_INPUT LIMIT_OUTPUT LIST_DIRECTORIES LOCK LOG MAKE_DIRECTORY NETRC NETRC_FILE NEWLINE_CONSUME NO_HEX_CONVERSION NO_SOURCE_PERMISSIONS OFFSET OLD PATTERN PROCESS READ REGEX RELATIVE RELATIVE_PATH RELEASE REMOVE REMOVE_RECURSE RENAME RESULT_VARIABLE SHOW_PROGRESS SSL STATUS STRINGS TIMESTAMP TLS_CAINFO TLS_VERIFY TO_CMAKE_PATH TO_NATIVE_PATH UPLOAD USERPWD USE_SOURCE_PERMISSIONS UTC UTF WRITE
syn keyword cmakeKWfind_file contained syn keyword cmakeKWfind_file contained
\ CMAKE_FIND_ROOT_PATH_BOTH DOC DVAR HINTS INCLUDE NAMES NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_FIND_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_SYSTEM_PATH NO_DEFAULT_PATH NO_SYSTEM_ENVIRONMENT_PATH ONLY_CMAKE_FIND_ROOT_PATH OS PATHS PATH_SUFFIXES VAR \ CMAKE_FIND_ROOT_PATH_BOTH DOC DVAR HINTS INCLUDE NAMES NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_FIND_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_SYSTEM_PATH NO_DEFAULT_PATH NO_SYSTEM_ENVIRONMENT_PATH ONLY_CMAKE_FIND_ROOT_PATH OS PATHS PATH_SUFFIXES VAR

View File

@ -232,6 +232,31 @@ Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
``HTTPHEADER <HTTP-header>`` ``HTTPHEADER <HTTP-header>``
HTTP header for operation. Suboption can be repeated several times. HTTP header for operation. Suboption can be repeated several times.
``NETRC <level>``
Specify whether the .netrc file is to be used for operation. If this
option is not specified, the value of the ``CMAKE_NETRC`` variable
will be used instead.
Valid levels are:
``IGNORED``
The .netrc file is ignored.
This is the default.
``OPTIONAL``
The .netrc file is optional, and information in the URL is preferred.
The file will be scanned to find which ever information is not specified
in the URL.
``REQUIRED``
The .netrc file is required, and information in the URL is ignored.
``NETRC_FILE <file>``
Specify an alternative .netrc file to the one in your home directory,
if the ``NETRC`` level is ``OPTIONAL`` or ``REQUIRED``. If this option
is not specified, the value of the ``CMAKE_NETRC_FILE`` variable will
be used instead.
If neither ``NETRC`` option is given CMake will check variables
``CMAKE_NETRC`` and ``CMAKE_NETRC_FILE``, respectively.
Additional options to ``DOWNLOAD`` are: Additional options to ``DOWNLOAD`` are:
``EXPECTED_HASH ALGO=<value>`` ``EXPECTED_HASH ALGO=<value>``

View File

@ -60,6 +60,8 @@ Variables that Provide Information
/variable/CMAKE_MATCH_n /variable/CMAKE_MATCH_n
/variable/CMAKE_MINIMUM_REQUIRED_VERSION /variable/CMAKE_MINIMUM_REQUIRED_VERSION
/variable/CMAKE_MINOR_VERSION /variable/CMAKE_MINOR_VERSION
/variable/CMAKE_NETRC
/variable/CMAKE_NETRC_FILE
/variable/CMAKE_PARENT_LIST_FILE /variable/CMAKE_PARENT_LIST_FILE
/variable/CMAKE_PATCH_VERSION /variable/CMAKE_PATCH_VERSION
/variable/CMAKE_PROJECT_DESCRIPTION /variable/CMAKE_PROJECT_DESCRIPTION

View File

@ -0,0 +1,9 @@
CMAKE_NETRC
-----------
This variable is used to initialize the ``NETRC`` option for
:command:`file(DOWNLOAD)` and :command:`file(DOWNLOAD)` commands and the
module :module:`ExternalProject`. See those commands for additional
information.
The local option takes precedence over this variable.

View File

@ -0,0 +1,9 @@
CMAKE_NETRC_FILE
----------------
This variable is used to initialize the ``NETRC_FILE`` option for
:command:`file(DOWNLOAD)` and :command:`file(DOWNLOAD)` commands and the
module :module:`ExternalProject`. See those commands for additional
information.
The local option takes precedence over this variable.

View File

@ -56,3 +56,41 @@ std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile)
#endif #endif
return e; return e;
} }
std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
const std::string& netrc_file)
{
std::string e;
CURL_NETRC_OPTION curl_netrc_level = CURL_NETRC_LAST;
::CURLcode res;
if (!netrc_level.empty()) {
if (netrc_level == "OPTIONAL") {
curl_netrc_level = CURL_NETRC_OPTIONAL;
} else if (netrc_level == "REQUIRED") {
curl_netrc_level = CURL_NETRC_REQUIRED;
} else if (netrc_level == "IGNORED") {
curl_netrc_level = CURL_NETRC_IGNORED;
} else {
e = "NETRC accepts OPTIONAL, IGNORED or REQUIRED but got: ";
e += netrc_level;
return e;
}
}
if (curl_netrc_level != CURL_NETRC_LAST &&
curl_netrc_level != CURL_NETRC_IGNORED) {
res = ::curl_easy_setopt(curl, CURLOPT_NETRC, curl_netrc_level);
check_curl_result(res, "Unable to set netrc level: ");
if (!e.empty()) {
return e;
}
// check to see if a .netrc file has been specified
if (!netrc_file.empty()) {
res = ::curl_easy_setopt(curl, CURLOPT_NETRC_FILE, netrc_file.c_str());
check_curl_result(res, "Unable to set .netrc file path : ");
}
}
return e;
}

View File

@ -9,5 +9,7 @@
#include <string> #include <string>
std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr); std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr);
std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
const std::string& netrc_file);
#endif #endif

View File

@ -2626,6 +2626,9 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
std::string statusVar; std::string statusVar;
bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY"); bool tls_verify = this->Makefile->IsOn("CMAKE_TLS_VERIFY");
const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO"); const char* cainfo = this->Makefile->GetDefinition("CMAKE_TLS_CAINFO");
std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
std::string netrc_file =
this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
std::string expectedHash; std::string expectedHash;
std::string hashMatchMSG; std::string hashMatchMSG;
std::unique_ptr<cmCryptoHash> hash; std::unique_ptr<cmCryptoHash> hash;
@ -2681,6 +2684,22 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
this->SetError("TLS_CAFILE missing file value."); this->SetError("TLS_CAFILE missing file value.");
return false; return false;
} }
} else if (*i == "NETRC_FILE") {
++i;
if (i != args.end()) {
netrc_file = *i;
} else {
this->SetError("DOWNLOAD missing file value for NETRC_FILE.");
return false;
}
} else if (*i == "NETRC") {
++i;
if (i != args.end()) {
netrc_level = *i;
} else {
this->SetError("DOWNLOAD missing level value for NETRC.");
return false;
}
} else if (*i == "EXPECTED_MD5") { } else if (*i == "EXPECTED_MD5") {
++i; ++i;
if (i == args.end()) { if (i == args.end()) {
@ -2822,6 +2841,16 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
return false; return false;
} }
// check to see if netrc parameters have been specified
// local command args takes precedence over CMAKE_NETRC*
netrc_level = cmSystemTools::UpperCase(netrc_level);
std::string const& netrc_option_err =
cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
if (!netrc_option_err.empty()) {
this->SetError(netrc_option_err);
return false;
}
cmFileCommandVectorOfChar chunkDebug; cmFileCommandVectorOfChar chunkDebug;
res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout); res = ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, &fout);
@ -2964,6 +2993,9 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
std::string statusVar; std::string statusVar;
bool showProgress = false; bool showProgress = false;
std::string userpwd; std::string userpwd;
std::string netrc_level = this->Makefile->GetSafeDefinition("CMAKE_NETRC");
std::string netrc_file =
this->Makefile->GetSafeDefinition("CMAKE_NETRC_FILE");
std::vector<std::string> curl_headers; std::vector<std::string> curl_headers;
@ -3000,6 +3032,22 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
statusVar = *i; statusVar = *i;
} else if (*i == "SHOW_PROGRESS") { } else if (*i == "SHOW_PROGRESS") {
showProgress = true; showProgress = true;
} else if (*i == "NETRC_FILE") {
++i;
if (i != args.end()) {
netrc_file = *i;
} else {
this->SetError("UPLOAD missing file value for NETRC_FILE.");
return false;
}
} else if (*i == "NETRC") {
++i;
if (i != args.end()) {
netrc_level = *i;
} else {
this->SetError("UPLOAD missing level value for NETRC.");
return false;
}
} else if (*i == "USERPWD") { } else if (*i == "USERPWD") {
++i; ++i;
if (i == args.end()) { if (i == args.end()) {
@ -3132,6 +3180,16 @@ bool cmFileCommand::HandleUploadCommand(std::vector<std::string> const& args)
check_curl_result(res, "UPLOAD cannot set user password: "); check_curl_result(res, "UPLOAD cannot set user password: ");
} }
// check to see if netrc parameters have been specified
// local command args takes precedence over CMAKE_NETRC*
netrc_level = cmSystemTools::UpperCase(netrc_level);
std::string const& netrc_option_err =
cmCurlSetNETRCOption(curl, netrc_level, netrc_file);
if (!netrc_option_err.empty()) {
this->SetError(netrc_option_err);
return false;
}
struct curl_slist* headers = nullptr; struct curl_slist* headers = nullptr;
for (std::string const& h : curl_headers) { for (std::string const& h : curl_headers) {
headers = ::curl_slist_append(headers, h.c_str()); headers = ::curl_slist_append(headers, h.c_str());