126
126
#endif /* SYS_PTX */
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. */
133
#include <sys/types.h>
134
#include <sys/socket.h>
135
#include <netinet/in.h>
138
extern void GETPRIVMODE(void);
139
extern void GETUSERMODE(void);
141
int __ntp_mpe_bind(int s, void *addr, int addrlen);
143
int __ntp_mpe_bind(int s, void *addr, int addrlen) {
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) {
153
/* ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0; */
154
result = bind(s,addr,addrlen);
155
if (priv == 1) GETUSERMODE();
157
result = bind(s,addr,addrlen);
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
172
int __ntp_mpe_fcntl(int fd, int cmd, int arg);
174
int __ntp_mpe_fcntl(int fd, int cmd, int arg) {
178
extern int sfcntl(int, int, int);
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);
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.
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.
207
* Some global data that needs to be shared between setitimer() and
208
* setitimer_mpe_handler().
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 };
220
* Undocumented, unsupported function to do alarm() in milliseconds.
223
extern unsigned int px_alarm(unsigned long, int *);
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).
231
static RETSIGTYPE setitimer_mpe_handler(int sig)
233
int alarm_hpe_status;
235
/* Update the new current alarm value */
237
setitimer_mpe_ctx.current_msec = setitimer_mpe_ctx.interval_msec;
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);
243
/* No more intervals, so restore previous original SIGALRM handler */
244
sigaction(SIGALRM, &setitimer_mpe_ctx.oldact, NULL);
247
/* Call the original SIGALRM handler if it is a function and not just a flag */
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);
257
* Our implementation of setitimer().
261
setitimer(int which, struct itimerval *value,
262
struct itimerval *ovalue)
265
int alarm_hpe_status;
266
unsigned long remaining_msec, value_msec, interval_msec;
267
struct sigaction newact;
270
* Convert the initial interval to milliseconds
273
if (value->it_value.tv_sec > (UINT_MAX / 1000))
274
value_msec = UINT_MAX;
276
value_msec = value->it_value.tv_sec * 1000;
278
value_msec += value->it_value.tv_usec / 1000;
281
* Convert the reset interval to milliseconds
284
if (value->it_interval.tv_sec > (UINT_MAX / 1000))
285
interval_msec = UINT_MAX;
287
interval_msec = value->it_interval.tv_sec * 1000;
289
interval_msec += value->it_interval.tv_usec / 1000;
291
if (value_msec > 0 && interval_msec > 0) {
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.
297
/* Read the current SIGALRM action */
299
if (sigaction(SIGALRM, NULL, &setitimer_mpe_ctx.oldact) < 0) {
300
fprintf(stderr,"MPE setitimer old handler failed, errno=%d\n",errno);
304
/* Initialize the new action to call our SIGALRM handler instead */
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;
310
if (sigaction(SIGALRM, &newact, NULL) < 0) {
311
fprintf(stderr,"MPE setitimer new handler failed, errno=%d\n",errno);
317
* Return previous itimerval if desired
320
if (ovalue != NULL) *ovalue = setitimer_mpe_ctx.current_itimerval;
323
* Save current parameters for later usage
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;
332
* Schedule the first alarm
335
remaining_msec = px_alarm(value_msec, &alarm_hpe_status);
336
if (alarm_hpe_status == 0)
343
* MPE lacks gettimeofday(), so we define our own.
346
int gettimeofday(struct timeval *tvp)
349
/* Documented, supported MPE functions. */
350
extern void GETPRIVMODE(void);
351
extern void GETUSERMODE(void);
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);
358
char pwf_since_boot, recover_pwf_time;
359
long long mpetime, offset_ticks, offset_usec;
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 */
367
mpetime = mpetime - offset_usec; /* Convert from local time to UTC */
368
tvp->tv_sec = mpetime / 1000000LL;
369
tvp->tv_usec = mpetime % 1000000LL;
375
* MPE lacks settimeofday(), so we define our own.
378
#define HAVE_SETTIMEOFDAY
380
int settimeofday(struct timeval *tvp)
383
/* Documented, supported MPE functions. */
384
extern void GETPRIVMODE(void);
385
extern void GETUSERMODE(void);
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);
393
char pwf_since_boot, recover_pwf_time;
394
long long big_sec, big_usec, mpetime, offset_ticks, offset_usec;
396
big_sec = tvp->tv_sec;
397
big_usec = tvp->tv_usec;
398
mpetime = (big_sec * 1000000LL) + big_usec; /* Desired UTC microseconds */
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);
128
412
const char *set_tod_using = "UNKNOWN";
424
printf("In ntp_set_tod\n");
138
427
#ifdef HAVE_CLOCK_SETTIME
140
429
struct timespec ts;
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;
146
437
rc = clock_settime(CLOCK_REALTIME, &ts);
149
set_tod_using = "clock_settime";
440
printf("ntp_set_tod: %s: %d: %s\n",
441
set_tod_using, rc, strerror(errno));
153
445
#endif /* HAVE_CLOCK_SETTIME */
154
446
#ifdef HAVE_SETTIMEOFDAY
448
struct timeval adjtv;
450
set_tod_using = "settimeofday";
452
* Some broken systems don't reset adjtime() when the
455
adjtv.tv_sec = adjtv.tv_usec = 0;
456
adjtime(&adjtv, NULL);
156
457
rc = SETTIMEOFDAY(tvp, tzp);
159
set_tod_using = "settimeofday";
460
printf("ntp_set_tod: %s: %d: %s\n",
461
set_tod_using, rc, strerror(errno));
163
465
#endif /* HAVE_SETTIMEOFDAY */
164
466
#ifdef HAVE_STIME
166
468
long tp = tvp->tv_sec;
470
set_tod_using = "stime";
168
471
rc = stime(&tp); /* lie as bad as SysVR4 */
171
set_tod_using = "stime";
474
printf("ntp_set_tod: %s: %d: %s\n",
475
set_tod_using, rc, strerror(errno));
175
479
#endif /* HAVE_STIME */
176
set_tod_using = "Failed!";
481
set_tod_using = "Failed!";
484
printf("ntp_set_tod: Final result: %s: %d: %s\n",
485
set_tod_using, rc, strerror(errno));
180
491
#endif /* not SYS_WINNT */
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 */