11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 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
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char rcsid[] = "Id: ns_ttl.c,v 1.1.206.1 2004/03/09 08:33:45 marka Exp";
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__RCSID("$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 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
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "arpa_nameser.h"
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <ctype.h>
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef SPRINTF_CHAR
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# define SPRINTF(x) strlen(sprintf/**/x)
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project# define SPRINTF(x) ((size_t)sprintf x)
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Forward. */
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int	fmt1(int t, char s, char **buf, size_t *buflen);
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Macros. */
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5050ace4fec5e8cb5afcbc656a4556fa528adfd760David 'Digit' Turner#define T(x) do { if ((x) < 0) return (-1); } while(0)
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Public. */
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectns_format_ttl(u_long src, char *dst, size_t dstlen) {
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *odst = dst;
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int secs, mins, hours, days, weeks, x;
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *p;
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	secs = src % 60;   src /= 60;
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	mins = src % 60;   src /= 60;
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hours = src % 24;  src /= 24;
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	days = src % 7;    src /= 7;
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	weeks = src;       src = 0;
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x = 0;
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (weeks) {
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(weeks, 'W', &dst, &dstlen));
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (days) {
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(days, 'D', &dst, &dstlen));
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (hours) {
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(hours, 'H', &dst, &dstlen));
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (mins) {
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(mins, 'M', &dst, &dstlen));
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (secs || !(weeks || days || hours || mins)) {
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		T(fmt1(secs, 'S', &dst, &dstlen));
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x++;
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (x > 1) {
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		int ch;
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (p = odst; (ch = *p) != '\0'; p++)
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (isascii(ch) && isupper(ch))
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				*p = tolower(ch);
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (dst - odst);
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _LIBC
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectns_parse_ttl(const char *src, u_long *dst) {
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_long ttl, tmp;
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int ch, digits, dirty;
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ttl = 0;
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tmp = 0;
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	digits = 0;
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	dirty = 0;
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while ((ch = *src++) != '\0') {
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!isascii(ch) || !isprint(ch))
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto einval;
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (isdigit(ch)) {
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			tmp *= 10;
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			tmp += (ch - '0');
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			digits++;
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (digits == 0)
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto einval;
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (islower(ch))
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ch = toupper(ch);
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (ch) {
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'W':  tmp *= 7;	/*FALLTHROUGH*/
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'D':  tmp *= 24;	/*FALLTHROUGH*/
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'H':  tmp *= 60;	/*FALLTHROUGH*/
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'M':  tmp *= 60;	/*FALLTHROUGH*/
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'S':  break;
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:   goto einval;
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ttl += tmp;
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		tmp = 0;
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		digits = 0;
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		dirty = 1;
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (digits > 0) {
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (dirty)
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto einval;
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ttl += tmp;
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*dst = ttl;
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project einval:
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	errno = EINVAL;
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (-1);
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Private. */
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfmt1(int t, char s, char **buf, size_t *buflen) {
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char tmp[50];
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	size_t len;
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	len = SPRINTF((tmp, "%d%c", t, s));
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (len + 1 > *buflen)
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	strcpy(*buf, tmp);
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*buf += len;
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	*buflen -= len;
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
165