1 /* 2 * Copyright (c) 1985 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)correct.c 2.5 (Berkeley) 06/18/88"; 20 #endif /* not lint */ 21 22 #include "globals.h" 23 #include <protocols/timed.h> 24 25 #ifdef MEASURE 26 extern FILE *fp; 27 #endif 28 29 /* 30 * `correct' sends to the slaves the corrections for their clocks 31 */ 32 33 correct(avdelta) 34 long avdelta; 35 { 36 int i; 37 int corr; 38 struct timeval adjlocal; 39 struct tsp msgs; 40 struct timeval mstotvround(); 41 struct tsp *answer, *acksend(); 42 43 #ifdef MEASURE 44 for(i=0; i<slvcount; i++) { 45 if (hp[i].delta == HOSTDOWN) 46 fprintf(fp, "%s\t", "down"); 47 else { 48 fprintf(fp, "%d\t", hp[i].delta); 49 } 50 } 51 fprintf(fp, "\n"); 52 #endif 53 corr = avdelta - hp[0].delta; 54 adjlocal = mstotvround(&corr); 55 adjclock(&adjlocal); 56 #ifdef MEASURE 57 fprintf(fp, "%d\t", corr); 58 #endif 59 60 for(i=1; i<slvcount; i++) { 61 if (hp[i].delta != HOSTDOWN) { 62 corr = avdelta - hp[i].delta; 63 msgs.tsp_time = mstotvround(&corr); 64 msgs.tsp_type = (u_char)TSP_ADJTIME; 65 (void)strcpy(msgs.tsp_name, hostname); 66 answer = acksend(&msgs, &hp[i].addr, hp[i].name, 67 TSP_ACK, (struct netinfo *)NULL); 68 if (answer == NULL) { 69 hp[i].delta = HOSTDOWN; 70 #ifdef MEASURE 71 fprintf(fp, "%s\t", "down"); 72 } else { 73 fprintf(fp, "%d\t", corr); 74 #endif 75 } 76 } else { 77 #ifdef MEASURE 78 fprintf(fp, "%s\t", "down"); 79 #endif 80 } 81 } 82 #ifdef MEASURE 83 fprintf(fp, "\n"); 84 #endif 85 } 86 87 /* 88 * `mstotvround' rounds up the value of the argument to the 89 * nearest multiple of five, and converts it into a timeval 90 */ 91 92 struct timeval mstotvround(x) 93 int *x; 94 { 95 int temp; 96 struct timeval adj; 97 98 temp = *x % 5; 99 if (temp >= 3) 100 *x = *x-temp+5; 101 else { 102 if (temp <= -3) 103 *x = *x - temp -5; 104 else 105 *x = *x-temp; 106 } 107 adj.tv_sec = *x/1000; 108 adj.tv_usec = (*x-adj.tv_sec*1000)*1000; 109 if (adj.tv_usec < 0) { 110 adj.tv_usec += 1000000; 111 adj.tv_sec--; 112 } 113 return(adj); 114 } 115 116 adjclock(corr) 117 struct timeval *corr; 118 { 119 struct timeval now; 120 121 if (timerisset(corr)) { 122 if (corr->tv_sec < MAXADJ && corr->tv_sec > - MAXADJ) { 123 (void)adjtime(corr, (struct timeval *)0); 124 } else { 125 syslog(LOG_WARNING, 126 "clock correction too large to adjust (%d sec)", 127 corr->tv_sec); 128 (void) gettimeofday(&now, (struct timezone *)0); 129 timevaladd(&now, corr); 130 if (settimeofday(&now, (struct timezone *)0) < 0) 131 syslog(LOG_ERR, "can't set time"); 132 } 133 } 134 } 135 136 timevaladd(tv1, tv2) 137 register struct timeval *tv1, *tv2; 138 { 139 140 tv1->tv_sec += tv2->tv_sec; 141 tv1->tv_usec += tv2->tv_usec; 142 if (tv1->tv_usec >= 1000000) { 143 tv1->tv_sec++; 144 tv1->tv_usec -= 1000000; 145 } 146 if (tv1->tv_usec < 0) { 147 tv1->tv_sec--; 148 tv1->tv_usec += 1000000; 149 } 150 } 151