1 /* 2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3 * unrestricted use provided that this legend is included on all tape 4 * media and as a part of the software program in whole or part. Users 5 * may copy or modify Sun RPC without charge, but are not authorized 6 * to license or distribute it to anyone else except as part of a product or 7 * program developed by the user. 8 * 9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 12 * 13 * Sun RPC is provided with no support and without any obligation on the 14 * part of Sun Microsystems, Inc. to assist in its use, correction, 15 * modification or enhancement. 16 * 17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 19 * OR ANY PART THEREOF. 20 * 21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 22 * or profits or other special, indirect and consequential damages, even if 23 * Sun has been advised of the possibility of such damages. 24 * 25 * Sun Microsystems, Inc. 26 * 2550 Garcia Avenue 27 * Mountain View, California 94043 28 */ 29 30 /* 31 * Copyright (c) 1988 by Sun Microsystems, Inc. 32 33 */ 34 35 /* 36 * rtime - get time from remote machine 37 * 38 * gets time, obtaining value from host 39 * on the udp/time socket. Since timeserver returns 40 * with time of day in seconds since Jan 1, 1900, must 41 * subtract seconds before Jan 1, 1970 to get 42 * what unix uses. 43 */ 44 #include "namespace.h" 45 #include <stdlib.h> 46 #include <string.h> 47 #include <unistd.h> 48 #include <errno.h> 49 #include <sys/types.h> 50 #include <sys/socket.h> 51 #include <sys/time.h> 52 #include <netinet/in.h> 53 #include <stdio.h> 54 #include <netdb.h> 55 #include "un-namespace.h" 56 57 #if defined(LIBC_SCCS) && !defined(lint) 58 static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI"; 59 #endif 60 #include <sys/cdefs.h> 61 __FBSDID("$FreeBSD$"); 62 63 extern int _rpc_dtablesize( void ); 64 65 #define NYEARS (unsigned long)(1970 - 1900) 66 #define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) 67 68 static void do_close( int ); 69 70 int 71 rtime(addrp, timep, timeout) 72 struct sockaddr_in *addrp; 73 struct timeval *timep; 74 struct timeval *timeout; 75 { 76 int s; 77 fd_set readfds; 78 int res; 79 unsigned long thetime; 80 struct sockaddr_in from; 81 socklen_t fromlen; 82 int type; 83 struct servent *serv; 84 85 if (timeout == NULL) { 86 type = SOCK_STREAM; 87 } else { 88 type = SOCK_DGRAM; 89 } 90 s = _socket(AF_INET, type, 0); 91 if (s < 0) { 92 return(-1); 93 } 94 addrp->sin_family = AF_INET; 95 96 /* TCP and UDP port are the same in this case */ 97 if ((serv = getservbyname("time", "tcp")) == NULL) { 98 return(-1); 99 } 100 101 addrp->sin_port = serv->s_port; 102 103 if (type == SOCK_DGRAM) { 104 res = _sendto(s, (char *)&thetime, sizeof(thetime), 0, 105 (struct sockaddr *)addrp, sizeof(*addrp)); 106 if (res < 0) { 107 do_close(s); 108 return(-1); 109 } 110 do { 111 FD_ZERO(&readfds); 112 FD_SET(s, &readfds); 113 res = _select(_rpc_dtablesize(), &readfds, 114 (fd_set *)NULL, (fd_set *)NULL, timeout); 115 } while (res < 0 && errno == EINTR); 116 if (res <= 0) { 117 if (res == 0) { 118 errno = ETIMEDOUT; 119 } 120 do_close(s); 121 return(-1); 122 } 123 fromlen = sizeof(from); 124 res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0, 125 (struct sockaddr *)&from, &fromlen); 126 do_close(s); 127 if (res < 0) { 128 return(-1); 129 } 130 } else { 131 if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) { 132 do_close(s); 133 return(-1); 134 } 135 res = _read(s, (char *)&thetime, sizeof(thetime)); 136 do_close(s); 137 if (res < 0) { 138 return(-1); 139 } 140 } 141 if (res != sizeof(thetime)) { 142 errno = EIO; 143 return(-1); 144 } 145 thetime = ntohl(thetime); 146 timep->tv_sec = thetime - TOFFSET; 147 timep->tv_usec = 0; 148 return(0); 149 } 150 151 static void 152 do_close(s) 153 int s; 154 { 155 int save; 156 157 save = errno; 158 (void)_close(s); 159 errno = save; 160 } 161