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