Home | History | Annotate | Download | only in nameser
      1 /*	$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
      5  * Copyright (c) 1996,1999 by Internet Software Consortium.
      6  *
      7  * Permission to use, copy, modify, and distribute this software for any
      8  * purpose with or without fee is hereby granted, provided that the above
      9  * copyright notice and this permission notice appear in all copies.
     10  *
     11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
     12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
     14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
     17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  */
     19 
     20 #include <sys/cdefs.h>
     21 #ifndef lint
     22 #ifdef notdef
     23 static const char rcsid[] = "Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp";
     24 #else
     25 __RCSID("$NetBSD: ns_ttl.c,v 1.8 2012/03/13 21:13:39 christos Exp $");
     26 #endif
     27 #endif
     28 
     29 /* Import. */
     30 
     31 #include <arpa/nameser.h>
     32 
     33 #include <assert.h>
     34 #include <ctype.h>
     35 #include <errno.h>
     36 #include <stdio.h>
     37 #include <string.h>
     38 
     39 /* Forward. */
     40 
     41 static int	fmt1(int t, char s, char **buf, size_t *buflen);
     42 
     43 /* Macros. */
     44 
     45 #define T(x) do { if ((x) < 0) return (-1); } while(0)
     46 
     47 /* Public. */
     48 
     49 int
     50 ns_format_ttl(u_long src, char *dst, size_t dstlen) {
     51 	char *odst = dst;
     52 	int secs, mins, hours, days, weeks, x;
     53 	char *p;
     54 
     55 	secs = (int)(src % 60);   src /= 60;
     56 	mins = (int)(src % 60);   src /= 60;
     57 	hours = (int)(src % 24);  src /= 24;
     58 	days = (int)(src % 7);    src /= 7;
     59 	weeks = (int)src;       src = 0;
     60 
     61 	x = 0;
     62 	if (weeks) {
     63 		T(fmt1(weeks, 'W', &dst, &dstlen));
     64 		x++;
     65 	}
     66 	if (days) {
     67 		T(fmt1(days, 'D', &dst, &dstlen));
     68 		x++;
     69 	}
     70 	if (hours) {
     71 		T(fmt1(hours, 'H', &dst, &dstlen));
     72 		x++;
     73 	}
     74 	if (mins) {
     75 		T(fmt1(mins, 'M', &dst, &dstlen));
     76 		x++;
     77 	}
     78 	if (secs || !(weeks || days || hours || mins)) {
     79 		T(fmt1(secs, 'S', &dst, &dstlen));
     80 		x++;
     81 	}
     82 
     83 	if (x > 1) {
     84 		int ch;
     85 
     86 		for (p = odst; (ch = *p) != '\0'; p++)
     87 			if (isascii(ch) && isupper(ch))
     88 				*p = tolower(ch);
     89 	}
     90 
     91 	_DIAGASSERT(__type_fit(int, dst - odst));
     92 	return (int)(dst - odst);
     93 }
     94 
     95 #ifndef _LIBC
     96 int
     97 ns_parse_ttl(const char *src, u_long *dst) {
     98 	u_long ttl, tmp;
     99 	int ch, digits, dirty;
    100 
    101 	ttl = 0;
    102 	tmp = 0;
    103 	digits = 0;
    104 	dirty = 0;
    105 	while ((ch = *src++) != '\0') {
    106 		if (!isascii(ch) || !isprint(ch))
    107 			goto einval;
    108 		if (isdigit(ch)) {
    109 			tmp *= 10;
    110 			tmp += (ch - '0');
    111 			digits++;
    112 			continue;
    113 		}
    114 		if (digits == 0)
    115 			goto einval;
    116 		if (islower(ch))
    117 			ch = toupper(ch);
    118 		switch (ch) {
    119 		case 'W':  tmp *= 7;	/*FALLTHROUGH*/
    120 		case 'D':  tmp *= 24;	/*FALLTHROUGH*/
    121 		case 'H':  tmp *= 60;	/*FALLTHROUGH*/
    122 		case 'M':  tmp *= 60;	/*FALLTHROUGH*/
    123 		case 'S':  break;
    124 		default:   goto einval;
    125 		}
    126 		ttl += tmp;
    127 		tmp = 0;
    128 		digits = 0;
    129 		dirty = 1;
    130 	}
    131 	if (digits > 0) {
    132 		if (dirty)
    133 			goto einval;
    134 		else
    135 			ttl += tmp;
    136 	} else if (!dirty)
    137 		goto einval;
    138 	*dst = ttl;
    139 	return (0);
    140 
    141  einval:
    142 	errno = EINVAL;
    143 	return (-1);
    144 }
    145 #endif
    146 
    147 /* Private. */
    148 
    149 static int
    150 fmt1(int t, char s, char **buf, size_t *buflen) {
    151 	char tmp[50];
    152 	size_t len;
    153 
    154 	len = (size_t)snprintf(tmp, sizeof(tmp), "%d%c", t, s);
    155 	if ((int)len < 0 || len + 1 > *buflen)
    156 		return (-1);
    157 	strcpy(*buf, tmp);
    158 	*buf += len;
    159 	*buflen -= len;
    160 	return (0);
    161 }
    162