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 * @(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI 30 * $FreeBSD: src/lib/libc/rpc/rtime.c,v 1.5 2000/01/27 23:06:41 jasone Exp $ 31 * $DragonFly: src/lib/libc/rpc/rtime.c,v 1.5 2005/11/13 12:27:04 swildner Exp $ 32 */ 33 34 /* 35 * Copyright (c) 1988 by Sun Microsystems, Inc. 36 37 */ 38 39 /* 40 * rtime - get time from remote machine 41 * 42 * gets time, obtaining value from host 43 * on the udp/time socket. Since timeserver returns 44 * with time of day in seconds since Jan 1, 1900, must 45 * subtract seconds before Jan 1, 1970 to get 46 * what unix uses. 47 */ 48 #include "namespace.h" 49 #include <stdlib.h> 50 #include <string.h> 51 #include <unistd.h> 52 #include <errno.h> 53 #include <sys/types.h> 54 #include <sys/socket.h> 55 #include <sys/time.h> 56 #include <netinet/in.h> 57 #include <stdio.h> 58 #include <netdb.h> 59 #include "un-namespace.h" 60 61 extern int _rpc_dtablesize ( void ); 62 63 #define NYEARS (unsigned long)(1970 - 1900) 64 #define TOFFSET (unsigned long)(60*60*24*(365*NYEARS + (NYEARS/4))) 65 66 static void do_close ( int ); 67 68 int 69 rtime(struct sockaddr_in *addrp, struct timeval *timep, struct timeval *timeout) 70 { 71 int s; 72 fd_set readfds; 73 int res; 74 unsigned long thetime; 75 struct sockaddr_in from; 76 int fromlen; 77 int type; 78 struct servent *serv; 79 80 if (timeout == NULL) { 81 type = SOCK_STREAM; 82 } else { 83 type = SOCK_DGRAM; 84 } 85 s = _socket(AF_INET, type, 0); 86 if (s < 0) { 87 return(-1); 88 } 89 addrp->sin_family = AF_INET; 90 91 /* TCP and UDP port are the same in this case */ 92 if ((serv = getservbyname("time", "tcp")) == NULL) { 93 return(-1); 94 } 95 96 addrp->sin_port = serv->s_port; 97 98 if (type == SOCK_DGRAM) { 99 res = _sendto(s, (char *)&thetime, sizeof(thetime), 0, 100 (struct sockaddr *)addrp, sizeof(*addrp)); 101 if (res < 0) { 102 do_close(s); 103 return(-1); 104 } 105 do { 106 FD_ZERO(&readfds); 107 FD_SET(s, &readfds); 108 res = _select(_rpc_dtablesize(), &readfds, 109 (fd_set *)NULL, (fd_set *)NULL, timeout); 110 } while (res < 0 && errno == EINTR); 111 if (res <= 0) { 112 if (res == 0) { 113 errno = ETIMEDOUT; 114 } 115 do_close(s); 116 return(-1); 117 } 118 fromlen = sizeof(from); 119 res = _recvfrom(s, (char *)&thetime, sizeof(thetime), 0, 120 (struct sockaddr *)&from, &fromlen); 121 do_close(s); 122 if (res < 0) { 123 return(-1); 124 } 125 } else { 126 if (_connect(s, (struct sockaddr *)addrp, sizeof(*addrp)) < 0) { 127 do_close(s); 128 return(-1); 129 } 130 res = _read(s, (char *)&thetime, sizeof(thetime)); 131 do_close(s); 132 if (res < 0) { 133 return(-1); 134 } 135 } 136 if (res != sizeof(thetime)) { 137 errno = EIO; 138 return(-1); 139 } 140 thetime = ntohl(thetime); 141 timep->tv_sec = thetime - TOFFSET; 142 timep->tv_usec = 0; 143 return(0); 144 } 145 146 static void 147 do_close(int s) 148 { 149 int save; 150 151 save = errno; 152 _close(s); 153 errno = save; 154 } 155