michael@0: /* $NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 christos Exp $ */ michael@0: michael@0: /* michael@0: * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") michael@0: * Copyright (c) 1996,1999 by Internet Software Consortium. michael@0: * michael@0: * Permission to use, copy, modify, and distribute this software for any michael@0: * purpose with or without fee is hereby granted, provided that the above michael@0: * copyright notice and this permission notice appear in all copies. michael@0: * michael@0: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES michael@0: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF michael@0: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR michael@0: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES michael@0: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN michael@0: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT michael@0: * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. michael@0: */ michael@0: michael@0: /* michael@0: * This version of this file is derived from Android 2.3 "Gingerbread", michael@0: * which contains uncredited changes by Android/Google developers. It has michael@0: * been modified in 2011 for use in the Android build of Mozilla Firefox by michael@0: * Mozilla contributors (including Michael Edwards , michael@0: * and Steve Workman ). michael@0: * These changes are offered under the same license as the original NetBSD michael@0: * file, whose copyright and license are unchanged above. michael@0: */ michael@0: michael@0: #define ANDROID_CHANGES 1 michael@0: #define MOZILLA_NECKO_EXCLUDE_CODE 1 michael@0: michael@0: #include michael@0: #ifndef lint michael@0: #ifdef notdef michael@0: static const char rcsid[] = "Id: ns_ttl.c,v 1.1.206.1 2004/03/09 08:33:45 marka Exp"; michael@0: #else michael@0: __RCSID("$NetBSD: ns_ttl.c,v 1.2 2004/05/20 20:35:05 christos Exp $"); michael@0: #endif michael@0: #endif michael@0: michael@0: /* Import. */ michael@0: michael@0: #include "arpa_nameser.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #ifdef SPRINTF_CHAR michael@0: # define SPRINTF(x) strlen(sprintf/**/x) michael@0: #else michael@0: # define SPRINTF(x) ((size_t)sprintf x) michael@0: #endif michael@0: michael@0: /* Forward. */ michael@0: michael@0: static int fmt1(int t, char s, char **buf, size_t *buflen); michael@0: michael@0: /* Macros. */ michael@0: michael@0: #define T(x) do { if ((x) < 0) return (-1); } while(0) michael@0: michael@0: /* Public. */ michael@0: michael@0: int michael@0: ns_format_ttl(u_long src, char *dst, size_t dstlen) { michael@0: char *odst = dst; michael@0: int secs, mins, hours, days, weeks, x; michael@0: char *p; michael@0: michael@0: secs = src % 60; src /= 60; michael@0: mins = src % 60; src /= 60; michael@0: hours = src % 24; src /= 24; michael@0: days = src % 7; src /= 7; michael@0: weeks = src; src = 0; michael@0: michael@0: x = 0; michael@0: if (weeks) { michael@0: T(fmt1(weeks, 'W', &dst, &dstlen)); michael@0: x++; michael@0: } michael@0: if (days) { michael@0: T(fmt1(days, 'D', &dst, &dstlen)); michael@0: x++; michael@0: } michael@0: if (hours) { michael@0: T(fmt1(hours, 'H', &dst, &dstlen)); michael@0: x++; michael@0: } michael@0: if (mins) { michael@0: T(fmt1(mins, 'M', &dst, &dstlen)); michael@0: x++; michael@0: } michael@0: if (secs || !(weeks || days || hours || mins)) { michael@0: T(fmt1(secs, 'S', &dst, &dstlen)); michael@0: x++; michael@0: } michael@0: michael@0: if (x > 1) { michael@0: int ch; michael@0: michael@0: for (p = odst; (ch = *p) != '\0'; p++) michael@0: if (isascii(ch) && isupper(ch)) michael@0: *p = tolower(ch); michael@0: } michael@0: michael@0: return (dst - odst); michael@0: } michael@0: michael@0: #ifndef MOZILLA_NECKO_EXCLUDE_CODE michael@0: #ifndef _LIBC michael@0: int michael@0: ns_parse_ttl(const char *src, u_long *dst) { michael@0: u_long ttl, tmp; michael@0: int ch, digits, dirty; michael@0: michael@0: ttl = 0; michael@0: tmp = 0; michael@0: digits = 0; michael@0: dirty = 0; michael@0: while ((ch = *src++) != '\0') { michael@0: if (!isascii(ch) || !isprint(ch)) michael@0: goto einval; michael@0: if (isdigit(ch)) { michael@0: tmp *= 10; michael@0: tmp += (ch - '0'); michael@0: digits++; michael@0: continue; michael@0: } michael@0: if (digits == 0) michael@0: goto einval; michael@0: if (islower(ch)) michael@0: ch = toupper(ch); michael@0: switch (ch) { michael@0: case 'W': tmp *= 7; /*FALLTHROUGH*/ michael@0: case 'D': tmp *= 24; /*FALLTHROUGH*/ michael@0: case 'H': tmp *= 60; /*FALLTHROUGH*/ michael@0: case 'M': tmp *= 60; /*FALLTHROUGH*/ michael@0: case 'S': break; michael@0: default: goto einval; michael@0: } michael@0: ttl += tmp; michael@0: tmp = 0; michael@0: digits = 0; michael@0: dirty = 1; michael@0: } michael@0: if (digits > 0) { michael@0: if (dirty) michael@0: goto einval; michael@0: else michael@0: ttl += tmp; michael@0: } michael@0: *dst = ttl; michael@0: return (0); michael@0: michael@0: einval: michael@0: errno = EINVAL; michael@0: return (-1); michael@0: } michael@0: #endif michael@0: #endif michael@0: michael@0: /* Private. */ michael@0: michael@0: static int michael@0: fmt1(int t, char s, char **buf, size_t *buflen) { michael@0: char tmp[50]; michael@0: size_t len; michael@0: michael@0: len = SPRINTF((tmp, "%d%c", t, s)); michael@0: if (len + 1 > *buflen) michael@0: return (-1); michael@0: strcpy(*buf, tmp); michael@0: *buf += len; michael@0: *buflen -= len; michael@0: return (0); michael@0: }