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