| /* vi: set sw=4 ts=4: */ | 
 | /* | 
 |  * adjtimex.c - read, and possibly modify, the Linux kernel `timex' variables. | 
 |  * | 
 |  * Originally written: October 1997 | 
 |  * Last hack: March 2001 | 
 |  * Copyright 1997, 2000, 2001 Larry Doolittle <LRDoolittle@lbl.gov> | 
 |  * | 
 |  * busyboxed 20 March 2001, Larry Doolittle <ldoolitt@recycle.lbl.gov> | 
 |  * | 
 |  * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 
 |  */ | 
 |  | 
 | //usage:#define adjtimex_trivial_usage | 
 | //usage:       "[-q] [-o OFF] [-f FREQ] [-p TCONST] [-t TICK]" | 
 | //usage:#define adjtimex_full_usage "\n\n" | 
 | //usage:       "Read and optionally set system timebase parameters. See adjtimex(2)\n" | 
 | //usage:     "\n	-q	Quiet" | 
 | //usage:     "\n	-o OFF	Time offset, microseconds" | 
 | //usage:     "\n	-f FREQ	Frequency adjust, integer kernel units (65536 is 1ppm)" | 
 | //usage:     "\n		(positive values make clock run faster)" | 
 | //usage:     "\n	-t TICK	Microseconds per tick, usually 10000" | 
 | //usage:     "\n	-p TCONST" | 
 |  | 
 | #include "libbb.h" | 
 | #ifdef __BIONIC__ | 
 | # include <linux/timex.h> | 
 | #else | 
 | # include <sys/timex.h> | 
 | #endif | 
 |  | 
 | static const uint16_t statlist_bit[] = { | 
 | 	STA_PLL, | 
 | 	STA_PPSFREQ, | 
 | 	STA_PPSTIME, | 
 | 	STA_FLL, | 
 | 	STA_INS, | 
 | 	STA_DEL, | 
 | 	STA_UNSYNC, | 
 | 	STA_FREQHOLD, | 
 | 	STA_PPSSIGNAL, | 
 | 	STA_PPSJITTER, | 
 | 	STA_PPSWANDER, | 
 | 	STA_PPSERROR, | 
 | 	STA_CLOCKERR, | 
 | 	0 | 
 | }; | 
 | static const char statlist_name[] = | 
 | 	"PLL"       "\0" | 
 | 	"PPSFREQ"   "\0" | 
 | 	"PPSTIME"   "\0" | 
 | 	"FFL"       "\0" | 
 | 	"INS"       "\0" | 
 | 	"DEL"       "\0" | 
 | 	"UNSYNC"    "\0" | 
 | 	"FREQHOLD"  "\0" | 
 | 	"PPSSIGNAL" "\0" | 
 | 	"PPSJITTER" "\0" | 
 | 	"PPSWANDER" "\0" | 
 | 	"PPSERROR"  "\0" | 
 | 	"CLOCKERR" | 
 | ; | 
 |  | 
 | static const char ret_code_descript[] = | 
 | 	"clock synchronized" "\0" | 
 | 	"insert leap second" "\0" | 
 | 	"delete leap second" "\0" | 
 | 	"leap second in progress" "\0" | 
 | 	"leap second has occurred" "\0" | 
 | 	"clock not synchronized" | 
 | ; | 
 |  | 
 | int adjtimex_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 
 | int adjtimex_main(int argc UNUSED_PARAM, char **argv) | 
 | { | 
 | 	enum { | 
 | 		OPT_quiet = 0x1 | 
 | 	}; | 
 | 	unsigned opt; | 
 | 	char *opt_o, *opt_f, *opt_p, *opt_t; | 
 | 	struct timex txc; | 
 | 	int i, ret; | 
 | 	const char *descript; | 
 |  | 
 | 	opt_complementary = "=0"; /* no valid non-option parameters */ | 
 | 	opt = getopt32(argv, "qo:f:p:t:", | 
 | 			&opt_o, &opt_f, &opt_p, &opt_t); | 
 | 	txc.modes = 0; | 
 | 	//if (opt & 0x1) // -q | 
 | 	if (opt & 0x2) { // -o | 
 | 		txc.offset = xatol(opt_o); | 
 | 		txc.modes |= ADJ_OFFSET_SINGLESHOT; | 
 | 	} | 
 | 	if (opt & 0x4) { // -f | 
 | 		txc.freq = xatol(opt_f); | 
 | 		txc.modes |= ADJ_FREQUENCY; | 
 | 	} | 
 | 	if (opt & 0x8) { // -p | 
 | 		txc.constant = xatol(opt_p); | 
 | 		txc.modes |= ADJ_TIMECONST; | 
 | 	} | 
 | 	if (opt & 0x10) { // -t | 
 | 		txc.tick = xatol(opt_t); | 
 | 		txc.modes |= ADJ_TICK; | 
 | 	} | 
 |  | 
 | 	ret = adjtimex(&txc); | 
 |  | 
 | 	if (ret < 0) { | 
 | 		bb_perror_nomsg_and_die(); | 
 | 	} | 
 |  | 
 | 	if (!(opt & OPT_quiet)) { | 
 | 		int sep; | 
 | 		const char *name; | 
 |  | 
 | 		printf( | 
 | 			"    mode:         %d\n" | 
 | 			"-o  offset:       %ld\n" | 
 | 			"-f  frequency:    %ld\n" | 
 | 			"    maxerror:     %ld\n" | 
 | 			"    esterror:     %ld\n" | 
 | 			"    status:       %d (", | 
 | 		txc.modes, txc.offset, txc.freq, txc.maxerror, | 
 | 		txc.esterror, txc.status); | 
 |  | 
 | 		/* representative output of next code fragment: | 
 | 		   "PLL | PPSTIME" */ | 
 | 		name = statlist_name; | 
 | 		sep = 0; | 
 | 		for (i = 0; statlist_bit[i]; i++) { | 
 | 			if (txc.status & statlist_bit[i]) { | 
 | 				if (sep) | 
 | 					fputs(" | ", stdout); | 
 | 				fputs(name, stdout); | 
 | 				sep = 1; | 
 | 			} | 
 | 			name += strlen(name) + 1; | 
 | 		} | 
 |  | 
 | 		descript = "error"; | 
 | 		if (ret <= 5) | 
 | 			descript = nth_string(ret_code_descript, ret); | 
 | 		printf(")\n" | 
 | 			"-p  timeconstant: %ld\n" | 
 | 			"    precision:    %ld\n" | 
 | 			"    tolerance:    %ld\n" | 
 | 			"-t  tick:         %ld\n" | 
 | 			"    time.tv_sec:  %ld\n" | 
 | 			"    time.tv_usec: %ld\n" | 
 | 			"    return value: %d (%s)\n", | 
 | 		txc.constant, | 
 | 		txc.precision, txc.tolerance, txc.tick, | 
 | 		(long)txc.time.tv_sec, (long)txc.time.tv_usec, ret, descript); | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } |