1258578Shrs/*- 2258578Shrs * Copyright (c) 2009, Sun Microsystems, Inc. 3258578Shrs * All rights reserved. 4258578Shrs * 5258578Shrs * Redistribution and use in source and binary forms, with or without 6258578Shrs * modification, are permitted provided that the following conditions are met: 7258578Shrs * - Redistributions of source code must retain the above copyright notice, 8258578Shrs * this list of conditions and the following disclaimer. 9258578Shrs * - Redistributions in binary form must reproduce the above copyright notice, 10258578Shrs * this list of conditions and the following disclaimer in the documentation 11258578Shrs * and/or other materials provided with the distribution. 12258578Shrs * - Neither the name of Sun Microsystems, Inc. nor the names of its 13258578Shrs * contributors may be used to endorse or promote products derived 14258578Shrs * from this software without specific prior written permission. 1526219Swpaul * 16258578Shrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17258578Shrs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18258578Shrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19258578Shrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20258578Shrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21258578Shrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22258578Shrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23258578Shrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24258578Shrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25258578Shrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26258578Shrs * 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 64296404Spfg#define NYEARS (unsigned long)(1970 - 1900) 65296404Spfg#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) 6626219Swpaul 6792905Sobrienstatic void do_close( int ); 6826219Swpaul 6926219Swpaulint 70287341Srodrigcrtime(struct sockaddr_in *addrp, struct timeval *timep, 71287341Srodrigc struct timeval *timeout) 7226219Swpaul{ 7326219Swpaul int s; 7426219Swpaul fd_set readfds; 7526219Swpaul int res; 7626219Swpaul unsigned long thetime; 7726219Swpaul struct sockaddr_in from; 78143344Sstefanf socklen_t fromlen; 7926219Swpaul int type; 8026219Swpaul struct servent *serv; 8126219Swpaul 8226219Swpaul if (timeout == NULL) { 8326219Swpaul type = SOCK_STREAM; 8426219Swpaul } else { 8526219Swpaul type = SOCK_DGRAM; 8626219Swpaul } 8771579Sdeischen s = _socket(AF_INET, type, 0); 8826219Swpaul if (s < 0) { 8926219Swpaul return(-1); 9026219Swpaul } 9126219Swpaul addrp->sin_family = AF_INET; 9226219Swpaul 9326219Swpaul /* TCP and UDP port are the same in this case */ 9426219Swpaul if ((serv = getservbyname("time", "tcp")) == NULL) { 9526219Swpaul return(-1); 9626219Swpaul } 9726219Swpaul 9826219Swpaul addrp->sin_port = serv->s_port; 9926219Swpaul 10026219Swpaul if (type == SOCK_DGRAM) { 101296404Spfg res = _sendto(s, (char *)&thetime, sizeof(thetime), 0, 10226219Swpaul (struct sockaddr *)addrp, sizeof(*addrp)); 10326219Swpaul if (res < 0) { 10426219Swpaul do_close(s); 105296404Spfg return(-1); 10626219Swpaul } 10726219Swpaul do { 10826219Swpaul FD_ZERO(&readfds); 10926219Swpaul FD_SET(s, &readfds); 11071579Sdeischen res = _select(_rpc_dtablesize(), &readfds, 11126219Swpaul (fd_set *)NULL, (fd_set *)NULL, timeout); 11226219Swpaul } while (res < 0 && errno == EINTR); 11326219Swpaul if (res <= 0) { 11426219Swpaul if (res == 0) { 11526219Swpaul errno = ETIMEDOUT; 11626219Swpaul } 11726219Swpaul do_close(s); 118296404Spfg return(-1); 11926219Swpaul } 12026219Swpaul fromlen = sizeof(from); 121296404Spfg res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0, 12226219Swpaul (struct sockaddr *)&from, &fromlen); 12326219Swpaul do_close(s); 12426219Swpaul if (res < 0) { 125296404Spfg return(-1); 12626219Swpaul } 12726219Swpaul } else { 12871579Sdeischen if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) { 12926219Swpaul do_close(s); 13026219Swpaul return(-1); 13126219Swpaul } 13256698Sjasone res = _read(s, (char *)&thetime, sizeof(thetime)); 13326219Swpaul do_close(s); 13426219Swpaul if (res < 0) { 13526219Swpaul return(-1); 13626219Swpaul } 13726219Swpaul } 13826219Swpaul if (res != sizeof(thetime)) { 13926219Swpaul errno = EIO; 140296404Spfg return(-1); 14126219Swpaul } 14226219Swpaul thetime = ntohl(thetime); 14326219Swpaul timep->tv_sec = thetime - TOFFSET; 14426219Swpaul timep->tv_usec = 0; 14526219Swpaul return(0); 14626219Swpaul} 14726219Swpaul 14826219Swpaulstatic void 149287341Srodrigcdo_close(int s) 15026219Swpaul{ 15126219Swpaul int save; 15226219Swpaul 15326219Swpaul save = errno; 15456698Sjasone (void)_close(s); 15526219Swpaul errno = save; 15626219Swpaul} 157