ns_ttl.c revision 1.8
11.8Schristos/*	$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $	*/
21.1Schristos
31.1Schristos/*
41.1Schristos * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
51.1Schristos * Copyright (c) 1996,1999 by Internet Software Consortium.
61.1Schristos *
71.1Schristos * Permission to use, copy, modify, and distribute this software for any
81.1Schristos * purpose with or without fee is hereby granted, provided that the above
91.1Schristos * copyright notice and this permission notice appear in all copies.
101.1Schristos *
111.1Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
121.1Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
131.1Schristos * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
141.1Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
151.1Schristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
161.1Schristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
171.1Schristos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
181.1Schristos */
191.1Schristos
201.2Schristos#include <sys/cdefs.h>
211.1Schristos#ifndef lint
221.2Schristos#ifdef notdef
231.6Schristosstatic const char rcsid[] = "Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp";
241.2Schristos#else
251.8Schristos__RCSID("$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $");
261.2Schristos#endif
271.1Schristos#endif
281.1Schristos
291.1Schristos/* Import. */
301.1Schristos
311.1Schristos#include "port_before.h"
321.1Schristos
331.1Schristos#include <arpa/nameser.h>
341.1Schristos
351.8Schristos#include <assert.h>
361.1Schristos#include <ctype.h>
371.1Schristos#include <errno.h>
381.1Schristos#include <stdio.h>
391.1Schristos#include <string.h>
401.1Schristos
411.1Schristos#include "port_after.h"
421.1Schristos
431.1Schristos#ifdef SPRINTF_CHAR
441.1Schristos# define SPRINTF(x) strlen(sprintf/**/x)
451.1Schristos#else
461.1Schristos# define SPRINTF(x) ((size_t)sprintf x)
471.1Schristos#endif
481.1Schristos
491.1Schristos/* Forward. */
501.1Schristos
511.1Schristosstatic int	fmt1(int t, char s, char **buf, size_t *buflen);
521.1Schristos
531.1Schristos/* Macros. */
541.1Schristos
551.3Schristos#define T(x) if ((x) < 0) return (-1)
561.1Schristos
571.1Schristos/* Public. */
581.1Schristos
591.1Schristosint
601.1Schristosns_format_ttl(u_long src, char *dst, size_t dstlen) {
611.1Schristos	char *odst = dst;
621.1Schristos	int secs, mins, hours, days, weeks, x;
631.1Schristos	char *p;
641.1Schristos
651.8Schristos	secs = (int)(src % 60);   src /= 60;
661.8Schristos	mins = (int)(src % 60);   src /= 60;
671.8Schristos	hours = (int)(src % 24);  src /= 24;
681.8Schristos	days = (int)(src % 7);    src /= 7;
691.8Schristos	weeks = (int)src;       src = 0;
701.1Schristos
711.1Schristos	x = 0;
721.1Schristos	if (weeks) {
731.1Schristos		T(fmt1(weeks, 'W', &dst, &dstlen));
741.1Schristos		x++;
751.1Schristos	}
761.1Schristos	if (days) {
771.1Schristos		T(fmt1(days, 'D', &dst, &dstlen));
781.1Schristos		x++;
791.1Schristos	}
801.1Schristos	if (hours) {
811.1Schristos		T(fmt1(hours, 'H', &dst, &dstlen));
821.1Schristos		x++;
831.1Schristos	}
841.1Schristos	if (mins) {
851.1Schristos		T(fmt1(mins, 'M', &dst, &dstlen));
861.1Schristos		x++;
871.1Schristos	}
881.1Schristos	if (secs || !(weeks || days || hours || mins)) {
891.1Schristos		T(fmt1(secs, 'S', &dst, &dstlen));
901.1Schristos		x++;
911.1Schristos	}
921.1Schristos
931.1Schristos	if (x > 1) {
941.1Schristos		int ch;
951.1Schristos
961.1Schristos		for (p = odst; (ch = *p) != '\0'; p++)
971.1Schristos			if (isascii(ch) && isupper(ch))
981.1Schristos				*p = tolower(ch);
991.1Schristos	}
1001.1Schristos
1011.8Schristos	_DIAGASSERT(__type_fit(int, dst - odst));
1021.8Schristos	return (int)(dst - odst);
1031.1Schristos}
1041.1Schristos
1051.2Schristos#ifndef _LIBC
1061.1Schristosint
1071.1Schristosns_parse_ttl(const char *src, u_long *dst) {
1081.1Schristos	u_long ttl, tmp;
1091.1Schristos	int ch, digits, dirty;
1101.1Schristos
1111.1Schristos	ttl = 0;
1121.1Schristos	tmp = 0;
1131.1Schristos	digits = 0;
1141.1Schristos	dirty = 0;
1151.1Schristos	while ((ch = *src++) != '\0') {
1161.1Schristos		if (!isascii(ch) || !isprint(ch))
1171.1Schristos			goto einval;
1181.1Schristos		if (isdigit(ch)) {
1191.1Schristos			tmp *= 10;
1201.1Schristos			tmp += (ch - '0');
1211.1Schristos			digits++;
1221.1Schristos			continue;
1231.1Schristos		}
1241.1Schristos		if (digits == 0)
1251.1Schristos			goto einval;
1261.1Schristos		if (islower(ch))
1271.1Schristos			ch = toupper(ch);
1281.1Schristos		switch (ch) {
1291.2Schristos		case 'W':  tmp *= 7;	/*FALLTHROUGH*/
1301.2Schristos		case 'D':  tmp *= 24;	/*FALLTHROUGH*/
1311.2Schristos		case 'H':  tmp *= 60;	/*FALLTHROUGH*/
1321.2Schristos		case 'M':  tmp *= 60;	/*FALLTHROUGH*/
1331.1Schristos		case 'S':  break;
1341.1Schristos		default:   goto einval;
1351.1Schristos		}
1361.1Schristos		ttl += tmp;
1371.1Schristos		tmp = 0;
1381.1Schristos		digits = 0;
1391.1Schristos		dirty = 1;
1401.1Schristos	}
1411.1Schristos	if (digits > 0) {
1421.1Schristos		if (dirty)
1431.1Schristos			goto einval;
1441.1Schristos		else
1451.1Schristos			ttl += tmp;
1461.4Schristos	} else if (!dirty)
1471.4Schristos		goto einval;
1481.1Schristos	*dst = ttl;
1491.1Schristos	return (0);
1501.1Schristos
1511.1Schristos einval:
1521.1Schristos	errno = EINVAL;
1531.1Schristos	return (-1);
1541.1Schristos}
1551.2Schristos#endif
1561.1Schristos
1571.1Schristos/* Private. */
1581.1Schristos
1591.1Schristosstatic int
1601.1Schristosfmt1(int t, char s, char **buf, size_t *buflen) {
1611.1Schristos	char tmp[50];
1621.1Schristos	size_t len;
1631.1Schristos
1641.1Schristos	len = SPRINTF((tmp, "%d%c", t, s));
1651.1Schristos	if (len + 1 > *buflen)
1661.1Schristos		return (-1);
1671.1Schristos	strcpy(*buf, tmp);
1681.1Schristos	*buf += len;
1691.1Schristos	*buflen -= len;
1701.1Schristos	return (0);
1711.1Schristos}
1721.4Schristos
1731.4Schristos/*! \file */
174