git: 1693fff35714 - main - devel/cbang: upgrade to 1.7.0

From: Thierry Thomas <thierry_at_FreeBSD.org>
Date: Fri, 30 Sep 2022 15:17:47 UTC
The branch main has been updated by thierry:

URL: https://cgit.FreeBSD.org/ports/commit/?id=1693fff35714540f3ca9a2393efab793e2125f2e

commit 1693fff35714540f3ca9a2393efab793e2125f2e
Author:     Thierry Thomas <thierry@FreeBSD.org>
AuthorDate: 2022-09-30 15:14:35 +0000
Commit:     Thierry Thomas <thierry@FreeBSD.org>
CommitDate: 2022-09-30 15:14:35 +0000

    devel/cbang: upgrade to 1.7.0
    
    This removes our previous patches, but add some new ones related to OpenSSL.
---
 devel/cbang/Makefile                               |   7 +-
 devel/cbang/distinfo                               |   6 +-
 .../cbang/files/patch-config_cbang_____init____.py |  10 -
 .../cbang/files/patch-src_cbang_js_v8_Context.cpp  |  15 -
 .../cbang/files/patch-src_cbang_net_IPAddress.cpp  |  12 -
 devel/cbang/files/patch-src_cbang_net_Swab.h       |  14 -
 devel/cbang/files/patch-src_cbang_openssl_BigNum.h |  10 +
 .../files/patch-src_cbang_openssl_KeyContext.cpp   |  22 ++
 .../files/patch-src_cbang_openssl_KeyPair.cpp      | 142 ++++++++
 .../cbang/files/patch-src_cbang_os_SystemInfo.cpp  |  34 --
 .../files/patch-src_cbang_os_SystemUtilities.cpp   |  11 -
 devel/cbang/files/patch-tests_testHarness          | 374 +--------------------
 devel/cbang/pkg-plist                              |   9 +-
 13 files changed, 191 insertions(+), 475 deletions(-)

diff --git a/devel/cbang/Makefile b/devel/cbang/Makefile
index 854e8d0f4d79..47dde6ce3bdb 100644
--- a/devel/cbang/Makefile
+++ b/devel/cbang/Makefile
@@ -1,6 +1,5 @@
 PORTNAME=	cbang
-PORTVERSION=	1.6.1
-PORTREVISION=	4
+PORTVERSION=	1.7.0
 CATEGORIES=	devel
 
 MAINTAINER=	thierry@FreeBSD.org
@@ -45,7 +44,7 @@ MAKE_ARGS+=	cc="${CC}"	\
 #		disable_local="zlib bzip2 lz4 sqlite3 expat boost libevent re2 libyaml"
 MAKE_ENV+=	LIBPATH="${LIBPATH}"	\
 		LIBRARY_PATH="${LIBPATH}:${LIBPATH}/mysql"
-LIBVER=		1.3.3
+LIBVER=		1.7.0
 PLIST_SUB=	VER=${LIBVER}
 
 TEST_WRKSRC=	${WRKSRC}/tests
@@ -59,6 +58,7 @@ post-install:
 	cd ${STAGEDIR}${PREFIX}/lib &&	\
 		${LN} -sf libcbang0.so.${LIBVER} libcbang0.so	&&	\
 		${LN} -sf libcbang0.so.${LIBVER} libcbang0.so.1
+	${STRIP_CMD} ${STAGEDIR}${PREFIX}/lib/libcbang0.so.${LIBVER}
 	# Needed to build CAMotics
 	${INSTALL_DATA} ${WRKSRC}/include/cbang/config.h	\
 		${STAGEDIR}${PREFIX}/include/cbang/
@@ -66,6 +66,7 @@ post-install:
 		${STAGEDIR}${PREFIX}/lib
 	${MKDIR} ${STAGEDIR}${DATADIR}
 	cd ${WRKSRC} && ${COPYTREE_SHARE} config ${STAGEDIR}${DATADIR}
+	${RM} ${STAGEDIR}${DATADIR}/config/cbang/__init__.py.orig
 
 do-test:
 	(cd ${TEST_WRKSRC} && ${DO_MAKE_TEST} && ./testHarness)
