Coverage Report

Created: 2026-02-26 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntp-dev/libntp/machines.c
Line
Count
Source
1
/* machines.c - provide special support for peculiar architectures
2
 *
3
 * Real bummers unite !
4
 *
5
 */
6
7
#ifdef HAVE_CONFIG_H
8
#include "config.h"
9
#endif
10
11
#include "ntp.h"
12
#include "ntp_machine.h"
13
#include "ntp_syslog.h"
14
#include "ntp_stdlib.h"
15
#include "ntp_unixtime.h"
16
#include "ntp_debug.h"
17
#include "ntp_tty.h"
18
19
#ifdef HAVE_UNISTD_H
20
#include <unistd.h>
21
#endif
22
23
#ifdef SYS_WINNT
24
#include <conio.h>
25
#else
26
#ifdef SYS_VXWORKS
27
#include "taskLib.h"
28
#include "sysLib.h"
29
#include "time.h"
30
#include "ntp_syslog.h"
31
32
/*  some translations to the world of vxWorkings -casey */
33
/* first some netdb type things */
34
#include "ioLib.h"
35
#include <socket.h>
36
int h_errno;
37
38
struct hostent *gethostbyname(char *name)
39
  {
40
  struct hostent *host1;
41
  h_errno = 0;          /* we are always successful!!! */
42
  host1 = (struct hostent *) emalloc (sizeof(struct hostent));
43
  host1->h_name = name;
44
  host1->h_addrtype = AF_INET;
45
  host1->h_aliases = name;
46
  host1->h_length = 4;
47
  host1->h_addr_list[0] = (char *)hostGetByName (name);
48
  host1->h_addr_list[1] = NULL;
49
  return host1;
50
  }
51
52
struct hostent *gethostbyaddr(char *name, int size, int addr_type)
53
  {
54
  struct hostent *host1;
55
  h_errno = 0;  /* we are always successful!!! */
56
  host1 = (struct hostent *) emalloc (sizeof(struct hostent));
57
  host1->h_name = name;
58
  host1->h_addrtype = AF_INET;
59
  host1->h_aliases = name;
60
  host1->h_length = 4;
61
  host1->h_addr_list = NULL;
62
  return host1;
63
  }
64
65
struct servent *getservbyname (char *name, char *type)
66
  {
67
  struct servent *serv1;
68
  serv1 = (struct servent *) emalloc (sizeof(struct servent));
69
  serv1->s_name = "ntp";      /* official service name */
70
  serv1->s_aliases = NULL;  /* alias list */
71
  serv1->s_port = 123;    /* port # */
72
  serv1->s_proto = "udp";     /* protocol to use */
73
  return serv1;
74
  }
75
76
/* second
77
 * vxworks thinks it has insomnia
78
 * we have to sleep for number of seconds
79
 */
80
81
#define CLKRATE   sysClkRateGet()
82
83
/* I am not sure how valid the granularity is - it is from G. Eger's port */
84
#define CLK_GRANULARITY  1    /* Granularity of system clock in usec  */
85
                /* Used to round down # usecs/tick    */
86
                /* On a VCOM-100, PIT gets 8 MHz clk, */
87
                /*  & it prescales by 32, thus 4 usec */
88
                /* on mv167, granularity is 1usec anyway*/
89
                /* To defeat rounding, set to 1     */
90
#define USECS_PER_SEC   MILLION   /* Microseconds per second  */
91
#define TICK (((USECS_PER_SEC / CLKRATE) / CLK_GRANULARITY) * CLK_GRANULARITY)
92
93
/* emulate unix sleep
94
 * casey
95
 */
96
void sleep(int seconds)
97
  {
98
  taskDelay(seconds*TICK);
99
  }
100
/* emulate unix alarm
101
 * that pauses and calls SIGALRM after the seconds are up...
102
 * so ... taskDelay() fudged for seconds should amount to the same thing.
103
 * casey
104
 */
105
void alarm (int seconds)
106
  {
107
  sleep(seconds);
108
  }
109
110
#endif /* SYS_VXWORKS */
111
112
#ifdef SYS_PTX      /* Does PTX still need this? */
113
/*#include <sys/types.h>  */
114
#include <sys/procstats.h>
115
116
int
117
gettimeofday(
118
  struct timeval *tvp
119
  )
