~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to libntp/machines.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2004-10-11 16:10:27 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041011161027-icyjbji8ujym633o
Tags: 1:4.2.0a-10ubuntu2
Use ntp.ubuntulinux.org instead of pool.ntp.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#endif
19
19
 
20
20
#ifdef SYS_WINNT
21
 
# include <conio.h>
 
21
int _getch(void);       /* Declare the one function rather than include conio.h */
22
22
#else
23
23
 
24
24
#ifdef SYS_VXWORKS
125
125
}
126
126
#endif /* SYS_PTX */
127
127
 
 
128
#ifdef MPE
 
129
/* This is a substitute for bind() that if called for an AF_INET socket
 
130
port less than 1024, GETPRIVMODE() and GETUSERMODE() calls will be done. */
 
131
 
 
132
#undef bind
 
133
#include <sys/types.h>
 
134
#include <sys/socket.h>
 
135
#include <netinet/in.h>
 
136
#include <sys/un.h>
 
137
 
 
138
extern void GETPRIVMODE(void);
 
139
extern void GETUSERMODE(void);
 
140
 
 
141
int __ntp_mpe_bind(int s, void *addr, int addrlen);
 
142
 
 
143
int __ntp_mpe_bind(int s, void *addr, int addrlen) {
 
144
        int priv = 0;
 
145
        int result;
 
146
 
 
147
if (addrlen == sizeof(struct sockaddr_in)) { /* AF_INET */
 
148
        if (((struct sockaddr_in *)addr)->sin_port > 0 &&
 
149
            ((struct sockaddr_in *)addr)->sin_port < 1024) {
 
150
                priv = 1;
 
151
                GETPRIVMODE();
 
152
        }
 
153
/*      ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0; */
 
154
        result = bind(s,addr,addrlen);
 
155
        if (priv == 1) GETUSERMODE();
 
156
} else /* AF_UNIX */
 
157
        result = bind(s,addr,addrlen);
 
158
 
 
159
return result;
 
160
}
 
161
 
 
162
/*
 
163
 * MPE stupidly requires sfcntl() to be used on sockets instead of fcntl(),
 
164
 * so we define a wrapper to analyze the file descriptor and call the correct
 
165
 * function.
 
166
 */
 
167
 
 
168
#undef fcntl
 
169
#include <errno.h>
 
170
#include <fcntl.h>
 
171
 
 
172
int __ntp_mpe_fcntl(int fd, int cmd, int arg);
 
173
 
 
174
int __ntp_mpe_fcntl(int fd, int cmd, int arg) {
 
175
        int len;
 
176
        struct sockaddr sa;
 
177
 
 
178
        extern int sfcntl(int, int, int);
 
179
 
 
180
        len = sizeof sa;
 
181
        if (getsockname(fd, &sa, &len) == -1) {
 
182
                if (errno == EAFNOSUPPORT) /* AF_UNIX socket */
 
183
                        return sfcntl(fd, cmd, arg);
 
184
                if (errno == ENOTSOCK) /* file or pipe */
 
185
                        return fcntl(fd, cmd, arg);
 
186
                return (-1); /* unknown getsockname() failure */
 
187
        } else /* AF_INET socket */
 
188
                return sfcntl(fd, cmd, arg);
 
189
}
 
190
 
 
191
/*
 
192
 * Setitimer emulation support.  Note that we implement this using alarm(),
 
193
 * and since alarm() only delivers one signal, we must re-enable the alarm
 
194
 * by enabling our own SIGALRM setitimer_mpe_handler routine to be called
 
195
 * before the real handler routine and re-enable the alarm at that time.
 
196
 *
 
197
 * Note that this solution assumes that sigaction(SIGALRM) is called before
 
198
 * calling setitimer().  If it should ever to become necessary to support
 
199
 * sigaction(SIGALRM) after calling setitimer(), it will be necessary to trap
 
200
 * those sigaction() calls.
 
201
 */
 
202
 
 
203
#include <limits.h>
 
204
#include <signal.h>
 
205
 
 
206
/*
 
207
 * Some global data that needs to be shared between setitimer() and
 
208
 * setitimer_mpe_handler().
 
209
 */
 
