afsconfig-and-rcsid-all-around-20010705
[openafs.git] / src / ntp / ntpsubs.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <afs/param.h>
11 #include <afsconfig.h>
12
13 RCSID("$Header$");
14
15 #include <stdio.h>
16 #include <sys/types.h>
17 #include <sys/param.h>
18 #include <sys/time.h>
19 #include <sys/uio.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
23 #include <errno.h>
24 #if defined(AIX)
25 #include <sys/syslog.h>
26 #else
27 #include <syslog.h>
28 #endif
29 #include "ntp.h"
30
31 extern int errno;
32
33 #define TRUE    1
34 #define FALSE   0
35
36 /*
37  *  The nice thing here is that the quantity is NEVER signed.
38  */
39 double
40 ul_fixed_to_double(t)
41         struct l_fixedpt *t;
42 {
43         double a, b;
44 #ifdef  GENERIC_UNS_BUG
45         register int i;
46
47         i = ntohl(t->fraction);
48         a = (afs_int32)((i >> 1) & 0x7fffffff);
49         a *= 2.0;
50         if (i & 1)
51                 a += 1.0;
52         a = a / (4.294967296e9);        /* shift dec point over by 32 bits */
53         i = ntohl(t->int_part);
54         b = (afs_int32)((i >> 1) & 0x7fffffff);
55         b *= 2.0;
56         if (i & 1)
57                 b += 1.0;
58 #else   /* GENERIC_UNS_BUG */
59         a = (afs_uint32) ntohl(t->fraction);
60 #ifdef  VAX_COMPILER_FLT_BUG
61         if (a < 0.0) a += 4.294967296e9;
62 #endif
63         a = a / (4.294967296e9);/* shift dec point over by 32 bits */
64         b = (afs_uint32) ntohl(t->int_part);
65 #ifdef  VAX_COMPILER_FLT_BUG
66         if (b < 0.0) b += 4.294967296e9;
67 #endif
68 #endif  /* GENERIC_UNS_BUG */
69         return (a + b);
70 }
71
72 /*
73  *  Here we have to worry about the high order bit being signed
74  */
75
76 #if     0
77 double
78 l_fixed_to_double(t)
79         struct l_fixedpt *t;
80 {
81         double a,b;
82
83         if (ntohl(t->int_part) & 0x80000000) {
84                 a = ntohl(~t->fraction);
85 #ifdef  VAX_COMPILER_FLT_BUG
86                 if (a < 0.0) a += 4.294967296e9;
87 #endif
88                 a = a / (4.294967296e9);
89                 b = ntohl(~t->int_part);
90 #ifdef  VAX_COMPILER_FLT_BUG
91                 if (b < 0.0) b += 4.294967296e9;
92 #endif
93                 a += b;
94                 a = -a;
95         } else {
96                 a = ntohl(t->fraction);
97 #ifdef  VAX_COMPILER_FLT_BUG
98                 if (a < 0.0) a += 4.294967296e9;
99 #endif
100                 a = a / (4.294967296e9);
101                 b = ntohl(t->int_part);
102 #ifdef  VAX_COMPILER_FLT_BUG
103                 if (b < 0.0) b += 4.294967296e9;
104 #endif
105                 a += b;
106         }
107         return (a);
108 }
109 #endif
110
111 /*
112  *  Here we have to worry about the high order bit being signed
113  */
114 double
115 s_fixed_to_double(t)
116         struct s_fixedpt *t;
117 {
118         double a;
119
120         if (ntohs(t->int_part) & 0x8000) {
121                 a = ntohs(~t->fraction & 0xFFFF);
122                 a = a / 65536.0;        /* shift dec point over by 16 bits */
123                 a +=  ntohs(~t->int_part & 0xFFFF);
124                 a = -a;
125         } else {
126                 a = ntohs(t->fraction);
127                 a = a / 65536.0;        /* shift dec point over by 16 bits */
128                 a += ntohs(t->int_part);
129         }
130         return (a);
131 }
132
133 void
134 double_to_l_fixed(t, value)
135         struct l_fixedpt *t;
136         double value;
137 {
138         double temp;
139
140         if (value >= (double) 0.0) {
141                 t->int_part = value;
142                 temp = value - t->int_part;
143                 temp *= 4.294967296e9;
144                 t->fraction = temp;
145                 t->int_part = htonl(t->int_part);
146                 t->fraction = htonl(t->fraction);
147         } else {
148                 value = -value;
149                 t->int_part = value;
150                 temp = value - t->int_part;
151                 temp *= 4.294967296e9;
152                 t->fraction = temp;
153                 t->int_part = htonl(~t->int_part);
154                 t->fraction = htonl(~t->fraction);
155         }
156 }
157
158 void
159 double_to_s_fixed(t, value)
160         struct s_fixedpt *t;
161         double value;
162 {
163         double temp;
164
165         if (value >= (double) 0.0) {
166                 t->int_part = value;
167                 temp = value - t->int_part;
168                 temp *= 65536.0;
169                 t->fraction = temp;
170                 t->int_part = htons(t->int_part);
171                 t->fraction = htons(t->fraction);
172         } else {
173                 value = -value;
174                 t->int_part = value;
175                 temp = value - t->int_part;
176                 temp *= 65536.0;
177                 t->fraction = temp;
178                 t->int_part = htons(~t->int_part);
179                 t->fraction = htons(~t->fraction);
180         }
181 }
182 /*
183         in the sun, trying to assign a float between 2^31 and 2^32
184         results in the value 2^31.  Neither 4.2bsd nor VMS have this
185         problem.  Reported it to Bob O'Brien of SMI
186 */
187 #ifndef AFS_SUN58_ENV
188 #ifdef SUN_FLT_BUG 
189 tstamp(stampp, tvp)
190         struct l_fixedpt *stampp;
191         struct timeval *tvp;
192 {
193         int tt;
194         double dd;
195
196         stampp->int_part = ntohl(JAN_1970 + tvp->tv_sec);
197         dd = (float) tvp->tv_usec / 1000000.0;
198         tt = dd * 2147483648.0;
199         stampp->fraction = ntohl((tt << 1));
200 }
201 #else
202 tstamp(stampp, tvp)
203         struct l_fixedpt *stampp;
204         struct timeval *tvp;
205 {
206         stampp->int_part = ntohl((afs_uint32) (JAN_1970 + tvp->tv_sec));
207         stampp->fraction = ntohl((afs_uint32) ((float) tvp->tv_usec * 4294.967295));
208 }
209 #endif
210 #endif /* AFS_SUN58_ENV */
211
212 /*
213  * ntoa is similar to inet_ntoa, but cycles through a set of 8 buffers
214  * so it can be invoked several times in a function parameter list.
215  */
216
217 char *
218 ntoa (in_addr)
219 struct in_addr in_addr;
220 {
221         static int i = 0;
222         static char bufs[8][20];
223         unsigned char *p = (unsigned char *) &in_addr.s_addr;
224
225         i = (i + 1) % (sizeof bufs / sizeof bufs[0]);
226         sprintf (bufs[i], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
227         return bufs[i];
228 }
229
230 /* calculate effective precision, but repeated calls to gettimeofday */
231
232 int MeasurePrecision (intervalP)
233   int *intervalP;
234 {
235 #if     defined(AFS_SUN5_ENV)
236 #define MAXTIMEDIFFS 100
237 #else
238 #define MAXTIMEDIFFS 10
239 #endif
240
241     int diff[MAXTIMEDIFFS];
242     int nDiff;
243     int interval;
244     int i;
245     int q;
246     struct timeval tv0;
247
248     gettimeofday (&tv0, 0);
249     nDiff = 0;
250     while (nDiff < MAXTIMEDIFFS) {
251         struct timeval tv, ntv;
252         int counting = 2;               /* a counting kernel */
253         gettimeofday (&tv, 0);
254         do {
255             gettimeofday (&ntv, 0);
256
257             /*
258              * Bail if we are taking too long -- 30 seconds is arbitrary,
259              * but better than the previous approach, which was to bail
260              * after an arbitrary count of calls to gettimeofday().  This
261              * caused problems because the machines kept getting faster
262              * and the count kept getting exceeded.
263              */
264             if (ntv.tv_sec - tv0.tv_sec > 30) return 0;
265
266             interval = (ntv.tv_sec - tv.tv_sec)*1000000 +
267                 ntv.tv_usec - tv.tv_usec;
268             if (interval <= counting) counting = interval+2;
269         } while (interval <= counting); /* RT & sun4/280 kernels count */
270         if (interval < 0) return 0;     /* shouldn't happen but who knows... */
271         if (interval > 0) diff[nDiff++] = interval;
272     }
273
274     /* find average interval */
275     interval = 0;
276     for (i=0; i<MAXTIMEDIFFS; i++)
277         interval += diff[i];
278     interval = (interval + (MAXTIMEDIFFS/2)) / MAXTIMEDIFFS; /* round */
279     if (interval == 0) return 0;        /* some problem... */
280     if (intervalP) *intervalP = interval;
281
282     /* calculate binary exponent of interval in seconds */
283     q = 1000000;
284     i = 0;
285     while (q > interval) {
286         q >>= 1;
287         i--;
288     }
289     return i;
290 }