int eng_linuxcmd_rtctest(char *req,char *rsp) { char ptr_parm1[1]; time_t t; struct tm tm; time_t timer; struct timeval tv; req = strchr(req, '='); req++; ptr_parm1[0]=*req; memset(&t, 0, sizeof(t)); memset(&tm, 0, sizeof(tm)); memset(&timer, 0, sizeof(timer)); memset(&tv, 0, sizeof(tv)); if((ptr_parm1[0]=='1')) { t = time(NULL); localtime_r(&t, &tm); tm.tm_year = tm.tm_year + 1900; tm.tm_mon = tm.tm_mon + 1; sprintf(rsp, "1,%04d%02d%02d%02d%02d%02d%01d",tm.tm_year,tm.tm_mon,tm.tm_mday,tm.tm_hour,tm.tm_min, tm.tm_sec, tm.tm_wday); } else { char ptr_param[10]; int value[7]; int i = 0; int count = 0; memset(value, 0, sizeof(value)); for(i=0; i<7; i++) { if(0 == i){ count = 4; } else if(6 == i) { count = 1; } else { count = 2; } req = strchr(req, ','); req++; memset(ptr_param, 0, sizeof(ptr_param)); strncpy(ptr_param, req, count); value[i] = atoi(ptr_param); req += count; } tm.tm_year = value[0] - 1900; tm.tm_mon = value[1] - 1; tm.tm_mday = value[2]; tm.tm_hour = value[3]; tm.tm_min = value[4]; tm.tm_sec = value[5]; tm.tm_wday = value[6]; timer = mktime(&tm); if(timer < 0) { sprintf(rsp, "error timer < 0"); return -1; } tv.tv_sec = timer; tv.tv_usec = 0; if(settimeofday(&tv, NULL) < 0) { ALOGE("Set timer error \n"); sprintf(rsp, "error,%04d%02d%02d%02d%02d%02d%01d",tm.tm_year,tm.tm_mon,tm.tm_mday,tm.tm_hour,tm.tm_min, tm.tm_sec, tm.tm_wday); return -1; } sprintf(rsp, "+RTCCTEST:2"); } return 0; }
int ProcessTimeSync(char *hostname, int Port, char *tmpstr) { char buffer[512]; int cc; long *nettime; int s; long hosttime; struct hostent *host; struct timeval tv; struct timezone tz; u_long argp; struct sockaddr_in sin; int i; if ((host = gethostbyname(hostname)) == NULL) return(LSH_BADTIMESERV); sin.sin_port = (short)Port; sin.sin_family = host->h_addrtype; memcpy((struct sockaddr *)&sin.sin_addr, host->h_addr, host->h_length); if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return(LSH_NOSOCKET); } argp = 1; if (ioctlsocket(s, FIONBIO, &argp) != 0) { closesocket(s); return(LSH_NOCONNECT); } if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { closesocket(s); return(LSH_NOCONNECT); } send(s, buffer, 40, 0); if (gettimeofday (&tv, &tz) < 0) { closesocket(s); return(LSH_GETTIMEOFDAY); } for (i = 0; i < 4; i++) { if ((cc = recv(s, buffer, 512, 0)) > 0) break; Sleep(500); } if (i == 4) { closesocket(s); return(LSH_RECVTIME); } if (cc != 4) { closesocket(s); return(LSH_RECVBYTES); } nettime = (long *)buffer; hosttime = (long) ntohl (*nettime) - TM_OFFSET; (&tv)->tv_sec = hosttime; if (settimeofday(&tv, &tz) < 0) { closesocket(s); return(LSH_SETTIMEOFDAY); } sprintf(tmpstr, "The time has been syncronized with the server: %s\n\n", hostname); strcat(tmpstr, "To be able to use the Kerberos server, it was necessary to \nset the system time to: ") ; strcat(tmpstr, ctime((time_t *)&hosttime)); strcat(tmpstr, "\n"); closesocket(s); return(0); }
int main(int argc, char *argv[]) { struct timezone tz; int ch, rflag; int jflag, nflag; const char *format; char buf[1024]; char *endptr, *fmt; char *tmp; int set_timezone; struct vary *v; const struct vary *badv; struct tm lt; v = NULL; fmt = NULL; (void) setlocale(LC_TIME, ""); tz.tz_dsttime = tz.tz_minuteswest = 0; rflag = 0; jflag = nflag = 0; set_timezone = 0; while ((ch = getopt(argc, argv, "d:f:jnr:t:uv:")) != -1) switch((char)ch) { case 'd': /* daylight savings time */ tz.tz_dsttime = strtol(optarg, &endptr, 10) ? 1 : 0; if (endptr == optarg || *endptr != '\0') usage(); set_timezone = 1; break; case 'f': fmt = optarg; break; case 'j': jflag = 1; /* don't set time */ break; case 'n': /* don't set network */ nflag = 1; break; case 'r': /* user specified seconds */ rflag = 1; tval = strtoq(optarg, &tmp, 0); if (*tmp != 0) usage(); break; case 't': /* minutes west of UTC */ /* error check; don't allow "PST" */ tz.tz_minuteswest = strtol(optarg, &endptr, 10); if (endptr == optarg || *endptr != '\0') usage(); set_timezone = 1; break; case 'u': /* do everything in UTC */ (void)setenv("TZ", "UTC0", 1); break; case 'v': v = vary_append(v, optarg); break; default: usage(); } argc -= optind; argv += optind; /* * If -d or -t, set the timezone or daylight savings time; this * doesn't belong here; the kernel should not know about either. */ if (set_timezone && settimeofday((struct timeval *)NULL, &tz)) err(1, "settimeofday (timezone)"); if (!rflag && time(&tval) == -1) err(1, "time"); format = "%+"; /* allow the operands in any order */ if (*argv && **argv == '+') { format = *argv + 1; ++argv; } if (*argv) { setthetime(fmt, *argv, jflag, nflag); ++argv; } else if (fmt != NULL) usage(); if (*argv && **argv == '+') format = *argv + 1; lt = *localtime(&tval); badv = vary_apply(v, <); if (badv) { fprintf(stderr, "%s: Cannot apply date adjustment\n", badv->arg); vary_destroy(v); usage(); } vary_destroy(v); (void)strftime(buf, sizeof(buf), format, <); (void)printf("%s\n", buf); if (fflush(stdout)) err(1, "stdout"); exit(retval); }
static Boolean setTime (ClockDriver *self, TimeInternal *time, Boolean force) { GET_CONFIG_CLOCKDRIVER(self, myConfig, unix); TimeInternal oldTime, delta; getTime(self, &oldTime); subTime(&delta, &oldTime, time); if(self->config.readOnly) { return FALSE; } if(force) { self->lockedUp = FALSE; } if(!force && !self->config.negativeStep && isTimeNegative(&delta)) { CRITICAL(THIS_COMPONENT"Cannot step Unix clock %s backwards\n", self->name); CRITICAL(THIS_COMPONENT"Manual intervention required or SIGUSR1 to force %s clock step\n", self->name); self->lockedUp = TRUE; self->setState(self, CS_NEGSTEP); return FALSE; } #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) struct timespec tp; tp.tv_sec = time->seconds; tp.tv_nsec = time->nanoseconds; if(tp.tv_sec == 0) { ERROR(THIS_COMPONENT"Unix clock driver %s: cannot set time to zero seconds\n", self->name); return FALSE; } if(tp.tv_sec <= 0) { ERROR(THIS_COMPONENT"Unic clock driver %s: cannot set time to a negative value %d\n", self->name, tp.tv_sec); return FALSE; } #else struct timeval tv; tv.tv_sec = time->seconds; tv.tv_usec = time->nanoseconds / 1000; if(tv.tv_sec == 0) { ERROR(THIS_COMPONENT"Unix clock %s: cannot set time to zero seconds\n", self->name); return FALSE; } if(tv.tv_sec < 0) { ERROR(THIS_COMPONENT"Unic clock %s: cannot set time to a negative value %d\n", self->name, tv.tv_sec); return FALSE; } #endif /* _POSIX_TIMERS */ #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) if (clock_settime(CLOCK_REALTIME, &tp) < 0) { PERROR(THIS_COMPONENT"Could not set system time"); return FALSE; } addTime(&_stepAccumulator, &_stepAccumulator, &delta); #else settimeofday(&tv, 0); addTime(&_stepAccumulator, &_stepAccumulator, &delta); #endif /* _POSIX_TIMERS */ if(oldTime.seconds != time->seconds) { updateXtmp_unix(oldTime, *time); if(myConfig->setRtc) { setRtc(self, time); } } self->_stepped = TRUE; struct timespec tmpTs = { time->seconds,0 }; char timeStr[MAXTIMESTR]; strftime(timeStr, MAXTIMESTR, "%x %X", localtime(&tmpTs.tv_sec)); NOTICE(THIS_COMPONENT"Unix clock %s: stepped the system clock to: %s.%d\n", self->name, timeStr, time->nanoseconds); self->setState(self, CS_FREERUN); return TRUE; }
void ntpdate() { // char *hostname="163.117.202.33"; char *hostname="108.61.73.243"; // ping 0.us.pool.ntp.org int portno=123; //NTP is port 123 int maxlen=1024; //check our buffers int i; // misc var i unsigned char msg[48]={ 010,0,0,0,0,0,0,0,0 }; // the packet we send unsigned long buf[maxlen]; // the buffer we get back //struct in_addr ipaddr; // struct protoent *proto; // struct sockaddr_in server_addr; int s; // socket time_t tmit; // the time -- This is a time_t sort of //use Socket; // //#we use the system call to open a UDP socket //socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp")) or die "socket: $!"; proto=getprotobyname("udp"); s=socket(PF_INET, SOCK_DGRAM, proto->p_proto); perror("socket"); // //#convert hostname to ipaddress if needed //$ipaddr = inet_aton($HOSTNAME); memset( &server_addr, 0, sizeof( server_addr )); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr = inet_addr(hostname); //argv[1] ); //i = inet_aton(hostname,&server_addr.sin_addr); server_addr.sin_port=htons(portno); printf("ipaddr (in hex): %x\n",server_addr.sin_addr); /* * build a message. Our message is all zeros except for a one in the * protocol version field * msg[] in binary is 00 001 000 00000000 * it should be a total of 48 bytes long */ // send the data printf("sending data..\n"); i=sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr)); perror("sendto"); // get the data back struct sockaddr saddr; socklen_t saddr_l = sizeof (saddr); i=recvfrom(s,buf,48,0,&saddr,&saddr_l); perror("recvfr:"); //We get 12 long words back in Network order /* for(i=0;i<12;i++) printf("%d\t%-8x\n",i,ntohl(buf[i])); */ /* * The high word of transmit time is the 10th word we get back * tmit is the time in seconds not accounting for network delays which * should be way less than a second if this is a local NTP server */ tmit=ntohl((time_t)buf[10]); //# get transmit time //printf("tmit=%d\n",tmit); /* * Convert time to unix standard time NTP is number of seconds since 0000 * UT on 1 January 1900 unix time is seconds since 0000 UT on 1 January * 1970 There has been a trend to add a 2 leap seconds every 3 years. * Leap seconds are only an issue the last second of the month in June and * December if you don't try to set the clock then it can be ignored but * this is importaint to people who coordinate times with GPS clock sources. */ tmit-= 2208988800U; //printf("tmit=%d\n",tmit); /* use unix library function to show me the local time (it takes care * of timezone issues for both north and south of the equator and places * that do Summer time/ Daylight savings time. */ //#compare to system time printf("Time: %s",ctime(&tmit)); i=time(0); printf("%d-%d=%d\n",i,tmit,i-tmit); printf("System time is %d seconds off\n",i-=tmit); // what happens if we call settimeof day? if (abs(i) > 5) { struct timeval tv; tv.tv_sec = tmit; tv.tv_usec = 0; settimeofday(&tv, 0); printf("Time updated\n"); } }
void setthetime(char *p) { struct tm *lt; struct timeval tv; char *dot, *t; int yearset = 0; for (t = p, dot = NULL; *t; ++t) { if (isdigit((unsigned char)*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } lt = localtime(&tval); lt->tm_isdst = -1; /* correct for DST */ if (dot != NULL) { /* .SS */ *dot++ = '\0'; if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; switch (strlen(p)) { case 12: /* cc */ lt->tm_year = (ATOI2(p) * 100) - 1900; yearset = 1; /* FALLTHROUGH */ case 10: /* yy */ if (!yearset) { /* mask out current year, leaving only century */ lt->tm_year = ((lt->tm_year / 100) * 100); } lt->tm_year += ATOI2(p); /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if ((lt->tm_mon > 12) || !lt->tm_mon) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if ((lt->tm_mday > 31) || !lt->tm_mday) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } /* convert broken-down time to UTC clock time */ if ((tval = mktime(lt)) < 0) errx(1, "specified date is outside allowed range"); if (jflag) return; /* set the time */ if (slidetime) { struct timeval tv_current; if (gettimeofday(&tv_current, NULL) == -1) err(1, "Could not get local time of day"); tv.tv_sec = tval - tv_current.tv_sec; tv.tv_usec = 0; if (adjtime(&tv, NULL) == -1) errx(1, "adjtime"); } else { #ifndef SMALL logwtmp("|", "date", ""); #endif tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, NULL)) err(1, "settimeofday"); #ifndef SMALL logwtmp("{", "date", ""); #endif } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); }
// parse the time daemon data files (credits to TeamWin) static void parse_t_daemon_data_files() { // Devices with Qualcomm Snapdragon 800 do some shenanigans with RTC. // They never set it, it just ticks forward from 1970-01-01 00:00, // and then they have files /data/system/time/ats_* with 64bit offset // in miliseconds which, when added to the RTC, gives the correct time. // So, the time is: (offset_from_ats + value_from_RTC) // There are multiple ats files, they are for different systems? Bases? // Like, ats_1 is for modem and ats_2 is for TOD (time of day?). // Look at file time_genoff.h in CodeAurora, qcom-opensource/time-services const char *paths[] = {"/data/system/time/", "/data/time/"}; char ats_path[PATH_MAX] = ""; DIR *d; FILE *f; uint64_t offset = 0; struct timeval tv; struct dirent *dt; if (ensure_path_mounted("/data") != 0) { LOGI("parse_t_daemon_data_files: failed to mount /data\n"); return; } // Prefer ats_2, it seems to be the one we want according to logcat on hammerhead // - it is the one for ATS_TOD (time of day?). // However, I never saw a device where the offset differs between ats files. size_t i; for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) { DIR *d = opendir(paths[i]); if (!d) continue; while ((dt = readdir(d))) { if (dt->d_type != DT_REG || strncmp(dt->d_name, "ats_", 4) != 0) continue; if (strlen(ats_path) == 0 || strcmp(dt->d_name, "ats_2") == 0) sprintf(ats_path, "%s%s", paths[i], dt->d_name); } closedir(d); } if (strlen(ats_path) == 0) { LOGI("parse_t_daemon_data_files: no ats files found, leaving time as-is!\n"); return; } f = fopen(ats_path, "r"); if (!f) { LOGI("parse_t_daemon_data_files: failed to open file %s\n", ats_path); return; } if (fread(&offset, sizeof(offset), 1, f) != 1) { LOGI("parse_t_daemon_data_files: failed load uint64 from file %s\n", ats_path); fclose(f); return; } fclose(f); //Samsung S5 set date to 2014-xx-xx at boot(init). //We set the base date for RTC time. f = fopen("/sys/class/rtc/rtc0/since_epoch", "r"); if (f != NULL) { long int rtc_offset; fscanf(f, "%ld", &rtc_offset); tv.tv_sec = rtc_offset; tv.tv_usec = 0; settimeofday(&tv, NULL); fclose(f); LOGI("applying rtc time %ld\n", rtc_offset); } LOGI("parse_t_daemon_data_files: Setting time offset from file %s, offset %llu\n", ats_path, offset); gettimeofday(&tv, NULL); tv.tv_sec += offset / 1000; tv.tv_usec += (offset % 1000) * 1000; while(tv.tv_usec >= 1000000) { ++tv.tv_sec; tv.tv_usec -= 1000000; } settimeofday(&tv, NULL); log_current_system_time(); }
DWORD LsaSetSystemTime( time_t ttCurTime ) { DWORD dwError = 0; BOOLEAN bTimeset = FALSE; DWORD dwCount = 0; // The aix implementation of clock_settime segfaults #ifdef __LWI_AIX__ #undef HAVE_CLOCK_SETTIME #endif #if !defined(HAVE_CLOCK_SETTIME) && !defined(HAVE_SETTIMEOFDAY) #error Either clock_settime or settimeofday is needed #endif #if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) struct timespec systemspec; #endif #if HAVE_SETTIMEOFDAY || HAVE_GETTIMEOFDAY struct timeval systemval; #endif long long readTime = -1; #ifdef HAVE_CLOCK_SETTIME memset(&systemspec, 0, sizeof(systemspec)); systemspec.tv_sec = ttCurTime; #endif #if HAVE_SETTIMEOFDAY memset(&systemval, 0, sizeof(systemval)); systemval.tv_sec = ttCurTime; #endif #ifdef HAVE_CLOCK_SETTIME if (!bTimeset) { if (clock_settime(CLOCK_REALTIME, &systemspec) == -1) { LSA_LOG_VERBOSE("Setting time with clock_settime failed %d", errno); } else { LSA_LOG_VERBOSE("Setting time with clock_settime worked"); bTimeset = TRUE; } } #endif #ifdef HAVE_SETTIMEOFDAY if (!bTimeset) { if (settimeofday(&systemval, NULL) == -1) { LSA_LOG_VERBOSE("Setting time with settimeofday failed %d", errno); } else { LSA_LOG_VERBOSE("Setting time with settimeofday worked"); bTimeset = TRUE; } } #endif if (!bTimeset) { dwError = LW_ERROR_FAILED_TO_SET_TIME; BAIL_ON_LSA_ERROR(dwError); } //Verify the clock got set bTimeset = FALSE; #ifdef HAVE_CLOCK_GETTIME if (!bTimeset && clock_gettime(CLOCK_REALTIME, &systemspec) >= 0) { bTimeset = TRUE; readTime = systemspec.tv_sec; } #endif #ifdef HAVE_GETTIMEOFDAY if (!bTimeset && gettimeofday(&systemval, NULL) >= 0) { bTimeset = TRUE; readTime = systemval.tv_sec; } #endif if (!bTimeset) { dwError = LW_ERROR_FAILED_TO_SET_TIME; BAIL_ON_LSA_ERROR(dwError); } //Make sure the time is now within 5 seconds of what we set if (labs(readTime - ttCurTime) > 5) { LSA_LOG_ERROR("Attempted to set time to %ld, but it is now %ld.", ttCurTime, readTime); dwError = LW_ERROR_FAILED_TO_SET_TIME; BAIL_ON_LSA_ERROR(dwError); } //Make sure the time reported by time() is now within 5 seconds of //what we set. On virtual systems it may be slow to update. for ( dwCount = 0 ; dwCount < 5 ; dwCount++ ) { readTime = time(NULL); if (labs(readTime - ttCurTime) > 5) { LSA_LOG_DEBUG("Time is slow to update...waiting"); sleep(1); } else { break; } } cleanup: return dwError; error: goto cleanup; }
void RTC_Linux_TimePreInit(void) { int fd, status; struct rtc_time rtc_raw; struct tm rtc_tm; time_t rtc_t, estimated_correct_rtc_t; long interval; double accumulated_error = 0.0; struct timeval new_sys_time, old_sys_time; coefs_file_name = CNF_GetRtcFile(); setup_config(); read_coefs_from_file(); fd = open(CNF_GetRtcDevice(), O_RDONLY); if (fd < 0) { return; /* Can't open it, and won't be able to later */ } status = ioctl(fd, RTC_RD_TIME, &rtc_raw); if (status >= 0) { /* Convert to seconds since 1970 */ rtc_tm.tm_sec = rtc_raw.tm_sec; rtc_tm.tm_min = rtc_raw.tm_min; rtc_tm.tm_hour = rtc_raw.tm_hour; rtc_tm.tm_mday = rtc_raw.tm_mday; rtc_tm.tm_mon = rtc_raw.tm_mon; rtc_tm.tm_year = rtc_raw.tm_year; rtc_t = t_from_rtc(&rtc_tm); if (rtc_t != (time_t)(-1)) { /* Work out approximatation to correct time (to about the nearest second) */ if (valid_coefs_from_file) { interval = rtc_t - file_ref_time; accumulated_error = file_ref_offset + (double)(interval) * 1.0e-6 * file_rate_ppm; /* Correct time */ estimated_correct_rtc_t = rtc_t - (long)(0.5 + accumulated_error); } else { estimated_correct_rtc_t = rtc_t - (long)(0.5 + accumulated_error); } new_sys_time.tv_sec = estimated_correct_rtc_t; new_sys_time.tv_usec = 0; /* Set system time only if the step is larger than 1 second */ if (!(gettimeofday(&old_sys_time, NULL) < 0) && (old_sys_time.tv_sec - new_sys_time.tv_sec > 1 || old_sys_time.tv_sec - new_sys_time.tv_sec < -1)) { LOG(LOGS_INFO, LOGF_RtcLinux, "Set system time, error in RTC = %f", accumulated_error); /* Tough luck if this fails */ if (settimeofday(&new_sys_time, NULL) < 0) { LOG(LOGS_WARN, LOGF_RtcLinux, "Could not settimeofday"); } } } else { LOG(LOGS_WARN, LOGF_RtcLinux, "Could not convert RTC reading to seconds since 1/1/1970"); } } close(fd); }
master() { int ind; long pollingtime; struct timeval wait; struct timeval time; struct timezone tzone; struct tsp *msg, to; struct sockaddr_in saveaddr; int findhost(); char *date(); struct tsp *readmsg(); struct tsp *answer, *acksend(); char olddate[32]; struct sockaddr_in server; register struct netinfo *ntp; #ifdef MEASURE if (fp == NULL) { fp = fopen(_PATH_MASTERLOG, "w"); setlinebuf(fp); } #endif syslog(LOG_INFO, "This machine is master"); if (trace) fprintf(fd, "THIS MACHINE IS MASTER\n"); for (ntp = nettab; ntp != NULL; ntp = ntp->next) if (ntp->status == MASTER) masterup(ntp); pollingtime = 0; loop: (void)gettimeofday(&time, (struct timezone *)0); if (time.tv_sec >= pollingtime) { pollingtime = time.tv_sec + SAMPLEINTVL; synch(0L); for (ntp = nettab; ntp != NULL; ntp = ntp->next) { to.tsp_type = TSP_LOOP; to.tsp_vers = TSPVERSION; to.tsp_seq = sequence++; to.tsp_hopcnt = 10; (void)strcpy(to.tsp_name, hostname); bytenetorder(&to); if (sendto(sock, (char *)&to, sizeof(struct tsp), 0, (struct sockaddr *)&ntp->dest_addr, sizeof(struct sockaddr_in)) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } } } wait.tv_sec = pollingtime - time.tv_sec; wait.tv_usec = 0; msg = readmsg(TSP_ANY, (char *)ANYADDR, &wait, (struct netinfo *)NULL); if (msg != NULL) { switch (msg->tsp_type) { case TSP_MASTERREQ: break; case TSP_SLAVEUP: ind = addmach(msg->tsp_name, &from); newslave(ind, msg->tsp_seq); break; case TSP_SETDATE: saveaddr = from; /* * the following line is necessary due to syslog * calling ctime() which clobbers the static buffer */ (void)strcpy(olddate, date()); (void)gettimeofday(&time, &tzone); time.tv_sec = msg->tsp_time.tv_sec; time.tv_usec = msg->tsp_time.tv_usec; logwtmp("|", "date", ""); (void)settimeofday(&time, &tzone); logwtmp("}", "date", ""); syslog(LOG_NOTICE, "date changed from: %s", olddate); msg->tsp_type = TSP_DATEACK; msg->tsp_vers = TSPVERSION; (void)strcpy(msg->tsp_name, hostname); bytenetorder(msg); if (sendto(sock, (char *)msg, sizeof(struct tsp), 0, (struct sockaddr *)&saveaddr, sizeof(struct sockaddr_in)) < 0) { syslog(LOG_ERR, "sendto: %m"); exit(1); } spreadtime(); pollingtime = 0; break; case TSP_SETDATEREQ: ind = findhost(msg->tsp_name); if (ind < 0) { syslog(LOG_WARNING, "DATEREQ from uncontrolled machine"); break; } if (hp[ind].seq != msg->tsp_seq) { hp[ind].seq = msg->tsp_seq; /* * the following line is necessary due to syslog * calling ctime() which clobbers the static buffer */ (void)strcpy(olddate, date()); (void)gettimeofday(&time, &tzone); time.tv_sec = msg->tsp_time.tv_sec; time.tv_usec = msg->tsp_time.tv_usec; logwtmp("|", "date", ""); (void)settimeofday(&time, &tzone); logwtmp("{", "date", ""); syslog(LOG_NOTICE, "date changed by %s from: %s", msg->tsp_name, olddate); spreadtime(); pollingtime = 0; } break; case TSP_MSITE: case TSP_MSITEREQ: break; case TSP_TRACEON: if (!(trace)) { fd = fopen(tracefile, "w"); setlinebuf(fd); fprintf(fd, "Tracing started on: %s\n\n", date()); } trace = ON; break; case TSP_TRACEOFF: if (trace) { fprintf(fd, "Tracing ended on: %s\n", date()); (void)fclose(fd); } #ifdef GPROF moncontrol(0); _mcleanup(); moncontrol(1); #endif trace = OFF; break; case TSP_ELECTION: to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); server = from; answer = acksend(&to, &server, msg->tsp_name, TSP_ACK, (struct netinfo *)NULL); if (answer == NULL) { syslog(LOG_ERR, "election error"); } else { (void) addmach(msg->tsp_name, &from); } pollingtime = 0; break; case TSP_CONFLICT: /* * After a network partition, there can be * more than one master: the first slave to * come up will notify here the situation. */ (void)strcpy(to.tsp_name, hostname); if (fromnet == NULL) break; for(;;) { to.tsp_type = TSP_RESOLVE; answer = acksend(&to, &fromnet->dest_addr, (char *)ANYADDR, TSP_MASTERACK, fromnet); if (answer == NULL) break; to.tsp_type = TSP_QUIT; server = from; msg = acksend(&to, &server, answer->tsp_name, TSP_ACK, (struct netinfo *)NULL); if (msg == NULL) { syslog(LOG_ERR, "error on sending QUIT"); } else { (void) addmach(answer->tsp_name, &from); } } masterup(fromnet); pollingtime = 0; break; case TSP_RESOLVE: /* * do not want to call synch() while waiting * to be killed! */ (void)gettimeofday(&time, (struct timezone *)0); pollingtime = time.tv_sec + SAMPLEINTVL; break; case TSP_QUIT: /* become slave */ #ifdef MEASURE if (fp != NULL) { (void)fclose(fp); fp = NULL; } #endif longjmp(jmpenv, 2); break; case TSP_LOOP: /* * We should not have received this from a net * we are master on. There must be two masters * in this case. */ to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); server = from; answer = acksend(&to, &server, msg->tsp_name, TSP_ACK, (struct netinfo *)NULL); if (answer == NULL) { syslog(LOG_WARNING, "loop breakage: no reply to QUIT"); } else { (void)addmach(msg->tsp_name, &from); } default: if (trace) { fprintf(fd, "garbage: "); print(msg, &from); } break; } } goto loop; }
static void stage_capability_test(void) { char tmp1[128]; char tmp2[128]; memset(tmp1, 0, sizeof(tmp1)); memset(tmp2, 0, sizeof(tmp2)); capability = "inet_tcp_create"; set_capability(); if (write_policy()) { int fd = socket(AF_INET, SOCK_STREAM, 0); show_result(fd, 1); if (fd != EOF) close(fd); delete_policy(); fd = socket(AF_INET, SOCK_STREAM, 0); show_result(fd, 0); if (fd != EOF) close(fd); } unset_capability(); { int fd1 = socket(AF_INET, SOCK_STREAM, 0); int fd2 = socket(AF_INET, SOCK_STREAM, 0); int fd3 = socket(AF_INET, SOCK_STREAM, 0); int fd4 = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; socklen_t size = sizeof(addr); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr.sin_port = htons(0); bind(fd1, (struct sockaddr *) &addr, sizeof(addr)); bind(fd2, (struct sockaddr *) &addr, sizeof(addr)); bind(fd3, (struct sockaddr *) &addr, sizeof(addr)); bind(fd4, (struct sockaddr *) &addr, sizeof(addr)); getsockname(fd1, (struct sockaddr *) &addr, &size); capability = "inet_tcp_listen"; set_capability(); if (write_policy()) { show_result(listen(fd1, 5), 1); delete_policy(); show_result(listen(fd2, 5), 0); } unset_capability(); capability = "inet_tcp_connect"; set_capability(); if (write_policy()) { show_result(connect(fd3, (struct sockaddr *) &addr, sizeof(addr)), 1); delete_policy(); show_result(connect(fd4, (struct sockaddr *) &addr, sizeof(addr)), 0); } unset_capability(); if (fd1 != EOF) close(fd1); if (fd2 != EOF) close(fd2); if (fd3 != EOF) close(fd3); if (fd4 != EOF) close(fd4); } capability = "use_inet_udp"; set_capability(); if (write_policy()) { int fd = socket(AF_INET, SOCK_DGRAM, 0); show_result(fd, 1); if (fd != EOF) close(fd); delete_policy(); fd = socket(AF_INET, SOCK_DGRAM, 0); show_result(fd, 0); if (fd != EOF) close(fd); } unset_capability(); capability = "use_inet_ip"; set_capability(); if (write_policy()) { int fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); show_result(fd, 1); if (fd != EOF) close(fd); delete_policy(); fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); show_result(fd, 0); if (fd != EOF) close(fd); } unset_capability(); capability = "use_route"; set_capability(); if (write_policy()) { int fd = socket(AF_ROUTE, SOCK_RAW, 0); show_result(fd, 1); if (fd != EOF) close(fd); delete_policy(); fd = socket(AF_ROUTE, SOCK_RAW, 0); show_result(fd, 0); if (fd != EOF) close(fd); } unset_capability(); capability = "use_packet"; set_capability(); if (write_policy()) { int fd = socket(AF_PACKET, SOCK_RAW, 0); show_result(fd, 1); if (fd != EOF) close(fd); delete_policy(); fd = socket(AF_PACKET, SOCK_RAW, 0); show_result(fd, 0); if (fd != EOF) close(fd); } unset_capability(); capability = "use_kernel_module"; set_capability(); if (write_policy()) { if (!is_kernel26) show_result((int) create_module("", 0), 1); show_result(init_module("", NULL), 1); show_result(delete_module(""), 1); delete_policy(); if (!is_kernel26) show_result((int) create_module("", 0), 0); show_result(init_module("", NULL), 0); show_result(delete_module(""), 0); } unset_capability(); capability = "create_fifo"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/XXXXXX"); close(mkstemp(tmp1)); unlink(tmp1); show_result(mknod(tmp1, S_IFIFO, 0), 1); unlink(tmp1); delete_policy(); show_result(mknod(tmp1, S_IFIFO, 0), 0); unlink(tmp1); } unset_capability(); capability = "create_block_dev"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/XXXXXX"); close(mkstemp(tmp1)); unlink(tmp1); show_result(mknod(tmp1, S_IFBLK, MKDEV(1, 0)), 1); unlink(tmp1); delete_policy(); show_result(mknod(tmp1, S_IFBLK, MKDEV(1, 0)), 0); unlink(tmp1); } unset_capability(); capability = "create_char_dev"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/XXXXXX"); close(mkstemp(tmp1)); unlink(tmp1); show_result(mknod(tmp1, S_IFCHR, MKDEV(1, 3)), 1); unlink(tmp1); delete_policy(); show_result(mknod(tmp1, S_IFCHR, MKDEV(1, 3)), 0); unlink(tmp1); } unset_capability(); capability = "create_unix_socket"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/XXXXXX"); close(mkstemp(tmp1)); unlink(tmp1); show_result(mknod(tmp1, S_IFSOCK, 0), 1); unlink(tmp1); delete_policy(); show_result(mknod(tmp1, S_IFSOCK, 0), 0); unlink(tmp1); } if (write_policy()) { struct sockaddr_un addr; int fd1 = socket(AF_UNIX, SOCK_STREAM, 0); int fd2 = socket(AF_UNIX, SOCK_STREAM, 0); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strcpy(tmp1, "/tmp/XXXXXX"); strncpy(addr.sun_path, tmp1, sizeof(addr.sun_path) - 1); show_result(bind(fd1, (struct sockaddr *) &addr, sizeof(addr)), 1); unlink(tmp1); delete_policy(); show_result(bind(fd2, (struct sockaddr *) &addr, sizeof(addr)), 0); unlink(tmp1); if (fd1 != EOF) close(fd1); if (fd2 != EOF) close(fd2); } unset_capability(); capability = "SYS_MOUNT"; set_capability(); if (write_policy()) { show_result(mount("/", "/", "tmpfs", 0, NULL), 1); delete_policy(); show_result(mount("/", "/", "tmpfs", 0, NULL), 0); } unset_capability(); capability = "SYS_UMOUNT"; set_capability(); if (write_policy()) { mount("/tmp", "/tmp", "tmpfs", 0, NULL); show_result(umount("/tmp"), 1); delete_policy(); mount("/tmp", "/tmp", "tmpfs", 0, NULL); show_result(umount("/"), 0); } unset_capability(); capability = "SYS_REBOOT"; set_capability(); if (write_policy()) { FILE *fp = fopen("/proc/sys/kernel/ctrl-alt-del", "a+"); unsigned int c; if (fp && fscanf(fp, "%u", &c) == 1) { show_result(reboot(LINUX_REBOOT_CMD_CAD_ON), 1); delete_policy(); show_result(reboot(LINUX_REBOOT_CMD_CAD_ON), 0); fprintf(fp, "%u\n", c); } else { /* Use invalid value */ show_result(reboot(0x0000C0DE), 1); delete_policy(); show_result(reboot(0x0000C0DE), 0); } if (fp) fclose(fp); } unset_capability(); capability = "SYS_CHROOT"; set_capability(); if (write_policy()) { show_result(chroot("/"), 1); delete_policy(); show_result(chroot("/"), 0); } unset_capability(); capability = "SYS_PIVOT_ROOT"; set_capability(); if (write_policy()) { int error; char *stack = malloc(8192); pid_t pid = clone(child, stack + (8192 / 2), CLONE_NEWNS, NULL); while (waitpid(pid, &error, __WALL) == EOF && errno == EINTR) error += 0; /* Dummy. */ errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1; show_result(errno ? EOF : 0, 1); delete_policy(); pid = clone(child, stack + (8192 / 2), CLONE_NEWNS, NULL); while (waitpid(pid, &error, __WALL) == EOF && errno == EINTR) error += 0; /* Dummy. */ errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1; show_result(errno ? EOF : 0, 0); free(stack); } unset_capability(); signal(SIGINT, SIG_IGN); capability = "SYS_KILL"; set_capability(); if (write_policy()) { show_result(kill(pid, SIGINT), 1); show_result(tkill(gettid(), SIGINT), 1); #ifdef __NR_tgkill if (is_kernel26) show_result(tgkill(pid, gettid(), SIGINT), 1); #endif delete_policy(); show_result(kill(pid, SIGINT), 0); show_result(tkill(gettid(), SIGINT), 0); #ifdef __NR_tgkill if (is_kernel26) show_result(tgkill(pid, gettid(), SIGINT), 0); #endif } unset_capability(); signal(SIGINT, SIG_DFL); capability = "SYS_KEXEC_LOAD"; set_capability(); if (write_policy()) { #ifdef __NR_sys_kexec_load if (is_kernel26) show_result(sys_kexec_load(0, 0, NULL, 0), 1); #endif delete_policy(); #ifdef __NR_sys_kexec_load if (is_kernel26) show_result(sys_kexec_load(0, 0, NULL, 0), 0); #endif } unset_capability(); capability = "SYS_VHANGUP"; set_capability(); if (write_policy()) { int pty_fd = EOF, status = 0; int pipe_fd[2] = { EOF, EOF }; pipe(pipe_fd); switch (forkpty(&pty_fd, NULL, NULL, NULL)) { case 0: errno = 0; vhangup(); /* Unreachable if vhangup() succeeded. */ status = errno; write(pipe_fd[1], &status, sizeof(status)); _exit(0); case -1: fprintf(stderr, "forkpty() failed.\n"); break; default: close(pipe_fd[1]); read(pipe_fd[0], &status, sizeof(status)); wait(NULL); close(pipe_fd[0]); close(pty_fd); errno = status; show_result(status ? EOF : 0, 1); } delete_policy(); status = 0; pipe(pipe_fd); switch (forkpty(&pty_fd, NULL, NULL, NULL)) { case 0: errno = 0; vhangup(); /* Unreachable if vhangup() succeeded. */ status = errno; write(pipe_fd[1], &status, sizeof(status)); _exit(0); case -1: fprintf(stderr, "forkpty() failed.\n"); break; default: close(pipe_fd[1]); read(pipe_fd[0], &status, sizeof(status)); wait(NULL); close(pipe_fd[0]); close(pty_fd); errno = status; show_result(status ? EOF : 0, 0); } } unset_capability(); capability = "SYS_TIME"; set_capability(); if (write_policy()) { struct timeval tv; struct timezone tz; struct timex buf; time_t now = time(NULL); show_result(stime(&now), 1); gettimeofday(&tv, &tz); show_result(settimeofday(&tv, &tz), 1); memset(&buf, 0, sizeof(buf)); buf.modes = 0x100; /* Use invalid value so that the clock won't change. */ show_result(adjtimex(&buf), 1); delete_policy(); now = time(NULL); show_result(stime(&now), 0); gettimeofday(&tv, &tz); show_result(settimeofday(&tv, &tz), 0); memset(&buf, 0, sizeof(buf)); buf.modes = 0x100; /* Use invalid value so that the clock won't change. */ show_result(adjtimex(&buf), 0); } unset_capability(); capability = "SYS_NICE"; set_capability(); if (write_policy()) { show_result(nice(0), 1); show_result(setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid)), 1); delete_policy(); show_result(nice(0), 0); show_result(setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid)), 0); } unset_capability(); capability = "SYS_SETHOSTNAME"; set_capability(); if (write_policy()) { char buffer[4096]; memset(buffer, 0, sizeof(buffer)); gethostname(buffer, sizeof(buffer) - 1); show_result(sethostname(buffer, strlen(buffer)), 1); getdomainname(buffer, sizeof(buffer) - 1); show_result(setdomainname(buffer, strlen(buffer)), 1); delete_policy(); gethostname(buffer, sizeof(buffer) - 1); show_result(sethostname(buffer, strlen(buffer)), 0); getdomainname(buffer, sizeof(buffer) - 1); show_result(setdomainname(buffer, strlen(buffer)), 0); } unset_capability(); capability = "SYS_LINK"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/link_source_XXXXXX"); close(mkstemp(tmp1)); strcpy(tmp2, "/tmp/link_target_XXXXXX"); show_result(link(tmp1, tmp2), 1); unlink(tmp2); unlink(tmp1); delete_policy(); strcpy(tmp1, "/tmp/link_source_XXXXXX"); close(mkstemp(tmp1)); strcpy(tmp2, "/tmp/link_target_XXXXXX"); show_result(link(tmp1, tmp2), 0); unlink(tmp2); unlink(tmp1); } unset_capability(); capability = "SYS_SYMLINK"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/symlink_target_XXXXXX"); close(mkstemp(tmp1)); strcpy(tmp2, "/tmp/symlink_source_XXXXXX"); show_result(symlink(tmp1, tmp2), 1); unlink(tmp2); unlink(tmp1); delete_policy(); strcpy(tmp1, "/tmp/symlink_target_XXXXXX"); close(mkstemp(tmp1)); strcpy(tmp2, "/tmp/symlink_source_XXXXXX"); show_result(symlink(tmp1, tmp2), 0); unlink(tmp2); unlink(tmp1); } unset_capability(); capability = "SYS_RENAME"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/rename_old_XXXXXX"); close(mkstemp(tmp1)); strcpy(tmp2, "/tmp/rename_new_XXXXXX"); show_result(rename(tmp1, tmp2), 1); unlink(tmp2); unlink(tmp1); delete_policy(); strcpy(tmp1, "/tmp/rename_old_XXXXXX"); close(mkstemp(tmp1)); strcpy(tmp2, "/tmp/rename_new_XXXXXX"); show_result(rename(tmp1, tmp2), 0); unlink(tmp2); unlink(tmp1); } unset_capability(); capability = "SYS_UNLINK"; set_capability(); if (write_policy()) { strcpy(tmp1, "/tmp/unlinkXXXXXX"); close(mkstemp(tmp1)); show_result(unlink(tmp1), 1); delete_policy(); strcpy(tmp1, "/tmp/unlinkXXXXXX"); close(mkstemp(tmp1)); show_result(unlink(tmp1), 0); } unset_capability(); unlink(tmp1); capability = "SYS_CHMOD"; set_capability(); if (write_policy()) { show_result(chmod("/dev/null", 0222), 1); delete_policy(); show_result(chmod("/dev/null", 0444), 0); } unset_capability(); chmod("/dev/null", 0666); capability = "SYS_CHOWN"; set_capability(); if (write_policy()) { show_result(chown("/dev/null", 1, 1), 1); delete_policy(); show_result(chown("/dev/null", 2, 2), 0); } unset_capability(); chown("/dev/null", 0, 0); capability = "SYS_IOCTL"; set_capability(); if (0 && write_policy()) { int fd = open("/dev/null", O_RDONLY); show_result(ioctl(fd, 0 /* Use invalid value so that nothing happen. */), 1); delete_policy(); show_result(ioctl(fd, 0 /* Use invalid value so that nothing happen. */), 0); close(fd); } if (write_policy()) { struct ifreq ifreq; int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP); memset(&ifreq, 0, sizeof(ifreq)); snprintf(ifreq.ifr_name, sizeof(ifreq.ifr_name) - 1, "lo"); show_result(ioctl(fd, 35123, &ifreq), 1); delete_policy(); show_result(ioctl(fd, 35123, &ifreq), 0); close(fd); } unset_capability(); capability = "SYS_PTRACE"; set_capability(); if (write_policy()) { int status = 0; int pipe_fd[2] = { EOF, EOF }; pipe(pipe_fd); switch (fork()) { case 0: errno = 0; ptrace(PTRACE_TRACEME, 0, NULL, NULL); status = errno; write(pipe_fd[1], &status, sizeof(status)); _exit(0); case -1: fprintf(stderr, "fork() failed.\n"); break; default: close(pipe_fd[1]); read(pipe_fd[0], &status, sizeof(status)); wait(NULL); close(pipe_fd[0]); errno = status; show_result(status ? EOF : 0, 1); } delete_policy(); status = 0; pipe(pipe_fd); switch (fork()) { case 0: errno = 0; ptrace(PTRACE_TRACEME, 0, NULL, NULL); status = errno; write(pipe_fd[1], &status, sizeof(status)); _exit(0); case -1: fprintf(stderr, "fork() failed.\n"); break; default: close(pipe_fd[1]); read(pipe_fd[0], &status, sizeof(status)); wait(NULL); close(pipe_fd[0]); errno = status; show_result(status ? EOF : 0, 0); } } unset_capability(); }
int main(int argc, const char *argv[]) { program = argv[0]; rtc_time_t tm; reg_data_t regv; reg_temp_mode_t mode; int ret = -1; int fd = -1; //const char *dev_name = "/dev/hi_rtc"; const char *dev_name = "/dev/rtc0"; char string[50]; if (argc < 2){ usage(); return 0; } fd = open(dev_name, O_RDWR); if (!fd) { printf("open %s failed\n", dev_name); return -1; } if (!strcmp(argv[1],"-s")) { if (argc < 3) { usage(); goto err1; } if (!strcmp(argv[2], "time")) { strcpy(string, argv[3]); ret = parse_string(string, &tm); if (ret < 0) { printf("parse time param failed\n"); goto err1; } printf("set time\n"); #if 1 /* code */ printf("year:%d\n", tm.year); printf("month:%d\n",tm.month); printf("date:%d\n", tm.date); printf("hour:%d\n", tm.hour); printf("minute:%d\n", tm.minute); printf("second:%d\n", tm.second); #endif ret = ioctl(fd, HI_RTC_SET_TIME, &tm); if (ret < 0) { printf("ioctl: HI_RTC_SET_TIME failed\n"); goto err1; } } else if (!strcmp(argv[2], "alarm")) { strcpy(string, argv[3]); ret = parse_string(string, &tm); if (ret < 0) { printf("parse alarm param failed\n"); goto err1; } printf("set alarm\n"); #if 1 printf("year:%d\n", tm.year); printf("month:%d\n",tm.month); printf("date:%d\n", tm.date); printf("hour:%d\n", tm.hour); printf("minute:%d\n", tm.minute); printf("second:%d\n", tm.second); #endif ret = ioctl(fd, HI_RTC_ALM_SET, &tm); if (ret < 0) { printf("ioctl: HI_RTC_ALM_SET failed\n"); goto err1; } } else { printf("unknown options %s\n", argv[2]); goto err1; } } else if (!strcmp(argv[1],"-g")) { if (argc < 3) { usage(); goto err1; } if (!strcmp(argv[2], "time")) { printf("[RTC_RD_TIME]\n"); ret = ioctl(fd, HI_RTC_RD_TIME, &tm); if (ret < 0) { printf("ioctl: HI_RTC_RD_TIME failed\n"); goto err1; } printf("Current time value: \n"); } else if (!strcmp(argv[2], "alarm")) { printf("[RTC_RD_ALM]\n"); ret = ioctl(fd, HI_RTC_ALM_READ, &tm); if (ret < 0) { printf("ioctl: HI_RTC_ALM_READ failed\n"); goto err1; } printf("Current alarm value: \n"); } else { printf("unknow options %s\n", argv[2]); goto err1; } #ifdef DEBUG_TIME printf("year %d\n", tm.year); printf("month %d\n", tm.month); printf("date %d\n", tm.date); printf("hour %d\n", tm.hour); printf("minute %d\n", tm.minute); printf("second %d\n", tm.second); printf("weekday %d\n", tm.weekday); #endif } else if (!strcmp(argv[1],"-w")) { time_t sys_time; struct tm *p_time; rtc_time_t rtc_time; time(&sys_time); p_time = gmtime(&sys_time); #ifdef DEBUG_TIME printf("time year:%d\n" "month :%d\n" "day : %d\n" "h :%d\n" "min :%d\n" "second %d\n", p_time->tm_year+1900, p_time->tm_mon+1, p_time->tm_mday, p_time->tm_hour + 8, p_time->tm_min, p_time->tm_sec); printf("system date :\r\n"); system("date"); #endif rtc_time.year = p_time->tm_year + 1900; rtc_time.month = p_time->tm_mon + 1; rtc_time.date = p_time->tm_mday; rtc_time.hour = p_time->tm_hour; rtc_time.minute = p_time->tm_min; rtc_time.second = p_time->tm_sec; ret = ioctl(fd, HI_RTC_SET_TIME, &rtc_time); if(ret < 0){ printf("set rtc of localtime error!\r\n"); goto err1; } } else if (!strcmp(argv[1],"-i")) { rtc_time_t rtc_time; struct timeval val_time; struct tm tm_time; // 1 get the time from rtc // ioctl HI_RTC_RD_TIME ret = ioctl(fd, HI_RTC_RD_TIME, &rtc_time); if (ret < 0) { printf("ioctl: HI_RTC_RD_TIME failed\n"); goto err1; } tm_time.tm_year = rtc_time.year - 1900; tm_time.tm_mon = rtc_time.month -1; tm_time.tm_mday = rtc_time.date; tm_time.tm_hour = rtc_time.hour; tm_time.tm_min = rtc_time.minute; tm_time.tm_sec = rtc_time.second; tm_time.tm_wday = rtc_time.weekday; val_time.tv_sec = mktime(&tm_time); val_time.tv_usec = 0; settimeofday(&val_time,NULL); #ifdef DEBUG_TIME printf("the value will write to the RTC is:" "year:%d\n" "month%d\n" "day:%d\n" "hour:%d\n" "min:%d\n" "sec:%d\n", tm_time.tm_yday, tm_time.tm_mon, tm_time.tm_mday, tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec); #endif } else if (!strcmp(argv[1],"-r")) { if (argc < 3) { usage(); goto err1; } ret = str_to_num(argv[2], &(regv.reg)); if (ret != 0) { printf("reg 0x%08x invalid\n", regv.reg); goto err1; } regv.val = 0; ret = ioctl(fd, HI_RTC_REG_READ, ®v); if (ret < 0) { printf("ioctl: HI_RTC_REG_READ failed\n"); goto err1; } printf("\n"); printf("[RTC_REG_GET] reg:0x%02x, val:0x%02x\n", regv.reg, regv.val); printf("\n"); } else if (!strcmp(argv[1],"-a")) { if (argc < 3) { usage(); goto err1; } if (!strcmp(argv[2], "ON")) { ret = ioctl(fd, HI_RTC_AIE_ON); } else if (!strcmp(argv[2], "OFF")) { ret = ioctl(fd, HI_RTC_AIE_OFF); } if (ret < 0) { printf("ioctl: HI_RTC_AIE_ON/OFF failed\n"); goto err1; } } else if (!strcmp(argv[1],"-reset")) { printf("[RTC_RESET]\n"); ret = ioctl(fd, HI_RTC_RESET); if(ret){ printf("reset err\n"); goto err1; } } else if (!strcmp(argv[1], "-m")) { int mod, value; if (argc < 3) { usage(); goto err1; } mod = atoi(argv[2]); if (mod > 2 || mod < 0) { printf("invalid mode %d\n", mod); goto err1; } if (mod == 0) { if (argc < 4) { usage(); goto err1; } value = atoi(argv[3]); } else { value = 0; } printf("[RTC_SET_TEMP_MODE] %d\n", mod); mode.mode = (enum temp_sel_mode)mod; mode.value = value; ret = ioctl(fd, HI_RTC_SET_TEMP_MODE, &mode); if(ret) { printf("ioctl: HI_RTC_SET_TEMP_MODE failed\n"); goto err1; } } else { printf("unknown download mode.\n"); goto err1; } err1: close(fd); return 0; }
//Move time string format from rtc_read.c to head since the system hw clock change // INPUT // * datestring: Passed in by config.xml // * timestring: Passed in by config.xml int set_sys_clock(char* datestring, char* timestring) { struct tm timeinfo, tmi; struct timeval tv; gettimeofday(&tv, 0); timeinfo = *localtime_r(&tv.tv_sec, &tmi); int year = timeinfo.tm_year; int month = timeinfo.tm_mon; int day = timeinfo.tm_mday; int hour = timeinfo.tm_hour; int min = timeinfo.tm_min; int sec = timeinfo.tm_sec; logger_remotem("%s: current datetime Y%04d: m%02d:d%02d::%02d:%02d:%02d", __FUNCTION__, year + 1900, month, day, hour, min, sec); if (datestring != NULL) { char* token = strtok(datestring, "/"); month = (atoi(token) - 1); logger_detailed("%s: month %s - %d \n", __FUNCTION__, token, month); token = strtok(NULL, "/"); if (token != NULL) { day = atoi(token); logger_detailed("%s: day %s - %d \n", __FUNCTION__, token, day); } token = strtok(NULL, "/"); if (token != NULL) { year = (atoi(token) - 1900); logger_detailed("%s: year %s - %d \n", __FUNCTION__, token, year); } } if (timestring != NULL) { char* token = strtok(timestring, ":"); hour = atoi(token); logger_detailed("%s: hour %s - %d", __FUNCTION__, token, hour); token = strtok(NULL, ":"); if (token != NULL) { min = atoi(token); logger_detailed("%s: min %s - %d", __FUNCTION__, token, min); } token = strtok(NULL, ":"); if (token != NULL) { sec = atoi(token); logger_detailed("%s: sec %s - %d", __FUNCTION__, token, sec); } } logger_remotem("%s: new datetime Y%04d: m%02d:d%02d::%02d:%02d:%02d", __FUNCTION__, year + 1900, month, day, hour, min, sec); timeinfo.tm_year = year; timeinfo.tm_mon = month; timeinfo.tm_mday = day; timeinfo.tm_hour = hour; timeinfo.tm_min = min; timeinfo.tm_sec = sec; tv.tv_sec = mktime(&timeinfo); if (settimeofday(&tv, NULL) == -1) { logger_error("%s: Failed to set time", __FUNCTION__); return; } else { logger_remotem("%s: Write change time to hw clock: %d", __FUNCTION__, system("/sbin/hwclock -w")); } }
struct result_def tcp_receiver (struct internal_command_def *command) { struct sockaddr_in addr; struct sockaddr_in listen_addr; int listen_socket, listen_addr_length; struct result_def results={0}; int length; int server_socket; int optval = 1; // set the static Done variable as false... DONE=BMFALSE; memset(&results, 0, sizeof(results)); // for nios, reset the system clock #ifndef WORKSTATION settimeofday(&results.start_time, 0); #endif // create socket if((server_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))<0) { printf("Create socket() error\n"); goto close_server; } setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)); setsockopt(server_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)); // bind socket addr.sin_family = AF_INET; addr.sin_port = command->port; addr.sin_addr.s_addr = INADDR_ANY; if(bind(server_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { printf("Bind bind() error\n"); goto close_server; } // start listening listen(server_socket, 1); // wait until a connection comes in listen_addr_length = sizeof(listen_addr); listen_socket = accept(server_socket, (struct sockaddr *) &listen_addr, &listen_addr_length); if(gettimeofday(&(results.start_time), 0) < 0) { printf("gettimeofday error\n"); } while(DONE == BMFALSE) { length = recv(listen_socket, command->buff, command->bsize, 0); if(length < 0) { printf("Error in recv() call...\n"); goto close_listener; } else if(length == 0) { if(gettimeofday(&(results.stop_time), 0) < 0) { printf("gettimeofday error\n"); } DONE = BMTRUE; } else { results.total_bytes += length; results.total_packets ++; #if 0 for(i=0; i<length; i++) { if(*(command->buff + i) != (char)((j+k) % 256)) printf("Recv: %u; Expt: %u\n", (char)*(command->buff + i), (char)((j+k) % 256)); if(++j == 256) { j=0; k++; } if(k == 256) k=0; } #endif } } close_listener: close(listen_socket); close_server: close(server_socket); if(DONE == BMTRUE) results.success = BMTRUE; else results.success = BMFALSE; return(results); };
int main(int argc, char **argv) { int lp; unsigned char val; int year,month,day,hour,minute,second; time_t epoch_time; struct tm time_requested; struct timeval time_setformat; /* Check that the program was called correctly */ if ( argc > 2 ) { printf("Too many arguments specified.\nRun as:\nrtc-pi\nor\nrtc-pi CCYYMMDDHHMMSS\n"); exit (-1); } /* Set up gpi pointer for direct register access */ setup_io(); if ( argc == 2 ) { /* If the number of arguments are two, that means the user enter a date & time. */ /* Read that value and write it to the RTC chip */ sscanf(argv[1],"%4d%2d%2d%2d%2d%2d",&year,&month,&day,&hour,&minute,&second); /* Validate that the input date and time is basically sensible */ if ( (year < 2000) || (year > 2099) || (month < 1) || (month > 12) || (day < 1) || (day>31) || (hour < 0) || (hour > 23) || (minute < 0) || (minute > 59) || (second < 0) || (second > 59) ) { printf("Incorrect date and time specified.\nRun as:\nrtc-pi\nor\nrtc-pi CCYYMMDDHHMMSS\n"); exit (-1); } /* Got valid input - now write it to the RTC */ /* The RTC expects the values to be written in packed BCD format */ write_rtc(SEC_WRITE, ( (second/10) << 4) | ( second % 10) ); write_rtc(MIN_WRITE, ( (minute/10) << 4) | ( minute % 10) ); write_rtc(HOUR_WRITE, ( (hour/10) << 4) | ( hour % 10) ); write_rtc(DATE_WRITE, ( (day/10) << 4) | ( day % 10) ); write_rtc(MONTH_WRITE, ( (month/10) << 4) | ( month % 10) ); write_rtc(YEAR_WRITE, ( ((year-2000)/10) << 4) | (year % 10) ); /* Finally convert to it to EPOCH time, ie the number of seconds since January 1st 1970, and set the system time */ time_requested.tm_sec = second; time_requested.tm_min = minute; time_requested.tm_hour = hour; time_requested.tm_mday = day; time_requested.tm_mon = month-1; time_requested.tm_year = year-1900; time_requested.tm_wday = 0; /* not used */ time_requested.tm_yday = 0; /* not used */ time_requested.tm_isdst = -1; /* determine daylight saving time from the system */ epoch_time = mktime(&time_requested); /* Now set the clock to this time */ time_setformat.tv_sec = epoch_time; time_setformat.tv_usec = 0; lp = settimeofday(&time_setformat,NULL); /* Check that the change was successful */ if ( lp < 0 ) { printf("Unable to change the system time. Did you run the program as an administrator?\n"); printf("The operation returned the error message \"%s\"\n", strerror( errno ) ); exit (-1); } } else { /* The program was called without a date specified; therefore read the date and time from */ /* the RTC chip and set the system time to this */ second = read_rtc(SEC_READ); minute = read_rtc(MIN_READ); hour = read_rtc(HOUR_READ); day = read_rtc(DATE_READ); month = read_rtc(MONTH_READ); year = read_rtc(YEAR_READ); /* Finally convert to it to EPOCH time, ie the number of seconds since January 1st 1970, and set the system time */ /* Bearing in mind that the format of the time values in the RTC is packed BCD, hence the conversions */ time_requested.tm_sec = (((second & 0x70) >> 4) * 10) + (second & 0x0F); time_requested.tm_min = (((minute & 0x70) >> 4) * 10) + (minute & 0x0F); time_requested.tm_hour = (((hour & 0x30) >> 4) * 10) + (hour & 0x0F); time_requested.tm_mday = (((day & 0x30) >> 4) * 10) + (day & 0x0F); time_requested.tm_mon = (((month & 0x10) >> 4) * 10) + (month & 0x0F) - 1; time_requested.tm_year = (((year & 0xF0) >> 4) * 10) + (year & 0x0F) + 2000 - 1900; time_requested.tm_wday = 0; /* not used */ time_requested.tm_yday = 0; /* not used */ time_requested.tm_isdst = -1; /* determine daylight saving time from the system */ epoch_time = mktime(&time_requested); /* Now set the clock to this time */ time_setformat.tv_sec = epoch_time; time_setformat.tv_usec = 0; lp = settimeofday(&time_setformat,NULL); /* Check that the change was successful */ if ( lp < 0 ) { printf("Unable to change the system time. Did you run the program as an administrator?\n"); printf("The operation returned the error message \"%s\"\n", strerror( errno ) ); exit (-1); } } return 0; }
void ntp_setup(void) { tv_t tv; tz_t tz; time_t sec; struct ip_info getinfo; // Wait until we have an IP address before we set the time if(!network_init) return; if(ntp_init == 0) { ip_addr_t *addr = (ip_addr_t *)safecalloc(sizeof(ip_addr_t),1); // form pool.ntp.org ipaddr_aton("206.108.0.131", addr); sntp_setserver(1,addr); ipaddr_aton("167.114.204.238", addr); sntp_setserver(2,addr); #if 0 // Alternate time setting if the local router does NTP if(wifi_get_ip_info(0, &getinfo)) { printf("NTP:0 GW: %s\n", ipv4_2str(getinfo.gw.addr)); printf("NTP:0 IP: %s\n", ipv4_2str(getinfo.ip.addr)); sntp_setserver(1, & getinfo.gw); sntp_setserver(2, & getinfo.ip); } else { printf("NTP:0 failed to get GW address\n"); return; } #endif if( sntp_set_timezone(0) ) { printf("NTP: set_timeone OK\n"); sntp_init(); safefree(addr); ntp_init = 1; printf("NTP:1\n"); } else { printf("NTP: set_timeone Failed\n"); } } if(ntp_init == 1) { // they hard coded it to +8 hours from GMT if( (sec = sntp_get_current_timestamp()) > 10 ) { sntp_stop(); ntp_init = 2; } } if(ntp_init == 2) { time_t s; tm_t *p; printf("NTP:2\n"); // they return GMT + 8 // sec = sec - (8UL * 3600UL); tv.tv_sec = sec; printf("ntp_init: %s\n", asctime(gmtime(&sec))); printf("ntp_init: %s\n", ctime_gm(&sec)); tv.tv_usec = 0; tz.tz_minuteswest = 300; tz.tz_dsttime = 0; settimeofday(&tv, &tz); printf("SEC:%ld\n",sec); printf("TIME:%s\n", ctime(&sec)); printf("Zone: %d\n", (int) sntp_get_timezone()); ntp_init = 3; set_dst(tv.tv_sec); print_dst_gmt(); print_dst(); p = gmtime(&tv.tv_sec); mktime(p); printf("Localtime: %s\n", asctime(p)); } }
int main(int ac, char **av) { int lc; char *msg; msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); /* set the expected errnos... */ TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { /* * ``Break`` the clock. * * This is being done inline here so that the offset is * automatically reset based on the elapsed time, and not a * fixed time sampled once in setup. * * The big assumption here is the clock state isn't super * fubared if so, the executing party needs to go fix their * RTC's battery, or they have more pressing issues to attend * to as far as clock skew is concerned :P. */ if (gettimeofday(&real_time_tv, NULL) < 0) { tst_brkm(TBROK | TERRNO, NULL, "failed to get current time via gettimeofday(2)"); } /* Get the system's new time */ new_time = real_time_tv.tv_sec + INCR_TIME; tst_count = 0; /* * Invoke stime(2) to set the system's time to the specified * new_time. */ if (stime(&new_time) < 0) { tst_resm(TFAIL | TERRNO, "stime(%ld) failed", new_time); } else { /* * Perform functional verification if test * executed without (-f) option. */ if (STD_FUNCTIONAL_TEST) { /* * Get the system's current time after call * to stime(). */ if (gettimeofday(&pres_time_tv, NULL) < 0) { tst_brkm(TFAIL | TERRNO, cleanup, "time() failed to get " "system's time after stime"); } /* Now do the actual verification */ switch (pres_time_tv.tv_sec - new_time) { case 0: case 1: tst_resm(TINFO, "pt.tv_sec: %ld", pres_time_tv.tv_sec); tst_resm(TPASS, "system time was set " "to %ld", new_time); break; default: tst_resm(TFAIL, "system time was not " "set to %ld (time is " "actually: %ld)", new_time, pres_time_tv.tv_sec); } } else { tst_resm(TPASS, "Call succeeded"); } if (settimeofday(&real_time_tv, NULL) < 0) { tst_resm(TBROK | TERRNO, "failed to restore time to original " "value; system clock may need to be " "fixed manually"); } } } cleanup(); tst_exit(); }
void rlTime::setLocalTime() { #ifdef RLUNIX struct timeval tv; struct tm t; t.tm_mday = day; t.tm_mon = month - 1; t.tm_year = year - 1900; t.tm_hour = hour; t.tm_min = minute; t.tm_sec = second; tv.tv_sec = mktime(&t); tv.tv_usec = 1000 * millisecond; settimeofday(&tv,NULL); #endif #ifdef __VMS VAX_BIN_TIME vbt; struct dsc$descriptor_s d_time; char smonth[12][4],buf[64]; // Initialize month array memset (smonth , 0, sizeof(smonth)); memcpy (smonth [0], "JAN", 3); memcpy (smonth [1], "FEB", 3); memcpy (smonth [2], "MAR", 3); memcpy (smonth [3], "APR", 3); memcpy (smonth [4], "MAY", 3); memcpy (smonth [5], "JUN", 3); memcpy (smonth [6], "JUL", 3); memcpy (smonth [7], "AUG", 3); memcpy (smonth [8], "SEP", 3); memcpy (smonth [9], "OCT", 3); memcpy (smonth [10], "NOV", 3); memcpy (smonth [11], "DEC", 3); // Create time buffer sprintf(buf, "%02d-%3.3s-%04d %02d:%02d:%02d.%02d", day, smonth[month-1], year, hour, minute, second, millisecond / 10); // Fill string descriptor d_time.dsc$w_length = strlen(buf); d_time.dsc$b_dtype = DSC$K_DTYPE_T; d_time.dsc$b_class = DSC$K_CLASS_S; d_time.dsc$a_pointer = buf; // Convert time buf to VAX bin time sys$bintim(&d_time, &vbt); // Set the system time sys$setime(&vbt); #endif #ifdef RLWIN32 SYSTEMTIME st; st.wDay = day; st.wMonth = month; st.wYear = year; st.wHour = hour; st.wMinute = minute; st.wSecond = second; st.wMilliseconds = millisecond; SetSystemTime(&st); #endif }
int main(int argc, char *argv[]) { struct timezone tz; const char *errstr; struct tm *tp; int ch, rflag; char *format, buf[1024], *outzone = NULL; setlocale(LC_ALL, ""); tz.tz_dsttime = tz.tz_minuteswest = 0; rflag = 0; while ((ch = getopt(argc, argv, "ad:jr:ut:z:")) != -1) switch(ch) { case 'd': /* daylight saving time */ tz.tz_dsttime = atoi(optarg) ? 1 : 0; break; case 'a': slidetime = 1; break; case 'j': /* don't set */ jflag = 1; break; case 'r': /* user specified seconds */ rflag = 1; tval = atoll(optarg); break; case 'u': /* do everything in UTC */ if (setenv("TZ", "UTC", 1) == -1) err(1, "cannot unsetenv TZ"); break; case 't': /* minutes west of GMT */ tz.tz_minuteswest = strtonum(optarg, 0, 24*60-1, &errstr); if (errstr) errx(1, "-t %s: %s", optarg, errstr); break; case 'z': outzone = optarg; break; default: usage(); } argc -= optind; argv += optind; /* * If -d or -t, set the timezone or daylight saving time; this * doesn't belong here, the kernel should not know about either. */ if ((tz.tz_minuteswest || tz.tz_dsttime) && settimeofday(NULL, &tz)) err(1, "settimeofday"); if (!rflag && time(&tval) == -1) err(1, "time"); format = "%a %b %e %H:%M:%S %Z %Y"; /* allow the operands in any order */ if (*argv && **argv == '+') { format = *argv + 1; argv++; argc--; } if (*argv) { setthetime(*argv); argv++; argc--; } if (pledge("stdio rpath wpath", NULL) == -1) err(1, "pledge"); if (*argv && **argv == '+') { format = *argv + 1; argc--; } if (argc > 0) errx(1, "too many arguments"); if (outzone) setenv("TZ", outzone, 1); tp = localtime(&tval); if (tp == NULL) errx(1, "conversion error"); (void)strftime(buf, sizeof(buf), format, tp); (void)printf("%s\n", buf); exit(0); }
void rfc1305(uint32_t *data) { /* struct ntptime *arrival; struct timeval udp_arrival; gettimeofday(&udp_arrival, NULL); arrival->coarse = udp_arrival.tv_sec + JAN_1970; arrival->fine = NTPFRAC(udp_arrival.tv_usec); */ /* // straight out of RFC-1305 Appendix A int li, vn, mode, stratum, poll, prec; int delay, disp, refid; struct ntptime reftime, orgtime, rectime, xmttime; #define Data(i) ntohl(((uint32_t *)data)[i]) li = Data(0) >> 30 & 0x03; vn = Data(0) >> 27 & 0x07; mode = Data(0) >> 24 & 0x07; stratum = Data(0) >> 16 & 0xff; poll = Data(0) >> 8 & 0xff; prec = Data(0) & 0xff; if (prec & 0x80) prec|=0xffffff00; delay = Data(1); disp = Data(2); refid = Data(3); reftime.coarse = Data(4); reftime.fine = Data(5); orgtime.coarse = Data(6); orgtime.fine = Data(7); rectime.coarse = Data(8); rectime.fine = Data(9); xmttime.coarse = Data(10); xmttime.fine = Data(11); #undef Data struct timeval tv_set; // it would be even better to subtract half the slop tv_set.tv_sec = xmttime.coarse - JAN_1970; // divide xmttime.fine by 4294.967296 tv_set.tv_usec = USEC(xmttime.fine); if (settimeofday(&tv_set,NULL)<0) { perror("settimeofday"); exit(1); } */ struct timeval tv_set; tv_set.tv_sec = ntohl(((uint32_t *)data)[10]) - JAN_1970; tv_set.tv_usec = USEC(ntohl(((uint32_t *)data)[11])); if (settimeofday(&tv_set, NULL) < 0) { perror("settimeofday"); exit(1); } /* double el_time,st_time; el_time=ntpdiff(&orgtime,arrival); // elapsed st_time=ntpdiff(&rectime,&xmttime); // stall return(el_time-st_time); */ }
int main(int argc, char *argv[]) { struct tm local; struct timeval tv, *stv; struct timezone tz, *stz; int kern_offset, wall_clock, disrtcset; size_t len; /* Avoid time_t here, can be unsigned long or worse */ long offset, localsec, diff; time_t initial_sec, final_sec; int ch; int initial_isdst = -1, final_isdst; int need_restore = False, sleep_mode = False, looping, init = Unknown; sigset_t mask, emask; while ((ch = getopt(argc, argv, "ais")) != -1) switch((char)ch) { case 'i': /* initial call, save offset */ if (init != Unknown) usage(); init = True; break; case 'a': /* adjustment call, use saved offset */ if (init != Unknown) usage(); init = False; break; case 's': sleep_mode = True; break; default: usage(); } if (init == Unknown) usage(); if (access(_PATH_CLOCK, F_OK) != 0) return 0; if (init) sleep_mode = True; sigemptyset(&mask); sigemptyset(&emask); sigaddset(&mask, SIGTERM); openlog("adjkerntz", LOG_PID|LOG_PERROR, LOG_DAEMON); (void) signal(SIGHUP, SIG_IGN); if (init && daemon(0, #ifdef DEBUG 1 #else 0 #endif )) { syslog(LOG_ERR, "daemon: %m"); return 1; } again: (void) sigprocmask(SIG_BLOCK, &mask, NULL); (void) signal(SIGTERM, fake); diff = 0; stv = NULL; stz = NULL; looping = False; wall_clock = (access(_PATH_CLOCK, F_OK) == 0); if (init && !sleep_mode) { init = False; if (!wall_clock) return 0; } tzset(); len = sizeof(kern_offset); if (sysctlbyname("machdep.adjkerntz", &kern_offset, &len, NULL, 0) == -1) { syslog(LOG_ERR, "sysctl(\"machdep.adjkerntz\"): %m"); return 1; } /****** Critical section, do all things as fast as possible ******/ /* get local CMOS clock and possible kernel offset */ if (gettimeofday(&tv, &tz)) { syslog(LOG_ERR, "gettimeofday: %m"); return 1; } /* get the actual local timezone difference */ initial_sec = tv.tv_sec; recalculate: local = *localtime(&initial_sec); if (diff == 0) initial_isdst = local.tm_isdst; local.tm_isdst = initial_isdst; /* calculate local CMOS diff from GMT */ localsec = mktime(&local); if (localsec == -1) { /* * XXX user can only control local time, and it is * unacceptable to fail here for init. 2:30 am in the * middle of the nonexistent hour means 3:30 am. */ if (!sleep_mode) { syslog(LOG_WARNING, "Warning: nonexistent local time, try to run later."); syslog(LOG_WARNING, "Giving up."); return 1; } syslog(LOG_WARNING, "Warning: nonexistent local time."); syslog(LOG_WARNING, "Will retry after %d minutes.", REPORT_PERIOD / 60); (void) signal(SIGTERM, SIG_DFL); (void) sigprocmask(SIG_UNBLOCK, &mask, NULL); (void) sleep(REPORT_PERIOD); goto again; } offset = -local.tm_gmtoff; #ifdef DEBUG fprintf(stderr, "Initial offset: %ld secs\n", offset); #endif /* correct the kerneltime for this diffs */ /* subtract kernel offset, if present, old offset too */ diff = offset - tz.tz_minuteswest * 60 - kern_offset; if (diff != 0) { #ifdef DEBUG fprintf(stderr, "Initial diff: %ld secs\n", diff); #endif /* Yet one step for final time */ final_sec = initial_sec + diff; /* get the actual local timezone difference */ local = *localtime(&final_sec); final_isdst = diff < 0 ? initial_isdst : local.tm_isdst; if (diff > 0 && initial_isdst != final_isdst) { if (looping) goto bad_final; looping = True; initial_isdst = final_isdst; goto recalculate; } local.tm_isdst = final_isdst; localsec = mktime(&local); if (localsec == -1) { bad_final: /* * XXX as above. The user has even less control, * but perhaps we never get here. */ if (!sleep_mode) { syslog(LOG_WARNING, "Warning: nonexistent final local time, try to run later."); syslog(LOG_WARNING, "Giving up."); return 1; } syslog(LOG_WARNING, "Warning: nonexistent final local time."); syslog(LOG_WARNING, "Will retry after %d minutes.", REPORT_PERIOD / 60); (void) signal(SIGTERM, SIG_DFL); (void) sigprocmask(SIG_UNBLOCK, &mask, NULL); (void) sleep(REPORT_PERIOD); goto again; } offset = -local.tm_gmtoff; #ifdef DEBUG fprintf(stderr, "Final offset: %ld secs\n", offset); #endif /* correct the kerneltime for this diffs */ /* subtract kernel offset, if present, old offset too */ diff = offset - tz.tz_minuteswest * 60 - kern_offset; if (diff != 0) { #ifdef DEBUG fprintf(stderr, "Final diff: %ld secs\n", diff); #endif /* * stv is abused as a flag. The important value * is in `diff'. */ stv = &tv; } } if (tz.tz_dsttime != 0 || tz.tz_minuteswest != 0) { tz.tz_dsttime = tz.tz_minuteswest = 0; /* zone info is garbage */ stz = &tz; } if (!wall_clock && stz == NULL) stv = NULL; /* if init or UTC clock and offset/date will be changed, */ /* disable RTC modification for a while. */ if ( (init && stv != NULL) || ((init || !wall_clock) && kern_offset != offset) ) { len = sizeof(disrtcset); if (sysctlbyname("machdep.disable_rtc_set", &disrtcset, &len, NULL, 0) == -1) { syslog(LOG_ERR, "sysctl(get: \"machdep.disable_rtc_set\"): %m"); return 1; } if (disrtcset == 0) { disrtcset = 1; need_restore = True; if (sysctlbyname("machdep.disable_rtc_set", NULL, NULL, &disrtcset, len) == -1) { syslog(LOG_ERR, "sysctl(set: \"machdep.disable_rtc_set\"): %m"); return 1; } } } if ( (init && (stv != NULL || stz != NULL)) || (stz != NULL && stv == NULL) ) { if (stv != NULL) { /* * Get the time again, as close as possible to * adjusting it, to minimise drift. * XXX we'd better not fail between here and * restoring disrtcset, since we don't clean up * anything. */ (void)gettimeofday(&tv, NULL); tv.tv_sec += diff; stv = &tv; } if (settimeofday(stv, stz)) { syslog(LOG_ERR, "settimeofday: %m"); return 1; } } /* setting machdep.adjkerntz have a side effect: resettodr(), which */ /* can be disabled by machdep.disable_rtc_set, so if init or UTC clock */ /* -- don't write RTC, else write RTC. */ if (kern_offset != offset) { kern_offset = offset; len = sizeof(kern_offset); if (sysctlbyname("machdep.adjkerntz", NULL, NULL, &kern_offset, len) == -1) { syslog(LOG_ERR, "sysctl(set: \"machdep.adjkerntz\"): %m"); return 1; } } len = sizeof(wall_clock); if (sysctlbyname("machdep.wall_cmos_clock", NULL, NULL, &wall_clock, len) == -1) { syslog(LOG_ERR, "sysctl(set: \"machdep.wall_cmos_clock\"): %m"); return 1; } if (need_restore) { need_restore = False; disrtcset = 0; len = sizeof(disrtcset); if (sysctlbyname("machdep.disable_rtc_set", NULL, NULL, &disrtcset, len) == -1) { syslog(LOG_ERR, "sysctl(set: \"machdep.disable_rtc_set\"): %m"); return 1; } } /****** End of critical section ******/ if (init && wall_clock) { sleep_mode = False; /* wait for signals and acts like -a */ (void) sigsuspend(&emask); goto again; } return 0; }
int API main (int argc, char *argv[], char *envp[]) { struct routeup rtc; int hwclock_fd = -1; time_t last_success = 0; struct opts opts; int wait_time = 0; set_conf_defaults(&opts); parse_argv(&opts, argc, argv); check_conf(&opts); load_conf(&opts); check_conf(&opts); if (!opts.sources) add_source_to_conf(&opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY); /* grab a handle to /dev/rtc for sync_hwclock() */ if (opts.should_sync_hwclock && (hwclock_fd = open (DEFAULT_RTC_DEVICE, O_RDONLY)) < 0) { pinfo ("can't open hwclock fd"); opts.should_sync_hwclock = 0; } /* set up a netlink context if we need one */ if (opts.should_netlink && routeup_setup (&rtc)) pfatal ("Can't open netlink socket"); if (!is_sane_time (time (NULL))) { struct timeval tv = { 0, 0 }; /* * If the time is before the build timestamp, we're probably on * a system with a broken rtc. Try loading the timestamp off * disk. */ tv.tv_sec = RECENT_COMPILE_DATE; if (opts.should_load_disk && load_disk_timestamp (timestamp_path, &tv.tv_sec)) pinfo ("can't load disk timestamp"); if (!opts.dry_run && settimeofday (&tv, NULL)) pfatal ("settimeofday() failed"); dbus_announce(); /* * don't save here - we either just loaded this time or used the * default time, and neither of those are good to save */ sync_and_save (hwclock_fd, opts.should_sync_hwclock, 0); } /* register a signal handler to save time at shutdown */ if (opts.should_save_disk) signal (SIGTERM, sigterm_handler); /* * Try once right away. If we fail, wait for a route to appear, then try * for a while; repeat whenever another route appears. Try until we * succeed. */ if (!tlsdate (&opts, envp)) { last_success = time (NULL); sync_and_save (hwclock_fd, opts.should_sync_hwclock, opts.should_save_disk); dbus_announce(); } /* * Loop until we catch a fatal signal or routeup_once() fails. We run * tlsdate at least once a day, but possibly as often as routes come up; * this should handle cases like a VPN being brought up and down * periodically. */ wait_time = add_jitter(opts.steady_state_interval, opts.jitter); while (wait_for_event (&rtc, opts.should_netlink, wait_time) >= 0) { /* * If a route just came up, run tlsdate; if it * succeeded, then we're good and can keep time locally * from now on. */ int i; int backoff = opts.wait_between_tries; wait_time = add_jitter(opts.steady_state_interval, opts.jitter); if (time (NULL) - last_success < opts.min_steady_state_interval) continue; for (i = 0; i < opts.max_tries && tlsdate (&opts, envp); ++i) { if (backoff < 1) fatal ("backoff too small? %d", backoff); sleep (backoff); if (backoff < MAX_SANE_BACKOFF) backoff *= 2; } if (i != opts.max_tries) { last_success = time (NULL); info ("tlsdate succeeded"); sync_and_save (hwclock_fd, opts.should_sync_hwclock, opts.should_save_disk); dbus_announce(); } } return 1; }
int main(const int argc, char *argv[]) { register const char * format; register const char * value; register const char * cp; register int ch; register int dousg; register int aflag = 0; register int dflag = 0; register int nflag = 0; register int tflag = 0; register int minuteswest; register int dsttime; register double adjust; time_t now; time_t t; INITIALIZE(dousg); INITIALIZE(minuteswest); INITIALIZE(dsttime); INITIALIZE(adjust); INITIALIZE(t); #ifdef LC_ALL (void) setlocale(LC_ALL, ""); #endif /* defined(LC_ALL) */ #if HAVE_GETTEXT #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined(TEXTDOMAINDIR) */ (void) textdomain(TZ_DOMAIN); #endif /* HAVE_GETTEXT */ (void) time(&now); format = value = NULL; while ((ch = getopt(argc, argv, "ucnd:t:a:")) != EOF && ch != -1) { switch (ch) { default: usage(); case 'u': /* do it in UTC */ case 'c': dogmt(); break; case 'n': /* don't set network */ nflag = 1; break; case 'd': /* daylight saving time */ if (dflag) { (void) fprintf(stderr, _("date: error: multiple -d's used")); usage(); } dflag = 1; cp = optarg; dsttime = atoi(cp); if (*cp == '\0' || *nondigit(cp) != '\0') wildinput(_("-t value"), optarg, _("must be a non-negative number")); break; case 't': /* minutes west of UTC */ if (tflag) { (void) fprintf(stderr, _("date: error: multiple -t's used")); usage(); } tflag = 1; cp = optarg; minuteswest = atoi(cp); if (*cp == '+' || *cp == '-') ++cp; if (*cp == '\0' || *nondigit(cp) != '\0') wildinput(_("-d value"), optarg, _("must be a number")); break; case 'a': /* adjustment */ if (aflag) { (void) fprintf(stderr, _("date: error: multiple -a's used")); usage(); } aflag = 1; cp = optarg; adjust = atof(cp); if (*cp == '+' || *cp == '-') ++cp; if (*cp == '\0' || strcmp(cp, ".") == 0) wildinput(_("-a value"), optarg, _("must be a number")); cp = nondigit(cp); if (*cp == '.') ++cp; if (*nondigit(cp) != '\0') wildinput(_("-a value"), optarg, _("must be a number")); break; } } while (optind < argc) { cp = argv[optind++]; if (*cp == '+') if (format == NULL) format = cp + 1; else { (void) fprintf(stderr, _("date: error: multiple formats in command line\n")); usage(); } else if (value == NULL) value = cp; else { (void) fprintf(stderr, _("date: error: multiple values in command line\n")); usage(); } } if (value != NULL) { /* ** This order ensures that "reasonable" twelve-digit inputs ** (such as 120203042006) won't be misinterpreted ** even if time_t's range all the way back to the thirteenth ** century. Do not change the order. */ t = convert(value, (dousg = TRUE), now); if (t == -1) t = convert(value, (dousg = FALSE), now); if (t == -1) { /* ** Out of range values, ** or time that falls in a DST transition hole? */ if ((cp = strchr(value, '.')) != NULL) { /* ** Ensure that the failure of ** TZ=America/New_York date 8712312359.60 ** doesn't get misdiagnosed. (It was ** TZ=America/New_York date 8712311859.60 ** when the leap second was inserted.) ** The normal check won't work since ** the given time is valid in UTC. */ if (atoi(cp + 1) >= SECSPERMIN) wildinput(_("time"), value, _("out of range seconds given")); } dogmt(); t = convert(value, FALSE, now); if (t == -1) t = convert(value, TRUE, now); wildinput(_("time"), value, (t == -1) ? _("out of range value given") : _("time skipped when clock springs forward")); } } /* ** Entire command line has now been checked. */ if (aflag) { #if HAVE_ADJTIME struct timeval tv; tv.tv_sec = (int) adjust; tv.tv_usec = (int) ((adjust - tv.tv_sec) * 1000000L); if (adjtime(&tv, NULL) != 0) oops("adjtime"); #endif /* HAVE_ADJTIME */ #if !HAVE_ADJTIME reset(now + adjust, nflag); #endif /* !HAVE_ADJTIME */ /* ** Sun silently ignores everything else; we follow suit. */ exit(retval); } if (dflag || tflag) { #if HAVE_SETTIMEOFDAY == 2 struct timezone tz; if (!dflag || !tflag) if (gettimeofday(NULL, &tz) != 0) oops("gettimeofday"); if (dflag) tz.tz_dsttime = dsttime; if (tflag) tz.tz_minuteswest = minuteswest; if (settimeofday(NULL, &tz) != 0) oops("settimeofday"); #endif /* HAVE_SETTIMEOFDAY == 2 */ #if HAVE_SETTIMEOFDAY != 2 (void) fprintf(stderr, _("date: warning: kernel doesn't keep -d/-t information, option ignored\n")); #endif /* HAVE_SETTIMEOFDAY != 2 */ } if (value == NULL) display(format); reset(t, nflag); checkfinal(value, dousg, t, now); #ifdef EBUG { struct tm tm; tm = *localtime(&t); timeout(stdout, "%c\n", &tm); exit(retval); } #endif /* defined EBUG */ display(format); /* gcc -Wall pacifier */ for ( ; ; ) continue; }
/* Set CLOCK to value TP. */ int clock_settime (clockid_t clock_id, const struct timespec *tp) { struct timeval tv; int retval; /* Make sure the time cvalue is OK. */ if (tp->tv_nsec < 0 || tp->tv_nsec >= 1000000000) { __set_errno (EINVAL); return -1; } switch (clock_id) { case CLOCK_REALTIME: TIMESPEC_TO_TIMEVAL (&tv, tp); retval = settimeofday (&tv, NULL); break; #if HP_TIMING_AVAIL case CLOCK_PROCESS_CPUTIME_ID: case CLOCK_THREAD_CPUTIME_ID: { hp_timing_t tsc; hp_timing_t usertime; /* First thing is to get the current time. */ HP_TIMING_NOW (tsc); if (__builtin_expect (freq == 0, 0)) { /* This can only happen if we haven't initialized the `freq' variable yet. Do this now. We don't have to protect this code against multiple execution since all of them should lead to the same result. */ freq = __get_clockfreq (); if (__builtin_expect (freq == 0, 0)) { /* Something went wrong. */ retval = -1; break; } } /* Convert the user-provided time into CPU ticks. */ usertime = tp->tv_sec * freq + (tp->tv_nsec * freq) / 1000000000ull; /* Determine the offset and use it as the new base value. */ if (clock_id != CLOCK_THREAD_CPUTIME_ID || __pthread_clock_settime == NULL) ;// GL(dl_cpuclock_offset) = tsc - usertime; else __pthread_clock_settime (tsc - usertime); retval = 0; } break; #endif default: __set_errno (EINVAL); retval = -1; break; } return retval; }
int main(int argc, char **argv) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ suseconds_t delta; /* parse standard options */ if ((msg = parse_opts(argc, argv, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { int condition_number = 1; /* reset Tst_count in case we are looping */ Tst_count = 0; tp.tv_sec = VAL_SEC; tp.tv_usec = VAL_MSEC; TEST(settimeofday(&tp, NULL)); if (TEST_RETURN == -1) { TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TFAIL, "Error Setting Time, errno=%d", TEST_ERRNO); } if ((gettimeofday(&tp2, (struct timezone *)&tp1)) == -1) { tst_resm(TBROK, "Error Getting Time, errno=%d", errno); } if (tp2.tv_sec > tp.tv_sec) { delta = (suseconds_t) (tp2.tv_sec - tp.tv_sec) * 1000 + (tp2.tv_usec - tp.tv_usec) / 1000; } else { delta = (suseconds_t) (tp.tv_sec - tp2.tv_sec) * 1000 + (tp.tv_usec - tp2.tv_usec) / 1000; } if (delta > -ACCEPTABLE_DELTA && delta < ACCEPTABLE_DELTA) { tst_resm(TPASS, "Test condition %d successful", condition_number++); } else { tst_resm(TFAIL, "Test condition %d failed", condition_number++); } /* Invalid Args : Error Condition where tp = NULL */ TEST(settimeofday((struct timeval *)-1, NULL)); if (TEST_RETURN == -1) { TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TPASS, "Test condition %d successful", condition_number++); } else { tst_resm(TFAIL, "Test condition %d failed", condition_number); } } cleanup(); tst_exit(); }
int slave(void) { int tries; long electiontime, refusetime, looktime, looptime, adjtime; u_short seq; long fastelection; #define FASTTOUT 3 struct in_addr cadr; struct timeval otime; struct sockaddr_in taddr; char tname[MAXHOSTNAMELEN]; struct tsp *msg, to; struct timeval ntime, wait, tmptv; time_t tsp_time_sec; struct tsp *answer; int timeout(); char olddate[32]; char newdate[32]; struct netinfo *ntp; struct hosttbl *htp; struct utmpx utx; old_slavenet = NULL; seq = 0; refusetime = 0; adjtime = 0; (void)gettimeofday(&ntime, NULL); electiontime = ntime.tv_sec + delay2; fastelection = ntime.tv_sec + FASTTOUT; if (justquit) looktime = electiontime; else looktime = fastelection; looptime = fastelection; if (slavenet) xmit(TSP_SLAVEUP, 0, &slavenet->dest_addr); if (status & MASTER) { for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == MASTER) masterup(ntp); } } loop: get_goodgroup(0); (void)gettimeofday(&ntime, NULL); if (ntime.tv_sec > electiontime) { if (trace) fprintf(fd, "election timer expired\n"); longjmp(jmpenv, 1); } if (ntime.tv_sec >= looktime) { if (trace) fprintf(fd, "Looking for nets to master\n"); if (Mflag && nignorednets > 0) { for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == IGNORE || ntp->status == NOMASTER) { lookformaster(ntp); if (ntp->status == MASTER) { masterup(ntp); } else if (ntp->status == MASTER) { ntp->status = NOMASTER; } } if (ntp->status == MASTER && --ntp->quit_count < 0) ntp->quit_count = 0; } makeslave(slavenet); /* prune extras */ setstatus(); } (void)gettimeofday(&ntime, NULL); looktime = ntime.tv_sec + delay2; } if (ntime.tv_sec >= looptime) { if (trace) fprintf(fd, "Looking for loops\n"); for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == MASTER) { to.tsp_type = TSP_LOOP; to.tsp_vers = TSPVERSION; to.tsp_seq = sequence++; to.tsp_hopcnt = MAX_HOPCNT; (void)strcpy(to.tsp_name, hostname); bytenetorder(&to); if (sendto(sock, (char *)&to, sizeof(struct tsp), 0, (struct sockaddr*)&ntp->dest_addr, sizeof(ntp->dest_addr)) < 0) { trace_sendto_err(ntp->dest_addr.sin_addr); } } } (void)gettimeofday(&ntime, NULL); looptime = ntime.tv_sec + delay2; } wait.tv_sec = min(electiontime,min(looktime,looptime)) - ntime.tv_sec; if (wait.tv_sec < 0) wait.tv_sec = 0; wait.tv_sec += FASTTOUT; wait.tv_usec = 0; msg = readmsg(TSP_ANY, ANYADDR, &wait, 0); if (msg != NULL) { /* * filter stuff not for us */ switch (msg->tsp_type) { case TSP_SETDATE: case TSP_TRACEOFF: case TSP_TRACEON: /* * XXX check to see they are from ourself */ break; case TSP_TEST: case TSP_MSITE: break; case TSP_MASTERUP: if (!fromnet) { if (trace) { fprintf(fd, "slave ignored: "); print(msg, &from); } goto loop; } break; default: if (!fromnet || fromnet->status == IGNORE || fromnet->status == NOMASTER) { if (trace) { fprintf(fd, "slave ignored: "); print(msg, &from); } goto loop; } break; } /* * now process the message */ switch (msg->tsp_type) { case TSP_ADJTIME: if (fromnet != slavenet) break; if (!good_host_name(msg->tsp_name)) { syslog(LOG_NOTICE, "attempted time adjustment by %s", msg->tsp_name); suppress(&from, msg->tsp_name, fromnet); break; } /* * Speed up loop detection in case we have a loop. * Otherwise the clocks can race until the loop * is found. */ (void)gettimeofday(&otime, NULL); if (adjtime < otime.tv_sec) looptime -= (looptime-otime.tv_sec)/2 + 1; setmaster(msg); if (seq != msg->tsp_seq) { seq = msg->tsp_seq; synch(tvtomsround(msg->tsp_time)); } (void)gettimeofday(&ntime, NULL); electiontime = ntime.tv_sec + delay2; fastelection = ntime.tv_sec + FASTTOUT; adjtime = ntime.tv_sec + SAMPLEINTVL*2; break; case TSP_SETTIME: if (fromnet != slavenet) break; if (seq == msg->tsp_seq) break; seq = msg->tsp_seq; /* adjust time for residence on the queue */ (void)gettimeofday(&otime, NULL); adj_msg_time(msg,&otime); /* * the following line is necessary due to syslog * calling ctime() which clobbers the static buffer */ (void)strlcpy(olddate, date(), sizeof(olddate)); tsp_time_sec = msg->tsp_time.tv_sec; (void)strlcpy(newdate, ctime(&tsp_time_sec), sizeof(newdate)); if (!good_host_name(msg->tsp_name)) { syslog(LOG_NOTICE, "attempted time setting by untrusted %s to %s", msg->tsp_name, newdate); suppress(&from, msg->tsp_name, fromnet); break; } setmaster(msg); tmptv.tv_sec = msg->tsp_time.tv_sec; tmptv.tv_usec = msg->tsp_time.tv_usec; timevalsub(&ntime, &tmptv, &otime); if (ntime.tv_sec < MAXADJ && ntime.tv_sec > -MAXADJ) { /* * do not change the clock if we can adjust it */ synch(tvtomsround(ntime)); } else { utx.ut_type = OLD_TIME; gettimeofday(&utx.ut_tv, NULL); pututxline(&utx); (void)settimeofday(&tmptv, 0); utx.ut_type = NEW_TIME; gettimeofday(&utx.ut_tv, NULL); pututxline(&utx); syslog(LOG_NOTICE, "date changed by %s from %s", msg->tsp_name, olddate); if (status & MASTER) spreadtime(); } (void)gettimeofday(&ntime, NULL); electiontime = ntime.tv_sec + delay2; fastelection = ntime.tv_sec + FASTTOUT; /* This patches a bad protocol bug. Imagine a system with several networks, * where there are a pair of redundant gateways between a pair of networks, * each running timed. Assume that we start with a third machine mastering * one of the networks, and one of the gateways mastering the other. * Imagine that the third machine goes away and the non-master gateway * decides to replace it. If things are timed just 'right,' we will have * each gateway mastering one network for a little while. If a SETTIME * message gets into the network at that time, perhaps from the newly * masterful gateway as it was taking control, the SETTIME will loop * forever. Each time a gateway receives it on its slave side, it will * call spreadtime to forward it on its mastered network. We are now in * a permanent loop, since the SETTIME msgs will keep any clock * in the network from advancing. Normally, the 'LOOP' stuff will detect * and correct the situation. However, with the clocks stopped, the * 'looptime' timer cannot expire. While they are in this state, the * masters will try to saturate the network with SETTIME packets. */ looptime = ntime.tv_sec + (looptime-otime.tv_sec)/2-1; break; case TSP_MASTERUP: if (slavenet && fromnet != slavenet) break; if (!good_host_name(msg->tsp_name)) { suppress(&from, msg->tsp_name, fromnet); if (electiontime > fastelection) electiontime = fastelection; break; } makeslave(fromnet); setmaster(msg); setstatus(); answerdelay(); xmit(TSP_SLAVEUP, 0, &from); (void)gettimeofday(&ntime, NULL); electiontime = ntime.tv_sec + delay2; fastelection = ntime.tv_sec + FASTTOUT; refusetime = 0; break; case TSP_MASTERREQ: if (fromnet->status != SLAVE) break; (void)gettimeofday(&ntime, NULL); electiontime = ntime.tv_sec + delay2; break; case TSP_SETDATE: tsp_time_sec = msg->tsp_time.tv_sec; (void)strlcpy(newdate, ctime(&tsp_time_sec), sizeof(newdate)); schgdate(msg, newdate); break; case TSP_SETDATEREQ: if (fromnet->status != MASTER) break; tsp_time_sec = msg->tsp_time.tv_sec; (void)strlcpy(newdate, ctime(&tsp_time_sec), sizeof(newdate)); htp = findhost(msg->tsp_name); if (htp == NULL) { syslog(LOG_WARNING, "DATEREQ from uncontrolled machine"); break; } if (!htp->good) { syslog(LOG_WARNING, "attempted date change by untrusted %s to %s", htp->name, newdate); spreadtime(); break; } schgdate(msg, newdate); break; case TSP_TRACEON: traceon(); break; case TSP_TRACEOFF: traceoff("Tracing ended at %s\n"); break; case TSP_SLAVEUP: newslave(msg); break; case TSP_ELECTION: if (fromnet->status == SLAVE) { (void)gettimeofday(&ntime, NULL); electiontime = ntime.tv_sec + delay2; fastelection = ntime.tv_sec + FASTTOUT; seq = 0; if (!good_host_name(msg->tsp_name)) { syslog(LOG_NOTICE, "suppress election of %s", msg->tsp_name); to.tsp_type = TSP_QUIT; electiontime = fastelection; } else if (cadr.s_addr != from.sin_addr.s_addr && ntime.tv_sec < refusetime) { /* if the candidate has to repeat itself, the old code would refuse it * the second time. That would prevent elections. */ to.tsp_type = TSP_REFUSE; } else { cadr.s_addr = from.sin_addr.s_addr; to.tsp_type = TSP_ACCEPT; refusetime = ntime.tv_sec + 30; } taddr = from; (void)strcpy(tname, msg->tsp_name); (void)strcpy(to.tsp_name, hostname); answerdelay(); if (!acksend(&to, &taddr, tname, TSP_ACK, 0, 0)) syslog(LOG_WARNING, "no answer from candidate %s\n", tname); } else { /* fromnet->status == MASTER */ htp = addmach(msg->tsp_name, &from,fromnet); to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); if (!acksend(&to, &htp->addr, htp->name, TSP_ACK, 0, htp->noanswer)) { syslog(LOG_ERR, "no reply from %s to ELECTION-QUIT", htp->name); (void)remmach(htp); } } break; case TSP_CONFLICT: if (fromnet->status != MASTER) break; /* * After a network partition, there can be * more than one master: the first slave to * come up will notify here the situation. */ (void)strcpy(to.tsp_name, hostname); /* The other master often gets into the same state, * with boring results. */ ntp = fromnet; /* (acksend() can leave fromnet=0 */ for (tries = 0; tries < 3; tries++) { to.tsp_type = TSP_RESOLVE; answer = acksend(&to, &ntp->dest_addr, ANYADDR, TSP_MASTERACK, ntp, 0); if (answer == NULL) break; htp = addmach(answer->tsp_name,&from,ntp); to.tsp_type = TSP_QUIT; answer = acksend(&to, &htp->addr, htp->name, TSP_ACK, 0, htp->noanswer); if (!answer) { syslog(LOG_WARNING, "conflict error: no reply from %s to QUIT", htp->name); (void)remmach(htp); } } masterup(ntp); break; case TSP_MSITE: if (!slavenet) break; taddr = from; to.tsp_type = TSP_MSITEREQ; to.tsp_vers = TSPVERSION; to.tsp_seq = 0; (void)strcpy(to.tsp_name, hostname); answer = acksend(&to, &slavenet->dest_addr, ANYADDR, TSP_ACK, slavenet, 0); if (answer != NULL && good_host_name(answer->tsp_name)) { setmaster(answer); to.tsp_type = TSP_ACK; (void)strcpy(to.tsp_name, answer->tsp_name); bytenetorder(&to); if (sendto(sock, (char *)&to, sizeof(struct tsp), 0, (struct sockaddr*)&taddr, sizeof(taddr)) < 0) { trace_sendto_err(taddr.sin_addr); } } break; case TSP_MSITEREQ: break; case TSP_ACCEPT: case TSP_REFUSE: case TSP_RESOLVE: break; case TSP_QUIT: doquit(msg); /* become a slave */ break; case TSP_TEST: electiontime = 0; break; case TSP_LOOP: /* looking for loops of masters */ if (!(status & MASTER)) break; if (fromnet->status == SLAVE) { if (!strcmp(msg->tsp_name, hostname)) { /* * Someone forwarded our message back to * us. There must be a loop. Tell the * master of this network to quit. * * The other master often gets into * the same state, with boring results. */ ntp = fromnet; for (tries = 0; tries < 3; tries++) { to.tsp_type = TSP_RESOLVE; answer = acksend(&to, &ntp->dest_addr, ANYADDR, TSP_MASTERACK, ntp,0); if (answer == NULL) break; taddr = from; (void)strcpy(tname, answer->tsp_name); to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); if (!acksend(&to, &taddr, tname, TSP_ACK, 0, 1)) { syslog(LOG_ERR, "no reply from %s to slave LOOP-QUIT", tname); } else { electiontime = 0; } } (void)gettimeofday(&ntime, NULL); looptime = ntime.tv_sec + FASTTOUT; } else { if (msg->tsp_hopcnt-- < 1) break; bytenetorder(msg); for (ntp = nettab; ntp != NULL; ntp = ntp->next) { if (ntp->status == MASTER && 0 > sendto(sock, (char *)msg, sizeof(struct tsp), 0, (struct sockaddr*)&ntp->dest_addr, sizeof(ntp->dest_addr))) trace_sendto_err(ntp->dest_addr.sin_addr); } } } else { /* fromnet->status == MASTER */ /* * We should not have received this from a net * we are master on. There must be two masters, * unless the packet was really from us. */ if (from.sin_addr.s_addr == fromnet->my_addr.s_addr) { if (trace) fprintf(fd,"discarding forwarded LOOP\n"); break; } /* * The other master often gets into the same * state, with boring results. */ ntp = fromnet; for (tries = 0; tries < 3; tries++) { to.tsp_type = TSP_RESOLVE; answer = acksend(&to, &ntp->dest_addr, ANYADDR, TSP_MASTERACK, ntp,0); if (!answer) break; htp = addmach(answer->tsp_name, &from,ntp); to.tsp_type = TSP_QUIT; (void)strcpy(to.tsp_name, hostname); if (!acksend(&to,&htp->addr,htp->name, TSP_ACK, 0, htp->noanswer)) { syslog(LOG_ERR, "no reply from %s to master LOOP-QUIT", htp->name); (void)remmach(htp); } } (void)gettimeofday(&ntime, NULL); looptime = ntime.tv_sec + FASTTOUT; } break; default: if (trace) { fprintf(fd, "garbage message: "); print(msg, &from); } break; } } goto loop; }
static void setthetime(const char *fmt, const char *p, int jflag, int nflag) { struct tm *lt; struct timeval tv; const char *dot, *t; int century; lt = localtime(&tval); lt->tm_isdst = -1; /* divine correct DST */ if (fmt != NULL) { t = strptime(p, fmt, lt); if (t == NULL) { fprintf(stderr, "Failed conversion of ``%s''" " using format ``%s''\n", p, fmt); badformat(); } else if (*t != '\0') fprintf(stderr, "Warning: Ignoring %ld extraneous" " characters in date string (%s)\n", (long) strlen(t), t); } else { for (t = p, dot = NULL; *t; ++t) { if (isdigit(*t)) continue; if (*t == '.' && dot == NULL) { dot = t; continue; } badformat(); } if (dot != NULL) { /* .ss */ dot++; /* *dot++ = '\0'; */ if (strlen(dot) != 2) badformat(); lt->tm_sec = ATOI2(dot); if (lt->tm_sec > 61) badformat(); } else lt->tm_sec = 0; century = 0; /* if p has a ".ss" field then let's pretend it's not there */ switch (strlen(p) - ((dot != NULL) ? 3 : 0)) { case 12: /* cc */ lt->tm_year = ATOI2(p) * 100 - TM_YEAR_BASE; century = 1; /* FALLTHROUGH */ case 10: /* yy */ if (century) lt->tm_year += ATOI2(p); else { lt->tm_year = ATOI2(p); if (lt->tm_year < 69) /* hack for 2000 ;-} */ lt->tm_year += 2000 - TM_YEAR_BASE; else lt->tm_year += 1900 - TM_YEAR_BASE; } /* FALLTHROUGH */ case 8: /* mm */ lt->tm_mon = ATOI2(p); if (lt->tm_mon > 12) badformat(); --lt->tm_mon; /* time struct is 0 - 11 */ /* FALLTHROUGH */ case 6: /* dd */ lt->tm_mday = ATOI2(p); if (lt->tm_mday > 31) badformat(); /* FALLTHROUGH */ case 4: /* HH */ lt->tm_hour = ATOI2(p); if (lt->tm_hour > 23) badformat(); /* FALLTHROUGH */ case 2: /* MM */ lt->tm_min = ATOI2(p); if (lt->tm_min > 59) badformat(); break; default: badformat(); } } /* convert broken-down time to GMT clock time */ if ((tval = mktime(lt)) == -1) errx(1, "nonexistent time"); if (!jflag) { /* set the time */ if (nflag || netsettime(tval)) { logwtmp("|", "date", ""); tv.tv_sec = tval; tv.tv_usec = 0; if (settimeofday(&tv, (struct timezone *)NULL)) err(1, "settimeofday (timeval)"); logwtmp("{", "date", ""); } if ((p = getlogin()) == NULL) p = "???"; syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p); } }
static void decode_msg(void *base, size_t len, struct timeval *tv, struct timespec *mrx_time) { struct ntp_msg *msg = base; double m_delta, org, rec, xmt, dst; double delay, offset; static guint transmit_delay; if (len < sizeof(*msg)) { connman_error("Invalid response from time server"); return; } if (!tv) { connman_error("Invalid packet timestamp from time server"); return; } DBG("flags : 0x%02x", msg->flags); DBG("stratum : %u", msg->stratum); DBG("poll : %f seconds (%d)", LOGTOD(msg->poll), msg->poll); DBG("precision : %f seconds (%d)", LOGTOD(msg->precision), msg->precision); DBG("root delay : %u seconds (fraction %u)", msg->rootdelay.seconds, msg->rootdelay.fraction); DBG("root disp. : %u seconds (fraction %u)", msg->rootdisp.seconds, msg->rootdisp.fraction); DBG("reference : 0x%04x", msg->refid); transmit_delay = LOGTOD(msg->poll); if (NTP_FLAGS_LI_DECODE(msg->flags) == NTP_FLAG_LI_NOTINSYNC) { DBG("ignoring unsynchronized peer"); return; } if (NTP_FLAGS_VN_DECODE(msg->flags) != NTP_FLAG_VN_VER4) { if (NTP_FLAGS_VN_DECODE(msg->flags) == NTP_FLAG_VN_VER3) { DBG("requested version %d, accepting version %d", NTP_FLAG_VN_VER4, NTP_FLAGS_VN_DECODE(msg->flags)); } else { DBG("unsupported version %d", NTP_FLAGS_VN_DECODE(msg->flags)); return; } } if (NTP_FLAGS_MD_DECODE(msg->flags) != NTP_FLAG_MD_SERVER) { DBG("unsupported mode %d", NTP_FLAGS_MD_DECODE(msg->flags)); return; } m_delta = mrx_time->tv_sec - mtx_time.tv_sec + 1.0e-9 * (mrx_time->tv_nsec - mtx_time.tv_nsec); org = tv->tv_sec + (1.0e-6 * tv->tv_usec) - m_delta + OFFSET_1900_1970; rec = ntohl(msg->rectime.seconds) + ((double) ntohl(msg->rectime.fraction) / UINT_MAX); xmt = ntohl(msg->xmttime.seconds) + ((double) ntohl(msg->xmttime.fraction) / UINT_MAX); dst = tv->tv_sec + (1.0e-6 * tv->tv_usec) + OFFSET_1900_1970; DBG("org=%f rec=%f xmt=%f dst=%f", org, rec, xmt, dst); offset = ((rec - org) + (xmt - dst)) / 2; delay = (dst - org) - (xmt - rec); DBG("offset=%f delay=%f", offset, delay); /* Remove the timeout, as timeserver has responded */ reset_timeout(); /* * Now poll the server every transmit_delay seconds * for time correction. */ if (poll_id > 0) g_source_remove(poll_id); DBG("Timeserver %s, next sync in %d seconds", timeserver, transmit_delay); poll_id = g_timeout_add_seconds(transmit_delay, next_poll, NULL); connman_info("ntp: time slew %+.6f s", offset); if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) { struct timeval adj; adj.tv_sec = (long) offset; adj.tv_usec = (offset - adj.tv_sec) * 1000000; DBG("adjusting time"); if (adjtime(&adj, &adj) < 0) { connman_error("Failed to adjust time"); return; } DBG("%lu seconds, %lu msecs", adj.tv_sec, adj.tv_usec); } else { struct timeval cur; double dtime; gettimeofday(&cur, NULL); dtime = offset + cur.tv_sec + 1.0e-6 * cur.tv_usec; cur.tv_sec = (long) dtime; cur.tv_usec = (dtime - cur.tv_sec) * 1000000; DBG("setting time"); if (settimeofday(&cur, NULL) < 0) { connman_error("Failed to set time"); return; } DBG("%lu seconds, %lu msecs", cur.tv_sec, cur.tv_usec); } }
void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int update_count ) { int time_difference; bool restart_tdt = false; if (!tp_time) restart_tdt = true; else if (tp_time == -1) { restart_tdt = true; /*if ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7020 || ( eSystemInfo::getInstance()->getHwType() == eSystemInfo::DM7000 && eSystemInfo::getInstance()->hasStandbyWakeupTimer() ) ) TODO !!!!!!! */ { eDebug("[eDVBLocalTimerHandler] no transponder tuned... or no TDT/TOT avail .. try to use RTC :)"); time_t rtc_time = getRTC(); if ( rtc_time ) // RTC Ready? { tm now; localtime_r(&rtc_time, &now); eDebug("[eDVBLocalTimerHandler] RTC time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_t linuxTime=time(0); localtime_r(&linuxTime, &now); eDebug("[eDVBLocalTimerHandler] Receiver time is %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_difference = rtc_time - linuxTime; eDebug("[eDVBLocalTimerHandler] RTC to Receiver time difference is %ld seconds", linuxTime - rtc_time ); if ( time_difference ) { eDebug("[eDVBLocalTimerHandler] set Linux Time to RTC Time"); timeval tnow; gettimeofday(&tnow,0); tnow.tv_sec=rtc_time; settimeofday(&tnow,0); } else if ( !time_difference ) eDebug("[eDVBLocalTimerHandler] no change needed"); else eDebug("[eDVBLocalTimerHandler] set to RTC time"); /*emit*/ m_timeUpdated(); } else eDebug("[eDVBLocalTimerHandler] getRTC returned time=0. RTC problem?"); } } else { std::map< eDVBChannelID, int >::iterator it( m_timeOffsetMap.find( chan->getChannelID() ) ); // current linux time time_t linuxTime = time(0); #ifdef DEBUG // current transponder time tm tp_now; localtime_r(&tp_time, &tp_now); eDebug("[eDVBLocalTimerHandler] Transponder time is %02d.%02d.%04d %02d:%02d:%02d", tp_now.tm_mday, tp_now.tm_mon + 1, tp_now.tm_year + 1900, tp_now.tm_hour, tp_now.tm_min, tp_now.tm_sec); #endif // difference between current enigma time and transponder time int enigma_diff = tp_time-linuxTime; int new_diff=0; bool updated = m_time_ready; if ( m_time_ready ) // ref time ready? { // difference between reference time (current enigma time) // and the transponder time eDebug("[eDVBLocalTimerHandler] diff is %d", enigma_diff); if ( abs(enigma_diff) < 120 ) { eDebug("[eDVBLocalTimerHandler] diff < 120 .. use Transponder Time"); m_timeOffsetMap[chan->getChannelID()] = 0; new_diff = enigma_diff; } else if ( it != m_timeOffsetMap.end() ) // correction saved? { eDebug("[eDVBLocalTimerHandler] we have correction %d", it->second); time_t CorrectedTpTime = tp_time+it->second; int ddiff = CorrectedTpTime-linuxTime; eDebug("[eDVBLocalTimerHandler] diff after add correction is %d", ddiff); if ( abs(it->second) < 300 ) // stored correction < 5 min { eDebug("[eDVBLocalTimerHandler] use stored correction(<5 min)"); new_diff = ddiff; } else if ( getRTC() ) { time_t rtc=getRTC(); m_timeOffsetMap[chan->getChannelID()] = rtc-tp_time; new_diff = rtc-linuxTime; // set enigma time to rtc eDebug("[eDVBLocalTimerHandler] update stored correction to %ld (calced against RTC time)", rtc-tp_time ); } else if ( abs(ddiff) <= 120 ) { // with stored correction calced time difference is lower 2 min // this don't help when a transponder have a clock running to slow or to fast // then its better to have a DM7020 with always running RTC eDebug("[eDVBLocalTimerHandler] use stored correction(corr < 2 min)"); new_diff = ddiff; } else // big change in calced correction.. hold current time and update correction { eDebug("[eDVBLocalTimerHandler] update stored correction to %d", -enigma_diff); m_timeOffsetMap[chan->getChannelID()] = -enigma_diff; } } else { eDebug("[eDVBLocalTimerHandler] no correction found... store calced correction(%d)",-enigma_diff); m_timeOffsetMap[chan->getChannelID()] = -enigma_diff; } } else // no time setted yet { if ( it != m_timeOffsetMap.end() ) { enigma_diff += it->second; eDebug("[eDVBLocalTimerHandler] we have correction (%d)... use", it->second ); } else eDebug("[eDVBLocalTimerHandler] dont have correction.. set Transponder Diff"); new_diff=enigma_diff; m_time_ready=true; } time_t t = linuxTime+new_diff; m_last_tp_time_difference=tp_time-t; if (!new_diff && updated) // overrride this check on first received TDT { eDebug("[eDVBLocalTimerHandler] not changed"); return; } if ( !update_count ) { // set rtc to calced transponder time when the first tdt is received on this // transponder setRTC(t); eDebug("[eDVBLocalTimerHandler] update RTC"); } else if (getRTC()) { if (abs(getRTC() - t) > 60) { eDebug("[eDVBLocalTimerHandler] difference between new linux time and RTC time is > 60 sec... transponder time looks not ok... use rtc time"); t = getRTC(); } else eDebug("[eDVBLocalTimerHandler] difference between linux time and RTC time is < 60 sec... so the transponder time looks ok"); } else eDebug("[eDVBLocalTimerHandler] no RTC available :("); tm now; localtime_r(&t, &now); eDebug("[eDVBLocalTimerHandler] time update to %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); time_difference = t - linuxTime; // calc our new linux_time -> enigma_time correction eDebug("[eDVBLocalTimerHandler] m_time_difference is %d", time_difference ); if ( time_difference ) { if ( (time_difference >= -15) && (time_difference <= 15) ) { // Slew small diffs ... // Even good transponders can differ by 0-5 sec, if we would step these // the system clock would permanentely jump around when zapping. timeval tdelta, tolddelta; tdelta.tv_sec=time_difference; int rc=adjtime(&tdelta,&tolddelta); if(rc==0) { eDebug("[eDVBLocalTimerHandler] slewing Linux Time by %03d seconds", time_difference); } else { eDebug("[eDVBLocalTimerHandler] slewing Linux Time by %03d seconds FAILED", time_difference); } } else { // ... only step larger diffs timeval tnow; gettimeofday(&tnow,0); tnow.tv_sec=t; settimeofday(&tnow,0); linuxTime=time(0); localtime_r(&linuxTime, &now); eDebug("[eDVBLocalTimerHandler] stepped Linux Time to %02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); } } /*emit*/ m_timeUpdated(); } if ( restart_tdt ) { std::map<iDVBChannel*, channel_data>::iterator it = m_knownChannels.find(chan); if ( it != m_knownChannels.end() ) { int system = iDVBFrontend::feSatellite; ePtr<iDVBFrontendParameters> parms; chan->getCurrentFrontendParameters(parms); if (parms) { parms->getSystem(system); } int updateCount = it->second.timetable->getUpdateCount(); it->second.timetable = NULL; if (system == iDVBFrontend::feATSC) { it->second.timetable = new STT(chan, updateCount); } else { it->second.timetable = new TDT(chan, updateCount); } it->second.timetable->startTimer(TIME_UPDATE_INTERVAL); // restart TDT for this transponder in 30min } } }
void elba_parsing (unsigned char *pBuf) // ---------------------------------------------------------------------------- // PARSING MESSAGE // Description : Message를 parsing 한다. // // Arguments : pBuf Is a pointer to the receive message buffer // Returns : none { //int i = 0; int nIsTimeMsg = 0; int nType = 0; point_info sPoint; struct timeval set_time; time_t tm_st; time_t tm_nd; double d_diff; struct tm user_stime; nType = pBuf[8]; nIsTimeMsg = pBuf[5]; if ( nIsTimeMsg == 0x0f ) { if ( nType == 0x40 ) { // 기준이 되는 시간. 1970-01-01 00:00 user_stime.tm_year = 1970 - 1900; // 주의 :년도는 1900년부터 시작 user_stime.tm_mon = 1 -1; // 주의 :월은 0부터 시작 user_stime.tm_mday = 1; user_stime.tm_hour = 0; user_stime.tm_min = 0; user_stime.tm_sec = 0; user_stime.tm_isdst = 0; // 썸머 타임 사용 안함 tm_st = mktime( &user_stime ); user_stime.tm_year = (2000 + pBuf[12]) -1900; // 주의 :년도는 1900년부터 시작 user_stime.tm_mon = (int)pBuf[13] - 1; // 주의 :월은 0부터 시작 user_stime.tm_mday = (int)pBuf[14]; user_stime.tm_hour = (int)pBuf[15]; user_stime.tm_min = (int)pBuf[16]; user_stime.tm_sec = 0; user_stime.tm_isdst = 0; // 썸머 타임 사용 안함 tm_nd = mktime( &user_stime ); d_diff = difftime( tm_nd, tm_st ); fprintf( stdout, "[Time Set] d_diff %f \n", d_diff ); gettimeofday( &set_time, NULL ); set_time.tv_sec = (long)d_diff; fprintf( stdout, "[Time Set] set_time.tv_sec %ld \n", set_time.tv_sec ); settimeofday( &set_time, NULL ); fprintf( stdout, "[Time Set] %d-%d-%d %d:%d \n", pBuf[12], pBuf[13], pBuf[14], pBuf[15], pBuf[16] ); fflush( stdout); system( "hwclock --systohc" ); } if ( gc_view_elba ) { fprintf(stdout, "\nGet Time "); fflush(stdout); } return; } switch (nType) { // Request Message // ex message > 0x7b 0x48 0x45 0x41 0x44 0x09 0xfe 0xfe 0x00 0x08 0xfe 0xfe 0x00 0x01 0xf6 0x15 0x54 0x41 0x49 0x4c 0x7d case 0x00: // get point information. sPoint.pcm = pBuf[12]; sPoint.pno = pBuf[13]; pthread_mutex_lock( &pointTable_mutex ); sPoint.value = g_fExPtbl[sPoint.pcm][sPoint.pno]; pthread_mutex_unlock( &pointTable_mutex ); // point_table의 값은 항상 update된 값을 가지고 있는 DB이기 때문에 // point_table의 값을 바로 올려보내줘도 괜찮을 것이라고 생각한다. // 만약 net32가 연결되어 있다면, // Net32는 느린 Device이기 때문에 먼저 3iS에서 요청을 처리하고 // Queue를 사용해서 새로운 값을 갱신하도록 한다. // 그러므로 Net32가 연결되어 있다면, // 3iS의 요청에 의해 2번의 응답을 보내게 되는 것이다. // only alive pcm /* for ( i = 0; i < 32; i++ ) { if ( g_cNode[i] > 0 && i == sPoint.pcm && sPoint.pcm != g_nMyPcm ) { sPoint.message_type = NET32_TYPE_REQUIRE; net32_push_queue(&sPoint); // send to net32_queue } } */ sPoint.message_type = NET32_TYPE_REQUIRE; net32_push_queue(&sPoint); // send to net32_queue sPoint.message_type = NET32_TYPE_REPORT; elba_push_queue(&sPoint); // send to elba queue. if ( gc_view_elba ) { fprintf(stdout, "\nRequest %d, %d ", sPoint.pcm, sPoint.pno); fflush(stdout); } break; // Commnad Message case 0x40: // get point information. sPoint.pcm = pBuf[12]; sPoint.pno = pBuf[13]; memcpy( &sPoint.value, (pBuf + 14), sizeof(float) ); sPoint.value = elba_change_byte_order(sPoint.value); // Interface for PLC //pthread_mutex_lock( &plcQ_mutex ); //putq( &plc_message_queue, &sPoint ); //pthread_mutex_unlock( &plcQ_mutex ); //g_iChkControl = 1; // 만약 Net32를 사용한다면, // point_table의 값을 갱신하지 않고 Net32로 data를 보낸다. // 하지만 Net32를 사용하지 않는 경우에는, // point_table의 값을 갱신하고 그 값을 3iS로 보낸다. sPoint.message_type = NET32_TYPE_COMMAND; pSet(sPoint.pcm, sPoint.pno, sPoint.value); if ( g_nMultiDdcFlag ) { pthread_mutex_lock( &pointTable_mutex ); g_fExPtbl[sPoint.pcm][sPoint.pno] = sPoint.value; pthread_mutex_unlock( &pointTable_mutex ); elba_push_queue(&sPoint); } if ( gc_view_elba ) { fprintf(stdout, "\nCommand %d, %d %0.1f", sPoint.pcm, sPoint.pno, sPoint.value); fflush(stdout); } break; default: break; } }