rtime.c revision 143344
126219Swpaul/* 226219Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 326219Swpaul * unrestricted use provided that this legend is included on all tape 426219Swpaul * media and as a part of the software program in whole or part. Users 526219Swpaul * may copy or modify Sun RPC without charge, but are not authorized 626219Swpaul * to license or distribute it to anyone else except as part of a product or 726219Swpaul * program developed by the user. 826219Swpaul * 926219Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1026219Swpaul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1126219Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1226219Swpaul * 1326219Swpaul * Sun RPC is provided with no support and without any obligation on the 1426219Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction, 1526219Swpaul * modification or enhancement. 1626219Swpaul * 1726219Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1826219Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 1926219Swpaul * OR ANY PART THEREOF. 2026219Swpaul * 2126219Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2226219Swpaul * or profits or other special, indirect and consequential damages, even if 2326219Swpaul * Sun has been advised of the possibility of such damages. 2426219Swpaul * 2526219Swpaul * Sun Microsystems, Inc. 2626219Swpaul * 2550 Garcia Avenue 2726219Swpaul * Mountain View, California 94043 2826219Swpaul */ 2926219Swpaul 3026219Swpaul/* 3126219Swpaul * Copyright (c) 1988 by Sun Microsystems, Inc. 3226219Swpaul 3326219Swpaul */ 3426219Swpaul 3526219Swpaul/* 3626219Swpaul * rtime - get time from remote machine 3726219Swpaul * 3826219Swpaul * gets time, obtaining value from host 3926219Swpaul * on the udp/time socket. Since timeserver returns 4026219Swpaul * with time of day in seconds since Jan 1, 1900, must 4126219Swpaul * subtract seconds before Jan 1, 1970 to get 4226219Swpaul * what unix uses. 4326219Swpaul */ 4471579Sdeischen#include "namespace.h" 4526219Swpaul#include <stdlib.h> 4626219Swpaul#include <string.h> 4726219Swpaul#include <unistd.h> 4826219Swpaul#include <errno.h> 4926219Swpaul#include <sys/types.h> 5026219Swpaul#include <sys/socket.h> 5126219Swpaul#include <sys/time.h> 5226219Swpaul#include <netinet/in.h> 5326219Swpaul#include <stdio.h> 5426219Swpaul#include <netdb.h> 5571579Sdeischen#include "un-namespace.h" 5626219Swpaul 5726219Swpaul#if defined(LIBC_SCCS) && !defined(lint) 5892990Sobrienstatic char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; 5926219Swpaul#endif 6092990Sobrien#include <sys/cdefs.h> 6192990Sobrien__FBSDID("$FreeBSD: head/lib/libc/rpc/rtime.c 143344 2005-03-10 00:57:01Z stefanf $"); 6226219Swpaul 6392905Sobrienextern int _rpc_dtablesize( void ); 6426219Swpaul 6526219Swpaul#define NYEARS (unsigned long)(1970 - 1900) 6626219Swpaul#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) 6726219Swpaul 6892905Sobrienstatic void do_close( int ); 6926219Swpaul 7026219Swpaulint 7126219Swpaulrtime(addrp, timep, timeout) 7226219Swpaul struct sockaddr_in *addrp; 7326219Swpaul struct timeval *timep; 7426219Swpaul struct timeval *timeout; 7526219Swpaul{ 7626219Swpaul int s; 7726219Swpaul fd_set readfds; 7826219Swpaul int res; 7926219Swpaul unsigned long thetime; 8026219Swpaul struct sockaddr_in from; 81143344Sstefanf socklen_t fromlen; 8226219Swpaul int type; 8326219Swpaul struct servent *serv; 8426219Swpaul 8526219Swpaul if (timeout == NULL) { 8626219Swpaul type = SOCK_STREAM; 8726219Swpaul } else { 8826219Swpaul type = SOCK_DGRAM; 8926219Swpaul } 9071579Sdeischen s = _socket(AF_INET, type, 0); 9126219Swpaul if (s < 0) { 9226219Swpaul return(-1); 9326219Swpaul } 9426219Swpaul addrp->sin_family = AF_INET; 9526219Swpaul 9626219Swpaul /* TCP and UDP port are the same in this case */ 9726219Swpaul if ((serv = getservbyname("time", "tcp")) == NULL) { 9826219Swpaul return(-1); 9926219Swpaul } 10026219Swpaul 10126219Swpaul addrp->sin_port = serv->s_port; 10226219Swpaul 10326219Swpaul if (type == SOCK_DGRAM) { 10471579Sdeischen res = _sendto(s, (char *)&thetime, sizeof(thetime), 0, 10526219Swpaul (struct sockaddr *)addrp, sizeof(*addrp)); 10626219Swpaul if (res < 0) { 10726219Swpaul do_close(s); 10826219Swpaul return(-1); 10926219Swpaul } 11026219Swpaul do { 11126219Swpaul FD_ZERO(&readfds); 11226219Swpaul FD_SET(s, &readfds); 11371579Sdeischen res = _select(_rpc_dtablesize(), &readfds, 11426219Swpaul (fd_set *)NULL, (fd_set *)NULL, timeout); 11526219Swpaul } while (res < 0 && errno == EINTR); 11626219Swpaul if (res <= 0) { 11726219Swpaul if (res == 0) { 11826219Swpaul errno = ETIMEDOUT; 11926219Swpaul } 12026219Swpaul do_close(s); 12126219Swpaul return(-1); 12226219Swpaul } 12326219Swpaul fromlen = sizeof(from); 12471579Sdeischen res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0, 12526219Swpaul (struct sockaddr *)&from, &fromlen); 12626219Swpaul do_close(s); 12726219Swpaul if (res < 0) { 12826219Swpaul return(-1); 12926219Swpaul } 13026219Swpaul } else { 13171579Sdeischen if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) { 13226219Swpaul do_close(s); 13326219Swpaul return(-1); 13426219Swpaul } 13556698Sjasone res = _read(s, (char *)&thetime, sizeof(thetime)); 13626219Swpaul do_close(s); 13726219Swpaul if (res < 0) { 13826219Swpaul return(-1); 13926219Swpaul } 14026219Swpaul } 14126219Swpaul if (res != sizeof(thetime)) { 14226219Swpaul errno = EIO; 14326219Swpaul return(-1); 14426219Swpaul } 14526219Swpaul thetime = ntohl(thetime); 14626219Swpaul timep->tv_sec = thetime - TOFFSET; 14726219Swpaul timep->tv_usec = 0; 14826219Swpaul return(0); 14926219Swpaul} 15026219Swpaul 15126219Swpaulstatic void 15226219Swpauldo_close(s) 15326219Swpaul int s; 15426219Swpaul{ 15526219Swpaul int save; 15626219Swpaul 15726219Swpaul save = errno; 15856698Sjasone (void)_close(s); 15926219Swpaul errno = save; 16026219Swpaul} 161