| /* | 
 |  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") | 
 |  * Copyright (c) 1996,1999 by Internet Software Consortium. | 
 |  * | 
 |  * Permission to use, copy, modify, and distribute this software for any | 
 |  * purpose with or without fee is hereby granted, provided that the above | 
 |  * copyright notice and this permission notice appear in all copies. | 
 |  * | 
 |  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | 
 |  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | 
 |  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | 
 |  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | 
 |  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | 
 |  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | 
 |  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | 
 |  * SOFTWARE. | 
 |  */ | 
 |  | 
 | #if !defined(_LIBC) && !defined(lint) | 
 | static const char rcsid[] = "$BINDId: ns_ttl.c,v 8.8 1999/10/13 16:39:36 vixie Exp $"; | 
 | #endif | 
 |  | 
 | /* Import. */ | 
 |  | 
 | #include <arpa/nameser.h> | 
 |  | 
 | #include <ctype.h> | 
 | #include <errno.h> | 
 | #include <stdio.h> | 
 | #include <string.h> | 
 |  | 
 | #ifdef SPRINTF_CHAR | 
 | # define SPRINTF(x) strlen(sprintf/**/x) | 
 | #else | 
 | # define SPRINTF(x) ((size_t)sprintf x) | 
 | #endif | 
 |  | 
 | /* Forward. */ | 
 |  | 
 | static int	fmt1(int t, char s, char **buf, size_t *buflen); | 
 |  | 
 | /* Macros. */ | 
 |  | 
 | #define T(x) if ((x) < 0) return (-1); else (void)NULL | 
 |  | 
 | /* Public. */ | 
 |  | 
 | int | 
 | ns_format_ttl(u_long src, char *dst, size_t dstlen) { | 
 | 	char *odst = dst; | 
 | 	int secs, mins, hours, days, weeks, x; | 
 | 	char *p; | 
 |  | 
 | 	secs = src % 60;   src /= 60; | 
 | 	mins = src % 60;   src /= 60; | 
 | 	hours = src % 24;  src /= 24; | 
 | 	days = src % 7;    src /= 7; | 
 | 	weeks = src;       src = 0; | 
 |  | 
 | 	x = 0; | 
 | 	if (weeks) { | 
 | 		T(fmt1(weeks, 'W', &dst, &dstlen)); | 
 | 		x++; | 
 | 	} | 
 | 	if (days) { | 
 | 		T(fmt1(days, 'D', &dst, &dstlen)); | 
 | 		x++; | 
 | 	} | 
 | 	if (hours) { | 
 | 		T(fmt1(hours, 'H', &dst, &dstlen)); | 
 | 		x++; | 
 | 	} | 
 | 	if (mins) { | 
 | 		T(fmt1(mins, 'M', &dst, &dstlen)); | 
 | 		x++; | 
 | 	} | 
 | 	if (secs || !(weeks || days || hours || mins)) { | 
 | 		T(fmt1(secs, 'S', &dst, &dstlen)); | 
 | 		x++; | 
 | 	} | 
 |  | 
 | 	if (x > 1) { | 
 | 		int ch; | 
 |  | 
 | 		for (p = odst; (ch = *p) != '\0'; p++) | 
 | 			if (isascii(ch) && isupper(ch)) | 
 | 				*p = tolower(ch); | 
 | 	} | 
 |  | 
 | 	return (dst - odst); | 
 | } | 
 | libresolv_hidden_def (ns_format_ttl) | 
 |  | 
 | // Seems not to be needed.  It's not exported from the DSO.  Some libresolv.a | 
 | // might depend on it so we let it in. | 
 | int | 
 | ns_parse_ttl(const char *src, u_long *dst) { | 
 | 	u_long ttl, tmp; | 
 | 	int ch, digits, dirty; | 
 |  | 
 | 	ttl = 0; | 
 | 	tmp = 0; | 
 | 	digits = 0; | 
 | 	dirty = 0; | 
 | 	while ((ch = *src++) != '\0') { | 
 | 		if (!isascii(ch) || !isprint(ch)) | 
 | 			goto einval; | 
 | 		if (isdigit(ch)) { | 
 | 			tmp *= 10; | 
 | 			tmp += (ch - '0'); | 
 | 			digits++; | 
 | 			continue; | 
 | 		} | 
 | 		if (digits == 0) | 
 | 			goto einval; | 
 | 		if (islower(ch)) | 
 | 			ch = toupper(ch); | 
 | 		switch (ch) { | 
 | 		case 'W':  tmp *= 7; | 
 | 		case 'D':  tmp *= 24; | 
 | 		case 'H':  tmp *= 60; | 
 | 		case 'M':  tmp *= 60; | 
 | 		case 'S':  break; | 
 | 		default:   goto einval; | 
 | 		} | 
 | 		ttl += tmp; | 
 | 		tmp = 0; | 
 | 		digits = 0; | 
 | 		dirty = 1; | 
 | 	} | 
 | 	if (digits > 0) { | 
 | 		if (dirty) | 
 | 			goto einval; | 
 | 		else | 
 | 			ttl += tmp; | 
 | 	} else if (!dirty) | 
 | 		goto einval; | 
 | 	*dst = ttl; | 
 | 	return (0); | 
 |  | 
 |  einval: | 
 | 	__set_errno (EINVAL); | 
 | 	return (-1); | 
 | } | 
 |  | 
 | /* Private. */ | 
 |  | 
 | static int | 
 | fmt1(int t, char s, char **buf, size_t *buflen) { | 
 | 	char tmp[50]; | 
 | 	size_t len; | 
 |  | 
 | 	len = SPRINTF((tmp, "%d%c", t, s)); | 
 | 	if (len + 1 > *buflen) | 
 | 		return (-1); | 
 | 	strcpy(*buf, tmp); | 
 | 	*buf += len; | 
 | 	*buflen -= len; | 
 | 	return (0); | 
 | } | 
 |  | 
 | /*! \file */ |