120
{
121
  /*
122
   * hi, this is Sequents sneak path to get to a clock
123
   * this is also the most logical syscall for such a function
124
   */
125
  return (get_process_stats(tvp, PS_SELF, (struct procstats *) 0,
126
          (struct procstats *) 0));
127
}
128
#endif /* SYS_PTX */
129
130
#ifdef MPE
131
/* This is a substitute for bind() that if called for an AF_INET socket
132
port less than 1024, GETPRIVMODE() and GETUSERMODE() calls will be done. */
133
134
#undef bind
135
#include <sys/types.h>
136
#include <sys/socket.h>
137
#include <netinet/in.h>
138
#include <sys/un.h>
139
140
extern void GETPRIVMODE(void);
141
extern void GETUSERMODE(void);
142
143
int __ntp_mpe_bind(int s, void *addr, int addrlen);
144
145
int __ntp_mpe_bind(int s, void *addr, int addrlen) {
146
  int priv = 0;
147
  int result;
148
149
if (addrlen == sizeof(struct sockaddr_in)) { /* AF_INET */
150
  if (((struct sockaddr_in *)addr)->sin_port > 0 &&
151
      ((struct sockaddr_in *)addr)->sin_port < 1024) {
152
    priv = 1;
153
    GETPRIVMODE();
154
  }
155
/*  ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0; */
156
  result = bind(s,addr,addrlen);
157
  if (priv == 1) GETUSERMODE();
158
} else /* AF_UNIX */
159
  result = bind(s,addr,addrlen);
160
161
return result;
162
}
163
164
/*
165
 * MPE stupidly requires sfcntl() to be used on sockets instead of fcntl(),
166
 * so we define a wrapper to analyze the file descriptor and call the correct
167
 * function.
168
 */
169
170
#undef fcntl
171
#include <errno.h>
172
#include <fcntl.h>
173
174
int __ntp_mpe_fcntl(int fd, int cmd, int arg);
175
176
int __ntp_mpe_fcntl(int fd, int cmd, int arg) {
177
  int len;
178
  struct sockaddr sa;
179
180
  extern int sfcntl(int, int, int);
181
182
  len = sizeof sa;
183
  if (getsockname(fd, &sa, &len) == -1) {
184
    if (errno == EAFNOSUPPORT) /* AF_UNIX socket */
185
      return sfcntl(fd, cmd, arg);
186
    if (errno == ENOTSOCK) /* file or pipe */
187
      return fcntl(fd, cmd, arg);
188
    return (-1); /* unknown getsockname() failure */
189
  } else /* AF_INET socket */
190
    return sfcntl(fd, cmd, arg);
191
}
192
193
/*
194
 * Setitimer emulation support.  Note that we implement this using alarm(),
195
 * and since alarm() only delivers one signal, we must re-enable the alarm
196
 * by enabling our own SIGALRM setitimer_mpe_handler routine to be called
197
 * before the real handler routine and re-enable the alarm at that time.
198
 *
199
 * Note that this solution assumes that sigaction(SIGALRM) is called before
200
 * calling setitimer().  If it should ever to become necessary to support
201
 * sigaction(SIGALRM) after calling setitimer(), it will be necessary to trap
202
 * those sigaction() calls.
203
 */
204
205
#include <limits.h>
206
#include <signal.h>
207
208
/*
209
 * Some global data that needs to be shared between setitimer() and
210
 * setitimer_mpe_handler().
211
 */
212
213
struct {
214
  unsigned long current_msec; /* current alarm() value in effect */
215
  unsigned long interval_msec;  /* next alarm() value from setitimer */
216
  unsigned long value_msec; /* first alarm() value from setitimer */
217
  struct itimerval current_itimerval; /* current itimerval in effect */
218
  struct sigaction oldact;  /* SIGALRM state saved by setitimer */
219
} setitimer_mpe_ctx = { 0, 0, 0 };
220
221
/*
222
 * Undocumented, unsupported function to do alarm() in milliseconds.
223
 */
224
225
extern unsigned int px_alarm(unsigned long, int *);
226
227
/*
228
 * The SIGALRM handler routine enabled by setitimer().  Re-enable the alarm or
229
 * restore the original SIGALRM setting if no more alarms are needed.  Then
230
 * call the original SIGALRM handler (if any).
231
 */
