]>
Commit | Line | Data |
---|---|---|
800d775e | 1 | /* |
a7ab6ec8 | 2 | * Copyright (c) 2010, Oracle America, Inc. |
cb636bb2 | 3 | * |
a7ab6ec8 UD |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions are | |
6 | * met: | |
cb636bb2 | 7 | * |
a7ab6ec8 UD |
8 | * * Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * * Redistributions in binary form must reproduce the above | |
11 | * copyright notice, this list of conditions and the following | |
12 | * disclaimer in the documentation and/or other materials | |
13 | * provided with the distribution. | |
14 | * * Neither the name of the "Oracle America, Inc." nor the names of its | |
15 | * contributors may be used to endorse or promote products derived | |
16 | * from this software without specific prior written permission. | |
ba488034 | 17 | * |
a7ab6ec8 UD |
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
22 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |
23 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
25 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
800d775e UD |
30 | */ |
31 | /* | |
32 | * rtime - get time from remote machine | |
33 | * | |
34 | * gets time, obtaining value from host | |
35 | * on the udp/time socket. Since timeserver returns | |
36 | * with time of day in seconds since Jan 1, 1900, must | |
37 | * subtract seconds before Jan 1, 1970 to get | |
38 | * what unix uses. | |
39 | */ | |
40 | #include <stdio.h> | |
41 | #include <unistd.h> | |
e054f494 | 42 | #include <stdint.h> |
800d775e UD |
43 | #include <rpc/rpc.h> |
44 | #include <rpc/clnt.h> | |
45 | #include <sys/types.h> | |
ba488034 | 46 | #include <sys/poll.h> |
800d775e UD |
47 | #include <sys/socket.h> |
48 | #include <sys/time.h> | |
49 | #include <rpc/auth_des.h> | |
50 | #include <errno.h> | |
51 | #include <netinet/in.h> | |
82f43dd2 | 52 | #include <shlib-compat.h> |
800d775e UD |
53 | |
54 | #define NYEARS (u_long)(1970 - 1900) | |
55 | #define TOFFSET (u_long)(60*60*24*(365*NYEARS + (NYEARS/4))) | |
56 | ||
57 | static void do_close (int); | |
58 | ||
59 | static void | |
60 | do_close (int s) | |
61 | { | |
62 | int save; | |
63 | ||
64 | save = errno; | |
50304ef0 | 65 | __close (s); |
800d775e UD |
66 | __set_errno (save); |
67 | } | |
68 | ||
69 | int | |
f8afba91 UD |
70 | rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep, |
71 | struct rpc_timeval *timeout) | |
800d775e UD |
72 | { |
73 | int s; | |
ba488034 UD |
74 | struct pollfd fd; |
75 | int milliseconds; | |
800d775e | 76 | int res; |
425838aa UD |
77 | /* RFC 868 says the time is transmitted as a 32-bit value. */ |
78 | uint32_t thetime; | |
800d775e | 79 | struct sockaddr_in from; |
9cfe5381 | 80 | socklen_t fromlen; |
800d775e UD |
81 | int type; |
82 | ||
83 | if (timeout == NULL) | |
84 | type = SOCK_STREAM; | |
85 | else | |
86 | type = SOCK_DGRAM; | |
87 | ||
50304ef0 | 88 | s = __socket (AF_INET, type, 0); |
800d775e UD |
89 | if (s < 0) |
90 | return (-1); | |
91 | ||
92 | addrp->sin_family = AF_INET; | |
93 | addrp->sin_port = htons (IPPORT_TIMESERVER); | |
94 | if (type == SOCK_DGRAM) | |
95 | { | |
b2bffca2 UD |
96 | res = __sendto (s, (char *) &thetime, sizeof (thetime), 0, |
97 | (struct sockaddr *) addrp, sizeof (*addrp)); | |
800d775e UD |
98 | if (res < 0) |
99 | { | |
100 | do_close (s); | |
101 | return -1; | |
102 | } | |
ba488034 UD |
103 | milliseconds = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000); |
104 | fd.fd = s; | |
105 | fd.events = POLLIN; | |
800d775e | 106 | do |
ba488034 | 107 | res = __poll (&fd, 1, milliseconds); |
800d775e UD |
108 | while (res < 0 && errno == EINTR); |
109 | if (res <= 0) | |
110 | { | |
111 | if (res == 0) | |
112 | __set_errno (ETIMEDOUT); | |
113 | do_close (s); | |
114 | return (-1); | |
115 | } | |
116 | fromlen = sizeof (from); | |
b2bffca2 UD |
117 | res = __recvfrom (s, (char *) &thetime, sizeof (thetime), 0, |
118 | (struct sockaddr *) &from, &fromlen); | |
800d775e UD |
119 | do_close (s); |
120 | if (res < 0) | |
121 | return -1; | |
122 | } | |
123 | else | |
124 | { | |
50304ef0 | 125 | if (__connect (s, (struct sockaddr *) addrp, sizeof (*addrp)) < 0) |
800d775e UD |
126 | { |
127 | do_close (s); | |
128 | return -1; | |
129 | } | |
50304ef0 | 130 | res = __read (s, (char *) &thetime, sizeof (thetime)); |
800d775e UD |
131 | do_close (s); |
132 | if (res < 0) | |
133 | return (-1); | |
134 | } | |
135 | if (res != sizeof (thetime)) | |
136 | { | |
137 | __set_errno (EIO); | |
138 | return -1; | |
139 | } | |
140 | thetime = ntohl (thetime); | |
141 | timep->tv_sec = thetime - TOFFSET; | |
142 | timep->tv_usec = 0; | |
143 | return 0; | |
144 | } | |
021db4be | 145 | libc_hidden_nolink_sunrpc (rtime, GLIBC_2_1) |