diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2021-11-18 15:54:46 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2021-11-18 15:54:46 +0300 |
commit | ee59f90d0a7044ba9d0a146aefceb34e78891ab5 (patch) | |
tree | 8c19aae17abd931fa9751339f03e8306e5609592 /libbutl/openssl.txx | |
parent | fe4ce42d093eeb009081958d4339818ef46274ea (diff) |
Add openssl::info() overloads
Diffstat (limited to 'libbutl/openssl.txx')
-rw-r--r-- | libbutl/openssl.txx | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/libbutl/openssl.txx b/libbutl/openssl.txx index f198c22..eebc332 100644 --- a/libbutl/openssl.txx +++ b/libbutl/openssl.txx @@ -1,6 +1,7 @@ // file : libbutl/openssl.txx -*- C++ -*- // license : MIT; see accompanying LICENSE file +#include <cstddef> // size_t #include <utility> // forward() namespace butl @@ -49,4 +50,69 @@ namespace butl // Note: leaving this scope closes any open ends of the pipes in io_data. } + + template <typename C, + typename E> + optional<openssl_info> openssl:: + info (const C& cmdc, E&& err, const process_env& env) + { + using namespace std; + + // Run the `openssl version` command. + // + openssl os (cmdc, + nullfd, fdstream_mode::text, forward<E> (err), + env, + "version"); + + // Read the command's stdout and wait for its completion. Bail out if the + // command didn't terminate successfully or stdout contains multiple + // lines. + // + string s; + getline (os.in, s); + + bool eof (os.in.eof () || + os.in.peek () == ifdstream::traits_type::eof ()); + + os.in.close (); + + if (!(os.wait () && eof)) + return nullopt; + + // Parse the version string. + // + // There is some variety in the version representations: + // + // OpenSSL 3.0.0 7 sep 2021 (Library: OpenSSL 3.0.0 7 sep 2021) + // OpenSSL 1.1.1l FIPS 24 Aug 2021 + // LibreSSL 2.8.3 + // + // We will only consider the first two space separated components as the + // program name and version. We will also assume that there are no leading + // spaces and the version is delimited from the program name with a single + // space character. + // + size_t e (s.find (' ')); + + // Bail out if there is no version present in the string or the program + // name is empty. + // + if (e == string::npos || e == 0) + return nullopt; + + string nm (s, 0, e); + + size_t b (e + 1); // The beginning of the version. + e = s.find (' ', b); // The end of the version. + + optional<semantic_version> ver ( + parse_semantic_version (string (s, b, e != string::npos ? e - b : e), + "" /* build_separators */)); + + if (!ver) + return nullopt; + + return openssl_info {move (nm), move (*ver)}; + } } |