[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