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