1*433d6423SLionel Sambuc /* Part of libhgfs - (c) 2009, D.C. van Moolenbroek */
2*433d6423SLionel Sambuc
3*433d6423SLionel Sambuc #include "inc.h"
4*433d6423SLionel Sambuc
5*433d6423SLionel Sambuc static u64_t time_offset;
6*433d6423SLionel Sambuc
7*433d6423SLionel Sambuc /*===========================================================================*
8*433d6423SLionel Sambuc * time_init *
9*433d6423SLionel Sambuc *===========================================================================*/
time_init(void)10*433d6423SLionel Sambuc void time_init(void)
11*433d6423SLionel Sambuc {
12*433d6423SLionel Sambuc /* Initialize the time conversion module.
13*433d6423SLionel Sambuc */
14*433d6423SLionel Sambuc
15*433d6423SLionel Sambuc /* Generate a 64-bit value for the offset to use in time conversion. The
16*433d6423SLionel Sambuc * HGFS time format uses Windows' FILETIME standard, expressing time in
17*433d6423SLionel Sambuc * 100ns-units since Jan 1, 1601 UTC. The value that is generated is
18*433d6423SLionel Sambuc * the difference between that time and the UNIX epoch, in 100ns units.
19*433d6423SLionel Sambuc */
20*433d6423SLionel Sambuc /* FIXME: we currently do not take into account timezones. */
21*433d6423SLionel Sambuc time_offset = (u64_t)116444736 * 1000000000;
22*433d6423SLionel Sambuc }
23*433d6423SLionel Sambuc
24*433d6423SLionel Sambuc /*===========================================================================*
25*433d6423SLionel Sambuc * time_put *
26*433d6423SLionel Sambuc *===========================================================================*/
time_put(struct timespec * tsp)27*433d6423SLionel Sambuc void time_put(struct timespec *tsp)
28*433d6423SLionel Sambuc {
29*433d6423SLionel Sambuc /* Store a POSIX timestamp pointed to by the given pointer onto the RPC buffer,
30*433d6423SLionel Sambuc * in HGFS timestamp format. If a NULL pointer is given, store a timestamp of
31*433d6423SLionel Sambuc * zero instead.
32*433d6423SLionel Sambuc */
33*433d6423SLionel Sambuc u64_t hgfstime;
34*433d6423SLionel Sambuc
35*433d6423SLionel Sambuc if (tsp != NULL) {
36*433d6423SLionel Sambuc hgfstime = ((u64_t)tsp->tv_sec * 10000000) + (tsp->tv_nsec / 100);
37*433d6423SLionel Sambuc hgfstime += time_offset;
38*433d6423SLionel Sambuc
39*433d6423SLionel Sambuc RPC_NEXT32 = ex64lo(hgfstime);
40*433d6423SLionel Sambuc RPC_NEXT32 = ex64hi(hgfstime);
41*433d6423SLionel Sambuc } else {
42*433d6423SLionel Sambuc RPC_NEXT32 = 0;
43*433d6423SLionel Sambuc RPC_NEXT32 = 0;
44*433d6423SLionel Sambuc }
45*433d6423SLionel Sambuc }
46*433d6423SLionel Sambuc
47*433d6423SLionel Sambuc /*===========================================================================*
48*433d6423SLionel Sambuc * time_get *
49*433d6423SLionel Sambuc *===========================================================================*/
time_get(struct timespec * tsp)50*433d6423SLionel Sambuc void time_get(struct timespec *tsp)
51*433d6423SLionel Sambuc {
52*433d6423SLionel Sambuc /* Get a HGFS timestamp from the RPC buffer, convert it into a POSIX timestamp,
53*433d6423SLionel Sambuc * and store the result in the given time pointer. If the given pointer is
54*433d6423SLionel Sambuc * NULL, however, simply skip over the timestamp in the RPC buffer.
55*433d6423SLionel Sambuc */
56*433d6423SLionel Sambuc u64_t hgfstime;
57*433d6423SLionel Sambuc u32_t time_lo, time_hi;
58*433d6423SLionel Sambuc
59*433d6423SLionel Sambuc if (tsp != NULL) {
60*433d6423SLionel Sambuc time_lo = RPC_NEXT32;
61*433d6423SLionel Sambuc time_hi = RPC_NEXT32;
62*433d6423SLionel Sambuc
63*433d6423SLionel Sambuc hgfstime = make64(time_lo, time_hi) - time_offset;
64*433d6423SLionel Sambuc
65*433d6423SLionel Sambuc tsp->tv_sec = (unsigned long)(hgfstime / 10000000);
66*433d6423SLionel Sambuc tsp->tv_nsec = (unsigned)(hgfstime % 10000000) * 100;
67*433d6423SLionel Sambuc }
68*433d6423SLionel Sambuc else RPC_ADVANCE(sizeof(u32_t) * 2);
69*433d6423SLionel Sambuc }
70