xref: /netbsd-src/external/bsd/libbind/dist/nameser/ns_ttl.c (revision 5bbd2a12505d72a8177929a37b5cee489d0a1cfd)
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