[Git][NTPsec/ntpsec][ntpc] 6 commits: INSTALL: Improve the Python 3 notes

James Browning gitlab at mg.gitlab.com
Fri Sep 11 04:46:02 UTC 2020



James Browning pushed to branch ntpc at NTPsec / ntpsec


Commits:
6b2491a8 by Richard Laager at 2020-09-07T19:15:36-05:00
INSTALL: Improve the Python 3 notes

- - - - -
ee3e2f8b by James Browning at 2020-09-10T21:45:19-07:00
build, pylib: ntpc... some singing/dancing


- - - - -
70f0be40 by James Browning at 2020-09-10T21:45:19-07:00
ntpc, ffi: Do _not_ rebuild on install. Doh.

- - - - -
15d473fd by James Browning at 2020-09-10T21:45:19-07:00
Feed it to the garbage smasher. -r2

- - - - -
3afdae44 by James Browning at 2020-09-10T21:45:19-07:00
FFI: Find that vnum sets the version backward in build and right installed

- - - - -
29fa43c9 by James Browning at 2020-09-10T21:45:19-07:00
ntp.ntpc: Change importado docstring to hopefully conform. -r4


- - - - -


6 changed files:

- INSTALL.adoc
- + libntp/ntp_c.c
- libntp/wscript
- + pylib/ntpc.py
- pylib/wscript
- wscript


Changes:

=====================================
INSTALL.adoc
=====================================
@@ -49,10 +49,9 @@ different packages depending on whether your base Python version is
 Python 2.x, x >= 6, or Python 3.x, x >= 3::
    Required to build, and for various scripts such as ntpviz (but see
    the guidance for packagers in devel/packaging.adoc).  Our Python code
-   has been written polyglot to also run with production versions of
-   Python 3.  Note that you will need both the ordinary Python
-   installation and Python dev tools, if your OS makes such a
-   distinction.
+   has been written polyglot to run with either Python 2 or Python 3.
+   Note that you will need both the ordinary Python installation and
+   Python dev tools, if your OS makes such a distinction.
 
    Some OS distros won't find our installed python libraries.
    More info in README-PYTHON.
@@ -65,9 +64,9 @@ psutil::
    Optional for ntpviz.  Allows running with ionice()
    Debian: python-psutil or python3-psutil
    Ubuntu: python-psutil or python3-psutil
-   Fedora/CentOS: python-psutil
+   Fedora/CentOS: python-psutil or python3-psutil
    Gentoo: dev-python/psutil
