Annotation of embedaddon/ntp/libntp/machines.c, revision 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>