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