1 /* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)correct.c 2.6 (Berkeley) 06/01/90"; 10 #endif /* not lint */ 11 12 #include "globals.h" 13 #include <protocols/timed.h> 14 15 #ifdef MEASURE 16 extern FILE *fp; 17 #endif 18 19 /* 20 * `correct' sends to the slaves the corrections for their clocks 21 */ 22 23 correct(avdelta) 24 long avdelta; 25 { 26 int i; 27 int corr; 28 struct timeval adjlocal; 29 struct tsp msgs; 30 struct timeval mstotvround(); 31 struct tsp *answer, *acksend(); 32 33 #ifdef MEASURE 34 for(i=0; i<slvcount; i++) { 35 if (hp[i].delta == HOSTDOWN) 36 fprintf(fp, "%s\t", "down"); 37 else { 38 fprintf(fp, "%d\t", hp[i].delta); 39 } 40 } 41 fprintf(fp, "\n"); 42 #endif 43 corr = avdelta - hp[0].delta; 44 adjlocal = mstotvround(&corr); 45 adjclock(&adjlocal); 46 #ifdef MEASURE 47 fprintf(fp, "%d\t", corr); 48 #endif 49 50 for(i=1; i<slvcount; i++) { 51 if (hp[i].delta != HOSTDOWN) { 52 corr = avdelta - hp[i].delta; 53 msgs.tsp_time = mstotvround(&corr); 54 msgs.tsp_type = (u_char)TSP_ADJTIME; 55 (void)strcpy(msgs.tsp_name, hostname); 56 answer = acksend(&msgs, &hp[i].addr, hp[i].name, 57 TSP_ACK, (struct netinfo *)NULL); 58 if (answer == NULL) { 59 hp[i].delta = HOSTDOWN; 60 #ifdef MEASURE 61 fprintf(fp, "%s\t", "down"); 62 } else { 63 fprintf(fp, "%d\t", corr); 64 #endif 65 } 66 } else { 67 #ifdef MEASURE 68 fprintf(fp, "%s\t", "down"); 69 #endif 70 } 71 } 72 #ifdef MEASURE 73 fprintf(fp, "\n"); 74 #endif 75 } 76 77 /* 78 * `mstotvround' rounds up the value of the argument to the 79 * nearest multiple of five, and converts it into a timeval 80 */ 81 82 struct timeval mstotvround(x) 83 int *x; 84 { 85 int temp; 86 struct timeval adj; 87 88 temp = *x % 5; 89 if (temp >= 3) 90 *x = *x-temp+5; 91 else { 92 if (temp <= -3) 93 *x = *x - temp -5; 94 else 95 *x = *x-temp; 96 } 97 adj.tv_sec = *x/1000; 98 adj.tv_usec = (*x-adj.tv_sec*1000)*1000; 99 if (adj.tv_usec < 0) { 100 adj.tv_usec += 1000000; 101 adj.tv_sec--; 102 } 103 return(adj); 104 } 105 106 adjclock(corr) 107 struct timeval *corr; 108 { 109 struct timeval now; 110 111 if (timerisset(corr)) { 112 if (corr->tv_sec < MAXADJ && corr->tv_sec > - MAXADJ) { 113 (void)adjtime(corr, (struct timeval *)0); 114 } else { 115 syslog(LOG_WARNING, 116 "clock correction too large to adjust (%d sec)", 117 corr->tv_sec); 118 (void) gettimeofday(&now, (struct timezone *)0); 119 timevaladd(&now, corr); 120 if (settimeofday(&now, (struct timezone *)0) < 0) 121 syslog(LOG_ERR, "can't set time"); 122 } 123 } 124 } 125 126 timevaladd(tv1, tv2) 127 register struct timeval *tv1, *tv2; 128 { 129 130 tv1->tv_sec += tv2->tv_sec; 131 tv1->tv_usec += tv2->tv_usec; 132 if (tv1->tv_usec >= 1000000) { 133 tv1->tv_sec++; 134 tv1->tv_usec -= 1000000; 135 } 136 if (tv1->tv_usec < 0) { 137 tv1->tv_sec--; 138 tv1->tv_usec += 1000000; 139 } 140 } 141