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 23static 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 41static 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 49int 50ns_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 96int 97ns_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 149static int 150fmt1(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