1fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle/*	$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1996,1999 by Internet Software Consortium.
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies.
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h>
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef lint
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef notdef
23fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravlestatic const char rcsid[] = "Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp";
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
25fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle__RCSID("$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $");
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Import. */
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31569fb9887d00104509df79fa77d92e3cf9afe7dbCalin Juravle#include <arpa/nameser.h>
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
33fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle#include <assert.h>
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <ctype.h>
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Forward. */
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int	fmt1(int t, char s, char **buf, size_t *buflen);
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Macros. */
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4550ace4fec5e8cb5afcbc656a4556fa528adfd760David 'Digit' Turner#define T(x) do { if ((x) < 0) return (-1); } while(0)
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Public. */
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectns_format_ttl(u_long src, char *dst, size_t dstlen) {
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *odst = dst;
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int secs, mins, hours, days, weeks, x;
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *p;
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
55fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	secs = (int)(src % 60);   src /= 60;
56fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	mins = (int)(src % 60);   src /= 60;
57fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	hours = (int)(src % 24);  src /= 24;
58fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	days = (int)(src % 7);    src /= 7;
59fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	weeks = (int)src;       src = 0;
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x = 0;
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (weeks) {
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(weeks, 'W', &dst, &dstlen));
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (days) {
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(days, 'D', &dst, &dstlen));
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (hours) {
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(hours, 'H', &dst, &dstlen));
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (mins) {
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(mins, 'M', &dst, &dstlen));
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (secs || !(weeks || days || hours || mins)) {
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(secs, 'S', &dst, &dstlen));
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (x > 1) {
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		int ch;
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (p = odst; (ch = *p) != '\0'; p++)
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (isascii(ch) && isupper(ch))
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p = tolower(ch);
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
91fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	_DIAGASSERT(__type_fit(int, dst - odst));
92fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	return (int)(dst - odst);
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _LIBC
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectns_parse_ttl(const char *src, u_long *dst) {
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_long ttl, tmp;
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ch, digits, dirty;
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ttl = 0;
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tmp = 0;
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	digits = 0;
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	dirty = 0;
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while ((ch = *src++) != '\0') {
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!isascii(ch) || !isprint(ch))
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto einval;
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (isdigit(ch)) {
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			tmp *= 10;
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			tmp += (ch - '0');
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			digits++;
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (digits == 0)
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto einval;
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (islower(ch))
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ch = toupper(ch);
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (ch) {
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'W':  tmp *= 7;	/*FALLTHROUGH*/
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'D':  tmp *= 24;	/*FALLTHROUGH*/
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'H':  tmp *= 60;	/*FALLTHROUGH*/
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'M':  tmp *= 60;	/*FALLTHROUGH*/
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'S':  break;
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:   goto einval;
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ttl += tmp;
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		tmp = 0;
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		digits = 0;
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		dirty = 1;
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (digits > 0) {
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (dirty)
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto einval;
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ttl += tmp;
136fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle	} else if (!dirty)
137fcb502e3ec032497bba7f8634fb214e0c05394d8Calin Juravle		goto einval;
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*dst = ttl;
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project einval:
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	errno = EINVAL;
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (-1);
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Private. */
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfmt1(int t, char s, char **buf, size_t *buflen) {
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char tmp[50];
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	size_t len;
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
154cfd8c45725d85f3e2bfccb6b14a9bff59fd5c4c7Dan Albert	len = (size_t)snprintf(tmp, sizeof(tmp), "%d%c", t, s);
155cfd8c45725d85f3e2bfccb6b14a9bff59fd5c4c7Dan Albert	if ((int)len < 0 || len + 1 > *buflen)
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	strcpy(*buf, tmp);
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*buf += len;
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*buflen -= len;
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
162