1 /*- 2 * SPDX-License-Identifier: ISC 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 #ifndef lint 21 static const char rcsid[] = "$Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp $"; 22 #endif 23 #include <sys/cdefs.h> 24 __FBSDID("$FreeBSD$"); 25 26 /* Import. */ 27 28 #include "port_before.h" 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 #include "port_after.h" 38 39 #ifdef SPRINTF_CHAR 40 # define SPRINTF(x) strlen(sprintf/**/x) 41 #else 42 # define SPRINTF(x) ((size_t)sprintf x) 43 #endif 44 45 /* Forward. */ 46 47 static int fmt1(int t, char s, char **buf, size_t *buflen); 48 49 /* Macros. */ 50 51 #define T(x) if ((x) < 0) return (-1); else (void)NULL 52 53 /* Public. */ 54 55 int 56 ns_format_ttl(u_long src, char *dst, size_t dstlen) { 57 char *odst = dst; 58 int secs, mins, hours, days, weeks, x; 59 char *p; 60 61 secs = src % 60; src /= 60; 62 mins = src % 60; src /= 60; 63 hours = src % 24; src /= 24; 64 days = src % 7; src /= 7; 65 weeks = src; src = 0; 66 67 x = 0; 68 if (weeks) { 69 T(fmt1(weeks, 'W', &dst, &dstlen)); 70 x++; 71 } 72 if (days) { 73 T(fmt1(days, 'D', &dst, &dstlen)); 74 x++; 75 } 76 if (hours) { 77 T(fmt1(hours, 'H', &dst, &dstlen)); 78 x++; 79 } 80 if (mins) { 81 T(fmt1(mins, 'M', &dst, &dstlen)); 82 x++; 83 } 84 if (secs || !(weeks || days || hours || mins)) { 85 T(fmt1(secs, 'S', &dst, &dstlen)); 86 x++; 87 } 88 89 if (x > 1) { 90 int ch; 91 92 for (p = odst; (ch = *p) != '\0'; p++) 93 if (isascii(ch) && isupper(ch)) 94 *p = tolower(ch); 95 } 96 97 return (dst - odst); 98 } 99 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; 124 case 'D': tmp *= 24; 125 case 'H': tmp *= 60; 126 case 'M': tmp *= 60; 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 } else if (!dirty) 141 goto einval; 142 *dst = ttl; 143 return (0); 144 145 einval: 146 errno = EINVAL; 147 return (-1); 148 } 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 166 /*! \file */ 167