xref: /freebsd/lib/libc/nameser/ns_ttl.c (revision 861249f5830e8658b61130e0ee7eaad2e93d0449)
165e96449SHajimu UMEMOTO /*
265e96449SHajimu UMEMOTO  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
365e96449SHajimu UMEMOTO  * Copyright (c) 1996,1999 by Internet Software Consortium.
465e96449SHajimu UMEMOTO  *
565e96449SHajimu UMEMOTO  * Permission to use, copy, modify, and distribute this software for any
665e96449SHajimu UMEMOTO  * purpose with or without fee is hereby granted, provided that the above
765e96449SHajimu UMEMOTO  * copyright notice and this permission notice appear in all copies.
865e96449SHajimu UMEMOTO  *
965e96449SHajimu UMEMOTO  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
1065e96449SHajimu UMEMOTO  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1165e96449SHajimu UMEMOTO  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
1265e96449SHajimu UMEMOTO  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1365e96449SHajimu UMEMOTO  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1465e96449SHajimu UMEMOTO  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
1565e96449SHajimu UMEMOTO  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1665e96449SHajimu UMEMOTO  */
1765e96449SHajimu UMEMOTO 
1865e96449SHajimu UMEMOTO #ifndef lint
19861249f5SHajimu UMEMOTO static const char rcsid[] = "$Id: ns_ttl.c,v 1.2.18.2 2005/07/28 07:38:10 marka Exp $";
2065e96449SHajimu UMEMOTO #endif
2165e96449SHajimu UMEMOTO 
2265e96449SHajimu UMEMOTO /* Import. */
2365e96449SHajimu UMEMOTO 
2465e96449SHajimu UMEMOTO #include "port_before.h"
2565e96449SHajimu UMEMOTO 
2665e96449SHajimu UMEMOTO #include <arpa/nameser.h>
2765e96449SHajimu UMEMOTO 
2865e96449SHajimu UMEMOTO #include <ctype.h>
2965e96449SHajimu UMEMOTO #include <errno.h>
3065e96449SHajimu UMEMOTO #include <stdio.h>
3165e96449SHajimu UMEMOTO #include <string.h>
3265e96449SHajimu UMEMOTO 
3365e96449SHajimu UMEMOTO #include "port_after.h"
3465e96449SHajimu UMEMOTO 
3565e96449SHajimu UMEMOTO #ifdef SPRINTF_CHAR
3665e96449SHajimu UMEMOTO # define SPRINTF(x) strlen(sprintf/**/x)
3765e96449SHajimu UMEMOTO #else
3865e96449SHajimu UMEMOTO # define SPRINTF(x) ((size_t)sprintf x)
3965e96449SHajimu UMEMOTO #endif
4065e96449SHajimu UMEMOTO 
4165e96449SHajimu UMEMOTO /* Forward. */
4265e96449SHajimu UMEMOTO 
4365e96449SHajimu UMEMOTO static int	fmt1(int t, char s, char **buf, size_t *buflen);
4465e96449SHajimu UMEMOTO 
4565e96449SHajimu UMEMOTO /* Macros. */
4665e96449SHajimu UMEMOTO 
4765e96449SHajimu UMEMOTO #define T(x) if ((x) < 0) return (-1); else (void)NULL
4865e96449SHajimu UMEMOTO 
4965e96449SHajimu UMEMOTO /* Public. */
5065e96449SHajimu UMEMOTO 
5165e96449SHajimu UMEMOTO int
5265e96449SHajimu UMEMOTO ns_format_ttl(u_long src, char *dst, size_t dstlen) {
5365e96449SHajimu UMEMOTO 	char *odst = dst;
5465e96449SHajimu UMEMOTO 	int secs, mins, hours, days, weeks, x;
5565e96449SHajimu UMEMOTO 	char *p;
5665e96449SHajimu UMEMOTO 
5765e96449SHajimu UMEMOTO 	secs = src % 60;   src /= 60;
5865e96449SHajimu UMEMOTO 	mins = src % 60;   src /= 60;
5965e96449SHajimu UMEMOTO 	hours = src % 24;  src /= 24;
6065e96449SHajimu UMEMOTO 	days = src % 7;    src /= 7;
6165e96449SHajimu UMEMOTO 	weeks = src;       src = 0;
6265e96449SHajimu UMEMOTO 
6365e96449SHajimu UMEMOTO 	x = 0;
6465e96449SHajimu UMEMOTO 	if (weeks) {
6565e96449SHajimu UMEMOTO 		T(fmt1(weeks, 'W', &dst, &dstlen));
6665e96449SHajimu UMEMOTO 		x++;
6765e96449SHajimu UMEMOTO 	}
6865e96449SHajimu UMEMOTO 	if (days) {
6965e96449SHajimu UMEMOTO 		T(fmt1(days, 'D', &dst, &dstlen));
7065e96449SHajimu UMEMOTO 		x++;
7165e96449SHajimu UMEMOTO 	}
7265e96449SHajimu UMEMOTO 	if (hours) {
7365e96449SHajimu UMEMOTO 		T(fmt1(hours, 'H', &dst, &dstlen));
7465e96449SHajimu UMEMOTO 		x++;
7565e96449SHajimu UMEMOTO 	}
7665e96449SHajimu UMEMOTO 	if (mins) {
7765e96449SHajimu UMEMOTO 		T(fmt1(mins, 'M', &dst, &dstlen));
7865e96449SHajimu UMEMOTO 		x++;
7965e96449SHajimu UMEMOTO 	}
8065e96449SHajimu UMEMOTO 	if (secs || !(weeks || days || hours || mins)) {
8165e96449SHajimu UMEMOTO 		T(fmt1(secs, 'S', &dst, &dstlen));
8265e96449SHajimu UMEMOTO 		x++;
8365e96449SHajimu UMEMOTO 	}
8465e96449SHajimu UMEMOTO 
8565e96449SHajimu UMEMOTO 	if (x > 1) {
8665e96449SHajimu UMEMOTO 		int ch;
8765e96449SHajimu UMEMOTO 
8865e96449SHajimu UMEMOTO 		for (p = odst; (ch = *p) != '\0'; p++)
8965e96449SHajimu UMEMOTO 			if (isascii(ch) && isupper(ch))
9065e96449SHajimu UMEMOTO 				*p = tolower(ch);
9165e96449SHajimu UMEMOTO 	}
9265e96449SHajimu UMEMOTO 
9365e96449SHajimu UMEMOTO 	return (dst - odst);
9465e96449SHajimu UMEMOTO }
9565e96449SHajimu UMEMOTO 
9665e96449SHajimu UMEMOTO int
9765e96449SHajimu UMEMOTO ns_parse_ttl(const char *src, u_long *dst) {
9865e96449SHajimu UMEMOTO 	u_long ttl, tmp;
9965e96449SHajimu UMEMOTO 	int ch, digits, dirty;
10065e96449SHajimu UMEMOTO 
10165e96449SHajimu UMEMOTO 	ttl = 0;
10265e96449SHajimu UMEMOTO 	tmp = 0;
10365e96449SHajimu UMEMOTO 	digits = 0;
10465e96449SHajimu UMEMOTO 	dirty = 0;
10565e96449SHajimu UMEMOTO 	while ((ch = *src++) != '\0') {
10665e96449SHajimu UMEMOTO 		if (!isascii(ch) || !isprint(ch))
10765e96449SHajimu UMEMOTO 			goto einval;
10865e96449SHajimu UMEMOTO 		if (isdigit(ch)) {
10965e96449SHajimu UMEMOTO 			tmp *= 10;
11065e96449SHajimu UMEMOTO 			tmp += (ch - '0');
11165e96449SHajimu UMEMOTO 			digits++;
11265e96449SHajimu UMEMOTO 			continue;
11365e96449SHajimu UMEMOTO 		}
11465e96449SHajimu UMEMOTO 		if (digits == 0)
11565e96449SHajimu UMEMOTO 			goto einval;
11665e96449SHajimu UMEMOTO 		if (islower(ch))
11765e96449SHajimu UMEMOTO 			ch = toupper(ch);
11865e96449SHajimu UMEMOTO 		switch (ch) {
11965e96449SHajimu UMEMOTO 		case 'W':  tmp *= 7;
12065e96449SHajimu UMEMOTO 		case 'D':  tmp *= 24;
12165e96449SHajimu UMEMOTO 		case 'H':  tmp *= 60;
12265e96449SHajimu UMEMOTO 		case 'M':  tmp *= 60;
12365e96449SHajimu UMEMOTO 		case 'S':  break;
12465e96449SHajimu UMEMOTO 		default:   goto einval;
12565e96449SHajimu UMEMOTO 		}
12665e96449SHajimu UMEMOTO 		ttl += tmp;
12765e96449SHajimu UMEMOTO 		tmp = 0;
12865e96449SHajimu UMEMOTO 		digits = 0;
12965e96449SHajimu UMEMOTO 		dirty = 1;
13065e96449SHajimu UMEMOTO 	}
13165e96449SHajimu UMEMOTO 	if (digits > 0) {
13265e96449SHajimu UMEMOTO 		if (dirty)
13365e96449SHajimu UMEMOTO 			goto einval;
13465e96449SHajimu UMEMOTO 		else
13565e96449SHajimu UMEMOTO 			ttl += tmp;
13665e96449SHajimu UMEMOTO 	} else if (!dirty)
13765e96449SHajimu UMEMOTO 		goto einval;
13865e96449SHajimu UMEMOTO 	*dst = ttl;
13965e96449SHajimu UMEMOTO 	return (0);
14065e96449SHajimu UMEMOTO 
14165e96449SHajimu UMEMOTO  einval:
14265e96449SHajimu UMEMOTO 	errno = EINVAL;
14365e96449SHajimu UMEMOTO 	return (-1);
14465e96449SHajimu UMEMOTO }
14565e96449SHajimu UMEMOTO 
14665e96449SHajimu UMEMOTO /* Private. */
14765e96449SHajimu UMEMOTO 
14865e96449SHajimu UMEMOTO static int
14965e96449SHajimu UMEMOTO fmt1(int t, char s, char **buf, size_t *buflen) {
15065e96449SHajimu UMEMOTO 	char tmp[50];
15165e96449SHajimu UMEMOTO 	size_t len;
15265e96449SHajimu UMEMOTO 
15365e96449SHajimu UMEMOTO 	len = SPRINTF((tmp, "%d%c", t, s));
15465e96449SHajimu UMEMOTO 	if (len + 1 > *buflen)
15565e96449SHajimu UMEMOTO 		return (-1);
15665e96449SHajimu UMEMOTO 	strcpy(*buf, tmp);
15765e96449SHajimu UMEMOTO 	*buf += len;
15865e96449SHajimu UMEMOTO 	*buflen -= len;
15965e96449SHajimu UMEMOTO 	return (0);
16065e96449SHajimu UMEMOTO }
161861249f5SHajimu UMEMOTO 
162861249f5SHajimu UMEMOTO /*! \file */
163