ns_ttl.c revision 1.4
11.4Schristos/*	$NetBSD: ns_ttl.c,v 1.4 2007/01/27 22:26:43 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.4Schristosstatic const char rcsid[] = "Id: ns_ttl.c,v 1.2.18.2 2005/07/28 07:38:10 marka Exp";
241.2Schristos#else
251.4Schristos__RCSID("$NetBSD: ns_ttl.c,v 1.4 2007/01/27 22:26:43 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.1Schristos#include <ctype.h>
361.1Schristos#include <errno.h>
371.1Schristos#include <stdio.h>
381.1Schristos#include <string.h>
391.1Schristos
401.1Schristos#include "port_after.h"
411.1Schristos
421.1Schristos#ifdef SPRINTF_CHAR
431.1Schristos# define SPRINTF(x) strlen(sprintf/**/x)
441.1Schristos#else
451.1Schristos# define SPRINTF(x) ((size_t)sprintf x)
461.1Schristos#endif
471.1Schristos
481.1Schristos/* Forward. */
491.1Schristos
501.1Schristosstatic int	fmt1(int t, char s, char **buf, size_t *buflen);
511.1Schristos
521.1Schristos/* Macros. */
531.1Schristos
541.3Schristos#define T(x) if ((x) < 0) return (-1)
551.1Schristos
561.1Schristos/* Public. */
571.1Schristos
581.1Schristosint
591.1Schristosns_format_ttl(u_long src, char *dst, size_t dstlen) {
601.1Schristos	char *odst = dst;
611.1Schristos	int secs, mins, hours, days, weeks, x;
621.1Schristos	char *p;
631.1Schristos
641.1Schristos	secs = src % 60;   src /= 60;
651.1Schristos	mins = src % 60;   src /= 60;
661.1Schristos	hours = src % 24;  src /= 24;
671.1Schristos	days = src % 7;    src /= 7;
681.1Schristos	weeks = src;       src = 0;
691.1Schristos
701.1Schristos	x = 0;
711.1Schristos	if (weeks) {
721.1Schristos		T(fmt1(weeks, 'W', &dst, &dstlen));
731.1Schristos		x++;
741.1Schristos	}
751.1Schristos	if (days) {
761.1Schristos		T(fmt1(days, 'D', &dst, &dstlen));
771.1Schristos		x++;
781.1Schristos	}
791.1Schristos	if (hours) {
801.1Schristos		T(fmt1(hours, 'H', &dst, &dstlen));
811.1Schristos		x++;
821.1Schristos	}
831.1Schristos	if (mins) {
841.1Schristos		T(fmt1(mins, 'M', &dst, &dstlen));
851.1Schristos		x++;
861.1Schristos	}
871.1Schristos	if (secs || !(weeks || days || hours || mins)) {
881.1Schristos		T(fmt1(secs, 'S', &dst, &dstlen));
891.1Schristos		x++;
901.1Schristos	}
911.1Schristos
921.1Schristos	if (x > 1) {
931.1Schristos		int ch;
941.1Schristos
951.1Schristos		for (p = odst; (ch = *p) != '\0'; p++)
961.1Schristos			if (isascii(ch) && isupper(ch))
971.1Schristos				*p = tolower(ch);
981.1Schristos	}
991.1Schristos
1001.1Schristos	return (dst - odst);
1011.1Schristos}
1021.1Schristos
1031.2Schristos#ifndef _LIBC
1041.1Schristosint
1051.1Schristosns_parse_ttl(const char *src, u_long *dst) {
1061.1Schristos	u_long ttl, tmp;
1071.1Schristos	int ch, digits, dirty;
1081.1Schristos
1091.1Schristos	ttl = 0;
1101.1Schristos	tmp = 0;
1111.1Schristos	digits = 0;
1121.1Schristos	dirty = 0;
1131.1Schristos	while ((ch = *src++) != '\0') {
1141.1Schristos		if (!isascii(ch) || !isprint(ch))
1151.1Schristos			goto einval;
1161.1Schristos		if (isdigit(ch)) {
1171.1Schristos			tmp *= 10;
1181.1Schristos			tmp += (ch - '0');
1191.1Schristos			digits++;
1201.1Schristos			continue;
1211.1Schristos		}
1221.1Schristos		if (digits == 0)
1231.1Schristos			goto einval;
1241.1Schristos		if (islower(ch))
1251.1Schristos			ch = toupper(ch);
1261.1Schristos		switch (ch) {
1271.2Schristos		case 'W':  tmp *= 7;	/*FALLTHROUGH*/
1281.2Schristos		case 'D':  tmp *= 24;	/*FALLTHROUGH*/
1291.2Schristos		case 'H':  tmp *= 60;	/*FALLTHROUGH*/
1301.2Schristos		case 'M':  tmp *= 60;	/*FALLTHROUGH*/
1311.1Schristos		case 'S':  break;
1321.1Schristos		default:   goto einval;
1331.1Schristos		}
1341.1Schristos		ttl += tmp;
1351.1Schristos		tmp = 0;
1361.1Schristos		digits = 0;
1371.1Schristos		dirty = 1;
1381.1Schristos	}
1391.1Schristos	if (digits > 0) {
1401.1Schristos		if (dirty)
1411.1Schristos			goto einval;
1421.1Schristos		else
1431.1Schristos			ttl += tmp;
1441.4Schristos	} else if (!dirty)
1451.4Schristos		goto einval;
1461.1Schristos	*dst = ttl;
1471.1Schristos	return (0);
1481.1Schristos
1491.1Schristos einval:
1501.1Schristos	errno = EINVAL;
1511.1Schristos	return (-1);
1521.1Schristos}
1531.2Schristos#endif
1541.1Schristos
1551.1Schristos/* Private. */
1561.1Schristos
1571.1Schristosstatic int
1581.1Schristosfmt1(int t, char s, char **buf, size_t *buflen) {
1591.1Schristos	char tmp[50];
1601.1Schristos	size_t len;
1611.1Schristos
1621.1Schristos	len = SPRINTF((tmp, "%d%c", t, s));
1631.1Schristos	if (len + 1 > *buflen)
1641.1Schristos		return (-1);
1651.1Schristos	strcpy(*buf, tmp);
1661.1Schristos	*buf += len;
1671.1Schristos	*buflen -= len;
1681.1Schristos	return (0);
1691.1Schristos}
1701.4Schristos
1711.4Schristos/*! \file */
172