Git Product home page Git Product logo

simplomon's Issues

Add pong test -- alive reporting from simplomon

I'd like to see simplomon being able to inform me via notifyer that it's alive, and since ping checks other servers, maybe pong (inspired from Ansible's ping which reponds with pong) could do so with a configurable interval, e.g. 3600 seconds.

Add ping test

Please add a ping test that allows:

  • Should pass/should fail
  • Source address/interface
  • Specifying IPv6/IPv4

This is to test firewall configurations (making sure things that shouldn't work, aren't working, and the inverse).

Ubuntu 20.04: compilation failed in `testrunner`

On Ubuntu 20.04, meson compile -C build/ fails in testrunner on 3 separate files.

As instructed, I'm using meson from pip, because meson on Ubuntu 20.04 has version 0.53.2

$ git lg | head -n 1
* b8b4ecc - (HEAD -> main, origin/main, origin/HEAD) remove prometheus command for now to fix build (5 days ago) <bert hubert>
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip3 install meson ninja
(venv) $ meson --version
1.4.0
(venv) $ ninja --version
1.11.1.git.kitware.jobserver-1
(venv) $ meson setup build
[..]
simplomon undefined

  Subprojects
    cpp-httplib  : YES 3 warnings
    curl         : YES 1 warnings
    doctest      : YES
    fmt          : YES
    nlohmann_json: YES
    simplesockets: YES
    sqlitewriter : YES

Found ninja-1.11.1.git.kitware.jobserver-1 at /home/gerdriaan/scm/simplomon/venv/bin/ninja
(venv) $ meson compile -C build/ | tee -a /tmp/simplomon-compilelog
[..]
[175/214] Compiling C++ object subprojects/sqlitewriter/demo.p/demo.cc.o
[176/214] Compiling C++ object subprojects/simplesockets/testrunner.p/sclasses.cc.o
[177/214] Compiling C++ object subprojects/sqlitewriter/libsqlitewriter.a.p/jsonhelper.cc.o
[178/214] Compiling C++ object subprojects/sqlitewriter/demo.p/jsonhelper.cc.o
[179/214] Compiling C++ object subprojects/simplesockets/testrunner.p/swrappers.cc.o
[180/214] Compiling C++ object subprojects/sqlitewriter/testrunner.p/jsonhelper.cc.o
[181/214] Compiling C++ object subprojects/sqlitewriter/testrunner.p/testrunner.cc.o
ninja: build stopped: subcommand failed.
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: /home/gerdriaan/scm/simplomon/venv/bin/ninja -C /home/gerdriaan/scm/simplomon/build
(venv) $

Excerpt from one error:

[172/214] Compiling C++ object subprojects/sqlitewriter/testrunner.p/sqlwriter.cc.o
FAILED: subprojects/sqlitewriter/testrunner.p/sqlwriter.cc.o 
c++ -Isubprojects/sqlitewriter/testrunner.p -Isubprojects/sqlitewriter -I../subprojects/sqlitewriter -I../subprojects/nlohmann_json-3.11.2/single_include -fdiagnostics-color=always -D_GLIBCXX_ASSERTIONS=1 -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c++17 -O0 -g -pthread -MD -MQ subprojects/sqlitewriter/testrunner.p/sqlwriter.cc.o -MF subprojects/sqlitewriter/testrunner.p/sqlwriter.cc.o.d -o subprojects/sqlitewriter/testrunner.p/sqlwriter.cc.o -c ../subprojects/sqlitewriter/sqlwriter.cc
../subprojects/sqlitewriter/sqlwriter.cc: In member function ‘void MiniSQLite::execPrep(const string&, std::vector<std::unordered_map<std::__cxx11::basic_string<char>, std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t> > >*)’:
../subprojects/sqlitewriter/sqlwriter.cc:134:94: error: no match for ‘operator=’ (operand types are ‘std::unordered_map<std::__cxx11::basic_string<char>, std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t> >::mapped_type’ {aka ‘std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>’} and ‘sqlite3_int64’ {aka ‘long long int’})
  134 |           row[sqlite3_column_name(d_stmts[table], n)]= sqlite3_column_int64(d_stmts[table], n);
      |                                                                                              ^
In file included from ../subprojects/sqlitewriter/sqlwriter.hh:5,
                 from ../subprojects/sqlitewriter/sqlwriter.cc:1:
/usr/include/c++/9/variant:1299:16: note: candidate: ‘std::variant<_Types>& std::variant<_Types>::operator=(const std::variant<_Types>&) [with _Types = {double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t}]’
 1299 |       variant& operator=(const variant&) = default;
      |                ^~~~~~~~
/usr/include/c++/9/variant:1299:26: note:   no known conversion for argument 1 from ‘sqlite3_int64’ {aka ‘long long int’} to ‘const std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>&’
 1299 |       variant& operator=(const variant&) = default;
      |                          ^~~~~~~~~~~~~~
/usr/include/c++/9/variant:1300:16: note: candidate: ‘std::variant<_Types>& std::variant<_Types>::operator=(std::variant<_Types>&&) [with _Types = {double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t}]’
 1300 |       variant& operator=(variant&&) = default;
      |                ^~~~~~~~
/usr/include/c++/9/variant:1300:26: note:   no known conversion for argument 1 from ‘sqlite3_int64’ {aka ‘long long int’} to ‘std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>&&’
 1300 |       variant& operator=(variant&&) = default;
      |                          ^~~~~~~~~
/usr/include/c++/9/variant:1362:2: note: candidate: ‘template<class _Tp> std::enable_if_t<((__exactly_once<std::variant<_Types>::__accepted_type<_Tp&&, typename std::enable_if<__not_self<_Tp&&>, void>::type> > && is_constructible_v<std::variant<_Types>::__accepted_type<_Tp&&, typename std::enable_if<__not_self<_Tp&&>, void>::type>, _Tp>) && is_assignable_v<std::variant<_Types>::__accepted_type<_Tp&&, typename std::enable_if<__not_self<_Tp&&>, void>::type>&, _Tp>), std::variant<_Types>&> std::variant<_Types>::operator=(_Tp&&) [with _Tp = _Tp; _Types = {double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t}]’
 1362 |  operator=(_Tp&& __rhs)
      |  ^~~~~~~~
/usr/include/c++/9/variant:1362:2: note:   template argument deduction/substitution failed:
/usr/include/c++/9/variant: In substitution of ‘template<class ... _Types> template<class _Tp, class> using __accepted_type = std::variant<_Types>::__to_type<__accepted_index<_Tp> > [with _Tp = long long int&&; <template-parameter-2-2> = std::enable_if<true, void>::type; _Types = {double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t}]’:
/usr/include/c++/9/variant:1358:14:   required by substitution of ‘template<class _Tp> std::enable_if_t<((__exactly_once<std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>::__accepted_type<_Tp&&, typename std::enable_if<__not_self<_Tp&&>, void>::type> > && is_constructible_v<std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>::__accepted_type<_Tp&&, typename std::enable_if<__not_self<_Tp&&>, void>::type>, _Tp>) && is_assignable_v<std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>::__accepted_type<_Tp&&, typename std::enable_if<__not_self<_Tp&&>, void>::type>&, _Tp>), std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>&> std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>::operator=<_Tp>(_Tp&&) [with _Tp = long long int]’
../subprojects/sqlitewriter/sqlwriter.cc:134:94:   required from here
/usr/include/c++/9/variant:1276:8: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
 1276 |  using __accepted_type = __to_type<__accepted_index<_Tp>>;
      |        ^~~~~~~~~~~~~~~

Two other failures, but full log omitted for brevity:

[173/214] Compiling C++ object subprojects/sqlitewriter/libsqlitewriter.a.p/sqlwriter.cc.o
FAILED: subprojects/sqlitewriter/libsqlitewriter.a.p/sqlwriter.cc.o 
c++ -Isubprojects/sqlitewriter/libsqlitewriter.a.p -Isubprojects/sqlitewriter -I../subprojects/sqlitewriter -I../subprojects/nlohmann_json-3.11.2/single_include -fdiagnostics-color=always -D_GLIBCXX_ASSERTIONS=1 -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c++17 -O0 -g -fPIC -pthread -MD -MQ subprojects/sqlitewriter/libsqlitewriter.a.p/sqlwriter.cc.o -MF subprojects/sqlitewriter/libsqlitewriter.a.p/sqlwriter.cc.o.d -o subprojects/sqlitewriter/libsqlitewriter.a.p/sqlwriter.cc.o -c ../subprojects/sqlitewriter/sqlwriter.cc
../subprojects/sqlitewriter/sqlwriter.cc: In member function ‘void MiniSQLite::execPrep(const string&, std::vector<std::unordered_map<std::__cxx11::basic_string<char>, std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t> > >*)’:
../subprojects/sqlitewriter/sqlwriter.cc:134:94: error: no match for ‘operator=’ (operand types are ‘std::unordered_map<std::__cxx11::basic_string<char>, std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t> >::mapped_type’ {aka ‘std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>’} and ‘sqlite3_int64’ {aka ‘long long int’})
  134 |           row[sqlite3_column_name(d_stmts[table], n)]= sqlite3_column_int64(d_stmts[table], n);
      |                                                                                              ^
[174/214] Compiling C++ object subprojects/sqlitewriter/demo.p/sqlwriter.cc.o
FAILED: subprojects/sqlitewriter/demo.p/sqlwriter.cc.o 
c++ -Isubprojects/sqlitewriter/demo.p -Isubprojects/sqlitewriter -I../subprojects/sqlitewriter -I../subprojects/nlohmann_json-3.11.2/single_include -fdiagnostics-color=always -D_GLIBCXX_ASSERTIONS=1 -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c++17 -O0 -g -pthread -MD -MQ subprojects/sqlitewriter/demo.p/sqlwriter.cc.o -MF subprojects/sqlitewriter/demo.p/sqlwriter.cc.o.d -o subprojects/sqlitewriter/demo.p/sqlwriter.cc.o -c ../subprojects/sqlitewriter/sqlwriter.cc
../subprojects/sqlitewriter/sqlwriter.cc: In member function ‘void MiniSQLite::execPrep(const string&, std::vector<std::unordered_map<std::__cxx11::basic_string<char>, std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t> > >*)’:
../subprojects/sqlitewriter/sqlwriter.cc:134:94: error: no match for ‘operator=’ (operand types are ‘std::unordered_map<std::__cxx11::basic_string<char>, std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t> >::mapped_type’ {aka ‘std::variant<double, long int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<unsigned char, std::allocator<unsigned char> >, std::nullptr_t>’} and ‘sqlite3_int64’ {aka ‘long long int’})
  134 |           row[sqlite3_column_name(d_stmts[table], n)]= sqlite3_column_int64(d_stmts[table], n);
      |                                                                                              ^

This looks similar to #5, except it's on Linux.

Currently installed dependency versions:

$ apt search '^(python3-pip|pkg-config|libnghttp2-dev|libssl-dev|liblua5.3-dev)' 2>/dev/null | grep -ie 'upgradable' -e 'install'
liblua5.3-dev/focal,now 5.3.3-1.1ubuntu2 amd64 [installed]
libnghttp2-dev/focal-updates,focal-security,now 1.40.0-1ubuntu0.2 amd64 [installed]
libssl-dev/focal-updates,focal-security 1.1.1f-1ubuntu2.22 amd64 [upgradable from: 1.1.1f-1ubuntu2.19]
pkg-config/focal,now 0.29.1-0ubuntu4 amd64 [installed,automatic]
python3-pip/focal-updates,focal-security 20.0.2-5ubuntu1.10 all [upgradable from: 20.0.2-5ubuntu1.9]

feature request: check dane records against smtp tls cert

As SMTP STARTTLS checks are on the roadmap, and there is infrastructure to query DNS, maybe it makes sense to add the option to validate that the certificate offered in SMTP STARTTLS matches the DANE records to the roadmap as well.

To reduce implementation effort, maybe limit it to the sane subset of DANE, so options 3 / 1 / 1 as advised in https://github.com/internetstandards/toolbox-wiki/blob/main/DANE-for-SMTP-how-to.md#publishing-dane-records

HTTP endpoint and HTTP redir check are vulnerable to Brotli ("zip") bombs if Brotli support is enabled

The recently added HTTP endpoint as well as the HTTP redirection check are vulnerable to the same issue as Trifecta when it comes to accepting crafted requests and responses with a Brotli Content-Encoding, a feature that is enabled by default if simplomon is compiled on a machine that has Brotli headers present.

Again, taking an example file from here and bunzipping it, we have a small Brotli file that uncompresses to a large amount of data. When we send this file, either as part of a request to the status endpoint or as a response to a redir check, simplomon will attempt to allocate enough memory to hold the result, which exceeds the amount of available memory. The exact behavior is somewhat system-dependent, but on my machine this triggers the OOM killer, which then kills the simplomon process.

% /tmp › curl -v -H 'Content-Encoding: br' --data-binary @10GB.html.br http://127.0.0.1:8080/health
*   Trying 127.0.0.1:8080...
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> POST /health HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/8.0.1
> Accept: */*
> Content-Encoding: br
> Content-Length: 27036
> Content-Type: application/x-www-form-urlencoded
> 
* Recv failure: Connection reset by peer
* Closing connection 0
curl: (56) Recv failure: Connection reset by peer

For the redir check, the following configuration allocates 10GB of memory:

httpredir{fromUrl="http://demo.52-7-242-28.nip.io", toUrl="http://example.com/"}

A possible mitigation would be the same as on the Trifecta side, that is, to disable Brotli support entirely. For simplomon, it seems unlikely that either requests or responses would benefit from compression at all.

In general, it might be sensible to document (perhaps in the README) whether it is expected that simplomon instances be available from the internet, and if not, perhaps bind to the loopback interface instead of 0.0.0.0.

netmon.cc doesn't compile on FreeBSD - netinet differences

Compilation fails on FreeBSD in netmon.cc

[1/2] Compiling C++ object simplomon.p/netmon.cc.o
FAILED: simplomon.p/netmon.cc.o 
ccache c++ -Isimplomon.p -I. -I.. -Isubprojects/cpp-httplib-0.13.1 -I../subprojects/cpp-httplib-0.13.1 -Isubprojects/simplesockets -I../subprojects/simplesockets -I/usr/local/include -I/usr/local/include/lua53 -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -std=c++20 -O0 -g -pthread -DCPPHTTPLIB_OPENSSL_SUPPORT -DCPPHTTPLIB_ZLIB_SUPPORT -DCPPHTTPLIB_BROTLI_SUPPORT -MD -MQ simplomon.p/netmon.cc.o -MF simplomon.p/netmon.cc.o.d -o simplomon.p/netmon.cc.o -c ../netmon.cc
In file included from ../netmon.cc:6:
In file included from ../simplomon.hh:6:
In file included from ../notifiers.hh:3:
../sol/sol.hpp:14541:32: warning: unknown warning group '-Wmaybe-uninitialized', ignored [-Wunknown-warning-option]
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
                               ^
../sol/sol.hpp:17294:32: warning: unknown warning group '-Wmaybe-uninitialized', ignored [-Wunknown-warning-option]
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
                               ^
In file included from ../netmon.cc:10:
/usr/include/netinet/ip_icmp.h:110:14: error: field has incomplete type 'struct ip'
                        struct ip idi_ip;
                                  ^
/usr/include/netinet/ip_icmp.h:110:11: note: forward declaration of 'ip'
                        struct ip idi_ip;
                               ^
../netmon.cc:220:11: error: no member named 'type' in 'icmphdr'
    p.hdr.type = ICMP_ECHO;
    ~~~~~ ^
../netmon.cc:221:11: error: no member named 'un' in 'icmphdr'
    p.hdr.un.echo.id = id;
    ~~~~~ ^
../netmon.cc:222:11: error: no member named 'un' in 'icmphdr'
    p.hdr.un.echo.sequence = seq;
    ~~~~~ ^
../netmon.cc:229:11: error: no member named 'checksum' in 'icmphdr'
    p.hdr.checksum = 0;
    ~~~~~ ^
../netmon.cc:230:11: error: no member named 'checksum' in 'icmphdr'
    p.hdr.checksum = internetchecksum(&p, sizeof(p));
    ~~~~~ ^
../netmon.cc:251:73: error: member access into incomplete type 'struct iphdr'
    struct icmphdr* icmp = (struct icmphdr*) ((char*)packet.c_str() + ip->ihl*4);
                                                                        ^
../netmon.cc:250:12: note: forward declaration of 'iphdr'
    struct iphdr *ip = (iphdr*)packet.c_str();
           ^
../netmon.cc:253:16: error: no member named 'un' in 'icmphdr'
    id = icmp->un.echo.id;
         ~~~~  ^
../netmon.cc:254:17: error: no member named 'un' in 'icmphdr'
    seq = icmp->un.echo.sequence;
          ~~~~  ^
../netmon.cc:256:31: error: member access into incomplete type 'struct iphdr'
    payload = packet.substr(ip->ihl*4 + sizeof(icmp));
                              ^
../netmon.cc:250:12: note: forward declaration of 'iphdr'
    struct iphdr *ip = (iphdr*)packet.c_str();
           ^
2 warnings and 10 errors generated.
ninja: build stopped: subcommand failed.

Check disk usage, potentially via SSH?

Hi,

I'm not sure if this falls into an area you would be interested in for simplemon. I recently was looking for a lean way to monitor my SMTP VPS (vCPU, 1GB RAM). I mainly wanted to make sure I dont run out of (very limited) disk space and couldn't find anything really small. I ended up with very slimmed down netdata that is sending the data to another beefier server. But it's still the biggest process on the VPS. I don't need no graphs or CPU usage or whatever else netdata provides, just a notification if the disk space is over 85%.

I think setting up an SSH key and adding the check config should be doable in 5mins, so maybe it's a feature request you might consider. Thanks!

warnings about unused variable during compile

Using build b14b8d4

ninja: Entering directory `/home/roel/tools/simplomon/build'
[1/16] Compiling C++ object simplomon.p/minicurl.cc.o
../minicurl.cc: In member function ‘void MiniCurl::setupURL(const string&, const ComboAddress*, const ComboAddress*)’:
../minicurl.cc:122:9: warning: unused variable ‘ret’ [-Wunused-variable]
  122 |     int ret = curl_easy_setopt(d_curl, CURLOPT_INTERFACE, src->toString().c_str());
      |         ^~~
[5/16] Compiling C++ object testrunner.p/minicurl.cc.o
../minicurl.cc: In member function ‘void MiniCurl::setupURL(const string&, const ComboAddress*, const ComboAddress*)’:
../minicurl.cc:122:9: warning: unused variable ‘ret’ [-Wunused-variable]
  122 |     int ret = curl_easy_setopt(d_curl, CURLOPT_INTERFACE, src->toString().c_str());
      |         ^~~
[16/16] Linking target testrunner

Unexpected response from SMTP server

Simplomon reports the following exception when it attempts to connect to my Postfix mail server:

Got an exception during check: Unexpected response from SMTP server: '503 5.5.1 Error: send HELO/EHLO first

I am willing to provide credentials to a test account if needed for troubleshooting.

Add file test with regexp

I mentioned this recently on the Fediverse, and now as a reminder. What I'd like to see is for simplomon being able to verify whether a particular file is on the file system, and check preferable via a regexp I specify if a string is contained therein.

Regexp check can also be useful on, say, https checks to determine whether a particular string or expression is contained in whatever the check responds with.

extra quote in pushover message

in my configuration I have stated https{url="https://mywebsite.com"}

When I get an alert (with Pushover) I get the alert:

https: [ipv4] Unable to retrieve URL 'https://mywebsite.com': SSL peer certificate or SSH remote key was not OK
In the (iPhone) Pushover app, the URL is a clickable link. When I click that link, the browser tries to open

https://snappass.leeuwen.net'
(including the extra ' at the end), which is not a valid URL.

"identical" alerts should not lead to revoking the old alert

As a simple example, dailyChime issues a new chime every day. This leads to a notification that the old chime is over. And then there is the new one. This is silly. We should have an identifier that says this is still the same alert, and that there is no need to announce that the old one was over.

This could happen with an explicit alert key perhaps.

Doesn't compile on FreeBSD without help (Doctest)

Hello,

I'm trying to get this to compile on FreeBSD (having never used meson/C++/etc before) and have managed to get it to work if I add:

incdir = include_directories('/usr/local/include/doctest')

and modify the testrunner executable() to include the include_directories

executable('testrunner', 'testrunner.cc', 'notifiers.cc', 'minicurl.cc', 'dnsmon.cc', 'record-types.cc', 
              'dnsmessages.cc', 'dns-storage.cc', 'netmon.cc', 'luabridge.cc',
       dependencies: [doctest_dep, curl_dep, json_dep, fmt_dep, cpphttplib, simplesockets_dep,
              lua_dep],
       include_directories: incdir)

Is this something that can be added in a portable way? Maybe something like:

if host_machine.system() in ['freebsd']
  incdir = include_directories('/usr/local/include/doctest')
  executable('testrunner', 'testrunner.cc', 'notifiers.cc', 'minicurl.cc', 'dnsmon.cc', 'record-types.cc', 'dnsmessages.cc', 'dns-storage.cc', 'netmon.cc', 'luabridge.cc',
        dependencies: [doctest_dep, curl_dep, json_dep, fmt_dep, cpphttplib, simplesockets_dep, lua_dep],
        include_directories: incdir)
else
  executable('testrunner', 'testrunner.cc', 'notifiers.cc', 'minicurl.cc', 'dnsmon.cc', 'record-types.cc', 'dnsmessages.cc', 'dns-storage.cc', 'netmon.cc', 'luabridge.cc',
        dependencies: [doctest_dep, curl_dep, json_dep, fmt_dep, cpphttplib, simplesockets_dep, lua_dep])
endif

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.