Commit 6f18a2ac authored by Jean-Claude BAU's avatar Jean-Claude BAU Committed by Maciej Lipinski

wr_date.c: Add option

The -n option in the wr_date tool is used for a dry run. It execute the
code without applying changes in the system and the hardware.
However calling "wr_date -n set host" was not setting the date but
applying the TAI offset. To make things more consistant, a new option
has been added. Calling "wr_date set host tai" now sets only the TAI
offset.
The wr_date script has been changed to take into account this
modification of the behavior.
parent 8ca5bb52
#!/bin/sh #!/bin/sh
# First of all, run 'wr_date -n set host', so to fix tai_offset in the kernel. Does not set the time # First of all, run 'wr_date set host tai', so to fix TAI offset in the kernel. Does not set the time
/wr/bin/wr_date -n set host > /dev/null /wr/bin/wr_date set host tai > /dev/null
F=/etc/wr_date.conf F=/etc/wr_date.conf
#CCS=/sys/bus/clocksource/devices/clocksource0/current_clocksource #CCS=/sys/bus/clocksource/devices/clocksource0/current_clocksource
......
...@@ -88,6 +88,9 @@ wr_mon: wr_mon.o term.o time_lib.o ...@@ -88,6 +88,9 @@ wr_mon: wr_mon.o term.o time_lib.o
wr_date: wr_date.o time_lib.o wr_date: wr_date.o time_lib.o
${CC} -o $@ $^ $(LDFLAGS) ${CC} -o $@ $^ $(LDFLAGS)
fix_tai_offset: fix_tai_offset.o time_lib.o
${CC} -o $@ $^ $(LDFLAGS)
wr_management: wr_management.o term.o wr_management: wr_management.o term.o
${CC} -o $@ $^ $(LDFLAGS) ${CC} -o $@ $^ $(LDFLAGS)
......
...@@ -12,67 +12,25 @@ ...@@ -12,67 +12,25 @@
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/timex.h> #include <time_lib.h>
#ifndef MOD_TAI #ifndef MOD_TAI
#define MOD_TAI 0x80 #define MOD_TAI 0x80
#endif #endif
#define WRDATE_CFG_FILE "/wr/etc/wrdate.conf"
#define WRDATE_LEAP_FILE "/etc/leap-seconds.list"
int opt_verbose = 1; int opt_verbose = 1;
char *prgname; char *prgname;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct timex t;
char s[128];
unsigned long long now, leapt, expire = 0;
int i, tai_offset = 0;
prgname = argv[0];
/* first: get the current offset */ int taiOffset;
memset(&t, 0, sizeof(t));
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", prgname,
strerror(errno));
return 0;
}
/* then, find the current time, using such offset */ prgname = argv[0];
now = time(NULL) + 2208988800LL; /* (for TAI: + utc_offset */
FILE *f = fopen(WRDATE_LEAP_FILE, "r"); if ( (taiOffset=fixHostTai(NULL,time(NULL),NULL,opt_verbose)) == -1 ) {
if (!f) { fprintf(stderr, "%s: Cannot fix TAI offset\n" ,prgname);
fprintf(stderr, "%s: %s: %s\n", prgname, WRDATE_LEAP_FILE,
strerror(errno));
return 0; return 0;
} }
while (fgets(s, sizeof(s), f)) { return taiOffset;
if (sscanf(s, "#@ %lli", &expire) == 1)
continue;
if (sscanf(s, "%lli %i", &leapt, &i) != 2)
continue;
/* check this line, and apply if if it's in the past */
if (leapt < now)
tai_offset = i;
}
fclose(f);
if (tai_offset != t.tai) {
if (opt_verbose)
printf("Previous TAI offset: %i\n", t.tai);
t.constant = tai_offset;
t.modes = MOD_TAI;
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", prgname,
strerror(errno));
return tai_offset;
}
}
if (opt_verbose)
printf("Current TAI offset: %i\n", t.tai);
return tai_offset;
} }
/** /*
* Time to string conversion functions * time_lib.c
*
* - Time to string conversion functions
* - Decode leap seconds file
*
* Created on: 2019
* Authors:
* - Jean-Claude BAU / CERN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License...
*/ */
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h>
#include <inttypes.h> #include <inttypes.h>
#include <sys/timex.h>
#include <ppsi/ppsi.h> #include <ppsi/ppsi.h>
char * timeIntervalToString(TimeInterval time,char *buf) { char * timeIntervalToString(TimeInterval time,char *buf) {
...@@ -132,3 +154,113 @@ int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval * ...@@ -132,3 +154,113 @@ int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *
return (result->tv_sec < 0) || (result->tv_usec<0); return (result->tv_sec < 0) || (result->tv_usec<0);
} }
/**
* Get the TAI offset decoding the leap seconds file
* @param leapSecondsFile The leapSecond file name. Use the default one if NULL
* @param utc Number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC)
* @param hasExpired if hasExpired is not NULL, set to 1 if the file has expired
* @return >=0 : TAI offset
* -1 : Error
*/
#define OFFSET_NTP_TIME_TO_UTC ((uint64_t)2208988800LL) /* NTP time to UTC (1900 to 1970 in seconds) */
static char *defaultLeapSecondsFile = "/etc/leap-seconds.list";
int getTaiOffsetFromLeapSecondsFile(char *leapSecondsFile, time_t utc, int *hasExpired) {
uint64_t expirationDate, ntpTime ;
int tai_offset = 9; /* For the time before 1972, we consider that the offset is 9 */
FILE *f;
char line[128];
if ( leapSecondsFile == NULL )
leapSecondsFile=defaultLeapSecondsFile;
ntpTime = (uint64_t)utc + OFFSET_NTP_TIME_TO_UTC;
f = fopen(leapSecondsFile, "r");
if (!f) {
fprintf(stderr, "%s: Cannot open file %s: %s\n", __func__, leapSecondsFile,strerror(errno));
return -1;
}
/* Scan the file */
while (fgets(line, sizeof(line), f)) {
int tai;
uint64_t leapNtpTime;
if ( strcmp(line,"# ")==0)
continue; // This is a comment
if (sscanf(line, "#@ %" PRIu64 , &expirationDate) == 1) {
if ( hasExpired !=NULL )
*hasExpired=ntpTime>expirationDate;
continue;
}
if (sscanf(line, "%" PRIu64 " %i", &leapNtpTime, &tai) != 2)
continue;
/* check this line, and apply it if it's in the past */
if (leapNtpTime < ntpTime)
tai_offset = tai;
else if (leapNtpTime > ntpTime)
break; // File read can be aborted
}
fclose(f);
return tai_offset;
}
/**
* Fix the TAI representation looking at the leap file
* @param leapSecondsFile The leapSecond file name. Use the default one if NULL
* @param utc Number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC)
* @param hasExpired if hasExpired is not NULL, set to 1 if the file has expired
* @param verbose Activate verbose mode
* @return >=0 : TAI offset
* -1 : Error
*/
int fixHostTai(char *leapSecondsFile, time_t utc, int *hasExpired, int verbose)
{
struct timex t;
int tai_offset;
/* first: get the current offset */
memset(&t, 0, sizeof(t));
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", __func__,
strerror(errno));
return 0;
}
if ( (tai_offset=getTaiOffsetFromLeapSecondsFile(NULL,utc,hasExpired))<0 ) {
fprintf(stderr, "%s: Cannot get TAI offset\n", __func__);
return 0;
}
if ( verbose && hasExpired && *hasExpired ) {
printf("Leap seconds file has expired.\n");
}
if (tai_offset != t.tai) {
if (verbose)
printf("Previous TAI offset: %i\n", t.tai);
t.constant = tai_offset;
t.modes = MOD_TAI;
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", __func__,
strerror(errno));
return tai_offset;
}
/* read back timex */
memset(&t, 0, sizeof(t));
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", __func__,
strerror(errno));
return 0;
}
}
if (verbose)
printf("Current TAI offset: %i\n", t.tai);
return tai_offset;
}
/*
* time_lib.h
*
* - Time to string conversion functions
* - Decode leap seconds file
*
* Created on: 2019
* Authors:
* - Jean-Claude BAU / CERN
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License...
*/
#include <ppsi/ppsi.h> #include <ppsi/ppsi.h>
#include <time.h>
#include <sys/time.h>
/* Prototypes */ /* Prototypes */
char * timeIntervalToString(TimeInterval time,char *buf); extern char * timeIntervalToString(TimeInterval time,char *buf);
char * timeToString(struct pp_time *time,char *buf); extern char * timeToString(struct pp_time *time,char *buf);
char * timestampToString(struct Timestamp *time,char *buf); extern char * timestampToString(struct Timestamp *time,char *buf);
char * relativeDifferenceToString(RelativeDifference time, char *buf ); extern char * relativeDifferenceToString(RelativeDifference time, char *buf );
int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y); extern int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y);
extern int getTaiOffsetFromLeapSecondsFile(char *leapSecondsFile, time_t utc, int *hasExpired);
extern int fixHostTai(char *leapSecondsFile, time_t utc, int *hasExpired, int verbose);
;
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#define MOD_TAI 0x80 #define MOD_TAI 0x80
#endif #endif
#define WRDATE_CFG_FILE "/etc/wr_date.conf" #define WRDATE_CFG_FILE "/etc/wr_date.conf"
#define WRDATE_LEAP_FILE "/etc/leap-seconds.list"
/* Address for hardware, from nic-hardware.h */ /* Address for hardware, from nic-hardware.h */
#define FPGA_BASE_PPSG 0x10010500 #define FPGA_BASE_PPSG 0x10010500
...@@ -36,7 +35,11 @@ ...@@ -36,7 +35,11 @@
extern int init_module(void *module, unsigned long len, const char *options); extern int init_module(void *module, unsigned long len, const char *options);
extern int delete_module(const char *module, unsigned int flags); extern int delete_module(const char *module, unsigned int flags);
void help(char *prgname) static int opt_verbose, opt_force, opt_not;
static char *opt_cfgfile = WRDATE_CFG_FILE;
static char *prgname;
void help(void)
{ {
fprintf(stderr, "%s: Use: \"%s [<options>] <cmd> [<args>]\n", fprintf(stderr, "%s: Use: \"%s [<options>] <cmd> [<args>]\n",
prgname, prgname); prgname, prgname);
...@@ -45,11 +48,12 @@ void help(char *prgname) ...@@ -45,11 +48,12 @@ void help(char *prgname)
" -f force: run even if not on a WR switch\n" " -f force: run even if not on a WR switch\n"
" -c <cfg> configfile to use in place of the default\n" " -c <cfg> configfile to use in place of the default\n"
" -v verbose: report what the program does\n" " -v verbose: report what the program does\n"
" -n do not act in practice\n" " -n do not act in practice - dry run\n"
" get print WR time to stdout\n" " get print WR time to stdout\n"
" get tohost print WR time and set system time\n" " get tohost print WR time and set system time\n"
" set <value> set WR time to scalar seconds\n" " set <value> set WR time to scalar seconds\n"
" set host set TAI from current host time.\n" " set host [tai] set TAI and WR time from current host time.\n"
" if tai option is set then set only the TAI offset.\n"
" stat print statistics between TAI (WR time) and linux UTC\n" " stat print statistics between TAI (WR time) and linux UTC\n"
" diff show the difference between WR FPGA time (HW) and linux time (SW)\n" " diff show the difference between WR FPGA time (HW) and linux time (SW)\n"
/* " set ntp set TAI from ntp and leap seconds" */ /* " set ntp set TAI from ntp and leap seconds" */
...@@ -58,9 +62,6 @@ void help(char *prgname) ...@@ -58,9 +62,6 @@ void help(char *prgname)
exit(1); exit(1);
} }
int opt_verbose, opt_force, opt_not;
char *opt_cfgfile = WRDATE_CFG_FILE;
char *prgname;
/* Check that we actualy are on the wr switch, exit if not */ /* Check that we actualy are on the wr switch, exit if not */
int wrdate_check_host(void) int wrdate_check_host(void)
...@@ -214,79 +215,6 @@ int wrdate_diff(volatile struct PPSG_WB *pps) ...@@ -214,79 +215,6 @@ int wrdate_diff(volatile struct PPSG_WB *pps)
return __wrdate_diff(pps,&ht, &wt); return __wrdate_diff(pps,&ht, &wt);
} }
/* Fix the TAI representation looking at the leap file */
int fix_host_tai(void)
{
struct timex t;
char s[128];
unsigned long long now, now_2014, leapt, expire = 0;
int i, *p, tai_offset = 0;
/* first: get the current offset */
memset(&t, 0, sizeof(t));
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", prgname,
strerror(errno));
return 0;
}
/*
* At the very start, we believe to be Jan 1st 1970. But
* what we really want is counting the tai_offset, so WR
* can then set system time by itself. And, being wrong by
* 1-2 seconds is ok (system time is for log messages only),
* but being off by 35 seconds is not. So let's use "35" by
* default, i.e. be aware we are at least in 2014
*/
now_2014 = 1417806803; /* as I write this */
/* then, find the current time, using such offset */
now = time(NULL);
if (now < now_2014)
now = now_2014;
now += 2208988800LL; /* (for TAI: + utc_offset) */
FILE *f = fopen(WRDATE_LEAP_FILE, "r");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", prgname, WRDATE_LEAP_FILE,
strerror(errno));
return 0;
}
while (fgets(s, sizeof(s), f)) {
if (sscanf(s, "#@ %lli", &expire) == 1)
continue;
if (sscanf(s, "%lli %i", &leapt, &i) != 2)
continue;
/* check this line, and apply it if it's in the past */
if (leapt < now)
tai_offset = i;
}
fclose(f);
/*
* Our WRS kernel has tai support, but our compiler does not.
* We are 32-bit only, and we know for sure that tai is
* exactly after stbcnt. It's a bad hack, but it works
*/
p = (int *)(&t.stbcnt) + 1;
if (tai_offset != *p) {
if (opt_verbose)
printf("Previous TAI offset: %i\n", *p);
t.constant = tai_offset;
t.modes = MOD_TAI;
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", prgname,
strerror(errno));
return tai_offset;
}
}
if (opt_verbose)
printf("Current TAI offset: %i\n", *p);
return tai_offset;
}
#define ADJ_SEC_ITER 10 #define ADJ_SEC_ITER 10
static int wait_wr_adjustment(volatile struct PPSG_WB *pps) static int wait_wr_adjustment(volatile struct PPSG_WB *pps)
...@@ -376,25 +304,18 @@ int installClockSourceModule(void) { ...@@ -376,25 +304,18 @@ int installClockSourceModule(void) {
} }
/* This sets WR time from host time */ /* This sets WR time from host time */
int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int deep) int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int tai_offset, int deep)
{ {
struct timeval tvh, tvr; /* host, rabbit */ struct timeval tvh, tvr; /* host, rabbit */
signed long long diff64; signed long long diff64;
signed long diff; signed long diff;
int tai_offset;
int modRemoved=0; int modRemoved=0;
if ( deep > 4 ) if ( deep > 4 )
return 0; /* Avoid stack overflow (recursive function) in case of error */ return 0; /* Avoid stack overflow (recursive function) in case of error */
tai_offset = fix_host_tai(); if ( ! opt_not) {
if (opt_not) {
if (!opt_verbose) return 0;
printf("Nothing done: -n option selected\n");
} else {
if ( deep==0) { if ( deep==0) {
modRemoved=removeClockSourceModule(); // The driver must be removed otherwise the time cannot be set properly modRemoved=removeClockSourceModule(); // The driver must be removed otherwise the time cannot be set properly
} }
...@@ -438,7 +359,7 @@ int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int deep ...@@ -438,7 +359,7 @@ int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int deep
asm("" : : : "memory"); /* barrier... */ asm("" : : : "memory"); /* barrier... */
pps->CR = pps->CR | PPSG_CR_CNT_ADJ; pps->CR = pps->CR | PPSG_CR_CNT_ADJ;
if ( wait_wr_adjustment(pps) && !adjSecOnly ) if ( wait_wr_adjustment(pps) && !adjSecOnly )
__wrdate_internal_set(pps,0,deep+1); /* adjust the usecs */ __wrdate_internal_set(pps,0,tai_offset,deep+1); /* adjust the usecs */
} else if ( !adjSecOnly ) { } else if ( !adjSecOnly ) {
if (opt_verbose) if (opt_verbose)
printf("adjusting by %li usecs\n", diff); printf("adjusting by %li usecs\n", diff);
...@@ -469,8 +390,39 @@ int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int deep ...@@ -469,8 +390,39 @@ int __wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly, int deep
} }
/* This sets WR time from host time */ /* This sets WR time from host time */
int wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly) { int wrdate_internal_set(volatile struct PPSG_WB *pps, int taiOnly, int adjSecOnly) {
return __wrdate_internal_set(pps,adjSecOnly,0); int tai_offset;
if (opt_not) {
// Do not change the TAI but display only information if verbose is enabled
struct timex t;
int taiOffset, hasExpired;
if (!opt_verbose) return 0;
/* first: get the current offset */
memset(&t, 0, sizeof(t));
if (adjtimex(&t) < 0) {
fprintf(stderr, "%s: adjtimex(): %s\n", __func__,
strerror(errno));
return 0;
}
printf("Current TAI offset= %d\n",t.tai);
if ( (taiOffset=getTaiOffsetFromLeapSecondsFile(NULL,time(NULL),&hasExpired))==-1) {
fprintf(stderr, "%s: Cannot fix read TAI offset from leap seconds file\n" ,prgname);
return 0;
}
printf("TAI offset form leap seconds file= %d\n",taiOffset);
if ( hasExpired )
printf("Leap seconds file has expired!\n");
} else {
if ( (tai_offset=fixHostTai(NULL,time(NULL),NULL,opt_verbose)) == -1 ) {
fprintf(stderr, "%s: Cannot fix TAI offset\n" ,prgname);
return 0;
}
}
if ( taiOnly )
return 0;
return __wrdate_internal_set(pps,adjSecOnly,tai_offset,0);
} }
/* This sets WR time from host time for grand master mode /* This sets WR time from host time for grand master mode
...@@ -481,7 +433,7 @@ int wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly) { ...@@ -481,7 +433,7 @@ int wrdate_internal_set(volatile struct PPSG_WB *pps, int adjSecOnly) {
#define LOW_LIMIT_HALF_SEC (300*1000) /* 300 ms */ #define LOW_LIMIT_HALF_SEC (300*1000) /* 300 ms */
#define HIGH_LIMIT_HALF_SEC (700*1000) /* 300 ms */ #define HIGH_LIMIT_HALF_SEC (700*1000) /* 300 ms */
int wrdate_internal_set_gm(volatile struct PPSG_WB *pps) { int wrdate_internal_set_gm(volatile struct PPSG_WB *pps, int taiOnly) {
if (opt_verbose ) { if (opt_verbose ) {
printf("Set WR time for grand master.\n"); printf("Set WR time for grand master.\n");
...@@ -492,7 +444,7 @@ int wrdate_internal_set_gm(volatile struct PPSG_WB *pps) { ...@@ -492,7 +444,7 @@ int wrdate_internal_set_gm(volatile struct PPSG_WB *pps) {
gettimeof_wr(&wt, pps); gettimeof_wr(&wt, pps);
if ( wt.tv_usec>LOW_LIMIT_HALF_SEC && wt.tv_usec<HIGH_LIMIT_HALF_SEC ) { if ( wt.tv_usec>LOW_LIMIT_HALF_SEC && wt.tv_usec<HIGH_LIMIT_HALF_SEC ) {
wrdate_internal_set(pps,1); wrdate_internal_set(pps,taiOnly,1);
return 0; return 0;
} else { } else {
useconds_t usec; useconds_t usec;
...@@ -528,38 +480,46 @@ int wrdate_set(volatile struct PPSG_WB *pps, int argc, char **argv) ...@@ -528,38 +480,46 @@ int wrdate_set(volatile struct PPSG_WB *pps, int argc, char **argv)
unsigned long t; /* WARNING: 64 bit */ unsigned long t; /* WARNING: 64 bit */
struct timeval tv; struct timeval tv;
if (!strcmp(argv[0], "host")) { if (argc>=1 && !strcmp(argv[0], "host")) {
int tm=getTimingMode(); int tm=getTimingMode();
int taiOnly;
taiOnly=argc>=2 && !strcmp(argv[1], "tai");
switch (tm) { switch (tm) {
case SPLL_MODE_GRAND_MASTER: case SPLL_MODE_GRAND_MASTER:
return wrdate_internal_set_gm(pps); return wrdate_internal_set_gm(pps,taiOnly);
case SPLL_MODE_FREE_RUNNING_MASTER : case SPLL_MODE_FREE_RUNNING_MASTER :
case SPLL_MODE_DISABLED : case SPLL_MODE_DISABLED :
return wrdate_internal_set(pps,0); return wrdate_internal_set(pps,taiOnly,0);
break; break;
case SPLL_MODE_SLAVE : case SPLL_MODE_SLAVE :
fprintf(stderr, "Slave timing mode: WR time cannot be set!!!\n"); fprintf(stderr, "Slave timing mode: WR time and TAI offset cannot be set!!!\n");
return -1; return -1;
default: default:
fprintf(stderr, "Cannot read Soft PLL timing mode. WR time cannot be set (ret=%d)\n",tm); fprintf(stderr, "Cannot read Soft PLL timing mode. WR time and TAI offset cannot be set (ret=%d)\n",tm);
return -1; return -1;
} }
} }
s = strdup(argv[0]); if ( argc>=1 ) {
if (sscanf(argv[0], "%li%s", &t, s) == 1) { s = strdup(argv[0]);
tv.tv_sec = t; if (sscanf(argv[0], "%li%s", &t, s) == 1) {
tv.tv_usec = 0; tv.tv_sec = t;
if (settimeofday(&tv, NULL) < 0) { tv.tv_usec = 0;
fprintf(stderr, "%s: settimeofday(%s): %s\n", if (settimeofday(&tv, NULL) < 0) {
prgname, argv[0], strerror(errno)); fprintf(stderr, "%s: settimeofday(%s): %s\n",
exit(1); prgname, argv[0], strerror(errno));
exit(1);
}
return wrdate_internal_set(pps,1,0);
} }
return wrdate_internal_set(pps,0);
}
/* FIXME: other time formats */ /* FIXME: other time formats */
printf(" FIXME\n"); printf(" FIXME\n");
return 0;
}
fprintf(stderr, "Missing parameter!! \n\n");
return 0; return 0;
} }
...@@ -635,13 +595,14 @@ int main(int argc, char **argv) ...@@ -635,13 +595,14 @@ int main(int argc, char **argv)
break; break;
case 'n': case 'n':
opt_not = 1; opt_not = 1;
printf("Dry run mode: No action will be performed\n");
break; break;
default: default:
help(argv[0]); help();
} }
} }
if (optind > argc - 1) if (optind > argc - 1)
help(argv[0]); help();
cmd = argv[optind++]; cmd = argv[optind++];
...@@ -659,7 +620,7 @@ int main(int argc, char **argv) ...@@ -659,7 +620,7 @@ int main(int argc, char **argv)
if (optind == argc - 1 && !strcmp(argv[optind], "tohost")) if (optind == argc - 1 && !strcmp(argv[optind], "tohost"))
tohost = 1; tohost = 1;
else if (optind < argc) else if (optind < argc)
help(argv[0]); help();
return wrdate_get(pps, tohost); return wrdate_get(pps, tohost);
} }
...@@ -674,7 +635,7 @@ int main(int argc, char **argv) ...@@ -674,7 +635,7 @@ int main(int argc, char **argv)
/* only other command is "set", with one on more arguments */ /* only other command is "set", with one on more arguments */
if (strcmp(cmd, "set") || optind > argc - 1) if (strcmp(cmd, "set") || optind > argc - 1)
help(argv[0]); help();
return wrdate_set(pps, argc-optind,&argv[optind]); return wrdate_set(pps, argc-optind,&argv[optind]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment