rtime.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #if 0
  2. static char sccsid[] = "@(#)rtime.c 2.2 88/08/10 4.0 RPCSRC; from 1.8 88/02/08 SMI";
  3. #endif
  4. /*
  5. * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  6. * unrestricted use provided that this legend is included on all tape
  7. * media and as a part of the software program in whole or part. Users
  8. * may copy or modify Sun RPC without charge, but are not authorized
  9. * to license or distribute it to anyone else except as part of a product or
  10. * program developed by the user.
  11. *
  12. * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  13. * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  14. * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  15. *
  16. * Sun RPC is provided with no support and without any obligation on the
  17. * part of Sun Microsystems, Inc. to assist in its use, correction,
  18. * modification or enhancement.
  19. *
  20. * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  21. * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  22. * OR ANY PART THEREOF.
  23. *
  24. * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  25. * or profits or other special, indirect and consequential damages, even if
  26. * Sun has been advised of the possibility of such damages.
  27. *
  28. * Sun Microsystems, Inc.
  29. * 2550 Garcia Avenue
  30. * Mountain View, California 94043
  31. */
  32. /*
  33. * Copyright (c) 1988 by Sun Microsystems, Inc.
  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. #define __FORCE_GLIBC
  45. #include <features.h>
  46. #include <stdio.h>
  47. #include <unistd.h>
  48. #include <rpc/rpc.h>
  49. #include <rpc/clnt.h>
  50. #include <sys/types.h>
  51. #include <sys/poll.h>
  52. #include <sys/socket.h>
  53. #include <sys/time.h>
  54. #include <rpc/auth_des.h>
  55. #include <errno.h>
  56. #include <netinet/in.h>
  57. /* libc_hidden_proto(read) */
  58. /* libc_hidden_proto(socket) */
  59. /* libc_hidden_proto(close) */
  60. libc_hidden_proto(connect)
  61. libc_hidden_proto(recvfrom)
  62. libc_hidden_proto(sendto)
  63. /* libc_hidden_proto(poll) */
  64. libc_hidden_proto(rtime)
  65. #define NYEARS (u_long)(1970 - 1900)
  66. #define TOFFSET (u_long)(60*60*24*(365*NYEARS + (NYEARS/4)))
  67. static void do_close (int);
  68. static void
  69. do_close (int s)
  70. {
  71. int save;
  72. save = errno;
  73. close (s);
  74. __set_errno (save);
  75. }
  76. int
  77. rtime (struct sockaddr_in *addrp, struct rpc_timeval *timep,
  78. struct rpc_timeval *timeout)
  79. {
  80. int s;
  81. struct pollfd fd;
  82. int milliseconds;
  83. int res;
  84. /* RFC 868 says the time is transmitted as a 32-bit value. */
  85. uint32_t thetime;
  86. struct sockaddr_in from;
  87. socklen_t fromlen;
  88. int type;
  89. if (timeout == NULL)
  90. type = SOCK_STREAM;
  91. else
  92. type = SOCK_DGRAM;
  93. s = socket (AF_INET, type, 0);
  94. if (s < 0)
  95. return (-1);
  96. addrp->sin_family = AF_INET;
  97. addrp->sin_port = htons (IPPORT_TIMESERVER);
  98. if (type == SOCK_DGRAM)
  99. {
  100. res = sendto (s, (char *) &thetime, sizeof (thetime), 0,
  101. (struct sockaddr *) addrp, sizeof (*addrp));
  102. if (res < 0)
  103. {
  104. do_close (s);
  105. return -1;
  106. }
  107. milliseconds = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000);
  108. fd.fd = s;
  109. fd.events = POLLIN;
  110. do
  111. res = poll (&fd, 1, milliseconds);
  112. while (res < 0 && errno == EINTR);
  113. if (res <= 0)
  114. {
  115. if (res == 0)
  116. __set_errno (ETIMEDOUT);
  117. do_close (s);
  118. return (-1);
  119. }
  120. fromlen = sizeof (from);
  121. res = recvfrom (s, (char *) &thetime, sizeof (thetime), 0,
  122. (struct sockaddr *) &from, &fromlen);
  123. do_close (s);
  124. if (res < 0)
  125. return -1;
  126. }
  127. else
  128. {
  129. if (connect (s, (struct sockaddr *) addrp, sizeof (*addrp)) < 0)
  130. {
  131. do_close (s);
  132. return -1;
  133. }
  134. res = read (s, (char *) &thetime, sizeof (thetime));
  135. do_close (s);
  136. if (res < 0)
  137. return (-1);
  138. }
  139. if (res != sizeof (thetime))
  140. {
  141. __set_errno (EIO);
  142. return -1;
  143. }
  144. thetime = ntohl (thetime);
  145. timep->tv_sec = thetime - TOFFSET;
  146. timep->tv_usec = 0;
  147. return 0;
  148. }
  149. libc_hidden_def (rtime)