rtime.c revision 50476
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 */ 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> 5426219Swpaul 5526219Swpaul#if defined(LIBC_SCCS) && !defined(lint) 5626219Swpaul/* from: static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; */ 5750476Speterstatic const char rcsid[] = "$FreeBSD: head/lib/libc/rpc/rtime.c 50476 1999-08-28 00:22:10Z peter $"; 5826219Swpaul#endif 5926219Swpaul 6026219Swpaulextern int _rpc_dtablesize __P(( void )); 6126219Swpaul 6226219Swpaul#define NYEARS (unsigned long)(1970 - 1900) 6326219Swpaul#define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) 6426219Swpaul 6526219Swpaulstatic void do_close __P(( int )); 6626219Swpaul 6726219Swpaulint 6826219Swpaulrtime(addrp, timep, timeout) 6926219Swpaul struct sockaddr_in *addrp; 7026219Swpaul struct timeval *timep; 7126219Swpaul struct timeval *timeout; 7226219Swpaul{ 7326219Swpaul int s; 7426219Swpaul fd_set readfds; 7526219Swpaul int res; 7626219Swpaul unsigned long thetime; 7726219Swpaul struct sockaddr_in from; 7826219Swpaul int fromlen; 7926219Swpaul int type; 8026219Swpaul struct servent *serv; 8126219Swpaul 8226219Swpaul if (timeout == NULL) { 8326219Swpaul type = SOCK_STREAM; 8426219Swpaul } else { 8526219Swpaul type = SOCK_DGRAM; 8626219Swpaul } 8726219Swpaul 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) { 10126219Swpaul res = sendto(s, (char *)&thetime, sizeof(thetime), 0, 10226219Swpaul (struct sockaddr *)addrp, sizeof(*addrp)); 10326219Swpaul if (res < 0) { 10426219Swpaul do_close(s); 10526219Swpaul return(-1); 10626219Swpaul } 10726219Swpaul do { 10826219Swpaul FD_ZERO(&readfds); 10926219Swpaul FD_SET(s, &readfds); 11026219Swpaul 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); 11826219Swpaul return(-1); 11926219Swpaul } 12026219Swpaul fromlen = sizeof(from); 12126219Swpaul res = recvfrom(s, (char *)&thetime, sizeof(thetime), 0, 12226219Swpaul (struct sockaddr *)&from, &fromlen); 12326219Swpaul do_close(s); 12426219Swpaul if (res < 0) { 12526219Swpaul return(-1); 12626219Swpaul } 12726219Swpaul } else { 12826219Swpaul if (connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) { 12926219Swpaul do_close(s); 13026219Swpaul return(-1); 13126219Swpaul } 13226219Swpaul 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; 14026219Swpaul 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 14926219Swpauldo_close(s) 15026219Swpaul int s; 15126219Swpaul{ 15226219Swpaul int save; 15326219Swpaul 15426219Swpaul save = errno; 15526219Swpaul (void) close(s); 15626219Swpaul errno = save; 15726219Swpaul} 158