text: // Copyright (c) 2017, The myobcoin Project
  // 
  // All rights reserved.
  // 
  // Redistribution and use in source and binary forms, with or without modification, are
  // permitted provided that the following conditions are met:
  // 
  // 1. Redistributions of source code must retain the above copyright notice, this list of
  //    conditions and the following disclaimer.
  // 
  // 2. Redistributions in binary form must reproduce the above copyright notice, this list
  //    of conditions and the following disclaimer in the documentation and/or other
  //    materials provided with the distribution.
  // 
  // 3. Neither the name of the copyright holder nor the names of its contributors may be
  //    used to endorse or promote products derived from this software without specific
  //    prior written permission.
  // 
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  #include "misc_log_ex.h"
  #include "util.h"
  #include "dns_utils.h"
  #include "updates.h"
  
  #undef myobcoin_DEFAULT_LOG_CATEGORY
  #define myobcoin_DEFAULT_LOG_CATEGORY "updates"
  
  namespace tools
  {
    bool check_updates(const std::string &software, const std::string &buildtag, std::string &version, std::string &hash)
    {
      std::vector<std::string> records;
      bool found = false;
  
      MDEBUG("Checking updates for " << buildtag << " " << software);
  
      // All four myobcoinPulse domains have DNSSEC on and valid
      static const std::vector<std::string> dns_urls = {
          "updates.myobcoinpulse.org",
          "updates.myobcoinpulse.net",
          "updates.myobcoinpulse.co",
          "updates.myobcoinpulse.se"
      };
  
      if (!tools::dns_utils::load_txt_records_from_dns(records, dns_urls))
        return false;
  
      for (const auto& record : records)
      {
        std::vector<std::string> fields;
        boost::split(fields, record, boost::is_any_of(":"));
        if (fields.size() != 4)
        {
          MWARNING("Updates record does not have 4 fields: " << record);
          continue;
        }
  
        if (software != fields[0] || buildtag != fields[1])
          continue;
  
        bool alnum = true;
        for (auto c: hash)
          if (!isalnum(c))
            alnum = false;
        if (hash.size() != 64 && !alnum)
        {
          MWARNING("Invalid hash: " << hash);
          continue;
        }
  
        // use highest version
        if (found)
        {
          int cmp = vercmp(version.c_str(), fields[2].c_str());
          if (cmp > 0)
            continue;
          if (cmp == 0 && hash != fields[3])
            MWARNING("Two matches found for " << software << " version " << version << " on " << buildtag);
        }
  
        version = fields[2];
        hash = fields[3];
  
        MINFO("Found new version " << version << " with hash " << hash);
        found = true;
      }
      return found;
    }
  
    std::string get_update_url(const std::string &software, const std::string &subdir, const std::string &buildtag, const std::string &version, bool user)
    {
      const char *base = user ? "https://downloads.getmyobcoin.org/" : "http://updates.getmyobcoin.org/";
  #ifdef _WIN32
      static const char extension[] = ".zip";
  #else
      static const char extension[] = ".tar.bz2";
  #endif
  
      std::string url;
  
      url =  base;
      if (!subdir.empty())
        url += subdir + "/";
      url = url + software + "-" + buildtag + "-v" + version + extension;
      return url;
    }
  }
  