diff --git a/python/pyglue.c b/python/pyglue.c index 156eaf73150..ed79df10be2 100644 --- a/python/pyglue.c +++ b/python/pyglue.c @@ -134,6 +134,49 @@ static PyObject *py_nttime2unix(PyObject *self, PyObject *args) return PyLong_FromLong((uint64_t)t); } +static PyObject *py_float2nttime(PyObject *self, PyObject *args) +{ + double ft = 0; + double ft_sec = 0; + double ft_nsec = 0; + struct timespec ts; + NTTIME nt = 0; + + if (!PyArg_ParseTuple(args, "d", &ft)) { + return NULL; + } + + ft_sec = (double)(int)ft; + ft_nsec = (ft - ft_sec) * 1.0e+9; + + ts.tv_sec = (int)ft_sec; + ts.tv_nsec = (int)ft_nsec; + + nt = full_timespec_to_nt_time(&ts); + + return PyLong_FromLongLong((uint64_t)nt); +} + +static PyObject *py_nttime2float(PyObject *self, PyObject *args) +{ + double ft = 0; + struct timespec ts; + const struct timespec ts_zero = { .tv_sec = 0, }; + NTTIME nt = 0; + + if (!PyArg_ParseTuple(args, "K", &nt)) { + return NULL; + } + + ts = nt_time_to_full_timespec(nt); + if (is_omit_timespec(&ts)) { + return PyFloat_FromDouble(1.0); + } + ft = timespec_elapsed2(&ts_zero, &ts); + + return PyFloat_FromDouble(ft); +} + static PyObject *py_nttime2string(PyObject *self, PyObject *args) { PyObject *ret; @@ -374,6 +417,10 @@ static PyMethodDef py_misc_methods[] = { "unix2nttime(timestamp) -> nttime" }, { "nttime2unix", (PyCFunction)py_nttime2unix, METH_VARARGS, "nttime2unix(nttime) -> timestamp" }, + { "float2nttime", (PyCFunction)py_float2nttime, METH_VARARGS, + "pytime2nttime(floattimestamp) -> nttime" }, + { "nttime2float", (PyCFunction)py_nttime2float, METH_VARARGS, + "nttime2pytime(nttime) -> floattimestamp" }, { "nttime2string", (PyCFunction)py_nttime2string, METH_VARARGS, "nttime2string(nttime) -> string" }, { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS, diff --git a/python/samba/__init__.py b/python/samba/__init__.py index fa047a813e2..cabae4eaf1f 100644 --- a/python/samba/__init__.py +++ b/python/samba/__init__.py @@ -368,6 +368,8 @@ fault_setup = _glue.fault_setup set_debug_level = _glue.set_debug_level get_debug_level = _glue.get_debug_level unix2nttime = _glue.unix2nttime +float2nttime = _glue.float2nttime +nttime2float = _glue.nttime2float nttime2string = _glue.nttime2string nttime2unix = _glue.nttime2unix unix2nttime = _glue.unix2nttime diff --git a/python/samba/tests/glue.py b/python/samba/tests/glue.py index 5f112f00ba0..e5d76c5a02a 100644 --- a/python/samba/tests/glue.py +++ b/python/samba/tests/glue.py @@ -43,6 +43,25 @@ class GlueTests(samba.tests.TestCase): def test_nttime2unix(self): self.assertEqual(_glue.nttime2unix(116444736010000000), 1) + def test_float2nttime(self): + self.assertEqual(_glue.float2nttime(1.0), 116444736010000000) + self.assertEqual(_glue.float2nttime(1611058908.0), 132555325080000000) + # NTTIME has a resolution of 100ns + self.assertEqual(_glue.float2nttime(1611058908.1234567), 132555325081234567) + self.assertEqual(_glue.float2nttime(1611058908.123456789), 132555325081234567) + + def test_nttime2float(self): + self.assertEqual(_glue.nttime2float(1), -11644473600.0) + self.assertEqual(_glue.nttime2float(0x7fffffffffffffff), 910692730085.4775) + self.assertEqual(_glue.nttime2float(0x8000000000000000), 910692730085.4775) + self.assertEqual(_glue.nttime2float(0xf000000000000000), 910692730085.4775) + self.assertEqual(_glue.nttime2float(116444736010000000), 1.0) + self.assertEqual(_glue.nttime2float(132555325080000000), 1611058908.0) + self.assertEqual(_glue.nttime2float(132555325081234567), 1611058908.1234567) + # NTTIME_OMIT (0) and NTTIME_FREEZE (UINT64_MAX) map to SAMBA_UTIME_OMIT (1) + self.assertEqual(_glue.nttime2float(0), 1.0) + self.assertEqual(_glue.nttime2float(0xffffffffffffffff), 1.0) + def test_nttime2string(self): string = _glue.nttime2string(116444736010000000) self.assertEqual(type(string), str)