diff --git a/devel/cbang/distinfo b/devel/cbang/distinfo
index f8b754e16ab4..41b6d6c20c4a 100644
--- a/devel/cbang/distinfo
+++ b/devel/cbang/distinfo
@@ -1,3 +1,3 @@
-TIMESTAMP = 1651868853
-SHA256 (CauldronDevelopmentLLC-cbang-1.6.1_GH0.tar.gz) = c59f54cd15fc8aaea09aa6c4a9f69995ed7cbfe179a50a179a162e501516c8a5
-SIZE (CauldronDevelopmentLLC-cbang-1.6.1_GH0.tar.gz) = 4789245
+TIMESTAMP = 1664451834
+SHA256 (CauldronDevelopmentLLC-cbang-1.7.0_GH0.tar.gz) = 2f467928f949e27aa28a4355b9c3019a3b3c727f98e75fee88b5524dfdb7c868
+SIZE (CauldronDevelopmentLLC-cbang-1.7.0_GH0.tar.gz) = 4800847
diff --git a/devel/cbang/files/patch-config_cbang_____init____.py b/devel/cbang/files/patch-config_cbang_____init____.py
deleted file mode 100644
index 1079051ff3cb..000000000000
--- a/devel/cbang/files/patch-config_cbang_____init____.py
+++ /dev/null
@@ -1,10 +0,0 @@
---- config/cbang/__init__.py.orig	2021-08-10 22:46:49 UTC
-+++ config/cbang/__init__.py
-@@ -99,6 +99,7 @@ def configure(conf):
- 
-     conf.CBRequireLib('cbang-boost')
-     conf.CBRequireLib('cbang')
-+    conf.CBRequireLib('sysinfo')
-     conf.CBRequireCXXHeader('cbang/Exception.h')
-     env.CBDefine('HAVE_CBANG')
- 
diff --git a/devel/cbang/files/patch-src_cbang_js_v8_Context.cpp b/devel/cbang/files/patch-src_cbang_js_v8_Context.cpp
deleted file mode 100644
index 01f0bf8823b3..000000000000
--- a/devel/cbang/files/patch-src_cbang_js_v8_Context.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
---- src/cbang/js/v8/Context.cpp.orig	2021-08-10 22:46:49 UTC
-+++ src/cbang/js/v8/Context.cpp
-@@ -50,7 +50,12 @@ Value Context::eval(const InputSource &src) {
-   v8::Local<v8::String> origin;
-   string filename = src.getName();
-   if (!filename.empty()) origin = Value::createString(filename);
-+
-+#if V8_MAJOR_VERSION < 10
-   v8::ScriptOrigin sOrigin(origin);
-+#else
-+  v8::ScriptOrigin sOrigin(Value::getIso(), origin);
-+#endif
- 
-   // Get script source
-   auto source = Value::createString(src.toString());
diff --git a/devel/cbang/files/patch-src_cbang_net_IPAddress.cpp b/devel/cbang/files/patch-src_cbang_net_IPAddress.cpp
deleted file mode 100644
index ab1d9c8d52fb..000000000000
--- a/devel/cbang/files/patch-src_cbang_net_IPAddress.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
---- src/cbang/net/IPAddress.cpp.orig	2021-08-10 22:46:49 UTC
-+++ src/cbang/net/IPAddress.cpp
-@@ -50,6 +50,9 @@
- #else
- #include <sys/types.h>
- #include <sys/socket.h>
-+#  ifdef __FreeBSD__
-+#include <netinet/in.h>
-+#  endif
- #include <netdb.h>
- #endif
- 
diff --git a/devel/cbang/files/patch-src_cbang_net_Swab.h b/devel/cbang/files/patch-src_cbang_net_Swab.h
deleted file mode 100644
index 0c35b3f259de..000000000000
--- a/devel/cbang/files/patch-src_cbang_net_Swab.h
+++ /dev/null
@@ -1,14 +0,0 @@
---- src/cbang/net/Swab.h.orig	2021-08-10 22:46:49 UTC
-+++ src/cbang/net/Swab.h
-@@ -42,7 +42,10 @@
- #elif __APPLE__
- #include <machine/endian.h>
- 
--#else // POSIX systems
-+#elif __FreeBSD__
-+#include <sys/endian.h>
-+
-+#else // other POSIX systems
- #include <endian.h>
- #endif
- 
diff --git a/devel/cbang/files/patch-src_cbang_openssl_BigNum.h b/devel/cbang/files/patch-src_cbang_openssl_BigNum.h
new file mode 100644
index 000000000000..e7667d6a6a34
--- /dev/null
+++ b/devel/cbang/files/patch-src_cbang_openssl_BigNum.h
@@ -0,0 +1,10 @@
+--- src/cbang/openssl/BigNum.h.orig	2022-09-17 22:00:36 UTC
++++ src/cbang/openssl/BigNum.h
+@@ -48,6 +48,7 @@ namespace cb {
+     ~BigNum();
+ 
+     BIGNUM *get() const {return bn;}
++    BIGNUM *adopt() {deallocate = false; return bn;}
+     bool isNull() const {return !bn;}
+     unsigned size() const;
+     std::string toBinString() const;
diff --git a/devel/cbang/files/patch-src_cbang_openssl_KeyContext.cpp b/devel/cbang/files/patch-src_cbang_openssl_KeyContext.cpp
new file mode 100644
index 000000000000..cb151817d4fb
--- /dev/null
+++ b/devel/cbang/files/patch-src_cbang_openssl_KeyContext.cpp
@@ -0,0 +1,22 @@
+--- src/cbang/openssl/KeyContext.cpp.orig	2022-09-17 22:00:36 UTC
++++ src/cbang/openssl/KeyContext.cpp
+@@ -121,8 +121,18 @@ void KeyContext::setRSAPubExp(uint64_t exp) {
+   BigNum num;
+   num.set(exp);
+ 
+-  if (EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, num.get()) <= 0)
++#if OPENSSL_VERSION_NUMBER < 0x3000000fL
++  int ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, num.get());
++#else
++  int ret = EVP_PKEY_CTX_set1_rsa_keygen_pubexp(ctx, num.get());
++#endif
++
++  if (ret <= 0)
+     THROW("Failed to set RSA public exponent: " << SSL::getErrorStr());
++
++#if OPENSSL_VERSION_NUMBER < 0x3000000fL
++  num.adopt(); // Don't deallocate
++#endif
+ }
+ 
+ 
diff --git a/devel/cbang/files/patch-src_cbang_openssl_KeyPair.cpp b/devel/cbang/files/patch-src_cbang_openssl_KeyPair.cpp
new file mode 100644
index 000000000000..3475015186bd
--- /dev/null
+++ b/devel/cbang/files/patch-src_cbang_openssl_KeyPair.cpp
@@ -0,0 +1,142 @@
+--- src/cbang/openssl/KeyPair.cpp.orig	2022-09-17 22:00:36 UTC
++++ src/cbang/openssl/KeyPair.cpp
+@@ -54,7 +54,10 @@
+ #include <openssl/dh.h>
+ #include <openssl/engine.h>
+ #include <openssl/opensslv.h>
++
++#if 0x3000000fL <= OPENSSL_VERSION_NUMBER
+ #include <openssl/core_names.h>
++#endif
+ 
+ #include <string.h>
+ 
+@@ -127,21 +130,44 @@ BigNum KeyPair::getParam(const char *id) const {
+ 
+ 
+ BigNum KeyPair::getParam(const char *id) const {
++#if 0x3000000fL <= OPENSSL_VERSION_NUMBER
+   BIGNUM *param = 0;
+   EVP_PKEY_get_bn_param(key, id, &param);
+   return BigNum(param, true);
++
++#else
++  THROW(__func__ << "() not supported with OpenSSL < v3.0");
++#endif
+ }
+ 
+ 
+ BigNum KeyPair::getRSA_E() const {
+   if (!isRSA()) THROW("Not an RSA key");
++
++#if 0x3000000fL <= OPENSSL_VERSION_NUMBER
+   return getParam(OSSL_PKEY_PARAM_RSA_E);
++
++#else
++  const BIGNUM *e;
++  RSA_get0_key(EVP_PKEY_get0_RSA(key), 0, &e, 0);
++  if (!e) THROW("RSA E not set");
++  return BigNum(e);
++#endif
+ }
+ 
+ 
+ BigNum KeyPair::getRSA_N() const {
+   if (!isRSA()) THROW("Not an RSA key");
++
++#if 0x3000000fL <= OPENSSL_VERSION_NUMBER
+   return getParam(OSSL_PKEY_PARAM_RSA_N);
++
++#else
++  const BIGNUM *n;
++  RSA_get0_key(EVP_PKEY_get0_RSA(key), &n, 0, 0);
++  if (!n) THROW("RSA N not set");
++  return BigNum(n);
++#endif
+ }
+ 
+ 
+@@ -154,14 +180,36 @@ BigNum KeyPair::getPublic() const  {
+   case EVP_PKEY_EC:  return EC_KEY_get0_public_key(key->pkey.ec);
+   }
+ 
+-#else // OPENSSL_VERSION_NUMBER < 0x1010000fL
++#elif OPENSSL_VERSION_NUMBER < 0x3000000fL
++  const BIGNUM *n = 0;
++
+   switch (EVP_PKEY_base_id(key)) {
++  case EVP_PKEY_RSA: RSA_get0_key(EVP_PKEY_get0_RSA(key), 0, &n, 0); return n;
++  case EVP_PKEY_DSA: DSA_get0_key(EVP_PKEY_get0_DSA(key), &n, 0); return n;
++  case EVP_PKEY_DH: DH_get0_key(EVP_PKEY_get0_DH(key), &n, 0); return n;
++  case EVP_PKEY_EC: {
++    const EC_KEY *ec = EVP_PKEY_get0_EC_KEY(key);
++    const EC_POINT *pt = EC_KEY_get0_public_key(ec);
++    const EC_GROUP *group = EC_KEY_get0_group(ec);
++    point_conversion_form_t form = EC_KEY_get_conv_form(ec);
++
++    if (pt && group) {
++      BIGNUM *n = BN_new();
++      EC_POINT_point2bn(group, pt, form, n, 0);
++      return BigNum(n, true);
++    }
++    return n;
++  }
++  }
++
++#else
++  switch (EVP_PKEY_base_id(key)) {
+   case EVP_PKEY_RSA: return getParam(OSSL_PKEY_PARAM_RSA_E);
+   case EVP_PKEY_DSA:
+   case EVP_PKEY_DH:  return getParam(OSSL_PKEY_PARAM_PUB_KEY);
+   case EVP_PKEY_EC:  break; // Cannot get EC pub key as a BigNum
+   }
+-#endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
++#endif
+ 
+   THROW("Invalid key type");
+ }
+@@ -176,14 +224,24 @@ BigNum KeyPair::getPrivate() const {
+   case EVP_PKEY_EC:  return EC_KEY_get0_private_key(key->pkey.ec);
+   }
+ 
+-#else // OPENSSL_VERSION_NUMBER < 0x1010000fL
++#elif OPENSSL_VERSION_NUMBER < 0x3000000fL
++  const BIGNUM *n = 0;
++
+   switch (EVP_PKEY_base_id(key)) {
++  case EVP_PKEY_RSA: RSA_get0_key(EVP_PKEY_get0_RSA(key), 0, 0, &n); return n;
++  case EVP_PKEY_DSA: DSA_get0_key(EVP_PKEY_get0_DSA(key), 0, &n); return n;
++  case EVP_PKEY_DH: DH_get0_key(EVP_PKEY_get0_DH(key), 0, &n); return n;
++  case EVP_PKEY_EC: return EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(key));
++  }
++
++#else
++  switch (EVP_PKEY_base_id(key)) {
+   case EVP_PKEY_RSA: return getParam(OSSL_PKEY_PARAM_RSA_D);
+   case EVP_PKEY_DSA:
+   case EVP_PKEY_DH:
+   case EVP_PKEY_EC:  return getParam(OSSL_PKEY_PARAM_PRIV_KEY);
+   }
+-#endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
++#endif
+ 
+   THROW("Invalid key type");
+ }
+@@ -197,8 +255,15 @@ bool KeyPair::match(const KeyPair &o) const {
+ 
+ 
+ bool KeyPair::match(const KeyPair &o) const {
+-  switch (EVP_PKEY_eq(key, o.key)) {
+-  case 0: case -1: return false;
++#if 0x3000000fL <= OPENSSL_VERSION_NUMBER
++  int ret = EVP_PKEY_eq(key, o.key);
++  if (ret == -1) ret = 0;
++#else
++  int ret = EVP_PKEY_cmp(key, o.key);
++#endif
++
++  switch (ret) {
++  case 0: return false;
+   case 1: return true;
+   default: THROW("Error comparing keys: " << SSL::getErrorStr());
+   }
diff --git a/devel/cbang/files/patch-src_cbang_os_SystemInfo.cpp b/devel/cbang/files/patch-src_cbang_os_SystemInfo.cpp
deleted file mode 100644
index f2519cae29f0..000000000000
--- a/devel/cbang/files/patch-src_cbang_os_SystemInfo.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
---- src/cbang/os/SystemInfo.cpp.orig	2021-08-10 22:46:49 UTC
-+++ src/cbang/os/SystemInfo.cpp
-@@ -64,6 +64,13 @@
- 
- #include "MacOSUtilities.h"
- 
-+#elif defined(__FreeBSD__)
-+#include <sys/sysinfo.h>
-+#include <sys/utsname.h>
-+#include <sys/sysctl.h>
-+#include <sys/ucred.h>
-+#include <unistd.h>
-+
- #else // !_MSC_VER && !__APPLE__
- #include <sys/sysinfo.h>
- #include <sys/utsname.h>
-@@ -90,7 +97,7 @@ uint32_t SystemInfo::getCPUCount() const {
-   GetSystemInfo(&sysinfo);
-   return sysinfo.dwNumberOfProcessors;
- 
--#elif defined(__APPLE__) || defined(__FreeBSD__)
-+#elif defined(__APPLE__)
-   int nm[2];
-   size_t length = 4;
-   uint32_t count;
-@@ -127,7 +134,7 @@ uint64_t SystemInfo::getMemoryInfo(memory_info_t type)
-     return (uint64_t)(info.ullAvailPhys + info.ullAvailPageFile);
-   }
- 
--#elif defined(__APPLE__) || defined(__FreeBSD__)
-+#elif defined(__APPLE__)
-   if (type == MEM_INFO_TOTAL) {
-     int64_t memory;
-     int mib[2];
diff --git a/devel/cbang/files/patch-src_cbang_os_SystemUtilities.cpp b/devel/cbang/files/patch-src_cbang_os_SystemUtilities.cpp
deleted file mode 100644
index 8790b791c73c..000000000000
--- a/devel/cbang/files/patch-src_cbang_os_SystemUtilities.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
---- src/cbang/os/SystemUtilities.cpp.orig	2021-08-10 22:46:49 UTC
-+++ src/cbang/os/SystemUtilities.cpp
-@@ -388,7 +388,7 @@ namespace cb {
-       size_t len = PATH_MAX;
-       path[0] = path[PATH_MAX] = 0;
- 
--      if (sysctl(mib, 4, path, &len, 0, 0) || *path)
-+      if (sysctl(mib, 4, path, &len, NULL, 0))
-         THROW("Failed to get executable path: " <<  SysError());
- 
-       return (char *)path;
diff --git a/devel/cbang/files/patch-tests_testHarness b/devel/cbang/files/patch-tests_testHarness
index 069e90c92696..17321d67b982 100644
--- a/devel/cbang/files/patch-tests_testHarness
+++ b/devel/cbang/files/patch-tests_testHarness
@@ -1,375 +1,9 @@
---- tests/testHarness.orig	2021-08-10 22:46:49 UTC
+--- tests/testHarness.orig	2022-09-17 22:00:36 UTC
 +++ tests/testHarness
-@@ -1,4 +1,4 @@
--#!/usr/bin/env python2
+@@ -1,4 +1,5 @@
+-#!/usr/bin/env python3
 +#! %%PYTHON_CMD%%
++# Note: the following code is not compatible with Python-3.x
  # -*- mode: python -*-
  #
  #  This software is available as Open-Source software under the
-@@ -50,9 +50,14 @@ import sqlite3
- import copy
- import operator
- import json
--from StringIO import StringIO
-+from six import string_types
- 
- try:
-+  from io import StringIO
-+except:
-+  from StringIO import StringIO
-+
-+try:
-   from collections import OrderedDict
- except:
-   def OrderedDict():
-@@ -105,8 +110,8 @@ def bar():
- 
- def labeled_bar(label):
-   length = len(label) + 2
--  width1 = (screen_width - length) / 2
--  width2 = screen_width - length - width1
-+  width1 = int((screen_width - length) / 2)
-+  width2 = int(screen_width - length - width1)
- 
-   str = width1 * '*' + ' ' + label + ' ' + width2 * '*' + '\n'
- 
-@@ -135,7 +140,7 @@ def ensure_parent_dir(file):
- 
- def copy_pattern(pattern, dst, ignores = []):
-   # shutil.ignore_patterns() is only in v2.6
--  ignore = lambda dir, files: filter(lambda f: f in ignores, files)
-+  ignore = lambda dir, files: list(filter(lambda f: f in ignores, files))
- 
-   for path in glob.glob(pattern):
-     dir, file = os.path.split(path)
-@@ -155,7 +160,7 @@ def read_file(path):
-   f = None
- 
-   try:
--    f = open(path, 'r')
-+    f = open(path, 'rt')
-     return f.read()
- 
-   finally:
-@@ -174,7 +179,7 @@ def write_file(path, data):
- 
- 
- def split_cmd_line(cmd):
--  if isinstance(cmd, basestring): return shlex.split(str(cmd))
-+  if isinstance(cmd, string_types): return shlex.split(str(cmd))
-   return cmd
- 
- 
-@@ -207,21 +212,20 @@ def execute_proc(command, timeout, **kwargs):
-       if timeout and timeout < start - time.time():
-         if sys.platform == 'win32': proc.kill()
-         else: os.killpg(proc.pid)
--        raise Exception, 'Timedout'
-+        raise Exception('Timedout')
-       time.sleep(0.1)
- 
-     return proc.returncode
- 
--  except Exception, e:
--    raise Exception, 'Running: ' + ' '.join(command) + \
--        '\nCaused by:' + str(e)
-+  except Exception as e:
-+    raise Exception('Running: ' + ' '.join(command) + '\nCaused by:' + str(e))
- 
- 
- def remove_tree(path):
-   mode = os.stat(path).st_mode
- 
-   if not os.path.islink(path) and os.path.isdir(path):
--    if (mode & 0700) != 0700: os.chmod(path, mode | 0700)
-+    if (mode & 0o0700) != 0o0700: os.chmod(path, mode | 0o0700)
- 
-     for name in os.listdir(path):
-       remove_tree(path + '/' + name)
-@@ -229,8 +233,8 @@ def remove_tree(path):
-     os.rmdir(path)
- 
-   else:
--    if sys.platform == 'win32' and (mode & 0200) != 0200:
--      os.chmod(path, mode | 0200)
-+    if sys.platform == 'win32' and (mode & 0o0200) != 0o0200:
-+      os.chmod(path, mode | 0o0200)
-     os.remove(path)
- 
- 
-@@ -258,13 +262,13 @@ class Logger:
- 
- 
-   def push(self, key):
--    #print 'JSON push(%s)' % key
-+    #print('JSON push(%s)' % key)
-     self.back()[key] = OrderedDict()
-     self.stack.append(self.back()[key])
- 
- 
-   def pop(self, key):
--    #print 'JSON pop(%s)' % key
-+    #print('JSON pop(%s)' % key)
-     self.stack.pop()
- 
- 
-@@ -556,7 +560,7 @@ class ReplaceFilter:
-     if replace is None: replace = ['']
-     if isinstance(replace, list): self.replace = replace
-     else: self.replace = list([replace])
--    self.replace = map(str, self.replace)
-+    self.replace = list(map(str, self.replace))
- 
- 
-   def __call__(self, line):
-@@ -585,10 +589,10 @@ class CheckFile(Check):
-     self.reason = filename
-     self.exists = exists
- 
--    if isinstance(filter, basestring): filter = MatchFilter(filter)
-+    if isinstance(filter, string_types): filter = MatchFilter(filter)
-     if isinstance(filter, (list, tuple)):
-       if not filter[0] in filter_classes:
--        raise 'Invalid filter "%s"' % filter[0]
-+        raise Exception('Invalid filter "%s"' % filter[0])
- 
-       klass = filter_classes[filter[0]]
-       filter = klass(*filter[1:])
-@@ -782,7 +786,7 @@ class CheckFilePattern(CheckFile):
- 
-       return CheckFile.check(self, test)
- 
--    except Exception, e:
-+    except Exception as e:
-       if options.verbose: output_stream.write(str(e))
-       return FAILED
- 
-@@ -810,7 +814,7 @@ class Table:
-     self.number = number
-     self.header = header
- 
--    self.widths = map(lambda x: 0, range(columns))
-+    self.widths = list(map(lambda x: 0, range(columns)))
-     self.rows = []
- 
- 
-@@ -862,8 +866,8 @@ class Table:
- 
-     # Check row width
-     if self.columns != len(row):
--      raise Exception, \
--          'Row has ' + len(row) + ' columns, expected ' + self.columns
-+      raise Exception('Row has ' + len(row) + ' columns, expected ' +
-+                      self.columns)
- 
-     self.rows.append(row)
- 
-@@ -879,8 +883,8 @@ class Table:
- 
- 
-   def bar(self):
--    return self.do_row(map(lambda x: x * self.row_sep, self.widths),
--                       self.corner, self.row_sep)
-+    return self.do_row(list(map(lambda x: x * self.row_sep, self.widths),
-+                            self.corner, self.row_sep))
- 
- 
-   def __str__(self):
-@@ -892,8 +896,8 @@ class Table:
- 
-     first = True
-     for row in self.rows:
--      row = map(lambda cell, width:
--                  cell.center(width, self.padding), row, self.widths)
-+      row = list(map(lambda cell, width:
-+                     cell.center(width, self.padding), row, self.widths))
-       s += self.do_row(row, self.col_sep, self.padding)
-       if self.separate_rows or (self.header and first):
-         s += self.bar()
-@@ -913,8 +917,8 @@ class CheckDB(CheckFile):
-       if col[0] == '"': return col
-       else: return '"%s"' % col
- 
--    if cols is not None: cols = map(quote_column, cols)
--    if orderBy is not None: orderBy = map(quote_column, orderBy)
-+    if cols is not None: cols = list(map(quote_column, cols))
-+    if orderBy is not None: orderBy = list(map(quote_column, orderBy))
- 
-     self.db = db
-     self.sql = sql
-@@ -923,7 +927,7 @@ class CheckDB(CheckFile):
- 
-     if sql is None:
-       if cols is None or table is None:
--        raise Exception, 'Must set either "sql" or "cols" and "table"'
-+        raise Exception('Must set either "sql" or "cols" and "table"')
-       if orderBy is None: orderBy = [cols[0]]
-       self.sql = 'SELECT ' + ', '.join(cols) + ' FROM "' + table + \
-           '" ORDER BY ' + ', '.join(orderBy)
-@@ -931,8 +935,8 @@ class CheckDB(CheckFile):
- 
-   def check(self, test):
-     # Clean up column names
--    header = map(lambda x: x.split()[len(x.split()) - 1], self.cols)
--    header = map(lambda x: x.strip(' "\''), header)
-+    header = list(map(lambda x: x.split()[len(x.split()) - 1], self.cols))
-+    header = list(map(lambda x: x.strip(' "\''), header))
- 
-     table = Table(len(header), 0, separate_rows = False, number = True)
-     table.add_row(header)
-@@ -946,9 +950,9 @@ class CheckDB(CheckFile):
-       conn = sqlite3.connect(db)
-       c = conn.cursor()
-       c.execute(self.sql)
--      for row in c: table.add_row(map(str, row))
-+      for row in c: table.add_row(list(map(str, row)))
-       c.close()
--    except Exception, e: return FAILED
-+    except Exception as e: return FAILED
- 
-     # Write
-     write_file(self.get_output(test),
-@@ -1027,7 +1031,7 @@ class Unit:
-       if os.path.exists(path):
-         self.config.update(json.loads(read_file(path)))
- 
--    except Exception, e:
-+    except Exception as e:
-       raise HarnessError('Failed to parse test.json file in %s: %s' % (
-          self.get_full_name(), e))
- 
-@@ -1041,12 +1045,13 @@ class Unit:
-       for check in checks:
-         if isinstance(check, Check): self.check.add(check)
-         else:
--          if isinstance(check, basestring):
-+          if isinstance(check, string_types):
-             check = [check]
- 
-           if isinstance(check, (list, tuple)) and len(check):
-             if not check[0] in check_classes:
--              raise 'Invalid check "%s" in %s' % (check[0], self.name)
-+              raise Exception('Invalid check "%s" in %s' %
-+                              (check[0], self.name))
- 
-             klass = check_classes[check[0]]
-             self.check.add(klass(*check[1:]))
-@@ -1064,11 +1069,11 @@ class Unit:
- 
-   def config_get_list(self, name, default = None, split = str.split):
-     value = self.config.get(name, default)
--    if isinstance(value, basestring): value = split(value)
-+    if isinstance(value, string_types): value = split(value)
- 
-     try:
--      return map(lambda item: item % self.config, value)
--    except Exception, e:
-+      return list(map(lambda item: item % self.config, value))
-+    except Exception as e:
-       raise HarnessError('Error resolving %s "%s": %s' % (name, value, e))
- 
- 
-@@ -1141,11 +1146,11 @@ class Unit:
-   def get_stdin_file(self):
-     stdin = self.config.get('stdin', None)
- 
--    if isinstance(stdin, basestring): return StringIO(stdin)
-+    if isinstance(stdin, string_types): return StringIO(stdin)
- 
-     if stdin is None and 'stdin_file' in self.config:
-       path = self.config_get('stdin_file')
--      if os.path.exists(path): return open(path, 'r')
-+      if os.path.exists(path): return open(path, 'rb')
- 
-     return stdin
- 
-@@ -1170,8 +1175,8 @@ class Unit:
- 
-     # Resolve command vars refs
-     try:
--      command = map(lambda s: s % self.config, command)
--    except Exception, e:
-+      command = list(map(lambda s: s % self.config, command))
-+    except Exception as e:
-       raise HarnessError('Error resolving command "%s": %s' % (command, e))
- 
-     return command
-@@ -1245,7 +1250,7 @@ class Unit:
-       self.status = self.check.check(self)
- 
-       # Check status
--      if self.status is None: raise Exception, 'Test result not set'
-+      if self.status is None: raise Exception('Test result not set')
-       self.reason = self.check.reason
- 
-     # Logging
-@@ -1343,12 +1348,12 @@ class Test(Unit):
- 
-   def initialize(self):
-     if self.units is None: Unit.initialize(self)
--    else: map(Unit.initialize, self.units)
-+    else: list(map(Unit.initialize, self.units))
- 
- 
-   def reset(self):
-     if self.units is None: Unit.reset(self)
--    else: map(Unit.reset, self.units)
-+    else: list(map(Unit.reset, self.units))
- 
- 
-   def view(self):
-@@ -1455,7 +1460,7 @@ class TestSuite:
-     if os.path.exists(path):
-       try:
-         self.config.update(json.loads(read_file(path)))
--      except Exception, e:
-+      except Exception as e:
-         raise HarnessError('Failed to parse suite test.json: ' + str(e))
- 
-       if 'command' in self.config:
-@@ -1575,8 +1580,8 @@ class TestSuite:
-       env.update(globals())
- 
-       try: execfile(script, env)
--      except Exception, e:
--        raise Exception, 'Exception in "%s": %s' % (script, str(e))
-+      except Exception as e:
-+        raise Exception('Exception in "%s": %s' % (script, str(e)))
- 
-       if not 'Suite' in env:
-         raise HarnessError(
-@@ -1655,7 +1660,7 @@ class TestSuite:
-     errStr = "'%s' not found and variable '%s' not set" % (name, conf_name)
-     if home_var is not None and home_var in os.environ:
-       errStr += ' and ' + home_var + '=' + os.environ[home_var]
--    raise Exception, errStr
-+    raise Exception(errStr)
- 
- 
- class TestResults:
-@@ -1893,7 +1898,7 @@ options, args = parser.parse_args()
- # Change dir
- if options.chdir is not None:
-   os.chdir(options.chdir)
--  if options.verbose: print "Changed directory: " + os.getcwd()
-+  if options.verbose: print("Changed directory: " + os.getcwd())
- 
- # Load config file
- if options.config is not None: config_file = options.config
-@@ -1925,14 +1930,14 @@ if options.valgrind:
- 
- if options.dump_config:
-   for name, value in config.items():
--    print "%s=%s" % (name, value)
-+    print("%s=%s" % (name, value))
-   sys.exit(0)
- 
- # Run
- try:
-   sys.exit(TestHarness(config).run(cmd_args))
- 
--except HarnessError, e:
-+except HarnessError as e:
-   sys.stdout.flush()
-   if e.show_usage: parser.error(e.msg)
-   else: sys.stderr.write('ERROR: ' + e.msg + '\n')
diff --git a/devel/cbang/pkg-plist b/devel/cbang/pkg-plist
index f6ee3399e15b..e4fa6680bea5 100644
--- a/devel/cbang/pkg-plist
+++ b/devel/cbang/pkg-plist
@@ -248,13 +248,16 @@ include/cbang/openssl/KeyGenCallback.h
 include/cbang/openssl/KeyGenPacifier.h
 include/cbang/openssl/KeyPair.h
 include/cbang/openssl/PasswordCallback.h
-include/cbang/openssl/RSA.h
 include/cbang/openssl/Revoked.h
 include/cbang/openssl/SSL.h
 include/cbang/openssl/SSLContext.h
 include/cbang/openssl/SecurityUtilities.h
 include/cbang/openssl/XORStreamFilter.h
-include/cbang/os/CPUID.h
+include/cbang/os/CPUInfo.h
+include/cbang/os/CPUInfoAArch64.h
+include/cbang/os/CPUInfoX86.h
+include/cbang/os/CPURegsAArch64.h
+include/cbang/os/CPURegsX86.h
 include/cbang/os/Condition.h
 include/cbang/os/Directory.h
 include/cbang/os/DirectoryWalker.h
@@ -343,6 +346,7 @@ include/cbang/util/Boolean.h
 include/cbang/util/CompilerInfo.h
 include/cbang/util/Features.h
 include/cbang/util/FormatCheck.h
+include/cbang/util/Hex.h
 include/cbang/util/HexString.h
 include/cbang/util/HumanNumber.h
 include/cbang/util/HumanSize.h
@@ -409,7 +413,6 @@ lib/libcbang0.so.%%VER%%
 %%DATADIR%%/config/bzip2/__init__.py
 %%DATADIR%%/config/bzip2/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
 %%DATADIR%%/config/cbang/__init__.py
-%%DATADIR%%/config/cbang/__init__.py.orig
 %%DATADIR%%/config/cbang/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc
 %%DATADIR%%/config/chakra/__init__.py
 %%DATADIR%%/config/chakra/__pycache__/__init__%%PYTHON_EXT_SUFFIX%%.pyc