-   SLES: python-psutil
+   SLES: python-psutil or python3-psutil
 
 sys/timepps.h::
    If you are building to supply Stratum 1 time service (that is, with


=====================================
libntp/ntp_c.c
=====================================
@@ -0,0 +1,119 @@
+/*
+ * Copyright the NTPsec project contributors
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Python binding for selected libntp library functions
+ */
+
+/* This include has to come early or we get warnings from redefining
+ * _POSIX_C_SOURCE and _XOPEN_SOURCE on some systems.
+ */
+#include "config.h"
+
+#include "ntp_machine.h"
+#include "ntpd.h"
+#include "ntp_io.h"
+#include "ntp_fp.h"
+#include "ntp_stdlib.h"
+#include "ntp_syslog.h"
+#include "timespecops.h"
+
+#include "ntp_config.h"
+#include "ntp_assert.h"
+
+#include "ntp_control.h"
+
+#include "pymodule-mac.h"
+
+void ntpc_setprogname(char*);
+char *ntpc_prettydate(char*);
+double ntpc_lfptofloat(char*);
+int ntpc_set_tod(int, int);
+bool ntpc_adj_systime(double);
+bool ntpc_step_systime(double);
+
+/* Don't include anything from OpenSSL */
+
+const char *progname = "libntpc";
+int   SYS_TYPE = TYPE_SYS;
+int  PEER_TYPE = TYPE_PEER;
+int CLOCK_TYPE = TYPE_CLOCK;
+
+/*
+ * Client utility functions
+ */
+
+void
+ntpc_setprogname(char *s)
+{
+	/*
+	 * This function is only called from clients.  Therefore
+	 * log to stderr rather than syslog, and suppress logfile
+	 * impediments.  If we ever want finer-grained control, that
+	 * will be easily implemented with additional arguments.
+	 */
+	syslogit = false;	/* don't log messages to syslog */
+	termlogit = true;	/* duplicate to stdout/err */
+	termlogit_pid = false;
+	msyslog_include_timestamp = false;
+	progname = strdup(s);
+}
+
+char *
+ntpc_prettydate(char *s)
+{
+	l_fp ts;
+
+	if (false == hextolfp(s+2, &ts)) {
+		errno = EINVAL;
+		return strdup("ERROR");
+	}
+	errno = 0;
+	return prettydate(ts);
+}
+
+double
+ntpc_lfptofloat(char *s)
+{
+	l_fp ts;
+	struct timespec tt;
+
+	if (false == hextolfp(s+2, &ts)) {
+		errno = EINVAL;
+		return -0;
+	}
+	errno = 0;
+	tt = lfp_stamp_to_tspec(ts, time(NULL));
+	return tt.tv_sec + (tt.tv_nsec * S_PER_NS);
+}
+
+int
+ntpc_set_tod(int seconds, int fractional)
+{
+	struct timespec ts;
+	ts.tv_sec = seconds;
+	ts.tv_nsec = fractional;
+
+	return ntp_set_tod(&ts);
+}
+
+bool
+ntpc_adj_systime(double adjustment)
+{
+	return adj_systime(adjustment, adjtime) ? 1 : 0;
+}
+
+bool
+ntpc_step_systime(double adjustment)
+{
+	doubletime_t full_adjustment;
+
+	/*
+	 * What we really want is for Python to parse a long double.
+	 * As this is, it's a potential source of problems in the Python
+	 * utilities if and when the time difference between the Unix epoch
+	 * and now exceeds the range of a double.
+	 */
+	full_adjustment = adjustment;
+	return step_systime(full_adjustment, ntp_set_tod);
+}


=====================================
libntp/wscript
=====================================
@@ -1,3 +1,5 @@
+import os
+
 def build(ctx):
 
     libntp_source = [
@@ -47,6 +49,20 @@ def build(ctx):
         use="CRYPTO SSL",
     )
 
+    if ctx.env['ntpc'] == 'ffi':
+        # Loadable FFI stub
+        ctx(
+            features="c cshlib",
+            install_path='${LIBDIR}/ntp',
+            includes=[ctx.bldnode.parent.abspath(), "../include"],
+            source=["ntp_c.c", "pymodule-mac.c"] + libntp_source_sharable,
+            target="../pylib/ntpc",  # Put the output in the pylib directory
+            use="M RT CRYPTO",
+            vnum=ctx.env['ntpcver'],
+        )
+        return
+    elif ctx.env['ntpc'] != 'ext':
+        return
     # Loadable Python extension
     ctx(
         features="c cshlib pyext",


=====================================
pylib/ntpc.py
=====================================
@@ -0,0 +1,146 @@
+# -*- coding: utf-8 -*-
+# SPDX-License-Identifier: BSD-2-Clause
+"""Access libntp funtions from Python."""
+from __future__ import absolute_import
+import ctypes
+import ctypes.util
+import errno
+import os
+import os.path
+import ntp.poly
+
+LIB = 'ntpc'
+
+
+def importado():
+    """Load the ntpc library or raise OSError trying."""
+    ntpc_paths = []         # places to look
+
+    j = __file__.split(os.sep)[:-1]
+    for i in ['lib%s.so', 'lib%s.dylib', '%s.dll']:
+        _ = os.sep.join(j + [i % LIB])
+        # print(_)
+        ntpc_paths.append(_)
+
+    ntpc_path = ctypes.util.find_library(LIB)
+    if ntpc_path:
+        ntpc_paths.append(ntpc_path)
+
+    for ntpc_path in ntpc_paths:
+        try:
+            lib = ctypes.CDLL(ntpc_path, use_errno=True)
+            return lib
+        except OSError:
+            pass
+
+    raise OSError("Can't find %s library" % LIB)
+
+
+_ntpc = importado()
+progname = ctypes.c_char_p.in_dll(_ntpc, 'progname')
+# log_sys = ctypes.c_bool.in_dll(_ntpc, 'syslogit')
+# log_term = ctypes.c_bool.in_dll(_ntpc, 'termlogit')
+# log_pid = ctypes.c_bool.in_dll(_ntpc, 'termlogit_pid')
+# log_time = ctypes.c_bool.in_dll(_ntpc, 'msyslog_include_timestamp')
+
+TYPE_SYS = ctypes.c_int.in_dll(_ntpc, 'SYS_TYPE').value
+TYPE_PEER = ctypes.c_int.in_dll(_ntpc, 'PEER_TYPE').value
+TYPE_CLOCK = ctypes.c_int.in_dll(_ntpc, 'CLOCK_TYPE').value
+
+
+def checkname(name):
+    """Check if name is a valid algorithm name."""
+    _ntpc.do_checkname.restype = ctypes.c_int
+    mid_bytes = ntp.poly.polybytes(name)
+    _ntpc.do_checkname.argtypes = [ctypes.c_char_p]
+    return _ntpc.do_checkname(mid_bytes)
+
+
+def mac(data, key, name):
+    """Compute HMAC or CMAC from data, key, and algorithm name."""
+    resultlen = ctypes.c_size_t()
+    result = (ctypes.c_char * 64)()
+    result.value = b'\0' * 64
+    _ntpc.do_mac.restype = None
+    _ntpc.do_mac(ntp.poly.polybytes(name),
+                 ntp.poly.polybytes(data), len(data),
+                 ntp.poly.polybytes(key), len(key),
+                 ctypes.byref(result), ctypes.byref(resultlen))
+    return result.value
+
+
+def setprogname(in_string):
+    """Set program name for logging purposes."""
+    mid_bytes = ntp.poly.polybytes(in_string)
+    _setprogname(mid_bytes)
+
+
+def _lfp_wrap(callback, in_string):
+    """NTP l_fp to other Python-style format."""
+    mid_bytes = ntp.poly.polybytes(in_string)
+    out_value = callback(mid_bytes)
+    err = ctypes.get_errno()
+    if err == errno.EINVAL:
+        raise ValueError('ill-formed hex date')
+    return out_value
+
+
+def statustoa(i_type, i_st):
+    """Convert a time stamp to something readable."""
+    mid_str = _statustoa(i_type, i_st)
+    return ntp.poly.polystr(mid_str)
+
+
+def prettydate(in_string):
+    """Convert a time stamp to something readable."""
+    mid_str = _lfp_wrap(_prettydate, in_string)
+    return ntp.poly.polystr(mid_str)
+
+
+def lfptofloat(in_string):
+    """NTP l_fp to Python-style float time."""
+    return _lfp_wrap(_lfptofloat, in_string)
+
+
+def msyslog(level, in_string):
+    """Log send a message to terminal or output."""
+    mid_bytes = ntp.poly.polybytes(in_string)
+    _msyslog(level, mid_bytes)
+
+
+# Set return type and argument types of hidden ffi handlers
+_msyslog = _ntpc.msyslog
+_msyslog.restype = None
+_msyslog.argtypes = [ctypes.c_int, ctypes.c_char_p]
+
+_setprogname = _ntpc.ntpc_setprogname
+_setprogname.restype = None
+_setprogname.argtypes = [ctypes.c_char_p]
+
+_prettydate = _ntpc.ntpc_prettydate
+_prettydate.restype = ctypes.c_char_p
+_prettydate.argtypes = [ctypes.c_char_p]
+
+_lfptofloat = _ntpc.ntpc_lfptofloat
+_lfptofloat.restype = ctypes.c_double
+_lfptofloat.argtypes = [ctypes.c_char_p]
+
+# Status string display from peer status word.
+_statustoa = _ntpc.statustoa
+_statustoa.restype = ctypes.c_char_p
+_statustoa.argtypes = [ctypes.c_int, ctypes.c_int]
+
+# Set time to nanosecond precision.
+set_tod = _ntpc.ntpc_set_tod
+set_tod.restype = ctypes.c_int
+set_tod.argtypes = [ctypes.c_int, ctypes.c_int]
+
+# Adjust system time by slewing.
+adj_systime = _ntpc.ntpc_adj_systime
+adj_systime.restype = ctypes.c_bool
+adj_systime.argtypes = [ctypes.c_double]
+
+# Adjust system time by stepping.
+step_systime = _ntpc.ntpc_step_systime
+step_systime.restype = ctypes.c_bool
+step_systime.argtypes = [ctypes.c_double]


=====================================
pylib/wscript
=====================================
@@ -35,8 +35,21 @@ def build(ctx):
     bldnode = ctx.bldnode.make_node('pylib')
     target1 = bldnode.make_node('control.py')
     target2 = bldnode.make_node('magic.py')
+    
+    bldnode.mkdir()
 
-    sources = srcnode.ant_glob('*.py')
+    if ctx.cmd not in ('install'):
+        ctx.add_group()
+        target3 = bldnode.ant_glob('*ntpc*')
+        for _ in target3:
+            ctx.exec_command("rm -f %s" % _.abspath())
+        ctx.add_group()
+
+    sources = []
+    if ctx.env['ntpc'] == 'ext':
+        sources = srcnode.ant_glob("*.py", excl='ntpc.py')
+    elif ctx.env['ntpc'] == 'ffi':
+        sources = srcnode.ant_glob('*.py')
     builds = [x.get_bld() for x in sources]
 
     # The rm's here were added to fix a reported (but underdocumented) problem
@@ -52,6 +65,9 @@ def build(ctx):
     #ctx.exec_command("rm -f %s" % target1.abspath())
     #ctx.exec_command("rm -f %s" % target2.abspath())
 
+    if ctx.env['ntpc'] is None:
+        return
+        
     # Make sure Python sees .py as well as .pyc/.pyo
     ctx(
         features="subst",


=====================================
wscript
=====================================
@@ -119,6 +119,9 @@ def configure(ctx):
             opt = flag.replace("--", "").upper()
             opt_map[opt] = ctx.env.OPT_STORE[flag]
 
+    ctx.env['ntpc'] = 'ffi'
+    ctx.env['ntpcver'] = '1.1.0'
+
     msg("--- Configuring host ---")
     ctx.setenv('host', ctx.env.derive())
 
@@ -1009,6 +1012,7 @@ def build(ctx):
         ctx.recurse("ntpd")
         return
 
+    ctx.recurse("pylib")
     if ctx.env.REFCLOCK_GENERIC or ctx.env.REFCLOCK_TRIMBLE:
         # required by the generic and Trimble refclocks
         ctx.recurse("libparse")
@@ -1017,7 +1021,6 @@ def build(ctx):
     ctx.recurse("ntpd")
     ctx.recurse("ntpfrob")
     ctx.recurse("ntptime")
-    ctx.recurse("pylib")
     ctx.recurse("attic")
     ctx.recurse("etc")
     ctx.recurse("tests")



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/212f92912460c0fde66c41bd62191a19c0ebbe54...29fa43c907e519ae42a4f0cc8d1f014fe460ecfe

-- 
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/-/compare/212f92912460c0fde66c41bd62191a19c0ebbe54...29fa43c907e519ae42a4f0cc8d1f014fe460ecfe
You're receiving this email because of your account on gitlab.com.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20200911/4f9ab4f4/attachment-0001.htm>


More information about the vc mailing list