Home | History | Annotate | Download | only in nameser
      1 /*	$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 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.1.206.1 2004/03/09 08:33:45 marka Exp";
     24 #else
     25 __RCSID("$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 christos Exp $");
     26 #endif
     27 #endif
     28 
     29 /* Import. */
     30 
     31 #include "arpa_nameser.h"
     32 
     33 #include <ctype.h>
     34 #include <errno.h>
     35 #include <stdio.h>
     36 #include <string.h>
     37 
     38 #ifdef SPRINTF_CHAR
     39 # define SPRINTF(x) strlen(sprintf/**/x)
     40 #else
     41 # define SPRINTF(x) ((size_t)sprintf x)
     42 #endif
     43 
     44 /* Forward. */
     45 
     46 static int	fmt1(int t, char s, char **buf, size_t *buflen);
     47 
     48 /* Macros. */
     49 
     50 #define T(x) do { if ((x) < 0) return (-1); } while(0)
     51 
     52 /* Public. */
     53 
     54 int
     55 ns_format_ttl(u_long src, char *dst, size_t dstlen) {
     56 	char *odst = dst;
     57 	int secs, mins, hours, days, weeks, x;
     58 	char *p;
     59 
     60 	secs = src % 60;   src /= 60;
     61 	mins = src % 60;   src /= 60;
     62 	hours = src % 24;  src /= 24;
     63 	days = src % 7;    src /= 7;
     64 	weeks = src;       src = 0;
     65 
     66 	x = 0;
     67 	if (weeks) {
     68 		T(fmt1(weeks, 'W', &dst, &dstlen));
     69 		x++;
     70 	}
     71 	if (days) {
     72 		T(fmt1(days, 'D', &dst, &dstlen));
     73 		x++;
     74 	}
     75 	if (hours) {
     76 		T(fmt1(hours, 'H', &dst, &dstlen));
     77 		x++;
     78 	}
     79 	if (mins) {
     80 		T(fmt1(mins, 'M', &dst, &dstlen));
     81 		x++;
     82 	}
     83 	if (secs || !(weeks || days || hours || mins)) {
     84 		T(fmt1(secs, 'S', &dst, &dstlen));
     85 		x++;
     86 	}
     87 
     88 	if (x > 1) {
     89 		int ch;
     90 
     91 		for (p = odst; (ch = *p) != '\0'; p++)
     92 			if (isascii(ch) && isupper(ch))
     93 				*p = tolower(ch);
     94 	}
     95 
     96 	return (dst - odst);
     97 }
     98 
     99 #ifndef _LIBC
    100 int
    101 ns_parse_ttl(const char *src, u_long *dst) {
    102 	u_long ttl, tmp;
    103 	int ch, digits, dirty;
    104 
    105 	ttl = 0;
    106 	tmp = 0;
    107 	digits = 0;
    108 	dirty = 0;
    109 	while ((ch = *src++) != '\0') {
    110 		if (!isascii(ch) || !isprint(ch))
    111 			goto einval;
    112 		if (isdigit(ch)) {
    113 			tmp *= 10;
    114 			tmp += (ch - '0');
    115 			digits++;
    116 			continue;
    117 		}
    118 		if (digits == 0)
    119 			goto einval;
    120 		if (islower(ch))
    121 			ch = toupper(ch);
    122 		switch (ch) {
    123 		case 'W':  tmp *= 7;	/*FALLTHROUGH*/
    124 		case 'D':  tmp *= 24;	/*FALLTHROUGH*/
    125 		case 'H':  tmp *= 60;	/*FALLTHROUGH*/
    126 		case 'M':  tmp *= 60;	/*FALLTHROUGH*/
    127 		case 'S':  break;
    128 		default:   goto einval;
    129 		}
    130 		ttl += tmp;
    131 		tmp = 0;
    132 		digits = 0;
    133 		dirty = 1;
    134 	}
    135 	if (digits > 0) {
    136 		if (dirty)
    137 			goto einval;
    138 		else
    139 			ttl += tmp;
    140 	}
    141 	*dst = ttl;
    142 	return (0);
    143 
    144  einval:
    145 	errno = EINVAL;
    146 	return (-1);
    147 }
    148 #endif
    149 
    150 /* Private. */
    151 
    152 static int
    153 fmt1(int t, char s, char **buf, size_t *buflen) {
    154 	char tmp[50];
    155 	size_t len;
    156 
    157 	len = SPRINTF((tmp, "%d%c", t, s));
    158 	if (len + 1 > *buflen)
    159 		return (-1);
    160 	strcpy(*buf, tmp);
    161 	*buf += len;
    162 	*buflen -= len;
    163 	return (0);
    164 }
    165