1*f14fb602SLionel Sambuc /* $NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $ */
22fe8fb19SBen Gras
32fe8fb19SBen Gras /*
42fe8fb19SBen Gras * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
52fe8fb19SBen Gras * Copyright (c) 1996,1999 by Internet Software Consortium.
62fe8fb19SBen Gras *
72fe8fb19SBen Gras * Permission to use, copy, modify, and distribute this software for any
82fe8fb19SBen Gras * purpose with or without fee is hereby granted, provided that the above
92fe8fb19SBen Gras * copyright notice and this permission notice appear in all copies.
102fe8fb19SBen Gras *
112fe8fb19SBen Gras * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
122fe8fb19SBen Gras * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
132fe8fb19SBen Gras * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
142fe8fb19SBen Gras * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
152fe8fb19SBen Gras * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
162fe8fb19SBen Gras * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
172fe8fb19SBen Gras * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
182fe8fb19SBen Gras */
192fe8fb19SBen Gras
202fe8fb19SBen Gras #include <sys/cdefs.h>
212fe8fb19SBen Gras #ifndef lint
222fe8fb19SBen Gras #ifdef notdef
232fe8fb19SBen Gras static const char rcsid[] = "Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp";
242fe8fb19SBen Gras #else
25*f14fb602SLionel Sambuc __RCSID("$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $");
262fe8fb19SBen Gras #endif
272fe8fb19SBen Gras #endif
282fe8fb19SBen Gras
292fe8fb19SBen Gras /* Import. */
302fe8fb19SBen Gras
312fe8fb19SBen Gras #include "port_before.h"
322fe8fb19SBen Gras
332fe8fb19SBen Gras #include <arpa/nameser.h>
342fe8fb19SBen Gras
35*f14fb602SLionel Sambuc #include <assert.h>
362fe8fb19SBen Gras #include <ctype.h>
372fe8fb19SBen Gras #include <errno.h>
382fe8fb19SBen Gras #include <stdio.h>
392fe8fb19SBen Gras #include <string.h>
402fe8fb19SBen Gras
412fe8fb19SBen Gras #include "port_after.h"
422fe8fb19SBen Gras
432fe8fb19SBen Gras #ifdef SPRINTF_CHAR
442fe8fb19SBen Gras # define SPRINTF(x) strlen(sprintf/**/x)
452fe8fb19SBen Gras #else
462fe8fb19SBen Gras # define SPRINTF(x) ((size_t)sprintf x)
472fe8fb19SBen Gras #endif
482fe8fb19SBen Gras
492fe8fb19SBen Gras /* Forward. */
502fe8fb19SBen Gras
512fe8fb19SBen Gras static int fmt1(int t, char s, char **buf, size_t *buflen);
522fe8fb19SBen Gras
532fe8fb19SBen Gras /* Macros. */
542fe8fb19SBen Gras
552fe8fb19SBen Gras #define T(x) if ((x) < 0) return (-1)
562fe8fb19SBen Gras
572fe8fb19SBen Gras /* Public. */
582fe8fb19SBen Gras
592fe8fb19SBen Gras int
ns_format_ttl(u_long src,char * dst,size_t dstlen)602fe8fb19SBen Gras ns_format_ttl(u_long src, char *dst, size_t dstlen) {
612fe8fb19SBen Gras char *odst = dst;
622fe8fb19SBen Gras int secs, mins, hours, days, weeks, x;
632fe8fb19SBen Gras char *p;
642fe8fb19SBen Gras
65*f14fb602SLionel Sambuc secs = (int)(src % 60); src /= 60;
66*f14fb602SLionel Sambuc mins = (int)(src % 60); src /= 60;
67*f14fb602SLionel Sambuc hours = (int)(src % 24); src /= 24;
68*f14fb602SLionel Sambuc days = (int)(src % 7); src /= 7;
69*f14fb602SLionel Sambuc weeks = (int)src; src = 0;
702fe8fb19SBen Gras
712fe8fb19SBen Gras x = 0;
722fe8fb19SBen Gras if (weeks) {
732fe8fb19SBen Gras T(fmt1(weeks, 'W', &dst, &dstlen));
742fe8fb19SBen Gras x++;
752fe8fb19SBen Gras }
762fe8fb19SBen Gras if (days) {
772fe8fb19SBen Gras T(fmt1(days, 'D', &dst, &dstlen));
782fe8fb19SBen Gras x++;
792fe8fb19SBen Gras }
802fe8fb19SBen Gras if (hours) {
812fe8fb19SBen Gras T(fmt1(hours, 'H', &dst, &dstlen));
822fe8fb19SBen Gras x++;
832fe8fb19SBen Gras }
842fe8fb19SBen Gras if (mins) {
852fe8fb19SBen Gras T(fmt1(mins, 'M', &dst, &dstlen));
862fe8fb19SBen Gras x++;
872fe8fb19SBen Gras }
882fe8fb19SBen Gras if (secs || !(weeks || days || hours || mins)) {
892fe8fb19SBen Gras T(fmt1(secs, 'S', &dst, &dstlen));
902fe8fb19SBen Gras x++;
912fe8fb19SBen Gras }
922fe8fb19SBen Gras
932fe8fb19SBen Gras if (x > 1) {
942fe8fb19SBen Gras int ch;
952fe8fb19SBen Gras
962fe8fb19SBen Gras for (p = odst; (ch = *p) != '\0'; p++)
972fe8fb19SBen Gras if (isascii(ch) && isupper(ch))
982fe8fb19SBen Gras *p = tolower(ch);
992fe8fb19SBen Gras }
1002fe8fb19SBen Gras
101*f14fb602SLionel Sambuc _DIAGASSERT(__type_fit(int, dst - odst));
102*f14fb602SLionel Sambuc return (int)(dst - odst);
1032fe8fb19SBen Gras }
1042fe8fb19SBen Gras
1052fe8fb19SBen Gras #ifndef _LIBC
1062fe8fb19SBen Gras int
ns_parse_ttl(const char * src,u_long * dst)1072fe8fb19SBen Gras ns_parse_ttl(const char *src, u_long *dst) {
1082fe8fb19SBen Gras u_long ttl, tmp;
1092fe8fb19SBen Gras int ch, digits, dirty;
1102fe8fb19SBen Gras
1112fe8fb19SBen Gras ttl = 0;
1122fe8fb19SBen Gras tmp = 0;
1132fe8fb19SBen Gras digits = 0;
1142fe8fb19SBen Gras dirty = 0;
1152fe8fb19SBen Gras while ((ch = *src++) != '\0') {
1162fe8fb19SBen Gras if (!isascii(ch) || !isprint(ch))
1172fe8fb19SBen Gras goto einval;
1182fe8fb19SBen Gras if (isdigit(ch)) {
1192fe8fb19SBen Gras tmp *= 10;
1202fe8fb19SBen Gras tmp += (ch - '0');
1212fe8fb19SBen Gras digits++;
1222fe8fb19SBen Gras continue;
1232fe8fb19SBen Gras }
1242fe8fb19SBen Gras if (digits == 0)
1252fe8fb19SBen Gras goto einval;
1262fe8fb19SBen Gras if (islower(ch))
1272fe8fb19SBen Gras ch = toupper(ch);
1282fe8fb19SBen Gras switch (ch) {
1292fe8fb19SBen Gras case 'W': tmp *= 7; /*FALLTHROUGH*/
1302fe8fb19SBen Gras case 'D': tmp *= 24; /*FALLTHROUGH*/
1312fe8fb19SBen Gras case 'H': tmp *= 60; /*FALLTHROUGH*/
1322fe8fb19SBen Gras case 'M': tmp *= 60; /*FALLTHROUGH*/
1332fe8fb19SBen Gras case 'S': break;
1342fe8fb19SBen Gras default: goto einval;
1352fe8fb19SBen Gras }
1362fe8fb19SBen Gras ttl += tmp;
1372fe8fb19SBen Gras tmp = 0;
1382fe8fb19SBen Gras digits = 0;
1392fe8fb19SBen Gras dirty = 1;
1402fe8fb19SBen Gras }
1412fe8fb19SBen Gras if (digits > 0) {
1422fe8fb19SBen Gras if (dirty)
1432fe8fb19SBen Gras goto einval;
1442fe8fb19SBen Gras else
1452fe8fb19SBen Gras ttl += tmp;
1462fe8fb19SBen Gras } else if (!dirty)
1472fe8fb19SBen Gras goto einval;
1482fe8fb19SBen Gras *dst = ttl;
1492fe8fb19SBen Gras return (0);
1502fe8fb19SBen Gras
1512fe8fb19SBen Gras einval:
1522fe8fb19SBen Gras errno = EINVAL;
1532fe8fb19SBen Gras return (-1);
1542fe8fb19SBen Gras }
1552fe8fb19SBen Gras #endif
1562fe8fb19SBen Gras
1572fe8fb19SBen Gras /* Private. */
1582fe8fb19SBen Gras
1592fe8fb19SBen Gras static int
fmt1(int t,char s,char ** buf,size_t * buflen)1602fe8fb19SBen Gras fmt1(int t, char s, char **buf, size_t *buflen) {
1612fe8fb19SBen Gras char tmp[50];
1622fe8fb19SBen Gras size_t len;
1632fe8fb19SBen Gras
1642fe8fb19SBen Gras len = SPRINTF((tmp, "%d%c", t, s));
1652fe8fb19SBen Gras if (len + 1 > *buflen)
1662fe8fb19SBen Gras return (-1);
1672fe8fb19SBen Gras strcpy(*buf, tmp);
1682fe8fb19SBen Gras *buf += len;
1692fe8fb19SBen Gras *buflen -= len;
1702fe8fb19SBen Gras return (0);
1712fe8fb19SBen Gras }
1722fe8fb19SBen Gras
1732fe8fb19SBen Gras /*! \file */
174