11 |
* Licensed under GPLv2 or later, see file License in this tarball for details. |
* Licensed under GPLv2 or later, see file License in this tarball for details. |
12 |
*/ |
*/ |
13 |
|
|
14 |
#include "busybox.h" |
#include "libbb.h" |
15 |
#include <sys/timex.h> |
#include <sys/timex.h> |
16 |
|
|
17 |
static const struct {int bit; const char *name;} statlist[] = { |
static const uint16_t statlist_bit[] = { |
18 |
{ STA_PLL, "PLL" }, |
STA_PLL, |
19 |
{ STA_PPSFREQ, "PPSFREQ" }, |
STA_PPSFREQ, |
20 |
{ STA_PPSTIME, "PPSTIME" }, |
STA_PPSTIME, |
21 |
{ STA_FLL, "FFL" }, |
STA_FLL, |
22 |
{ STA_INS, "INS" }, |
STA_INS, |
23 |
{ STA_DEL, "DEL" }, |
STA_DEL, |
24 |
{ STA_UNSYNC, "UNSYNC" }, |
STA_UNSYNC, |
25 |
{ STA_FREQHOLD, "FREQHOLD" }, |
STA_FREQHOLD, |
26 |
{ STA_PPSSIGNAL, "PPSSIGNAL" }, |
STA_PPSSIGNAL, |
27 |
{ STA_PPSJITTER, "PPSJITTER" }, |
STA_PPSJITTER, |
28 |
{ STA_PPSWANDER, "PPSWANDER" }, |
STA_PPSWANDER, |
29 |
{ STA_PPSERROR, "PPSERROR" }, |
STA_PPSERROR, |
30 |
{ STA_CLOCKERR, "CLOCKERR" }, |
STA_CLOCKERR, |
31 |
{ 0, NULL } }; |
0 |
32 |
|
}; |
33 |
static const char * const ret_code_descript[] = { |
static const char statlist_name[] = |
34 |
"clock synchronized", |
"PLL" "\0" |
35 |
"insert leap second", |
"PPSFREQ" "\0" |
36 |
"delete leap second", |
"PPSTIME" "\0" |
37 |
"leap second in progress", |
"FFL" "\0" |
38 |
"leap second has occurred", |
"INS" "\0" |
39 |
"clock not synchronized" }; |
"DEL" "\0" |
40 |
|
"UNSYNC" "\0" |
41 |
|
"FREQHOLD" "\0" |
42 |
|
"PPSSIGNAL" "\0" |
43 |
|
"PPSJITTER" "\0" |
44 |
|
"PPSWANDER" "\0" |
45 |
|
"PPSERROR" "\0" |
46 |
|
"CLOCKERR" |
47 |
|
; |
48 |
|
|
49 |
|
static const char ret_code_descript[] = |
50 |
|
"clock synchronized" "\0" |
51 |
|
"insert leap second" "\0" |
52 |
|
"delete leap second" "\0" |
53 |
|
"leap second in progress" "\0" |
54 |
|
"leap second has occurred" "\0" |
55 |
|
"clock not synchronized" |
56 |
|
; |
57 |
|
|
58 |
|
int adjtimex_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
59 |
int adjtimex_main(int argc, char **argv) |
int adjtimex_main(int argc, char **argv) |
60 |
{ |
{ |
61 |
enum { |
enum { |
64 |
unsigned opt; |
unsigned opt; |
65 |
char *opt_o, *opt_f, *opt_p, *opt_t; |
char *opt_o, *opt_f, *opt_p, *opt_t; |
66 |
struct timex txc; |
struct timex txc; |
67 |
int i, ret, sep; |
int i, ret; |
68 |
const char *descript; |
const char *descript; |
69 |
txc.modes=0; |
txc.modes=0; |
70 |
|
|
71 |
opt = getopt32(argc, argv, "qo:f:p:t:", |
opt = getopt32(argv, "qo:f:p:t:", |
72 |
&opt_o, &opt_f, &opt_p, &opt_t); |
&opt_o, &opt_f, &opt_p, &opt_t); |
73 |
//if (opt & 0x1) // -q |
//if (opt & 0x1) // -q |
74 |
if (opt & 0x2) { // -o |
if (opt & 0x2) { // -o |
75 |
txc.offset = xatoi(opt_o); |
txc.offset = xatol(opt_o); |
76 |
txc.modes |= ADJ_OFFSET_SINGLESHOT; |
txc.modes |= ADJ_OFFSET_SINGLESHOT; |
77 |
} |
} |
78 |
if (opt & 0x4) { // -f |
if (opt & 0x4) { // -f |
79 |
txc.freq = xatou(opt_f); |
txc.freq = xatol(opt_f); |
80 |
txc.modes |= ADJ_FREQUENCY; |
txc.modes |= ADJ_FREQUENCY; |
81 |
} |
} |
82 |
if (opt & 0x8) { // -p |
if (opt & 0x8) { // -p |
83 |
txc.constant = xatoi(opt_p); |
txc.constant = xatol(opt_p); |
84 |
txc.modes |= ADJ_TIMECONST; |
txc.modes |= ADJ_TIMECONST; |
85 |
} |
} |
86 |
if (opt & 0x10) { // -t |
if (opt & 0x10) { // -t |
87 |
txc.tick = xatoi(opt_t); |
txc.tick = xatol(opt_t); |
88 |
txc.modes |= ADJ_TICK; |
txc.modes |= ADJ_TICK; |
89 |
} |
} |
90 |
if (argc != optind) { /* no valid non-option parameters */ |
if (argc != optind) { /* no valid non-option parameters */ |
93 |
|
|
94 |
ret = adjtimex(&txc); |
ret = adjtimex(&txc); |
95 |
|
|
96 |
if (ret < 0) perror("adjtimex"); |
if (ret < 0) { |
97 |
|
bb_perror_nomsg_and_die(); |
98 |
|
} |
99 |
|
|
100 |
|
if (!(opt & OPT_quiet)) { |
101 |
|
int sep; |
102 |
|
const char *name; |
103 |
|
|
|
if (!(opt & OPT_quiet) && ret>=0) { |
|
104 |
printf( |
printf( |
105 |
" mode: %d\n" |
" mode: %d\n" |
106 |
"-o offset: %ld\n" |
"-o offset: %ld\n" |
107 |
"-f frequency: %ld\n" |
"-f frequency: %ld\n" |
108 |
" maxerror: %ld\n" |
" maxerror: %ld\n" |
109 |
" esterror: %ld\n" |
" esterror: %ld\n" |
110 |
" status: %d ( ", |
" status: %d (", |
111 |
txc.modes, txc.offset, txc.freq, txc.maxerror, |
txc.modes, txc.offset, txc.freq, txc.maxerror, |
112 |
txc.esterror, txc.status); |
txc.esterror, txc.status); |
113 |
|
|
114 |
/* representative output of next code fragment: |
/* representative output of next code fragment: |
115 |
"PLL | PPSTIME" */ |
"PLL | PPSTIME" */ |
116 |
sep=0; |
name = statlist_name; |
117 |
for (i=0; statlist[i].name; i++) { |
sep = 0; |
118 |
if (txc.status & statlist[i].bit) { |
for (i = 0; statlist_bit[i]; i++) { |
119 |
if (sep) fputs(" | ",stdout); |
if (txc.status & statlist_bit[i]) { |
120 |
fputs(statlist[i].name,stdout); |
if (sep) |
121 |
sep=1; |
fputs(" | ", stdout); |
122 |
|
fputs(name, stdout); |
123 |
|
sep = 1; |
124 |
} |
} |
125 |
|
name += strlen(name) + 1; |
126 |
} |
} |
127 |
|
|
128 |
descript = "error"; |
descript = "error"; |
129 |
if (ret >= 0 && ret <= 5) descript = ret_code_descript[ret]; |
if (ret <= 5) |
130 |
printf(" )\n" |
descript = nth_string(ret_code_descript, ret); |
131 |
|
printf(")\n" |
132 |
"-p timeconstant: %ld\n" |
"-p timeconstant: %ld\n" |
133 |
" precision: %ld\n" |
" precision: %ld\n" |
134 |
" tolerance: %ld\n" |
" tolerance: %ld\n" |
140 |
txc.precision, txc.tolerance, txc.tick, |
txc.precision, txc.tolerance, txc.tick, |
141 |
(long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript); |
(long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript); |
142 |
} |
} |
143 |
return (ret<0); |
|
144 |
|
return 0; |
145 |
} |
} |