blob: 0830734eec9f6564f376e77f7f8e041c04c77f67 [file] [log] [blame]
Bernhard Reutner-Fischerc89982d2006-06-03 19:49:21 +00001/* vi: set sw=4 ts=4: */
Mark Whitley6f932772001-03-20 19:18:10 +00002/*
Denys Vlasenko95f79532017-08-02 14:26:33 +02003 * adjtimex.c - read, and possibly modify, the Linux kernel 'timex' variables.
Mark Whitley6f932772001-03-20 19:18:10 +00004 *
5 * Originally written: October 1997
6 * Last hack: March 2001
7 * Copyright 1997, 2000, 2001 Larry Doolittle <LRDoolittle@lbl.gov>
8 *
Mark Whitley6f932772001-03-20 19:18:10 +00009 * busyboxed 20 March 2001, Larry Doolittle <ldoolitt@recycle.lbl.gov>
Bernhard Reutner-Fischerc89982d2006-06-03 19:49:21 +000010 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +020011 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Mark Whitley6f932772001-03-20 19:18:10 +000012 */
Denys Vlasenkofb4da162016-11-22 23:14:24 +010013//config:config ADJTIMEX
Denys Vlasenko4eed2c62017-07-18 22:01:24 +020014//config: bool "adjtimex (4.5 kb)"
Denys Vlasenkofb4da162016-11-22 23:14:24 +010015//config: default y
16//config: select PLATFORM_LINUX
17//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +020018//config: Adjtimex reads and optionally sets adjustment parameters for
19//config: the Linux clock adjustment algorithm.
Mark Whitley6f932772001-03-20 19:18:10 +000020
Denys Vlasenkof88e3bf2016-11-22 23:54:17 +010021//applet:IF_ADJTIMEX(APPLET(adjtimex, BB_DIR_SBIN, BB_SUID_DROP))
22
23//kbuild:lib-$(CONFIG_ADJTIMEX) += adjtimex.o
24
Pere Orga5bc8c002011-04-11 03:29:49 +020025//usage:#define adjtimex_trivial_usage
26//usage: "[-q] [-o OFF] [-f FREQ] [-p TCONST] [-t TICK]"
27//usage:#define adjtimex_full_usage "\n\n"
Denys Vlasenkoe152cb82014-04-17 11:29:34 +020028//usage: "Read or set kernel time variables. See adjtimex(2)\n"
Pere Orga5bc8c002011-04-11 03:29:49 +020029//usage: "\n -q Quiet"
30//usage: "\n -o OFF Time offset, microseconds"
31//usage: "\n -f FREQ Frequency adjust, integer kernel units (65536 is 1ppm)"
Pere Orga5bc8c002011-04-11 03:29:49 +020032//usage: "\n -t TICK Microseconds per tick, usually 10000"
Denys Vlasenkoe152cb82014-04-17 11:29:34 +020033//usage: "\n (positive -t or -f values make clock run faster)"
Pere Orga5bc8c002011-04-11 03:29:49 +020034//usage: "\n -p TCONST"
35
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000036#include "libbb.h"
Denys Vlasenko8f6ce092011-07-08 08:34:28 +020037#ifdef __BIONIC__
38# include <linux/timex.h>
39#else
40# include <sys/timex.h>
41#endif
Mark Whitley6f932772001-03-20 19:18:10 +000042
Denys Vlasenko3e134eb2016-04-22 18:09:21 +020043static const uint16_t statlist_bit[] ALIGN2 = {
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000044 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
Denis Vlasenko6ca409e2007-08-12 20:58:27 +000058};
Denys Vlasenko3e134eb2016-04-22 18:09:21 +020059static const char statlist_name[] ALIGN1 =
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000060 "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;
Mark Whitley6f932772001-03-20 19:18:10 +000074
Denys Vlasenko3e134eb2016-04-22 18:09:21 +020075static const char ret_code_descript[] ALIGN1 =
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000076 "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"
Denis Vlasenko6ca409e2007-08-12 20:58:27 +000081 "clock not synchronized"
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000082;
Mark Whitley6f932772001-03-20 19:18:10 +000083
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000084int adjtimex_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denys Vlasenkoe992bae2009-11-28 15:18:53 +010085int adjtimex_main(int argc UNUSED_PARAM, char **argv)
Mark Whitley6f932772001-03-20 19:18:10 +000086{
Denis Vlasenko109d21f2006-09-22 08:47:54 +000087 enum {
88 OPT_quiet = 0x1
89 };
Denis Vlasenko67b23e62006-10-03 21:00:06 +000090 unsigned opt;
Denis Vlasenko109d21f2006-09-22 08:47:54 +000091 char *opt_o, *opt_f, *opt_p, *opt_t;
Mark Whitley6f932772001-03-20 19:18:10 +000092 struct timex txc;
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000093 int i, ret;
"Vladimir N. Oleynik"1f0262b2005-10-20 11:17:48 +000094 const char *descript;
Denis Vlasenko109d21f2006-09-22 08:47:54 +000095
Denys Vlasenkoe992bae2009-11-28 15:18:53 +010096 opt_complementary = "=0"; /* no valid non-option parameters */
Denis Vlasenkofe7cd642007-08-18 15:32:12 +000097 opt = getopt32(argv, "qo:f:p:t:",
Denis Vlasenko109d21f2006-09-22 08:47:54 +000098 &opt_o, &opt_f, &opt_p, &opt_t);
Denys Vlasenkoe992bae2009-11-28 15:18:53 +010099 txc.modes = 0;
Denis Vlasenko109d21f2006-09-22 08:47:54 +0000100 //if (opt & 0x1) // -q
101 if (opt & 0x2) { // -o
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +0000102 txc.offset = xatol(opt_o);
Denis Vlasenko109d21f2006-09-22 08:47:54 +0000103 txc.modes |= ADJ_OFFSET_SINGLESHOT;
104 }
105 if (opt & 0x4) { // -f
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +0000106 txc.freq = xatol(opt_f);
Denis Vlasenko109d21f2006-09-22 08:47:54 +0000107 txc.modes |= ADJ_FREQUENCY;
108 }
109 if (opt & 0x8) { // -p
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +0000110 txc.constant = xatol(opt_p);
Denis Vlasenko109d21f2006-09-22 08:47:54 +0000111 txc.modes |= ADJ_TIMECONST;
112 }
113 if (opt & 0x10) { // -t
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +0000114 txc.tick = xatol(opt_t);
Denis Vlasenko109d21f2006-09-22 08:47:54 +0000115 txc.modes |= ADJ_TICK;
Mark Whitley6f932772001-03-20 19:18:10 +0000116 }
Mark Whitley6f932772001-03-20 19:18:10 +0000117
118 ret = adjtimex(&txc);
119
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000120 if (ret < 0) {
121 bb_perror_nomsg_and_die();
122 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000123
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000124 if (!(opt & OPT_quiet)) {
Denys Vlasenkoe152cb82014-04-17 11:29:34 +0200125 const char *sep;
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000126 const char *name;
127
Mark Whitley6f932772001-03-20 19:18:10 +0000128 printf(
129 " mode: %d\n"
Denys Vlasenkoe152cb82014-04-17 11:29:34 +0200130 "-o offset: %ld us\n"
131 "-f freq.adjust: %ld (65536 = 1ppm)\n"
Mark Whitley6f932772001-03-20 19:18:10 +0000132 " maxerror: %ld\n"
133 " esterror: %ld\n"
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000134 " status: %d (",
Mark Whitley6f932772001-03-20 19:18:10 +0000135 txc.modes, txc.offset, txc.freq, txc.maxerror,
136 txc.esterror, txc.status);
137
138 /* representative output of next code fragment:
Denys Vlasenkoe152cb82014-04-17 11:29:34 +0200139 * "PLL | PPSTIME"
140 */
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000141 name = statlist_name;
Denys Vlasenkoe152cb82014-04-17 11:29:34 +0200142 sep = "";
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000143 for (i = 0; statlist_bit[i]; i++) {
144 if (txc.status & statlist_bit[i]) {
Denys Vlasenkoe152cb82014-04-17 11:29:34 +0200145 printf("%s%s", sep, name);
146 sep = " | ";
Mark Whitley6f932772001-03-20 19:18:10 +0000147 }
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000148 name += strlen(name) + 1;
Mark Whitley6f932772001-03-20 19:18:10 +0000149 }
150
151 descript = "error";
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000152 if (ret <= 5)
153 descript = nth_string(ret_code_descript, ret);
154 printf(")\n"
Mark Whitley6f932772001-03-20 19:18:10 +0000155 "-p timeconstant: %ld\n"
Denys Vlasenkoe152cb82014-04-17 11:29:34 +0200156 " precision: %ld us\n"
Mark Whitley6f932772001-03-20 19:18:10 +0000157 " tolerance: %ld\n"
Denys Vlasenkoe152cb82014-04-17 11:29:34 +0200158 "-t tick: %ld us\n"
Mark Whitley6f932772001-03-20 19:18:10 +0000159 " time.tv_sec: %ld\n"
160 " time.tv_usec: %ld\n"
161 " return value: %d (%s)\n",
162 txc.constant,
163 txc.precision, txc.tolerance, txc.tick,
Eric Andersene76c3b02001-04-05 03:14:39 +0000164 (long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript);
Mark Whitley6f932772001-03-20 19:18:10 +0000165 }
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000166
167 return 0;
Mark Whitley6f932772001-03-20 19:18:10 +0000168}