|  | /* | 
|  | * 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 */ |