232
233
static RETSIGTYPE setitimer_mpe_handler(int sig)
234
{
235
int alarm_hpe_status;
236
237
/* Update the new current alarm value */
238
239
setitimer_mpe_ctx.current_msec = setitimer_mpe_ctx.interval_msec;
240
241
if (setitimer_mpe_ctx.interval_msec > 0) {
242
  /* Additional intervals needed; re-arm the alarm timer */
243
  px_alarm(setitimer_mpe_ctx.interval_msec,&alarm_hpe_status);
244
} else {
245
  /* No more intervals, so restore previous original SIGALRM handler */
246
  sigaction(SIGALRM, &setitimer_mpe_ctx.oldact, NULL);
247
}
248
249
/* Call the original SIGALRM handler if it is a function and not just a flag */
250
251
if (setitimer_mpe_ctx.oldact.sa_handler != SIG_DFL &&
252
    setitimer_mpe_ctx.oldact.sa_handler != SIG_ERR &&
253
    setitimer_mpe_ctx.oldact.sa_handler != SIG_IGN)
254
  (*setitimer_mpe_ctx.oldact.sa_handler)(SIGALRM);
255
256
}
257
258
/*
259
 * Our implementation of setitimer().
260
 */
261
262
int
263
setitimer(int which, struct itimerval *value,
264
      struct itimerval *ovalue)
265
{
266
267
int alarm_hpe_status;
268
unsigned long remaining_msec, value_msec, interval_msec;
269
struct sigaction newact;
270
271
/* 
272
 * Convert the initial interval to milliseconds
273
 */
274
275
if (value->it_value.tv_sec > (UINT_MAX / 1000))
276
  value_msec = UINT_MAX;
277
else
278
  value_msec = value->it_value.tv_sec * 1000;
279
280
value_msec += value->it_value.tv_usec / 1000;
281
282
/*
283
 * Convert the reset interval to milliseconds
284
 */
285
286
if (value->it_interval.tv_sec > (UINT_MAX / 1000))
287
  interval_msec = UINT_MAX;
288
else
289
  interval_msec = value->it_interval.tv_sec * 1000;
290
291
interval_msec += value->it_interval.tv_usec / 1000;
292
293
if (value_msec > 0 && interval_msec > 0) {
294
  /*
295
   * We'll be starting an interval timer that will be repeating, so we need to
296
   * insert our own SIGALRM signal handler to schedule the repeats.
297
   */
298
299
  /* Read the current SIGALRM action */
300
301
  if (sigaction(SIGALRM, NULL, &setitimer_mpe_ctx.oldact) < 0) {
302
    fprintf(stderr,"MPE setitimer old handler failed, errno=%d\n",errno);
303
    return -1;
304
  }
305
306
  /* Initialize the new action to call our SIGALRM handler instead */
307
308
  newact.sa_handler = &setitimer_mpe_handler;
309
  newact.sa_mask = setitimer_mpe_ctx.oldact.sa_mask;
310
  newact.sa_flags = setitimer_mpe_ctx.oldact.sa_flags;
311
 
312
  if (sigaction(SIGALRM, &newact, NULL) < 0) {
313
    fprintf(stderr,"MPE setitimer new handler failed, errno=%d\n",errno);
314
    return -1;
315
  }
316
}
317
318
/*
319
 * Return previous itimerval if desired
320
 */
321
322
if (ovalue != NULL) *ovalue = setitimer_mpe_ctx.current_itimerval;
323
324
/*
325
 * Save current parameters for later usage
326
 */
327
328
setitimer_mpe_ctx.current_itimerval = *value;
329
setitimer_mpe_ctx.current_msec = value_msec;
330
setitimer_mpe_ctx.value_msec = value_msec;
331
setitimer_mpe_ctx.interval_msec = interval_msec;
332
333
/*
334
 * Schedule the first alarm
335
 */
336
337
remaining_msec = px_alarm(value_msec, &alarm_hpe_status);
338
if (alarm_hpe_status == 0)
339
  return (0);
340
else
341
  return (-1);
342
}
343
344
/* 
345
 * MPE lacks gettimeofday(), so we define our own.
346
 */
