ns_ttl.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (c) 1996,1999 by Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  10. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  11. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  12. * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  15. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  16. * SOFTWARE.
  17. */
  18. /* Import. */
  19. #include <arpa/nameser.h>
  20. #include <ctype.h>
  21. #include <errno.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #ifdef SPRINTF_CHAR
  25. # define SPRINTF(x) strlen(sprintf/**/x)
  26. #else
  27. # define SPRINTF(x) ((size_t)sprintf x)
  28. #endif
  29. /* Forward. */
  30. static int fmt1(int t, char s, char **buf, size_t *buflen);
  31. /* Macros. */
  32. #define T(x) if ((x) < 0) return (-1); else (void)NULL
  33. /* Public. */
  34. int
  35. ns_format_ttl(u_long src, char *dst, size_t dstlen) {
  36. char *odst = dst;
  37. int secs, mins, hours, days, weeks, x;
  38. char *p;
  39. secs = src % 60; src /= 60;
  40. mins = src % 60; src /= 60;
  41. hours = src % 24; src /= 24;
  42. days = src % 7; src /= 7;
  43. weeks = src; src = 0;
  44. x = 0;
  45. if (weeks) {
  46. T(fmt1(weeks, 'W', &dst, &dstlen));
  47. x++;
  48. }
  49. if (days) {
  50. T(fmt1(days, 'D', &dst, &dstlen));
  51. x++;
  52. }
  53. if (hours) {
  54. T(fmt1(hours, 'H', &dst, &dstlen));
  55. x++;
  56. }
  57. if (mins) {
  58. T(fmt1(mins, 'M', &dst, &dstlen));
  59. x++;
  60. }
  61. if (secs || !(weeks || days || hours || mins)) {
  62. T(fmt1(secs, 'S', &dst, &dstlen));
  63. x++;
  64. }
  65. if (x > 1) {
  66. int ch;
  67. for (p = odst; (ch = *p) != '\0'; p++)
  68. if (isascii(ch) && isupper(ch))
  69. *p = tolower(ch);
  70. }
  71. return (dst - odst);
  72. }
  73. libresolv_hidden_def (ns_format_ttl)
  74. // Seems not to be needed. It's not exported from the DSO. Some libresolv.a
  75. // might depend on it so we let it in.
  76. int
  77. ns_parse_ttl(const char *src, u_long *dst) {
  78. u_long ttl, tmp;
  79. int ch, digits, dirty;
  80. ttl = 0;
  81. tmp = 0;
  82. digits = 0;
  83. dirty = 0;
  84. while ((ch = *src++) != '\0') {
  85. if (!isascii(ch) || !isprint(ch))
  86. goto einval;
  87. if (isdigit(ch)) {
  88. tmp *= 10;
  89. tmp += (ch - '0');
  90. digits++;
  91. continue;
  92. }
  93. if (digits == 0)
  94. goto einval;
  95. if (islower(ch))
  96. ch = toupper(ch);
  97. switch (ch) {
  98. case 'W': tmp *= 7;
  99. case 'D': tmp *= 24;
  100. case 'H': tmp *= 60;
  101. case 'M': tmp *= 60;
  102. case 'S': break;
  103. default: goto einval;
  104. }
  105. ttl += tmp;
  106. tmp = 0;
  107. digits = 0;
  108. dirty = 1;
  109. }
  110. if (digits > 0) {
  111. if (dirty)
  112. goto einval;
  113. else
  114. ttl += tmp;
  115. } else if (!dirty)
  116. goto einval;
  117. *dst = ttl;
  118. return (0);
  119. einval:
  120. __set_errno (EINVAL);
  121. return (-1);
  122. }
  123. /* Private. */
  124. static int
  125. fmt1(int t, char s, char **buf, size_t *buflen) {
  126. char tmp[50];
  127. size_t len;
  128. len = SPRINTF((tmp, "%d%c", t, s));
  129. if (len + 1 > *buflen)
  130. return (-1);
  131. strcpy(*buf, tmp);
  132. *buf += len;
  133. *buflen -= len;
  134. return (0);
  135. }
  136. /*! \file */