[LIBTIRPC]
[reactos.git] / reactos / dll / win32 / libtirpc / src / rtime.c
1 /*
2 * Copyright (c) 2009, Sun Microsystems, Inc.
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 are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * Copyright (c) 1988 by Sun Microsystems, Inc.
31
32 */
33
34 /*
35 * rtime - get time from remote machine
36 *
37 * gets time, obtaining value from host
38 * on the udp/time socket. Since timeserver returns
39 * with time of day in seconds since Jan 1, 1900, must
40 * subtract seconds before Jan 1, 1970 to get
41 * what unix uses.
42 */
43 #include <wintirpc.h>
44 //#include <pthread.h>
45 #include <stdlib.h>
46 #include <string.h>
47 //#include <unistd.h>
48 #include <errno.h>
49 #include <sys/types.h>
50 //#include <sys/socket.h>
51 //#include <sys/time.h>
52 //#include <netinet/in.h>
53 #include <stdio.h>
54 //#include <netdb.h>
55 //#include <sys/select.h>
56
57 extern int _rpc_dtablesize( void );
58
59 #define NYEARS (unsigned long)(1970 - 1900)
60 #define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4)))
61
62 #ifndef __REACTOS__
63 static void do_close( SOCKET );
64 #else
65 static void do_close( int );
66 #endif
67
68 int
69 rtime(addrp, timep, timeout)
70 struct sockaddr_in *addrp;
71 struct timeval *timep;
72 struct timeval *timeout;
73 {
74 SOCKET s;
75 fd_set readfds;
76 int res;
77 unsigned long thetime;
78 struct sockaddr_in from;
79 int fromlen;
80 int type;
81 struct servent *serv;
82
83 if (timeout == NULL) {
84 type = SOCK_STREAM;
85 } else {
86 type = SOCK_DGRAM;
87 }
88 s = socket(AF_INET, type, 0);
89 if (s == INVALID_SOCKET) {
90 return(-1);
91 }
92 addrp->sin_family = AF_INET;
93
94 /* TCP and UDP port are the same in this case */
95 if ((serv = getservbyname("time", "tcp")) == NULL) {
96 return(-1);
97 }
98
99 addrp->sin_port = serv->s_port;
100
101 if (type == SOCK_DGRAM) {
102 res = sendto(s, (char *)&thetime, sizeof(thetime), 0,
103 (struct sockaddr *)addrp, sizeof(*addrp));
104 if (res == SOCKET_ERROR) {
105 do_close(s);
106 return(-1);
107 }
108 do {
109 FD_ZERO(&readfds);
110 FD_SET(s, &readfds);
111 res = select(_rpc_dtablesize(), &readfds,
112 (fd_set *)NULL, (fd_set *)NULL, timeout);
113 } while (res == SOCKET_ERROR && WSAGetLastError() == WSAEINTR);
114 if (res == 0 || res == SOCKET_ERROR) {
115 if (res == 0) {
116 errno = WSAETIMEDOUT;
117 }
118 do_close(s);
119 return(-1);
120 }
121 fromlen = sizeof(from);
122 res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0,
123 (struct sockaddr *)&from, &fromlen);
124 do_close(s);
125 if (res == SOCKET_ERROR) {
126 return(-1);
127 }
128 } else {
129 if (connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) == SOCKET_ERROR) {
130 do_close(s);
131 return(-1);
132 }
133 res = recv(s, (char *)&thetime, sizeof(thetime), 0);
134 do_close(s);
135 if (res == SOCKET_ERROR) {
136 return(-1);
137 }
138 }
139 if (res != sizeof(thetime)) {
140 errno = EIO;
141 return(-1);
142 }
143 thetime = ntohl(thetime);
144 timep->tv_sec = thetime - TOFFSET;
145 timep->tv_usec = 0;
146 return(0);
147 }
148
149 static void
150 do_close(s)
151 int s;
152 {
153 int save;
154
155 save = errno;
156 (void)closesocket(s);
157 errno = save;
158 }