347
348
int gettimeofday(struct timeval *tvp)
349
350
{
351
/* Documented, supported MPE functions. */
352
extern void GETPRIVMODE(void);
353
extern void GETUSERMODE(void);
354
355
/* Undocumented, unsupported MPE functions. */
356
extern long long get_time(void);
357
extern void get_time_change_info(long long *, char *, char *);
358
extern long long ticks_to_micro(long long);
359
360
char pwf_since_boot, recover_pwf_time;
361
long long mpetime, offset_ticks, offset_usec;
362
363
GETPRIVMODE();
364
mpetime = get_time(); /* MPE local time usecs since Jan 1 1970 */
365
get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
366
offset_usec = ticks_to_micro(offset_ticks);  /* UTC offset usecs */
367
GETUSERMODE();
368
369
mpetime = mpetime - offset_usec;  /* Convert from local time to UTC */
370
tvp->tv_sec = mpetime / 1000000LL;
371
tvp->tv_usec = mpetime % 1000000LL;
372
373
return 0;
374
}
375
376
/* 
377
 * MPE lacks settimeofday(), so we define our own.
378
 */
379
380
#define HAVE_SETTIMEOFDAY
381
382
int settimeofday(struct timeval *tvp)
383
384
{
385
/* Documented, supported MPE functions. */
386
extern void GETPRIVMODE(void);
387
extern void GETUSERMODE(void);
388
389
/* Undocumented, unsupported MPE functions. */
390
extern void get_time_change_info(long long *, char *, char *);
391
extern void initialize_system_time(long long, int);
392
extern void set_time_correction(long long, int, int);
393
extern long long ticks_to_micro(long long);
394
395
char pwf_since_boot, recover_pwf_time;
396
long long big_sec, big_usec, mpetime, offset_ticks, offset_usec;
397
398
big_sec = tvp->tv_sec;
399
big_usec = tvp->tv_usec;
400
mpetime = (big_sec * 1000000LL) + big_usec;  /* Desired UTC microseconds */
401
402
GETPRIVMODE();
403
set_time_correction(0LL,0,0); /* Cancel previous time correction, if any */
404
get_time_change_info(&offset_ticks, &pwf_since_boot, &recover_pwf_time);
405
offset_usec = ticks_to_micro(offset_ticks); /* UTC offset microseconds */
406
mpetime = mpetime + offset_usec; /* Convert from UTC to local time */
407
initialize_system_time(mpetime,1);
408
GETUSERMODE();
409
410
return 0;
411
}
412
#endif /* MPE */
413
414
#define SET_TOD_UNDETERMINED  0
415
0
#define SET_TOD_CLOCK_SETTIME 1
416
0
#define SET_TOD_SETTIMEOFDAY  2
417
#define SET_TOD_STIME   3
418
419
const char * const set_tod_used[] = {
420
  "undetermined",
421
  "clock_settime",
422
  "settimeofday",
423
  "stime"
424
};
425
426
pset_tod_using  set_tod_using = NULL;
427
428
429
int
430
ntp_set_tod(
431
  struct timeval *tvp,
432
  void *tzp
433
  )