210
 
 
211
struct {
 
212
        unsigned long current_msec;     /* current alarm() value in effect */
 
213
        unsigned long interval_msec;    /* next alarm() value from setitimer */
 
214
        unsigned long value_msec;       /* first alarm() value from setitimer */
 
215
        struct itimerval current_itimerval; /* current itimerval in effect */
 
216
        struct sigaction oldact;        /* SIGALRM state saved by setitimer */
 
217
} setitimer_mpe_ctx = { 0, 0, 0 };
 
218
 
 
219
/*
 
220
 * Undocumented, unsupported function to do alarm() in milliseconds.
 
221
 */
 
222
 
 
223
extern unsigned int px_alarm(unsigned long, int *);
 
224
 
 
225
/*
 
226
 * The SIGALRM handler routine enabled by setitimer().  Re-enable the alarm or
 
227
 * restore the original SIGALRM setting if no more alarms are needed.  Then
 
228
 * call the original SIGALRM handler (if any).
 
229
 */
 
230
 
 
231
static RETSIGTYPE setitimer_mpe_handler(int sig)
 
232
{
 
233
int alarm_hpe_status;
 
234
 
 
235
/* Update the new current alarm value */
 
236
 
 
237
setitimer_mpe_ctx.current_msec = setitimer_mpe_ctx.interval_msec;
 
238
 
 
239
if (setitimer_mpe_ctx.interval_msec > 0) {
 
240
  /* Additional intervals needed; re-arm the alarm timer */
 
241
  px_alarm(setitimer_mpe_ctx.interval_msec,&alarm_hpe_status);
 
242
} else {
 
243
  /* No more intervals, so restore previous original SIGALRM handler */
 
244
  sigaction(SIGALRM, &setitimer_mpe_ctx.oldact, NULL);
 
245
}
 
246
 
 
247
/* Call the original SIGALRM handler if it is a function and not just a flag */
 
248
 
 
249
if (setitimer_mpe_ctx.oldact.sa_handler != SIG_DFL &&
 
250
    setitimer_mpe_ctx.oldact.sa_handler != SIG_ERR &&
 
251
    setitimer_mpe_ctx.oldact.sa_handler != SIG_IGN)
 
252
  (*setitimer_mpe_ctx.oldact.sa_handler)(SIGALRM);
 
253
 
 
254
}
 
255
 
 
256
/*
 
257
 * Our implementation of setitimer().
 
258
 */
 
259
 
 
260
int
 
261
setitimer(int which, struct itimerval *value,
 
262
            struct itimerval *ovalue)
 
263
{
 
264
 
 
265
int alarm_hpe_status;
 
266
unsigned long remaining_msec, value_msec, interval_msec;
 
267
struct sigaction newact;
 
268
 
 
269
/* 
 
270
 * Convert the initial interval to milliseconds
 
271
 */
 
272
 
 
273
if (value->it_value.tv_sec > (UINT_MAX / 1000))
 
274
  value_msec = UINT_MAX;
 
275
else
 
276
  value_msec = value->it_value.tv_sec * 1000;
 
277
 
 
278
value_msec += value->it_value.tv_usec / 1000;
 
279
 
 
280
/*
 
281
 * Convert the reset interval to milliseconds
 
282
 */
 
283
 
 
284
if (value->it_interval.tv_sec > (UINT_MAX / 1000))
 
285
  interval_msec = UINT_MAX;
 
286
else
 
287
  interval_msec = value->it_interval.tv_sec * 1000;
 
288
 
 
289
interval_msec += value->it_interval.tv_usec / 1000;
 
290
 
 
291
if (value_msec > 0 && interval_msec > 0) {
 
292
  /*
 
293
   * We'll be starting an interval timer that will be repeating, so we need to
 
294
   * insert our own SIGALRM signal handler to schedule the repeats.
 
295
   */
 
296
 
 
297
  /* Read the current SIGALRM action */
 
298
 
 
299
  if (sigaction(SIGALRM, NULL, &setitimer_mpe_ctx.oldact) < 0) {
 
300
    fprintf(stderr,"MPE setitimer old handler failed, errno=%d\n",errno);
 
301
    return -1;
 
302
  }
 
303
 
 
304
  /* Initialize the new action to call our SIGALRM handler instead */
 
305
 
 
306
  newact.sa_handler = &setitimer_mpe_handler;
 
307
  newact.sa_mask = setitimer_mpe_ctx.oldact.sa_mask;
 
308
  newact.sa_flags = setitimer_mpe_ctx.oldact.sa_flags;
 
309
 
 
310
  if (sigaction(SIGALRM, &newact, NULL) < 0) {
 
311
    fprintf(stderr,"MPE setitimer new handler failed, errno=%d\n",errno);
 
312
    return -1;
 
313
  }
 
314
}
 
315
 
 
316
/*
 
317
 * Return previous itimerval if desired
 
318
 */
 
319
 
 
320
if (ovalue != NULL) *ovalue = setitimer_mpe_ctx.current_itimerval;
 
321
 
 
322
/*
 
323
 * Save current parameters for later usage
 
324
 */
 
325
 
 
326
setitimer_mpe_ctx.current_itimerval = *value;
 
327
setitimer_mpe_ctx.current_msec = value_msec;
 
328
setitimer_mpe_ctx.value_msec = value_msec;
 
329
setitimer_mpe_ctx.interval_msec = interval_msec;
 
330
 
 
331
/*
 
332
 * Schedule the first alarm
 
333
 */
 
334
 
 
335
remaining_msec = px_alarm(value_msec, &alarm_hpe_status);
 
336
if (alarm_hpe_status == 0)
 
337
  return (0);
 
338
else
 
339
  return (-1);
 
340
}
 
