1135446Strhodes/* 2262706Serwin * Copyright (C) 2004-2007, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 1999-2001, 2003 Internet Software Consortium. 4135446Strhodes * 5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18262706Serwin/* 19262706Serwin * Copyright (c) 1990, 1993 20262706Serwin * The Regents of the University of California. All rights reserved. 21262706Serwin * 22262706Serwin * Redistribution and use in source and binary forms, with or without 23262706Serwin * modification, are permitted provided that the following conditions 24262706Serwin * are met: 25262706Serwin * 1. Redistributions of source code must retain the above copyright 26262706Serwin * notice, this list of conditions and the following disclaimer. 27262706Serwin * 2. Redistributions in binary form must reproduce the above copyright 28262706Serwin * notice, this list of conditions and the following disclaimer in the 29262706Serwin * documentation and/or other materials provided with the distribution. 30262706Serwin * 3. Neither the name of the University nor the names of its contributors 31262706Serwin * may be used to endorse or promote products derived from this software 32262706Serwin * without specific prior written permission. 33262706Serwin * 34262706Serwin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 35262706Serwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 36262706Serwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 37262706Serwin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 38262706Serwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 39262706Serwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 40262706Serwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 41262706Serwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 42262706Serwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 43262706Serwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 44262706Serwin * SUCH DAMAGE. 45262706Serwin */ 46135446Strhodes 47170222Sdougb/*! \file */ 48170222Sdougb 49135446Strhodes#include <config.h> 50135446Strhodes 51135446Strhodes#include <ctype.h> 52135446Strhodes 53170222Sdougb#include <isc/mem.h> 54170222Sdougb#include <isc/print.h> 55170222Sdougb#include <isc/region.h> 56135446Strhodes#include <isc/string.h> 57170222Sdougb#include <isc/util.h> 58135446Strhodes 59135446Strhodesstatic char digits[] = "0123456789abcdefghijklmnoprstuvwxyz"; 60135446Strhodes 61135446Strhodesisc_uint64_t 62135446Strhodesisc_string_touint64(char *source, char **end, int base) { 63135446Strhodes isc_uint64_t tmp; 64135446Strhodes isc_uint64_t overflow; 65135446Strhodes char *s = source; 66135446Strhodes char *o; 67135446Strhodes char c; 68135446Strhodes 69135446Strhodes if ((base < 0) || (base == 1) || (base > 36)) { 70135446Strhodes *end = source; 71135446Strhodes return (0); 72135446Strhodes } 73135446Strhodes 74135446Strhodes while (*s != 0 && isascii(*s&0xff) && isspace(*s&0xff)) 75135446Strhodes s++; 76135446Strhodes if (*s == '+' /* || *s == '-' */) 77135446Strhodes s++; 78135446Strhodes if (base == 0) { 79135446Strhodes if (*s == '0' && (*(s+1) == 'X' || *(s+1) == 'x')) { 80135446Strhodes s += 2; 81135446Strhodes base = 16; 82135446Strhodes } else if (*s == '0') 83135446Strhodes base = 8; 84135446Strhodes else 85135446Strhodes base = 10; 86135446Strhodes } 87135446Strhodes if (*s == 0) { 88135446Strhodes *end = source; 89135446Strhodes return (0); 90135446Strhodes } 91135446Strhodes overflow = ~0; 92135446Strhodes overflow /= base; 93135446Strhodes tmp = 0; 94135446Strhodes 95135446Strhodes while ((c = *s) != 0) { 96143731Sdougb c = tolower(c&0xff); 97135446Strhodes /* end ? */ 98135446Strhodes if ((o = strchr(digits, c)) == NULL) { 99135446Strhodes *end = s; 100135446Strhodes return (tmp); 101135446Strhodes } 102135446Strhodes /* end ? */ 103135446Strhodes if ((o - digits) >= base) { 104135446Strhodes *end = s; 105135446Strhodes return (tmp); 106135446Strhodes } 107135446Strhodes /* overflow ? */ 108135446Strhodes if (tmp > overflow) { 109135446Strhodes *end = source; 110135446Strhodes return (0); 111135446Strhodes } 112135446Strhodes tmp *= base; 113135446Strhodes /* overflow ? */ 114135446Strhodes if ((tmp + (o - digits)) < tmp) { 115135446Strhodes *end = source; 116135446Strhodes return (0); 117135446Strhodes } 118135446Strhodes tmp += o - digits; 119135446Strhodes s++; 120135446Strhodes } 121135446Strhodes *end = s; 122135446Strhodes return (tmp); 123135446Strhodes} 124135446Strhodes 125170222Sdougbisc_result_t 126170222Sdougbisc_string_copy(char *target, size_t size, const char *source) { 127170222Sdougb REQUIRE(size > 0U); 128170222Sdougb 129170222Sdougb if (strlcpy(target, source, size) >= size) { 130170222Sdougb memset(target, ISC_STRING_MAGIC, size); 131170222Sdougb return (ISC_R_NOSPACE); 132170222Sdougb } 133170222Sdougb 134170222Sdougb ENSURE(strlen(target) < size); 135170222Sdougb 136170222Sdougb return (ISC_R_SUCCESS); 137170222Sdougb} 138170222Sdougb 139170222Sdougbvoid 140170222Sdougbisc_string_copy_truncate(char *target, size_t size, const char *source) { 141170222Sdougb REQUIRE(size > 0U); 142170222Sdougb 143170222Sdougb strlcpy(target, source, size); 144170222Sdougb 145170222Sdougb ENSURE(strlen(target) < size); 146170222Sdougb} 147170222Sdougb 148170222Sdougbisc_result_t 149170222Sdougbisc_string_append(char *target, size_t size, const char *source) { 150170222Sdougb REQUIRE(size > 0U); 151170222Sdougb REQUIRE(strlen(target) < size); 152170222Sdougb 153170222Sdougb if (strlcat(target, source, size) >= size) { 154170222Sdougb memset(target, ISC_STRING_MAGIC, size); 155170222Sdougb return (ISC_R_NOSPACE); 156170222Sdougb } 157170222Sdougb 158170222Sdougb ENSURE(strlen(target) < size); 159170222Sdougb 160170222Sdougb return (ISC_R_SUCCESS); 161170222Sdougb} 162170222Sdougb 163170222Sdougbvoid 164170222Sdougbisc_string_append_truncate(char *target, size_t size, const char *source) { 165170222Sdougb REQUIRE(size > 0U); 166170222Sdougb REQUIRE(strlen(target) < size); 167170222Sdougb 168170222Sdougb strlcat(target, source, size); 169170222Sdougb 170170222Sdougb ENSURE(strlen(target) < size); 171170222Sdougb} 172170222Sdougb 173170222Sdougbisc_result_t 174170222Sdougbisc_string_printf(char *target, size_t size, const char *format, ...) { 175170222Sdougb va_list args; 176170222Sdougb size_t n; 177170222Sdougb 178170222Sdougb REQUIRE(size > 0U); 179170222Sdougb 180170222Sdougb va_start(args, format); 181170222Sdougb n = vsnprintf(target, size, format, args); 182170222Sdougb va_end(args); 183170222Sdougb 184170222Sdougb if (n >= size) { 185170222Sdougb memset(target, ISC_STRING_MAGIC, size); 186170222Sdougb return (ISC_R_NOSPACE); 187170222Sdougb } 188170222Sdougb 189170222Sdougb ENSURE(strlen(target) < size); 190170222Sdougb 191170222Sdougb return (ISC_R_SUCCESS); 192170222Sdougb} 193170222Sdougb 194170222Sdougbvoid 195225361Sdougbisc_string_printf_truncate(char *target, size_t size, const char *format, ...) 196225361Sdougb{ 197170222Sdougb va_list args; 198170222Sdougb 199170222Sdougb REQUIRE(size > 0U); 200170222Sdougb 201170222Sdougb va_start(args, format); 202225361Sdougb /* check return code? */ 203225361Sdougb (void)vsnprintf(target, size, format, args); 204170222Sdougb va_end(args); 205170222Sdougb 206170222Sdougb ENSURE(strlen(target) < size); 207170222Sdougb} 208170222Sdougb 209135446Strhodeschar * 210170222Sdougbisc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source) { 211170222Sdougb char *target; 212170222Sdougb 213170222Sdougb REQUIRE(mctx != NULL); 214170222Sdougb REQUIRE(source != NULL); 215170222Sdougb 216170222Sdougb target = (char *) isc_mem_allocate(mctx, source->length + 1); 217170222Sdougb if (target != NULL) { 218262706Serwin memmove(source->base, target, source->length); 219170222Sdougb target[source->length] = '\0'; 220170222Sdougb } 221170222Sdougb 222170222Sdougb return (target); 223170222Sdougb} 224170222Sdougb 225170222Sdougbchar * 226135446Strhodesisc_string_separate(char **stringp, const char *delim) { 227135446Strhodes char *string = *stringp; 228135446Strhodes char *s; 229135446Strhodes const char *d; 230135446Strhodes char sc, dc; 231135446Strhodes 232135446Strhodes if (string == NULL) 233135446Strhodes return (NULL); 234135446Strhodes 235135446Strhodes for (s = string; (sc = *s) != '\0'; s++) 236135446Strhodes for (d = delim; (dc = *d) != '\0'; d++) 237135446Strhodes if (sc == dc) { 238135446Strhodes *s++ = '\0'; 239135446Strhodes *stringp = s; 240135446Strhodes return (string); 241135446Strhodes } 242135446Strhodes *stringp = NULL; 243135446Strhodes return (string); 244135446Strhodes} 245135446Strhodes 246135446Strhodessize_t 247135446Strhodesisc_string_strlcpy(char *dst, const char *src, size_t size) 248135446Strhodes{ 249135446Strhodes char *d = dst; 250135446Strhodes const char *s = src; 251135446Strhodes size_t n = size; 252135446Strhodes 253135446Strhodes /* Copy as many bytes as will fit */ 254135446Strhodes if (n != 0U && --n != 0U) { 255135446Strhodes do { 256135446Strhodes if ((*d++ = *s++) == 0) 257135446Strhodes break; 258135446Strhodes } while (--n != 0U); 259135446Strhodes } 260135446Strhodes 261135446Strhodes /* Not enough room in dst, add NUL and traverse rest of src */ 262135446Strhodes if (n == 0U) { 263135446Strhodes if (size != 0U) 264135446Strhodes *d = '\0'; /* NUL-terminate dst */ 265135446Strhodes while (*s++) 266135446Strhodes ; 267135446Strhodes } 268135446Strhodes 269135446Strhodes return(s - src - 1); /* count does not include NUL */ 270135446Strhodes} 271135446Strhodes 272135446Strhodessize_t 273135446Strhodesisc_string_strlcat(char *dst, const char *src, size_t size) 274135446Strhodes{ 275135446Strhodes char *d = dst; 276135446Strhodes const char *s = src; 277135446Strhodes size_t n = size; 278135446Strhodes size_t dlen; 279135446Strhodes 280135446Strhodes /* Find the end of dst and adjust bytes left but don't go past end */ 281135446Strhodes while (n-- != 0U && *d != '\0') 282135446Strhodes d++; 283135446Strhodes dlen = d - dst; 284135446Strhodes n = size - dlen; 285135446Strhodes 286135446Strhodes if (n == 0U) 287135446Strhodes return(dlen + strlen(s)); 288135446Strhodes while (*s != '\0') { 289135446Strhodes if (n != 1U) { 290135446Strhodes *d++ = *s; 291135446Strhodes n--; 292135446Strhodes } 293135446Strhodes s++; 294135446Strhodes } 295135446Strhodes *d = '\0'; 296135446Strhodes 297135446Strhodes return(dlen + (s - src)); /* count does not include NUL */ 298135446Strhodes} 299262706Serwin 300262706Serwinchar * 301262706Serwinisc_string_strcasestr(const char *str, const char *search) { 302262706Serwin char c, sc, *s; 303262706Serwin size_t len; 304262706Serwin 305262706Serwin if ((c = *search++) != 0) { 306262706Serwin c = tolower((unsigned char) c); 307262706Serwin len = strlen(search); 308262706Serwin do { 309262706Serwin do { 310262706Serwin if ((sc = *str++) == 0) 311262706Serwin return (NULL); 312262706Serwin } while ((char) tolower((unsigned char) sc) != c); 313262706Serwin } while (strncasecmp(str, search, len) != 0); 314262706Serwin str--; 315262706Serwin } 316262706Serwin DE_CONST(str, s); 317262706Serwin return (s); 318262706Serwin 319262706Serwin} 320