1 /*
2  * Copyright the NTPsec project contributors
3  * SPDX-License-Identifier: BSD-2-Clause
4  *
5  * Python binding for selected libntp library functions
6  */
7 
8 /* This include has to come early or we get warnings from redefining
9  * _POSIX_C_SOURCE and _XOPEN_SOURCE on some systems.
10  */
11 #include "config.h"
12 
13 #include "ntp_machine.h"
14 #include "ntpd.h"
15 #include "ntp_io.h"
16 #include "ntp_fp.h"
17 #include "ntp_stdlib.h"
18 #include "ntp_syslog.h"
19 #include "timespecops.h"
20 
21 #include "ntp_config.h"
22 #include "ntp_assert.h"
23 
24 #include "ntp_control.h"
25 
26 #include "pymodule-mac.h"
27 
28 void ntpc_setprogname(char*);
29 char *ntpc_prettydate(char*);
30 double ntpc_lfptofloat(char*);
31 int ntpc_set_tod(int, int);
32 bool ntpc_adj_systime(double);
33 bool ntpc_step_systime(double);
34 
35 /* Don't include anything from OpenSSL */
36 
37 const char *version = NTPSEC_VERSION_EXTENDED;
38 const char *progname = "libntpc";
39 int   SYS_TYPE = TYPE_SYS;
40 int  PEER_TYPE = TYPE_PEER;
41 int CLOCK_TYPE = TYPE_CLOCK;
42 
43 /*
44  * Client utility functions
45  */
46 
47 void
ntpc_setprogname(char * s)48 ntpc_setprogname(char *s)
49 {
50 	/*
51 	 * This function is only called from clients.  Therefore
52 	 * log to stderr rather than syslog, and suppress logfile
53 	 * impediments.  If we ever want finer-grained control, that
54 	 * will be easily implemented with additional arguments.
55 	 */
56 	syslogit = false;	/* don't log messages to syslog */
57 	termlogit = true;	/* duplicate to stdout/err */
58 	termlogit_pid = false;
59 	msyslog_include_timestamp = false;
60 	progname = strdup(s);
61 }
62 
63 char *
ntpc_prettydate(char * s)64 ntpc_prettydate(char *s)
65 {
66 	l_fp ts;
67 
68 	if (false == hextolfp(s+2, &ts)) {
69 		errno = EINVAL;
70 		return strdup("ERROR");
71 	}
72 	errno = 0;
73 	return prettydate(ts);
74 }
75 
76 double
ntpc_lfptofloat(char * s)77 ntpc_lfptofloat(char *s)
78 {
79 	l_fp ts;
80 	struct timespec tt;
81 
82 	if (false == hextolfp(s+2, &ts)) {
83 		errno = EINVAL;
84 		return -0;
85 	}
86 	errno = 0;
87 	tt = lfp_stamp_to_tspec(ts, time(NULL));
88 	return tt.tv_sec + (tt.tv_nsec * S_PER_NS);
89 }
90 
91 int
ntpc_set_tod(int seconds,int fractional)92 ntpc_set_tod(int seconds, int fractional)
93 {
94 	struct timespec ts;
95 	ts.tv_sec = seconds;
96 	ts.tv_nsec = fractional;
97 
98 	return ntp_set_tod(&ts);
99 }
100 
101 bool
ntpc_adj_systime(double adjustment)102 ntpc_adj_systime(double adjustment)
103 {
104 	return adj_systime(adjustment, adjtime) ? 1 : 0;
105 }
106 
107 bool
ntpc_step_systime(double adjustment)108 ntpc_step_systime(double adjustment)
109 {
110 	doubletime_t full_adjustment;
111 
112 	/*
113 	 * What we really want is for Python to parse a long double.
114 	 * As this is, it's a potential source of problems in the Python
115 	 * utilities if and when the time difference between the Unix epoch
116 	 * and now exceeds the range of a double.
117 	 */
118 	full_adjustment = adjustment;
119 	return step_systime(full_adjustment, ntp_set_tod);
120 }
121