Bump to version 1.22.1
[platform/upstream/busybox.git] / miscutils / adjtimex.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * adjtimex.c - read, and possibly modify, the Linux kernel `timex' variables.
4  *
5  * Originally written: October 1997
6  * Last hack: March 2001
7  * Copyright 1997, 2000, 2001 Larry Doolittle <LRDoolittle@lbl.gov>
8  *
9  * busyboxed 20 March 2001, Larry Doolittle <ldoolitt@recycle.lbl.gov>
10  *
11  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
12  */
13
14 //usage:#define adjtimex_trivial_usage
15 //usage:       "[-q] [-o OFF] [-f FREQ] [-p TCONST] [-t TICK]"
16 //usage:#define adjtimex_full_usage "\n\n"
17 //usage:       "Read and optionally set system timebase parameters. See adjtimex(2)\n"
18 //usage:     "\n        -q      Quiet"
19 //usage:     "\n        -o OFF  Time offset, microseconds"
20 //usage:     "\n        -f FREQ Frequency adjust, integer kernel units (65536 is 1ppm)"
21 //usage:     "\n                (positive values make clock run faster)"
22 //usage:     "\n        -t TICK Microseconds per tick, usually 10000"
23 //usage:     "\n        -p TCONST"
24
25 #include "libbb.h"
26 #ifdef __BIONIC__
27 # include <linux/timex.h>
28 #else
29 # include <sys/timex.h>
30 #endif
31
32 static const uint16_t statlist_bit[] = {
33         STA_PLL,
34         STA_PPSFREQ,
35         STA_PPSTIME,
36         STA_FLL,
37         STA_INS,
38         STA_DEL,
39         STA_UNSYNC,
40         STA_FREQHOLD,
41         STA_PPSSIGNAL,
42         STA_PPSJITTER,
43         STA_PPSWANDER,
44         STA_PPSERROR,
45         STA_CLOCKERR,
46         0
47 };
48 static const char statlist_name[] =
49         "PLL"       "\0"
50         "PPSFREQ"   "\0"
51         "PPSTIME"   "\0"
52         "FFL"       "\0"
53         "INS"       "\0"
54         "DEL"       "\0"
55         "UNSYNC"    "\0"
56         "FREQHOLD"  "\0"
57         "PPSSIGNAL" "\0"
58         "PPSJITTER" "\0"
59         "PPSWANDER" "\0"
60         "PPSERROR"  "\0"
61         "CLOCKERR"
62 ;
63
64 static const char ret_code_descript[] =
65         "clock synchronized" "\0"
66         "insert leap second" "\0"
67         "delete leap second" "\0"
68         "leap second in progress" "\0"
69         "leap second has occurred" "\0"
70         "clock not synchronized"
71 ;
72
73 int adjtimex_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
74 int adjtimex_main(int argc UNUSED_PARAM, char **argv)
75 {
76         enum {
77                 OPT_quiet = 0x1
78         };
79         unsigned opt;
80         char *opt_o, *opt_f, *opt_p, *opt_t;
81         struct timex txc;
82         int i, ret;
83         const char *descript;
84
85         opt_complementary = "=0"; /* no valid non-option parameters */
86         opt = getopt32(argv, "qo:f:p:t:",
87                         &opt_o, &opt_f, &opt_p, &opt_t);
88         txc.modes = 0;
89         //if (opt & 0x1) // -q
90         if (opt & 0x2) { // -o
91                 txc.offset = xatol(opt_o);
92                 txc.modes |= ADJ_OFFSET_SINGLESHOT;
93         }
94         if (opt & 0x4) { // -f
95                 txc.freq = xatol(opt_f);
96                 txc.modes |= ADJ_FREQUENCY;
97         }
98         if (opt & 0x8) { // -p
99                 txc.constant = xatol(opt_p);
100                 txc.modes |= ADJ_TIMECONST;
101         }
102         if (opt & 0x10) { // -t
103                 txc.tick = xatol(opt_t);
104                 txc.modes |= ADJ_TICK;
105         }
106
107         ret = adjtimex(&txc);
108
109         if (ret < 0) {
110                 bb_perror_nomsg_and_die();
111         }
112
113         if (!(opt & OPT_quiet)) {
114                 int sep;
115                 const char *name;
116
117                 printf(
118                         "    mode:         %d\n"
119                         "-o  offset:       %ld\n"
120                         "-f  frequency:    %ld\n"
121                         "    maxerror:     %ld\n"
122                         "    esterror:     %ld\n"
123                         "    status:       %d (",
124                 txc.modes, txc.offset, txc.freq, txc.maxerror,
125                 txc.esterror, txc.status);
126
127                 /* representative output of next code fragment:
128                    "PLL | PPSTIME" */
129                 name = statlist_name;
130                 sep = 0;
131                 for (i = 0; statlist_bit[i]; i++) {
132                         if (txc.status & statlist_bit[i]) {
133                                 if (sep)
134                                         fputs(" | ", stdout);
135                                 fputs(name, stdout);
136                                 sep = 1;
137                         }
138                         name += strlen(name) + 1;
139                 }
140
141                 descript = "error";
142                 if (ret <= 5)
143                         descript = nth_string(ret_code_descript, ret);
144                 printf(")\n"
145                         "-p  timeconstant: %ld\n"
146                         "    precision:    %ld\n"
147                         "    tolerance:    %ld\n"
148                         "-t  tick:         %ld\n"
149                         "    time.tv_sec:  %ld\n"
150                         "    time.tv_usec: %ld\n"
151                         "    return value: %d (%s)\n",
152                 txc.constant,
153                 txc.precision, txc.tolerance, txc.tick,
154                 (long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript);
155         }
156
157         return 0;
158 }