341
 
 
342
/* 
 
343
 * MPE lacks gettimeofday(), so we define our own.
 
344
 */
 
345
 
 
346
int gettimeofday(struct timeval *tvp)
 
347
 
 
348
{
 
349
/* Documented, supported MPE functions. */
 
350
extern void GETPRIVMODE(void);
 
351
extern void GETUSERMODE(void);
 
352
 
 
353
/* Undocumented, unsupported MPE functions. */
 
354
extern long long get_time(void);
 
355
extern void get_time_change_info(long long *, char *, char *);
 
356
extern long long ticks_to_micro(long long);
 
357
 
 
358
char pwf_since_boot, recover_pwf_time;
 
359
long long mpetime, offset_ticks, offset_usec;
 
360
 
 
361
GETPRIVMODE();
 
362
mpetime = get_time(); /* MPE local time usecs since Jan 1 1970 */
 
363
get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
 
364
offset_usec = ticks_to_micro(offset_ticks);  /* UTC offset usecs */
 
365
GETUSERMODE();
 
366
 
 
367
mpetime = mpetime - offset_usec;  /* Convert from local time to UTC */
 
368
tvp->tv_sec = mpetime / 1000000LL;
 
369
tvp->tv_usec = mpetime % 1000000LL;
 
370
 
 
371
return 0;
 
372
}
 
373
 
 
374
/* 
 
375
 * MPE lacks settimeofday(), so we define our own.
 
376
 */
 
377
 
 
378
#define HAVE_SETTIMEOFDAY
 
379
 
 
380
int settimeofday(struct timeval *tvp)
 
381
 
 
382
{
 
383
/* Documented, supported MPE functions. */
 
384
extern void GETPRIVMODE(void);
 
385
extern void GETUSERMODE(void);
 
386
 
 
387
/* Undocumented, unsupported MPE functions. */
 
388
extern void get_time_change_info(long long *, char *, char *);
 
389
extern void initialize_system_time(long long, int);
 
390
extern void set_time_correction(long long, int, int);
 
391
extern long long ticks_to_micro(long long);
 
392
 
 
393
char pwf_since_boot, recover_pwf_time;
 
394
long long big_sec, big_usec, mpetime, offset_ticks, offset_usec;
 
395
 
 
396
big_sec = tvp->tv_sec;
 
397
big_usec = tvp->tv_usec;
 
398
mpetime = (big_sec * 1000000LL) + big_usec;  /* Desired UTC microseconds */
 
399
 
 
400
GETPRIVMODE();
 
401
set_time_correction(0LL,0,0); /* Cancel previous time correction, if any */
 
402
get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
 
403
offset_usec = ticks_to_micro(offset_ticks); /* UTC offset microseconds */
 
404
mpetime = mpetime + offset_usec; /* Convert from UTC to local time */
 
405
initialize_system_time(mpetime,1);
 
406
GETUSERMODE();
 
407
 
 
408
return 0;
 
409
}
 
