/contrib/ntp/libntp/prettydate.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 132 lines · 90 code · 23 blank · 19 comment · 8 complexity · 2f96c70b9208c3bef0742711736e6bbb MD5 · raw file

  1. /*
  2. * prettydate - convert a time stamp to something readable
  3. */
  4. #include <stdio.h>
  5. #include "ntp_fp.h"
  6. #include "ntp_unixtime.h" /* includes <sys/time.h> */
  7. #include "lib_strbuf.h"
  8. #include "ntp_stdlib.h"
  9. static const char *months[] = {
  10. "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  11. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  12. };
  13. static const char *days[] = {
  14. "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  15. };
  16. /* Helper function to handle possible wraparound of the ntp epoch.
  17. Works by assuming that the localtime/gmtime library functions
  18. have been updated so that they work
  19. */
  20. #define MAX_EPOCH_NR 1000
  21. struct tm *
  22. ntp2unix_tm(
  23. u_long ntp, int local
  24. )
  25. {
  26. time_t t, curr;
  27. struct tm *tm;
  28. int curr_year, epoch_nr;
  29. /* First get the current year: */
  30. curr = time(NULL);
  31. tm = local ? localtime(&curr) : gmtime(&curr);
  32. if (!tm) return NULL;
  33. curr_year = 1900 + tm->tm_year;
  34. /* Convert the ntp timestamp to a unix utc seconds count: */
  35. t = (time_t) ntp - JAN_1970;
  36. /* Check that the ntp timestamp is not before a 136 year window centered
  37. around the current year:
  38. Failsafe in case of an infinite loop:
  39. Allow up to 1000 epochs of 136 years each!
  40. */
  41. for (epoch_nr = 0; epoch_nr < MAX_EPOCH_NR; epoch_nr++) {
  42. tm = local ? localtime(&t) : gmtime(&t);
  43. #if SIZEOF_TIME_T < 4
  44. # include "Bletch: sizeof(time_t) < 4!"
  45. #endif
  46. #if SIZEOF_TIME_T == 4
  47. /* If 32 bits, then year is 1970-2038, so no sense looking */
  48. epoch_nr = MAX_EPOCH_NR;
  49. #else /* SIZEOF_TIME_T > 4 */
  50. /* Check that the resulting year is in the correct epoch: */
  51. if (1900 + tm->tm_year > curr_year - 68) break;
  52. /* Epoch wraparound: Add 2^32 seconds! */
  53. t += (time_t) 65536 << 16;
  54. #endif /* SIZEOF_TIME_T > 4 */
  55. }
  56. return tm;
  57. }
  58. char *
  59. prettydate(
  60. l_fp *ts
  61. )
  62. {
  63. char *bp;
  64. struct tm *tm;
  65. time_t sec;
  66. u_long msec;
  67. LIB_GETBUF(bp);
  68. sec = ts->l_ui;
  69. msec = ts->l_uf / 4294967; /* fract / (2 ** 32 / 1000) */
  70. tm = ntp2unix_tm(sec, 1);
  71. if (!tm) {
  72. (void) sprintf(bp, "%08lx.%08lx --- --- -- ---- --:--:--",
  73. (u_long)ts->l_ui, (u_long)ts->l_uf);
  74. }
  75. else {
  76. (void) sprintf(bp, "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03lu",
  77. (u_long)ts->l_ui, (u_long)ts->l_uf, days[tm->tm_wday],
  78. months[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year,
  79. tm->tm_hour,tm->tm_min, tm->tm_sec, msec);
  80. }
  81. return bp;
  82. }
  83. char *
  84. gmprettydate(
  85. l_fp *ts
  86. )
  87. {
  88. char *bp;
  89. struct tm *tm;
  90. time_t sec;
  91. u_long msec;
  92. LIB_GETBUF(bp);
  93. sec = ts->l_ui;
  94. msec = ts->l_uf / 4294967; /* fract / (2 ** 32 / 1000) */
  95. tm = ntp2unix_tm(sec, 0);
  96. if (!tm) {
  97. (void) sprintf(bp, "%08lx.%08lx --- --- -- ---- --:--:--",
  98. (u_long)ts->l_ui, (u_long)ts->l_uf);
  99. }
  100. else {
  101. (void) sprintf(bp, "%08lx.%08lx %s, %s %2d %4d %2d:%02d:%02d.%03lu",
  102. (u_long)ts->l_ui, (u_long)ts->l_uf, days[tm->tm_wday],
  103. months[tm->tm_mon], tm->tm_mday, 1900 + tm->tm_year,
  104. tm->tm_hour,tm->tm_min, tm->tm_sec, msec);
  105. }
  106. return bp;
  107. }