adjtimex.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * adjtimex.c - read, and possibly modify, the Linux kernel `timex' variables.
  3. *
  4. * Originally written: October 1997
  5. * Last hack: March 2001
  6. * Copyright 1997, 2000, 2001 Larry Doolittle <LRDoolittle@lbl.gov>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License (Version 2,
  10. * June 1991) as published by the Free Software Foundation. At the
  11. * time of writing, that license was published by the FSF with the URL
  12. * http://www.gnu.org/copyleft/gpl.html, and is incorporated herein by
  13. * reference.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * This adjtimex(1) is very similar in intent to adjtimex(8) by Steven
  21. * Dick <ssd@nevets.oau.org> and Jim Van Zandt <jrv@vanzandt.mv.com>
  22. * (see http://metalab.unc.edu/pub/Linux/system/admin/time/adjtimex*).
  23. * That version predates this one, and is _much_ bigger and more
  24. * featureful. My independently written version was very similar to
  25. * Steven's from the start, because they both follow the kernel timex
  26. * structure. I further tweaked this version to be equivalent to Steven's
  27. * where possible, but I don't like getopt_long, so the actual usage
  28. * syntax is incompatible.
  29. *
  30. * Amazingly enough, my Red Hat 5.2 sys/timex (and sub-includes)
  31. * don't actually give a prototype for adjtimex(2), so building
  32. * this code (with -Wall) gives a warning. Later versions of
  33. * glibc fix this issue.
  34. *
  35. * This program is too simple for a Makefile, just build with:
  36. * gcc -Wall -O adjtimex.c -o adjtimex
  37. *
  38. * busyboxed 20 March 2001, Larry Doolittle <ldoolitt@recycle.lbl.gov>
  39. * It will autosense if it is built in a busybox environment, based
  40. * on the BB_VER preprocessor macro.
  41. */
  42. #include <stdio.h>
  43. #include <sys/types.h>
  44. #include <stdlib.h>
  45. #include <unistd.h>
  46. #include <sys/timex.h>
  47. #include "busybox.h"
  48. static struct {int bit; char *name;} statlist[] = {
  49. { STA_PLL, "PLL" },
  50. { STA_PPSFREQ, "PPSFREQ" },
  51. { STA_PPSTIME, "PPSTIME" },
  52. { STA_FLL, "FFL" },
  53. { STA_INS, "INS" },
  54. { STA_DEL, "DEL" },
  55. { STA_UNSYNC, "UNSYNC" },
  56. { STA_FREQHOLD, "FREQHOLD" },
  57. { STA_PPSSIGNAL, "PPSSIGNAL" },
  58. { STA_PPSJITTER, "PPSJITTER" },
  59. { STA_PPSWANDER, "PPSWANDER" },
  60. { STA_PPSERROR, "PPSERROR" },
  61. { STA_CLOCKERR, "CLOCKERR" },
  62. { 0, NULL } };
  63. static char *ret_code_descript[] = {
  64. "clock synchronized",
  65. "insert leap second",
  66. "delete leap second",
  67. "leap second in progress",
  68. "leap second has occurred",
  69. "clock not synchronized" };
  70. #ifdef BB_VER
  71. #define main adjtimex_main
  72. #else
  73. void usage(char *prog)
  74. {
  75. fprintf(stderr,
  76. "Usage: %s [ -q ] [ -o offset ] [ -f frequency ] [ -p timeconstant ] [ -t tick ]\n",
  77. prog);
  78. }
  79. #define bb_show_usage() usage(argv[0])
  80. #endif
  81. int main(int argc, char ** argv)
  82. {
  83. struct timex txc;
  84. int quiet=0;
  85. int c, i, ret, sep;
  86. char *descript;
  87. txc.modes=0;
  88. for (;;) {
  89. c = getopt( argc, argv, "qo:f:p:t:");
  90. if (c == EOF) break;
  91. switch (c) {
  92. case 'q':
  93. quiet=1;
  94. break;
  95. case 'o':
  96. txc.offset = atoi(optarg);
  97. txc.modes |= ADJ_OFFSET_SINGLESHOT;
  98. break;
  99. case 'f':
  100. txc.freq = atoi(optarg);
  101. txc.modes |= ADJ_FREQUENCY;
  102. break;
  103. case 'p':
  104. txc.constant = atoi(optarg);
  105. txc.modes |= ADJ_TIMECONST;
  106. break;
  107. case 't':
  108. txc.tick = atoi(optarg);
  109. txc.modes |= ADJ_TICK;
  110. break;
  111. default:
  112. bb_show_usage();
  113. exit(1);
  114. }
  115. }
  116. if (argc != optind) { /* no valid non-option parameters */
  117. bb_show_usage();
  118. exit(1);
  119. }
  120. ret = adjtimex(&txc);
  121. if (ret < 0) perror("adjtimex");
  122. if (!quiet && ret>=0) {
  123. printf(
  124. " mode: %d\n"
  125. "-o offset: %ld\n"
  126. "-f frequency: %ld\n"
  127. " maxerror: %ld\n"
  128. " esterror: %ld\n"
  129. " status: %d ( ",
  130. txc.modes, txc.offset, txc.freq, txc.maxerror,
  131. txc.esterror, txc.status);
  132. /* representative output of next code fragment:
  133. "PLL | PPSTIME" */
  134. sep=0;
  135. for (i=0; statlist[i].name; i++) {
  136. if (txc.status & statlist[i].bit) {
  137. if (sep) fputs(" | ",stdout);
  138. fputs(statlist[i].name,stdout);
  139. sep=1;
  140. }
  141. }
  142. descript = "error";
  143. if (ret >= 0 && ret <= 5) descript = 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. return (ret<0);
  157. }