Annotation of embedaddon/ntp/libntp/machines.c, revision 1.1.1.1

1.1       misho       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 "lib_strbuf.h"
                     17: 
                     18: #ifdef HAVE_UNISTD_H
                     19: #include <unistd.h>
                     20: #endif
                     21: 
                     22: #ifdef SYS_WINNT
                     23: int _getch(void);      /* Declare the one function rather than include conio.h */
                     24: #else
                     25: 
                     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 *) malloc (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 *) malloc (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 *) malloc (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: #define SET_TOD_CLOCK_SETTIME  1
                    416: #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: {
                    435:        static int tod;
                    436:        int rc = -1;
                    437:        int saved_errno = 0;
                    438: 
                    439: #ifdef DEBUG
                    440:        if (debug)
                    441:            printf("In ntp_set_tod\n");
                    442: #endif
                    443: 
                    444: #ifdef HAVE_CLOCK_SETTIME
                    445:        if (rc && (SET_TOD_CLOCK_SETTIME == tod || !tod)) {
                    446:                struct timespec ts;
                    447: 
                    448:                /* Convert timeval to timespec */
                    449:                ts.tv_sec = tvp->tv_sec;
                    450:                ts.tv_nsec = 1000 *  tvp->tv_usec;
                    451: 
                    452:                errno = 0;
                    453:                rc = clock_settime(CLOCK_REALTIME, &ts);
                    454:                saved_errno = errno;
                    455: #ifdef DEBUG
                    456:                if (debug) {
                    457:                        printf("ntp_set_tod: clock_settime: %d: %s\n",
                    458:                               rc, strerror(saved_errno));
                    459:                }
                    460: #endif
                    461:                if (!tod && !rc)
                    462:                        tod = SET_TOD_CLOCK_SETTIME;
                    463: 
                    464:        }
                    465: #endif /* HAVE_CLOCK_SETTIME */
                    466: #ifdef HAVE_SETTIMEOFDAY
                    467:        if (rc && (SET_TOD_SETTIMEOFDAY == tod || !tod)) {
                    468:                struct timeval adjtv;
                    469: 
                    470:                /*
                    471:                 * Some broken systems don't reset adjtime() when the
                    472:                 * clock is stepped.
                    473:                 */
                    474:                adjtv.tv_sec = adjtv.tv_usec = 0;
                    475:                adjtime(&adjtv, NULL);
                    476:                errno = 0;
                    477:                rc = SETTIMEOFDAY(tvp, tzp);
                    478:                saved_errno = errno;
                    479: #ifdef DEBUG
                    480:                if (debug) {
                    481:                        printf("ntp_set_tod: settimeofday: %d: %s\n",
                    482:                               rc, strerror(saved_errno));
                    483:                }
                    484: #endif
                    485:                if (!tod && !rc)
                    486:                        tod = SET_TOD_SETTIMEOFDAY;
                    487:        }
                    488: #endif /* HAVE_SETTIMEOFDAY */
                    489: #ifdef HAVE_STIME
                    490:        if (rc && (SET_TOD_STIME == tod || !tod)) {
                    491:                long tp = tvp->tv_sec;
                    492: 
                    493:                errno = 0;
                    494:                rc = stime(&tp); /* lie as bad as SysVR4 */
                    495:                saved_errno = errno;
                    496: #ifdef DEBUG
                    497:                if (debug) {
                    498:                        printf("ntp_set_tod: stime: %d: %s\n",
                    499:                               rc, strerror(saved_errno));
                    500:                }
                    501: #endif
                    502:                if (!tod && !rc)
                    503:                        tod = SET_TOD_STIME;
                    504:        }
                    505: #endif /* HAVE_STIME */
                    506: 
                    507: #ifdef DEBUG
                    508:        if (debug) {
                    509:                printf("ntp_set_tod: Final result: %s: %d: %s\n",
                    510:                        set_tod_used[tod], rc, strerror(saved_errno));
                    511:        }
                    512: #endif
                    513:        /*
                    514:         * Say how we're setting the time of day
                    515:         */
                    516:        if (!rc && NULL != set_tod_using) {
                    517:                (*set_tod_using)(set_tod_used[tod]);
                    518:                set_tod_using = NULL;
                    519:        }
                    520: 
                    521:        if (rc)
                    522:                errno = saved_errno;
                    523: 
                    524:        return rc;
                    525: }
                    526: 
                    527: #endif /* not SYS_WINNT */
                    528: 
                    529: #if defined (SYS_WINNT) || defined (SYS_VXWORKS) || defined(MPE)
                    530: /* getpass is used in ntpq.c and ntpdc.c */
                    531: 
                    532: char *
                    533: getpass(const char * prompt)
                    534: {
                    535:        int c, i;
                    536:        static char password[32];
                    537: 
                    538:        fprintf(stderr, "%s", prompt);
                    539:        fflush(stderr);
                    540: 
                    541:        for (i=0; i<sizeof(password)-1 && ((c=_getch())!='\n' && c!='\r'); i++) {
                    542:                password[i] = (char) c;
                    543:        }
                    544:        password[i] = '\0';
                    545: 
                    546:        fputc('\n', stderr);
                    547:        fflush(stderr);
                    548: 
                    549:        return password;
                    550: }
                    551: #endif /* SYS_WINNT */
                    552: 
                    553: #if !defined(HAVE_MEMSET)
                    554: void
                    555: ntp_memset(
                    556:        char *a,
                    557:        int x,
                    558:        int c
                    559:        )
                    560: {
                    561:        while (c-- > 0)
                    562:                *a++ = (char) x;
                    563: }
                    564: #endif /*POSIX*/

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>