1261046Smav/*- 2261046Smav * Copyright (c) 2009, Sun Microsystems, Inc. 3261046Smav * All rights reserved. 4261046Smav * 5261046Smav * Redistribution and use in source and binary forms, with or without 6261046Smav * modification, are permitted provided that the following conditions are met: 7261046Smav * - Redistributions of source code must retain the above copyright notice, 8261046Smav * this list of conditions and the following disclaimer. 9261046Smav * - Redistributions in binary form must reproduce the above copyright notice, 10261046Smav * this list of conditions and the following disclaimer in the documentation 11261046Smav * and/or other materials provided with the distribution. 12261046Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 13261046Smav * contributors may be used to endorse or promote products derived 14261046Smav * from this software without specific prior written permission. 1526219Swpaul * 16261046Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17261046Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18261046Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19261046Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20261046Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21261046Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22261046Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23261046Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24261046Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25261046Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26261046Smav * POSSIBILITY OF SUCH DAMAGE. 2726219Swpaul */ 2826219Swpaul 2926219Swpaul/* 3026219Swpaul * Copyright (c) 1988 by Sun Microsystems, Inc. 3126219Swpaul 3226219Swpaul */ 3326219Swpaul 3426219Swpaul/* 3526219Swpaul * rtime - get time from remote machine 3626219Swpaul * 3726219Swpaul * gets time, obtaining value from host 3826219Swpaul * on the udp/time socket. Since timeserver returns 3926219Swpaul * with time of day in seconds since Jan 1, 1900, must 4026219Swpaul * subtract seconds before Jan 1, 1970 to get 4126219Swpaul * what unix uses. 4226219Swpaul */ 4371579Sdeischen#include "namespace.h" 4426219Swpaul#include <stdlib.h> 4526219Swpaul#include <string.h> 4626219Swpaul#include <unistd.h> 4726219Swpaul#include <errno.h> 4826219Swpaul#include <sys/types.h> 4926219Swpaul#include <sys/socket.h> 5026219Swpaul#include <sys/time.h> 5126219Swpaul#include <netinet/in.h> 5226219Swpaul#include <stdio.h> 5326219Swpaul#include <netdb.h> 5471579Sdeischen#include "un-namespace.h" 5526219Swpaul 5626219Swpaul#if defined(LIBC_SCCS) && !defined(lint) 5792990Sobrienstatic char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; 5826219Swpaul#endif 5992990Sobrien#include <sys/cdefs.h> 6092990Sobrien__FBSDID("$FreeBSD$"); 6126219Swpaul 6292905Sobrienextern int _rpc_dtablesize( void ); 6326219Swpaul 6426219Swpaul#define NYEARS (unsigned long)(1970 - 1900) 6526219Swpaul#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) 6626219Swpaul 6792905Sobrienstatic void do_close( int ); 6826219Swpaul 6926219Swpaulint 7026219Swpaulrtime(addrp, timep, timeout) 7126219Swpaul struct sockaddr_in *addrp; 7226219Swpaul struct timeval *timep; 7326219Swpaul struct timeval *timeout; 7426219Swpaul{ 7526219Swpaul int s; 7626219Swpaul fd_set readfds; 7726219Swpaul int res; 7826219Swpaul unsigned long thetime; 7926219Swpaul struct sockaddr_in from; 80143344Sstefanf socklen_t fromlen; 8126219Swpaul int type; 8226219Swpaul struct servent *serv; 8326219Swpaul 8426219Swpaul if (timeout == NULL) { 8526219Swpaul type = SOCK_STREAM; 8626219Swpaul } else { 8726219Swpaul type = SOCK_DGRAM; 8826219Swpaul } 8971579Sdeischen s = _socket(AF_INET, type, 0); 9026219Swpaul if (s < 0) { 9126219Swpaul return(-1); 9226219Swpaul } 9326219Swpaul addrp->sin_family = AF_INET; 9426219Swpaul 9526219Swpaul /* TCP and UDP port are the same in this case */ 9626219Swpaul if ((serv = getservbyname("time", "tcp")) == NULL) { 9726219Swpaul return(-1); 9826219Swpaul } 9926219Swpaul 10026219Swpaul addrp->sin_port = serv->s_port; 10126219Swpaul 10226219Swpaul if (type == SOCK_DGRAM) { 10371579Sdeischen res = _sendto(s, (char *)&thetime, sizeof(thetime), 0, 10426219Swpaul (struct sockaddr *)addrp, sizeof(*addrp)); 10526219Swpaul if (res < 0) { 10626219Swpaul do_close(s); 10726219Swpaul return(-1); 10826219Swpaul } 10926219Swpaul do { 11026219Swpaul FD_ZERO(&readfds); 11126219Swpaul FD_SET(s, &readfds); 11271579Sdeischen res = _select(_rpc_dtablesize(), &readfds, 11326219Swpaul (fd_set *)NULL, (fd_set *)NULL, timeout); 11426219Swpaul } while (res < 0 && errno == EINTR); 11526219Swpaul if (res <= 0) { 11626219Swpaul if (res == 0) { 11726219Swpaul errno = ETIMEDOUT; 11826219Swpaul } 11926219Swpaul do_close(s); 12026219Swpaul return(-1); 12126219Swpaul } 12226219Swpaul fromlen = sizeof(from); 12371579Sdeischen res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0, 12426219Swpaul (struct sockaddr *)&from, &fromlen); 12526219Swpaul do_close(s); 12626219Swpaul if (res < 0) { 12726219Swpaul return(-1); 12826219Swpaul } 12926219Swpaul } else { 13071579Sdeischen if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) { 13126219Swpaul do_close(s); 13226219Swpaul return(-1); 13326219Swpaul } 13456698Sjasone res = _read(s, (char *)&thetime, sizeof(thetime)); 13526219Swpaul do_close(s); 13626219Swpaul if (res < 0) { 13726219Swpaul return(-1); 13826219Swpaul } 13926219Swpaul } 14026219Swpaul if (res != sizeof(thetime)) { 14126219Swpaul errno = EIO; 14226219Swpaul return(-1); 14326219Swpaul } 14426219Swpaul thetime = ntohl(thetime); 14526219Swpaul timep->tv_sec = thetime - TOFFSET; 14626219Swpaul timep->tv_usec = 0; 14726219Swpaul return(0); 14826219Swpaul} 14926219Swpaul 15026219Swpaulstatic void 15126219Swpauldo_close(s) 15226219Swpaul int s; 15326219Swpaul{ 15426219Swpaul int save; 15526219Swpaul 15626219Swpaul save = errno; 15756698Sjasone (void)_close(s); 15826219Swpaul errno = save; 15926219Swpaul} 160