blob: c12a10b25f4c789d29e4f6cfb4abdd1c44dd19ef [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/*
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 *
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 *
Rob Landley8fba99f2006-05-27 22:08:01 +000011 * Licensed under GPLv2 or later, see file License in this tarball for details.
Mark Whitley6f932772001-03-20 19:18:10 +000012 */
13
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000014#include "libbb.h"
Mark Whitley6f932772001-03-20 19:18:10 +000015#include <sys/timex.h>
Mark Whitley6f932772001-03-20 19:18:10 +000016
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000017static const uint16_t statlist_bit[] = {
18 STA_PLL,
19 STA_PPSFREQ,
20 STA_PPSTIME,
21 STA_FLL,
22 STA_INS,
23 STA_DEL,
24 STA_UNSYNC,
25 STA_FREQHOLD,
26 STA_PPSSIGNAL,
27 STA_PPSJITTER,
28 STA_PPSWANDER,
29 STA_PPSERROR,
30 STA_CLOCKERR,
31 0
Denis Vlasenko6ca409e2007-08-12 20:58:27 +000032};
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000033static const char statlist_name[] =
34 "PLL" "\0"
35 "PPSFREQ" "\0"
36 "PPSTIME" "\0"
37 "FFL" "\0"
38 "INS" "\0"
39 "DEL" "\0"
40 "UNSYNC" "\0"
41 "FREQHOLD" "\0"
42 "PPSSIGNAL" "\0"
43 "PPSJITTER" "\0"
44 "PPSWANDER" "\0"
45 "PPSERROR" "\0"
46 "CLOCKERR"
47;
Mark Whitley6f932772001-03-20 19:18:10 +000048
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000049static 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"
Denis Vlasenko6ca409e2007-08-12 20:58:27 +000055 "clock not synchronized"
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000056;
Mark Whitley6f932772001-03-20 19:18:10 +000057
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000058int adjtimex_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denys Vlasenkoe992bae2009-11-28 15:18:53 +010059int adjtimex_main(int argc UNUSED_PARAM, char **argv)
Mark Whitley6f932772001-03-20 19:18:10 +000060{
Denis Vlasenko109d21f2006-09-22 08:47:54 +000061 enum {
62 OPT_quiet = 0x1
63 };
Denis Vlasenko67b23e62006-10-03 21:00:06 +000064 unsigned opt;
Denis Vlasenko109d21f2006-09-22 08:47:54 +000065 char *opt_o, *opt_f, *opt_p, *opt_t;
Mark Whitley6f932772001-03-20 19:18:10 +000066 struct timex txc;
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000067 int i, ret;
"Vladimir N. Oleynik"1f0262b2005-10-20 11:17:48 +000068 const char *descript;
Denis Vlasenko109d21f2006-09-22 08:47:54 +000069
Denys Vlasenkoe992bae2009-11-28 15:18:53 +010070 opt_complementary = "=0"; /* no valid non-option parameters */
Denis Vlasenkofe7cd642007-08-18 15:32:12 +000071 opt = getopt32(argv, "qo:f:p:t:",
Denis Vlasenko109d21f2006-09-22 08:47:54 +000072 &opt_o, &opt_f, &opt_p, &opt_t);
Denys Vlasenkoe992bae2009-11-28 15:18:53 +010073 txc.modes = 0;
Denis Vlasenko109d21f2006-09-22 08:47:54 +000074 //if (opt & 0x1) // -q
75 if (opt & 0x2) { // -o
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +000076 txc.offset = xatol(opt_o);
Denis Vlasenko109d21f2006-09-22 08:47:54 +000077 txc.modes |= ADJ_OFFSET_SINGLESHOT;
78 }
79 if (opt & 0x4) { // -f
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +000080 txc.freq = xatol(opt_f);
Denis Vlasenko109d21f2006-09-22 08:47:54 +000081 txc.modes |= ADJ_FREQUENCY;
82 }
83 if (opt & 0x8) { // -p
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +000084 txc.constant = xatol(opt_p);
Denis Vlasenko109d21f2006-09-22 08:47:54 +000085 txc.modes |= ADJ_TIMECONST;
86 }
87 if (opt & 0x10) { // -t
Denis Vlasenkodd2b2f72007-03-14 23:00:26 +000088 txc.tick = xatol(opt_t);
Denis Vlasenko109d21f2006-09-22 08:47:54 +000089 txc.modes |= ADJ_TICK;
Mark Whitley6f932772001-03-20 19:18:10 +000090 }
Mark Whitley6f932772001-03-20 19:18:10 +000091
92 ret = adjtimex(&txc);
93
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000094 if (ret < 0) {
95 bb_perror_nomsg_and_die();
96 }
Eric Andersenc7bda1c2004-03-15 08:29:22 +000097
Denis Vlasenkobfc3d822007-11-04 04:10:17 +000098 if (!(opt & OPT_quiet)) {
99 int sep;
100 const char *name;
101
Mark Whitley6f932772001-03-20 19:18:10 +0000102 printf(
103 " mode: %d\n"
104 "-o offset: %ld\n"
105 "-f frequency: %ld\n"
106 " maxerror: %ld\n"
107 " esterror: %ld\n"
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000108 " status: %d (",
Mark Whitley6f932772001-03-20 19:18:10 +0000109 txc.modes, txc.offset, txc.freq, txc.maxerror,
110 txc.esterror, txc.status);
111
112 /* representative output of next code fragment:
113 "PLL | PPSTIME" */
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000114 name = statlist_name;
115 sep = 0;
116 for (i = 0; statlist_bit[i]; i++) {
117 if (txc.status & statlist_bit[i]) {
118 if (sep)
119 fputs(" | ", stdout);
120 fputs(name, stdout);
121 sep = 1;
Mark Whitley6f932772001-03-20 19:18:10 +0000122 }
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000123 name += strlen(name) + 1;
Mark Whitley6f932772001-03-20 19:18:10 +0000124 }
125
126 descript = "error";
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000127 if (ret <= 5)
128 descript = nth_string(ret_code_descript, ret);
129 printf(")\n"
Mark Whitley6f932772001-03-20 19:18:10 +0000130 "-p timeconstant: %ld\n"
131 " precision: %ld\n"
132 " tolerance: %ld\n"
133 "-t tick: %ld\n"
134 " time.tv_sec: %ld\n"
135 " time.tv_usec: %ld\n"
136 " return value: %d (%s)\n",
137 txc.constant,
138 txc.precision, txc.tolerance, txc.tick,
Eric Andersene76c3b02001-04-05 03:14:39 +0000139 (long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript);
Mark Whitley6f932772001-03-20 19:18:10 +0000140 }
Denis Vlasenkobfc3d822007-11-04 04:10:17 +0000141
142 return 0;
Mark Whitley6f932772001-03-20 19:18:10 +0000143}