434
0
{
435
0
  static int  tod;
436
0
  int   rc;
437
0
  int   saved_errno;
438
439
0
  TRACE(1, ("In ntp_set_tod\n"));
440
0
  rc = -1;
441
0
  saved_errno = 0;
442
443
0
#ifdef HAVE_CLOCK_SETTIME
444
0
  if (rc && (SET_TOD_CLOCK_SETTIME == tod || !tod)) {
445
0
    struct timespec ts;
446
447
    /* Convert timeval to timespec */
448
0
    ts.tv_sec = tvp->tv_sec;
449
0
    ts.tv_nsec = 1000 *  tvp->tv_usec;
450
451
0
    errno = 0;
452
0
    rc = clock_settime(CLOCK_REALTIME, &ts);
453
0
    saved_errno = errno;
454
0
    TRACE(1, ("ntp_set_tod: clock_settime: %d %m\n", rc));
455
0
    if (!tod && !rc)
456
0
      tod = SET_TOD_CLOCK_SETTIME;
457
458
0
  }
459
0
#endif /* HAVE_CLOCK_SETTIME */
460
0
#ifdef HAVE_SETTIMEOFDAY
461
0
  if (rc && (SET_TOD_SETTIMEOFDAY == tod || !tod)) {
462
0
    struct timeval adjtv;
463
464
    /*
465
     * Some broken systems don't reset adjtime() when the
466
     * clock is stepped.
467
     */
468
0
    adjtv.tv_sec = adjtv.tv_usec = 0;
469
0
    adjtime(&adjtv, NULL);
470
0
    errno = 0;
471
0
    rc = SETTIMEOFDAY(tvp, tzp);
472
0
    saved_errno = errno;
473
0
    TRACE(1, ("ntp_set_tod: settimeofday: %d %m\n", rc));
474
0
    if (!tod && !rc)
475
0
      tod = SET_TOD_SETTIMEOFDAY;
476
0
  }
477
0
#endif /* HAVE_SETTIMEOFDAY */
478
#ifdef HAVE_STIME
479
  if (rc && (SET_TOD_STIME == tod || !tod)) {
480
    long tp = tvp->tv_sec;
481
482
    errno = 0;
483
    rc = stime(&tp); /* lie as bad as SysVR4 */
484
    saved_errno = errno;
485
    TRACE(1, ("ntp_set_tod: stime: %d %m\n", rc));
486
    if (!tod && !rc)
487
      tod = SET_TOD_STIME;
488
  }
489
#endif /* HAVE_STIME */
490
491
0
  errno = saved_errno;  /* for %m below */
492
0
  TRACE(1, ("ntp_set_tod: Final result: %s: %d %m\n",
493
0
      set_tod_used[tod], rc));
494
  /*
495
   * Say how we're setting the time of day
496
   */
497
0
  if (!rc && NULL != set_tod_using) {
498
0
    (*set_tod_using)(set_tod_used[tod]);
499
0
    set_tod_using = NULL;
500
0
  }
501
502
0
  if (rc)
503
0
    errno = saved_errno;
504
505
0
  return rc;
506
0
}
507
508
#endif /* not SYS_WINNT */
509
510
#if defined (SYS_WINNT) || defined (SYS_VXWORKS) || defined(MPE)
511
/* getpass is used in ntpq.c and ntpdc.c */
512
513
char *
514
getpass(const char * prompt)
515
{
516
  int c, i;
517
  static char password[32];
518
519
  fprintf(stderr, "%s", prompt);
520
  fflush(stderr);
521
522
  for (i=0; i<sizeof(password)-1 && ((c=_getch())!='\n' && c!='\r'); i++) {
523
    password[i] = (char) c;
524
  }
525
  password[i] = '\0';
526
527
  fputc('\n', stderr);
528
  fflush(stderr);
529
530
  return password;
531
}
532
#endif /* SYS_WINNT */
533
534
535
static const int baudTable[][2] = {
536
  {B0, 0},
537
  {B50, 50},
538
  {B75, 75},
539
  {B110, 110},
540
  {B134, 134},
541
  {B150, 150},
542
  {B200, 200},
543
  {B300, 300},
544
  {B600, 600},
545
  {B1200, 1200},
546
  {B1800, 1800},
547
  {B2400, 2400},
548
  {B4800, 4800},
549
  {B9600, 9600},
550
  {B19200, 19200},
551
  {B38400, 38400},
552
#   ifdef B57600
553
  {B57600, 57600 },
554
#   endif
555
#   ifdef B115200
556
  {B115200, 115200},
557
#   endif
558
  {-1, -1}
559
};
560
561
562
int  symBaud2numBaud(int symBaud)
563
0
{
564
0
  int i;
565
566
0
  for (i = 0; baudTable[i][1] >= 0; ++i) {
567
0
    if (baudTable[i][0] == symBaud) {
568
0
      break;
569
0
    }
570
0
  }
571
0
  return baudTable[i][1];
572
0
}
573
574
575
#if 0 /* unused */
576
int  numBaud2symBaud(int numBaud)
577
{
578
  int i;
579
580
  for (i = 0; baudTable[i][1] >= 0; ++i) {
581
    if (baudTable[i][1] == numBaud) {
582
      break;
583
    }
584
  }
585
  return baudTable[i][0];
586
}
587
#endif  /* unused fn */