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 | |
19 | /* Import. */ |
20 | |
21 | #include <arpa/nameser.h> |
22 | |
23 | #include <ctype.h> |
24 | #include <errno.h> |
25 | #include <stdio.h> |
26 | #include <string.h> |
27 | |
28 | #ifdef SPRINTF_CHAR |
29 | # define SPRINTF(x) strlen(sprintf/**/x) |
30 | #else |
31 | # define SPRINTF(x) ((size_t)sprintf x) |
32 | #endif |
33 | |
34 | /* Forward. */ |
35 | |
36 | static int fmt1(int t, char s, char **buf, size_t *buflen); |
37 | |
38 | /* Macros. */ |
39 | |
40 | #define T(x) if ((x) < 0) return (-1); else (void)NULL |
41 | |
42 | /* Public. */ |
43 | |
44 | int |
45 | ns_format_ttl(u_long src, char *dst, size_t dstlen) { |
46 | char *odst = dst; |
47 | int secs, mins, hours, days, weeks, x; |
48 | char *p; |
49 | |
50 | secs = src % 60; src /= 60; |
51 | mins = src % 60; src /= 60; |
52 | hours = src % 24; src /= 24; |
53 | days = src % 7; src /= 7; |
54 | weeks = src; src = 0; |
55 | |
56 | x = 0; |
57 | if (weeks) { |
58 | T(fmt1(weeks, 'W', &dst, &dstlen)); |
59 | x++; |
60 | } |
61 | if (days) { |
62 | T(fmt1(days, 'D', &dst, &dstlen)); |
63 | x++; |
64 | } |
65 | if (hours) { |
66 | T(fmt1(hours, 'H', &dst, &dstlen)); |
67 | x++; |
68 | } |
69 | if (mins) { |
70 | T(fmt1(mins, 'M', &dst, &dstlen)); |
71 | x++; |
72 | } |
73 | if (secs || !(weeks || days || hours || mins)) { |
74 | T(fmt1(secs, 'S', &dst, &dstlen)); |
75 | x++; |
76 | } |
77 | |
78 | if (x > 1) { |
79 | int ch; |
80 | |
81 | for (p = odst; (ch = *p) != '\0'; p++) |
82 | if (isascii(ch) && isupper(ch)) |
83 | *p = tolower(ch); |
84 | } |
85 | |
86 | return (dst - odst); |
87 | } |
88 | libresolv_hidden_def (ns_format_ttl) |
89 | |
90 | // Seems not to be needed. It's not exported from the DSO. Some libresolv.a |
91 | // might depend on it so we let it in. |
92 | int |
93 | ns_parse_ttl(const char *src, u_long *dst) { |
94 | u_long ttl, tmp; |
95 | int ch, digits, dirty; |
96 | |
97 | ttl = 0; |
98 | tmp = 0; |
99 | digits = 0; |
100 | dirty = 0; |
101 | while ((ch = *src++) != '\0') { |
102 | if (!isascii(ch) || !isprint(ch)) |
103 | goto einval; |
104 | if (isdigit(ch)) { |
105 | tmp *= 10; |
106 | tmp += (ch - '0'); |
107 | digits++; |
108 | continue; |
109 | } |
110 | if (digits == 0) |
111 | goto einval; |
112 | if (islower(ch)) |
113 | ch = toupper(ch); |
114 | switch (ch) { |
115 | case 'W': tmp *= 7; |
116 | case 'D': tmp *= 24; |
117 | case 'H': tmp *= 60; |
118 | case 'M': tmp *= 60; |
119 | case 'S': break; |
120 | default: goto einval; |
121 | } |
122 | ttl += tmp; |
123 | tmp = 0; |
124 | digits = 0; |
125 | dirty = 1; |
126 | } |
127 | if (digits > 0) { |
128 | if (dirty) |
129 | goto einval; |
130 | else |
131 | ttl += tmp; |
132 | } else if (!dirty) |
133 | goto einval; |
134 | *dst = ttl; |
135 | return (0); |
136 | |
137 | einval: |
138 | __set_errno (EINVAL); |
139 | return (-1); |
140 | } |
141 | |
142 | /* Private. */ |
143 | |
144 | static int |
145 | fmt1(int t, char s, char **buf, size_t *buflen) { |
146 | char tmp[50]; |
147 | size_t len; |
148 | |
149 | len = SPRINTF((tmp, "%d%c" , t, s)); |
150 | if (len + 1 > *buflen) |
151 | return (-1); |
152 | strcpy(*buf, tmp); |
153 | *buf += len; |
154 | *buflen -= len; |
155 | return (0); |
156 | } |
157 | |
158 | /*! \file */ |
159 | |