|
1 /* $NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 christos Exp $ */ |
|
2 |
|
3 /* |
|
4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") |
|
5 * Copyright (c) 1996,1999 by Internet Software Consortium. |
|
6 * |
|
7 * Permission to use, copy, modify, and distribute this software for any |
|
8 * purpose with or without fee is hereby granted, provided that the above |
|
9 * copyright notice and this permission notice appear in all copies. |
|
10 * |
|
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES |
|
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR |
|
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
|
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
18 */ |
|
19 |
|
20 /* |
|
21 * This version of this file is derived from Android 2.3 "Gingerbread", |
|
22 * which contains uncredited changes by Android/Google developers. It has |
|
23 * been modified in 2011 for use in the Android build of Mozilla Firefox by |
|
24 * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>, |
|
25 * and Steve Workman <sjhworkman@gmail.com>). |
|
26 * These changes are offered under the same license as the original NetBSD |
|
27 * file, whose copyright and license are unchanged above. |
|
28 */ |
|
29 |
|
30 #define ANDROID_CHANGES 1 |
|
31 #define MOZILLA_NECKO_EXCLUDE_CODE 1 |
|
32 |
|
33 #include <sys/cdefs.h> |
|
34 #ifndef lint |
|
35 #ifdef notdef |
|
36 static const char rcsid[] = "Id: ns_ttl.c,v 1.1.206.1 2004/03/09 08:33:45 marka Exp"; |
|
37 #else |
|
38 __RCSID("$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 christos Exp $"); |
|
39 #endif |
|
40 #endif |
|
41 |
|
42 /* Import. */ |
|
43 |
|
44 #include "arpa_nameser.h" |
|
45 |
|
46 #include <ctype.h> |
|
47 #include <errno.h> |
|
48 #include <stdio.h> |
|
49 #include <string.h> |
|
50 |
|
51 #ifdef SPRINTF_CHAR |
|
52 # define SPRINTF(x) strlen(sprintf/**/x) |
|
53 #else |
|
54 # define SPRINTF(x) ((size_t)sprintf x) |
|
55 #endif |
|
56 |
|
57 /* Forward. */ |
|
58 |
|
59 static int fmt1(int t, char s, char **buf, size_t *buflen); |
|
60 |
|
61 /* Macros. */ |
|
62 |
|
63 #define T(x) do { if ((x) < 0) return (-1); } while(0) |
|
64 |
|
65 /* Public. */ |
|
66 |
|
67 int |
|
68 ns_format_ttl(u_long src, char *dst, size_t dstlen) { |
|
69 char *odst = dst; |
|
70 int secs, mins, hours, days, weeks, x; |
|
71 char *p; |
|
72 |
|
73 secs = src % 60; src /= 60; |
|
74 mins = src % 60; src /= 60; |
|
75 hours = src % 24; src /= 24; |
|
76 days = src % 7; src /= 7; |
|
77 weeks = src; src = 0; |
|
78 |
|
79 x = 0; |
|
80 if (weeks) { |
|
81 T(fmt1(weeks, 'W', &dst, &dstlen)); |
|
82 x++; |
|
83 } |
|
84 if (days) { |
|
85 T(fmt1(days, 'D', &dst, &dstlen)); |
|
86 x++; |
|
87 } |
|
88 if (hours) { |
|
89 T(fmt1(hours, 'H', &dst, &dstlen)); |
|
90 x++; |
|
91 } |
|
92 if (mins) { |
|
93 T(fmt1(mins, 'M', &dst, &dstlen)); |
|
94 x++; |
|
95 } |
|
96 if (secs || !(weeks || days || hours || mins)) { |
|
97 T(fmt1(secs, 'S', &dst, &dstlen)); |
|
98 x++; |
|
99 } |
|
100 |
|
101 if (x > 1) { |
|
102 int ch; |
|
103 |
|
104 for (p = odst; (ch = *p) != '\0'; p++) |
|
105 if (isascii(ch) && isupper(ch)) |
|
106 *p = tolower(ch); |
|
107 } |
|
108 |
|
109 return (dst - odst); |
|
110 } |
|
111 |
|
112 #ifndef MOZILLA_NECKO_EXCLUDE_CODE |
|
113 #ifndef _LIBC |
|
114 int |
|
115 ns_parse_ttl(const char *src, u_long *dst) { |
|
116 u_long ttl, tmp; |
|
117 int ch, digits, dirty; |
|
118 |
|
119 ttl = 0; |
|
120 tmp = 0; |
|
121 digits = 0; |
|
122 dirty = 0; |
|
123 while ((ch = *src++) != '\0') { |
|
124 if (!isascii(ch) || !isprint(ch)) |
|
125 goto einval; |
|
126 if (isdigit(ch)) { |
|
127 tmp *= 10; |
|
128 tmp += (ch - '0'); |
|
129 digits++; |
|
130 continue; |
|
131 } |
|
132 if (digits == 0) |
|
133 goto einval; |
|
134 if (islower(ch)) |
|
135 ch = toupper(ch); |
|
136 switch (ch) { |
|
137 case 'W': tmp *= 7; /*FALLTHROUGH*/ |
|
138 case 'D': tmp *= 24; /*FALLTHROUGH*/ |
|
139 case 'H': tmp *= 60; /*FALLTHROUGH*/ |
|
140 case 'M': tmp *= 60; /*FALLTHROUGH*/ |
|
141 case 'S': break; |
|
142 default: goto einval; |
|
143 } |
|
144 ttl += tmp; |
|
145 tmp = 0; |
|
146 digits = 0; |
|
147 dirty = 1; |
|
148 } |
|
149 if (digits > 0) { |
|
150 if (dirty) |
|
151 goto einval; |
|
152 else |
|
153 ttl += tmp; |
|
154 } |
|
155 *dst = ttl; |
|
156 return (0); |
|
157 |
|
158 einval: |
|
159 errno = EINVAL; |
|
160 return (-1); |
|
161 } |
|
162 #endif |
|
163 #endif |
|
164 |
|
165 /* Private. */ |
|
166 |
|
167 static int |
|
168 fmt1(int t, char s, char **buf, size_t *buflen) { |
|
169 char tmp[50]; |
|
170 size_t len; |
|
171 |
|
172 len = SPRINTF((tmp, "%d%c", t, s)); |
|
173 if (len + 1 > *buflen) |
|
174 return (-1); |
|
175 strcpy(*buf, tmp); |
|
176 *buf += len; |
|
177 *buflen -= len; |
|
178 return (0); |
|
179 } |