xref: /illumos-gate/usr/src/uts/common/fs/smbclnt/netsmb/smb_time.c (revision adee678425979226b2b55d1a0b39ce4c989382e9)
1 /*
2  * Copyright (c) 2000-2001, Boris Popov
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *    This product includes software developed by Boris Popov.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $Id: smbfs_subr.c,v 1.18 2005/02/02 00:22:23 lindak Exp $
33  */
34 
35 /*
36  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37  * Use is subject to license terms.
38  *
39  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
40  */
41 
42 /*
43  * Time conversion functions (to/from DOS, NT times)
44  * From BSD/Darwin smbfs_subr.c
45  */
46 
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/time.h>
50 #include <sys/vnode.h>
51 #include <sys/sunddi.h>
52 
53 #include <netsmb/smb_osdep.h>
54 
55 #include <netsmb/smb.h>
56 #include <netsmb/smb_conn.h>
57 #include <netsmb/smb_subr.h>
58 
59 /*
60  * Number of seconds between 1970 and 1601 year
61  * (134774 days)
62  */
63 const uint64_t DIFF1970TO1601 = 11644473600ULL;
64 const uint32_t TEN_MIL = 10000000UL;
65 
66 /*
67  * Convert NT time (tenths of microseconds since 1601)
68  * to Unix seconds+nanoseconds since 1970.  Any time
69  * earlier than 1970 is converted to Unix time zero.
70  * Both are GMT-based (no time zone adjustments).
71  */
72 void
73 smb_time_NT2local(uint64_t nt_time, struct timespec *tsp)
74 {
75 	uint64_t nt_sec;	/* seconds */
76 	uint64_t nt_tus;	/* tenths of uSec. */
77 
78 	/* Optimize time zero. */
79 	if (nt_time == 0) {
80 		tsp->tv_sec = 0;
81 		tsp->tv_nsec = 0;
82 		return;
83 	}
84 
85 	nt_sec = nt_time / TEN_MIL;
86 	nt_tus = nt_time % TEN_MIL;
87 
88 	if (nt_sec <= DIFF1970TO1601) {
89 		tsp->tv_sec = 0;
90 		tsp->tv_nsec = 0;
91 		return;
92 	}
93 	tsp->tv_sec = nt_sec - DIFF1970TO1601;
94 	tsp->tv_nsec = nt_tus * 100;
95 }
96 
97 /*
98  * Convert Unix time (seconds+nanoseconds since 1970)
99  * to NT time (tenths of microseconds since 1601).
100  * Exception: Convert time zero (really any time in
101  * the first second of 1970) to NT time zero.
102  * Both are GMT-based (no time zone adjustments).
103  */
104 void
105 smb_time_local2NT(struct timespec *tsp, uint64_t *nt_time)
106 {
107 	uint64_t nt_sec;	/* seconds */
108 	uint64_t nt_tus;	/* tenths of uSec. */
109 
110 	if (tsp->tv_sec == 0) {
111 		*nt_time = 0;
112 		return;
113 	}
114 
115 	nt_sec = tsp->tv_sec + DIFF1970TO1601;
116 	nt_tus = tsp->tv_nsec / 100;
117 
118 	*nt_time = (uint64_t)nt_sec * TEN_MIL + nt_tus;
119 }
120 
121 /*
122  * Time zone conversion stuff, only used in old dialects.
123  * Don't adjust time zero for either conversion.
124  */
125 void
126 smb_time_local2server(struct timespec *tsp, int tzoff, long *seconds)
127 {
128 	if (tsp->tv_sec <= (tzoff * 60))
129 		*seconds = 0;
130 	else
131 		*seconds = tsp->tv_sec - (tzoff * 60);
132 }
133 
134 void
135 smb_time_server2local(ulong_t seconds, int tzoff, struct timespec *tsp)
136 {
137 	if (seconds == 0)
138 		tsp->tv_sec = 0;
139 	else
140 		tsp->tv_sec = seconds + tzoff * 60;
141 	tsp->tv_nsec = 0;
142 }
143