xref: /minix3/minix/lib/libhgfs/time.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
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