410
#endif /* MPE */
 
411
 
128
412
const char *set_tod_using = "UNKNOWN";
129
413
 
130
414
int
133
417
        void *tzp
134
418
        )
135
419
{
136
 
        int rc;
 
420
        int rc = -1;
 
421
 
 
422
#ifdef DEBUG
 
423
        if (debug)
 
424
            printf("In ntp_set_tod\n");
 
425
#endif
137
426
 
138
427
#ifdef HAVE_CLOCK_SETTIME
139
 
        {
 
428
        if (rc) {
140
429
                struct timespec ts;
141
430
 
 
431
                set_tod_using = "clock_settime";
142
432
                /* Convert timeval to timespec */
143
433
                ts.tv_sec = tvp->tv_sec;
144
434
                ts.tv_nsec = 1000 *  tvp->tv_usec;
145
435
 
 
436
                errno = 0;
146
437
                rc = clock_settime(CLOCK_REALTIME, &ts);
147
 
                if (!rc)
148
 
                {
149
 
                        set_tod_using = "clock_settime";
150
 
                        return rc;
 
438
#ifdef DEBUG
 
439
                if (debug) {
 
440
                        printf("ntp_set_tod: %s: %d: %s\n",
 
441
                               set_tod_using, rc, strerror(errno));
151
442
                }
 
443
#endif
152
444
        }
153
445
#endif /* HAVE_CLOCK_SETTIME */
154
446
#ifdef HAVE_SETTIMEOFDAY
155
 
        {
 
447
        if (rc) {
 
448
                struct timeval adjtv;
 
449
 
 
450
                set_tod_using = "settimeofday";
 
451
                /*
 
452
                 * Some broken systems don't reset adjtime() when the
 
453
                 * clock is stepped.
 
454
                 */
 
455
                adjtv.tv_sec = adjtv.tv_usec = 0;
 
456
                adjtime(&adjtv, NULL);
156
457
                rc = SETTIMEOFDAY(tvp, tzp);
157
 
                if (!rc)
158
 
                {
159
 
                        set_tod_using = "settimeofday";
160
 
                        return rc;
 
458
#ifdef DEBUG
 
459
                if (debug) {
 
460
                        printf("ntp_set_tod: %s: %d: %s\n",
 
461
                               set_tod_using, rc, strerror(errno));
161
462
                }
 
463
#endif
162
464
        }
163
465
#endif /* HAVE_SETTIMEOFDAY */
164
466
#ifdef HAVE_STIME
165
 
        {
 
467
        if (rc) {
166
468
                long tp = tvp->tv_sec;
167
469
 
 
470
                set_tod_using = "stime";
168
471
                rc = stime(&tp); /* lie as bad as SysVR4 */
169
 
                if (!rc)
170
 
                {
171
 
                        set_tod_using = "stime";
172
 
                        return rc;
 
472
#ifdef DEBUG
 
473
                if (debug) {
 
474
                        printf("ntp_set_tod: %s: %d: %s\n",
 
475
                               set_tod_using, rc, strerror(errno));
173
476
                }
 
477
#endif
174
478
        }
175
479
#endif /* HAVE_STIME */
176
 
        set_tod_using = "Failed!";
177
 
        return -1;
 
480
        if (rc)
 
481
            set_tod_using = "Failed!";
 
482
#ifdef DEBUG
 
483
        if (debug) {
 
484
                printf("ntp_set_tod: Final result: %s: %d: %s\n",
 
485
                        set_tod_using, rc, strerror(errno));
 
486
        }
 
487
#endif
 
488
        return rc;
178
489
}
179
490
 
180
491
#endif /* not SYS_WINNT */
181
492
 
182
 
#if defined (SYS_WINNT) || defined (SYS_VXWORKS)
 
493
#if defined (SYS_WINNT) || defined (SYS_VXWORKS) || defined(MPE)
183
494
/* getpass is used in ntpq.c and ntpdc.c */
184
495
 
185
496
char *