1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include "libbb.h"
37#ifdef __BIONIC__
38# include <linux/timex.h>
39#else
40# include <sys/timex.h>
41#endif
42
43static const uint16_t statlist_bit[] ALIGN2 = {
44 STA_PLL,
45 STA_PPSFREQ,
46 STA_PPSTIME,
47 STA_FLL,
48 STA_INS,
49 STA_DEL,
50 STA_UNSYNC,
51 STA_FREQHOLD,
52 STA_PPSSIGNAL,
53 STA_PPSJITTER,
54 STA_PPSWANDER,
55 STA_PPSERROR,
56 STA_CLOCKERR,
57 0
58};
59static const char statlist_name[] ALIGN1 =
60 "PLL" "\0"
61 "PPSFREQ" "\0"
62 "PPSTIME" "\0"
63 "FFL" "\0"
64 "INS" "\0"
65 "DEL" "\0"
66 "UNSYNC" "\0"
67 "FREQHOLD" "\0"
68 "PPSSIGNAL" "\0"
69 "PPSJITTER" "\0"
70 "PPSWANDER" "\0"
71 "PPSERROR" "\0"
72 "CLOCKERR"
73;
74
75static const char ret_code_descript[] ALIGN1 =
76 "clock synchronized" "\0"
77 "insert leap second" "\0"
78 "delete leap second" "\0"
79 "leap second in progress" "\0"
80 "leap second has occurred" "\0"
81 "clock not synchronized"
82;
83
84int adjtimex_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
85int adjtimex_main(int argc UNUSED_PARAM, char **argv)
86{
87 enum {
88 OPT_quiet = 0x1
89 };
90 unsigned opt;
91 char *opt_o, *opt_f, *opt_p, *opt_t;
92 struct timex txc;
93 int ret;
94 const char *descript;
95
96 memset(&txc, 0, sizeof(txc));
97
98 opt = getopt32(argv, "^" "qo:f:p:t:"
99 "\0" "=0",
100 &opt_o, &opt_f, &opt_p, &opt_t
101 );
102
103 if (opt & 0x2) {
104 txc.offset = xatol(opt_o);
105 txc.modes |= ADJ_OFFSET_SINGLESHOT;
106 }
107 if (opt & 0x4) {
108 txc.freq = xatol(opt_f);
109 txc.modes |= ADJ_FREQUENCY;
110 }
111 if (opt & 0x8) {
112 txc.constant = xatol(opt_p);
113 txc.modes |= ADJ_TIMECONST;
114 }
115 if (opt & 0x10) {
116 txc.tick = xatol(opt_t);
117 txc.modes |= ADJ_TICK;
118 }
119
120
121
122
123
124
125 ret = adjtimex(&txc);
126 if (ret < 0)
127 bb_perror_nomsg_and_die();
128
129 if (!(opt & OPT_quiet)) {
130 const char *sep;
131 const char *name;
132 int i;
133
134 printf(
135 " mode: %d\n"
136 "-o offset: %ld us\n"
137 "-f freq.adjust: %ld (65536 = 1ppm)\n"
138 " maxerror: %ld\n"
139 " esterror: %ld\n"
140 " status: %d (",
141 txc.modes, txc.offset, txc.freq, txc.maxerror,
142 txc.esterror, txc.status
143 );
144
145
146
147
148 name = statlist_name;
149 sep = "";
150 for (i = 0; statlist_bit[i]; i++) {
151 if (txc.status & statlist_bit[i]) {
152 printf("%s%s", sep, name);
153 sep = " | ";
154 }
155 name += strlen(name) + 1;
156 }
157
158 descript = "error";
159 if (ret <= 5)
160 descript = nth_string(ret_code_descript, ret);
161 printf(")\n"
162 "-p timeconstant: %ld\n"
163 " precision: %ld us\n"
164 " tolerance: %ld\n"
165 "-t tick: %ld us\n"
166 " time.tv_sec: %ld\n"
167 " time.tv_usec: %ld\n"
168 " return value: %d (%s)\n",
169 txc.constant,
170 txc.precision, txc.tolerance, txc.tick,
171 (long)txc.time.tv_sec, (long)txc.time.tv_usec,
172 ret, descript
173 );
174 }
175
176 return 0;
177}
178