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