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 tarball for details. 12 */ 13 14#include "libbb.h" 15#include <sys/timex.h> 16 17static 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 32}; 33static 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; 48 49static 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 58int adjtimex_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 59int adjtimex_main(int argc UNUSED_PARAM, char **argv) 60{ 61 enum { 62 OPT_quiet = 0x1 63 }; 64 unsigned opt; 65 char *opt_o, *opt_f, *opt_p, *opt_t; 66 struct timex txc; 67 int i, ret; 68 const char *descript; 69 70 opt_complementary = "=0"; /* no valid non-option parameters */ 71 opt = getopt32(argv, "qo:f:p:t:", 72 &opt_o, &opt_f, &opt_p, &opt_t); 73 txc.modes = 0; 74 //if (opt & 0x1) // -q 75 if (opt & 0x2) { // -o 76 txc.offset = xatol(opt_o); 77 txc.modes |= ADJ_OFFSET_SINGLESHOT; 78 } 79 if (opt & 0x4) { // -f 80 txc.freq = xatol(opt_f); 81 txc.modes |= ADJ_FREQUENCY; 82 } 83 if (opt & 0x8) { // -p 84 txc.constant = xatol(opt_p); 85 txc.modes |= ADJ_TIMECONST; 86 } 87 if (opt & 0x10) { // -t 88 txc.tick = xatol(opt_t); 89 txc.modes |= ADJ_TICK; 90 } 91 92 ret = adjtimex(&txc); 93 94 if (ret < 0) { 95 bb_perror_nomsg_and_die(); 96 } 97 98 if (!(opt & OPT_quiet)) { 99 int sep; 100 const char *name; 101 102 printf( 103 " mode: %d\n" 104 "-o offset: %ld\n" 105 "-f frequency: %ld\n" 106 " maxerror: %ld\n" 107 " esterror: %ld\n" 108 " status: %d (", 109 txc.modes, txc.offset, txc.freq, txc.maxerror, 110 txc.esterror, txc.status); 111 112 /* representative output of next code fragment: 113 "PLL | PPSTIME" */ 114 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; 122 } 123 name += strlen(name) + 1; 124 } 125 126 descript = "error"; 127 if (ret <= 5) 128 descript = nth_string(ret_code_descript, ret); 129 printf(")\n" 130 "-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, 139 (long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript); 140 } 141 142 return 0; 143} 144