X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcstrutil.c;h=5ba4c02e271d22d1a8d4731e8d67a475d22fc69a;hp=d1f04883d69d99818031a839b35feda68cc30f8c;hb=9905799a86c606304fd7df2cd401de1740a272a1;hpb=b3e67d3dfa6409755be33f352b5a86fbb094a570 diff --git a/lib/silcutil/silcstrutil.c b/lib/silcutil/silcstrutil.c index d1f04883..5ba4c02e 100644 --- a/lib/silcutil/silcstrutil.c +++ b/lib/silcutil/silcstrutil.c @@ -1,10 +1,10 @@ /* - silcstrutil.c + silcstrutil.c Author: Pekka Riikonen - Copyright (C) 2002 Pekka Riikonen + Copyright (C) 2002 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,15 +18,14 @@ */ /* $Id$ */ -#include "silcincludes.h" +#include "silc.h" #include "silcstrutil.h" static unsigned char pem_enc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* Encodes data into PEM encoding. Returns NULL terminated PEM encoded - data string. Note: This is originally public domain code and is - still PD. */ + data string. */ char *silc_pem_encode(unsigned char *data, SilcUInt32 len) { @@ -102,8 +101,7 @@ char *silc_pem_encode_file(unsigned char *data, SilcUInt32 data_len) return pem2; } -/* Decodes PEM into data. Returns the decoded data. Note: This is - originally public domain code and is still PD. */ +/* Decodes PEM into data. Returns the decoded data. */ unsigned char *silc_pem_decode(unsigned char *pem, SilcUInt32 pem_len, SilcUInt32 *ret_len) @@ -172,239 +170,155 @@ unsigned char *silc_pem_decode(unsigned char *pem, SilcUInt32 pem_len, return data; } -/* Encodes the string `bin' of which encoding is `bin_encoding' to the - UTF-8 encoding into the buffer `utf8' which is of size of `utf8_size'. - Returns the length of the UTF-8 encoded string, or zero (0) on error. - By default `bin_encoding' is ASCII, and the caller needs to know the - encoding of the input string if it is anything else. */ +#ifndef HAVE_SNPRINTF +/* Outputs string according to the `format'. */ -SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, - SilcStringEncoding bin_encoding, - unsigned char *utf8, SilcUInt32 utf8_size) +int silc_snprintf(char *str, SilcUInt32 size, const char *format, ...) { - SilcUInt32 enclen = 0, i, charval = 0; - if (!bin || !bin_len) - return 0; +} +#endif /* HAVE_SNPRINTF */ - for (i = 0; i < bin_len; i++) { - switch (bin_encoding) { - case SILC_STRING_ASCII: - charval = bin[i]; - break; - case SILC_STRING_ASCII_ESC: - break; - case SILC_STRING_BMP: - break; - case SILC_STRING_UNIVERSAL: - break; - } +/* Concatenates the `src' into `dest'. If `src_len' is more than the + size of the `dest' (minus NULL at the end) the `src' will be + truncated to fit. */ - if (charval < 0x80) { - if (utf8) { - if (enclen > utf8_size) - return 0; +char *silc_strncat(char *dest, SilcUInt32 dest_size, + const char *src, SilcUInt32 src_len) +{ + int len; - utf8[enclen] = (unsigned char)charval; - } - enclen++; - } else if (charval < 0x800) { - if (utf8) { - if (enclen + 2 > utf8_size) - return 0; - - utf8[enclen ] = (unsigned char )(((charval >> 6) & 0x1f) | 0xc0); - utf8[enclen + 1] = (unsigned char )((charval & 0x3f) | 0x80); - } - enclen += 2; - } else if (charval < 0x10000) { - if (utf8) { - if (enclen + 3 > utf8_size) - return 0; - - utf8[enclen ] = (unsigned char )(((charval >> 12) & 0xf) | 0xe0); - utf8[enclen + 1] = (unsigned char )(((charval >> 6) & 0x3f) | 0x80); - utf8[enclen + 2] = (unsigned char )((charval & 0x3f) | 0x80); - } - enclen += 3; - } else if (charval < 0x200000) { - if (utf8) { - if (enclen + 4 > utf8_size) - return 0; - - utf8[enclen ] = (unsigned char )(((charval >> 18) & 0x7) | 0xf0); - utf8[enclen + 1] = (unsigned char )(((charval >> 12) & 0x3f) | 0x80); - utf8[enclen + 2] = (unsigned char )(((charval >> 6) & 0x3f) | 0x80); - utf8[enclen + 3] = (unsigned char )((charval & 0x3f) | 0x80); - } - enclen += 4; - } else if (charval < 0x4000000) { - if (utf8) { - if (enclen + 5 > utf8_size) - return 0; - - utf8[enclen ] = (unsigned char )(((charval >> 24) & 0x3) | 0xf8); - utf8[enclen + 1] = (unsigned char )(((charval >> 18) & 0x3f) | 0x80); - utf8[enclen + 2] = (unsigned char )(((charval >> 12) & 0x3f) | 0x80); - utf8[enclen + 3] = (unsigned char )(((charval >> 6) & 0x3f) | 0x80); - utf8[enclen + 4] = (unsigned char )((charval & 0x3f) | 0x80); - } - enclen += 5; - } else { - if (utf8) { - if (enclen + 6 > utf8_size) - return 0; - - utf8[enclen ] = (unsigned char )(((charval >> 30) & 0x1) | 0xfc); - utf8[enclen + 1] = (unsigned char )(((charval >> 24) & 0x3f) | 0x80); - utf8[enclen + 2] = (unsigned char )(((charval >> 18) & 0x3f) | 0x80); - utf8[enclen + 3] = (unsigned char )(((charval >> 12) & 0x3f) | 0x80); - utf8[enclen + 4] = (unsigned char )(((charval >> 6) & 0x3f) | 0x80); - utf8[enclen + 5] = (unsigned char )((charval & 0x3f) | 0x80); - } - enclen += 6; - } + dest[dest_size - 1] = '\0'; + + len = dest_size - 1 - strlen(dest); + if (len < src_len) { + if (len > 0) + strncat(dest, src, len); + } else { + strncat(dest, src, src_len); } - return enclen; + return dest; } -/* Decodes UTF-8 encoded string `utf8' to string of which encoding is - to be `bin_encoding', into the `bin' buffer of size of `bin_size'. - Returns the length of the decoded buffer, or zero (0) on error. - By default `bin_encoding' is ASCII, and the caller needs to know to - which encoding the output string is to be encoded if ASCII is not - desired. */ +/* Compares two strings. Strings may include wildcards '*' and '?'. + Returns TRUE if strings match. */ -SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, - SilcStringEncoding bin_encoding, - unsigned char *bin, SilcUInt32 bin_size) +int silc_string_compare(char *string1, char *string2) { - SilcUInt32 enclen = 0, i, charval; - - if (!utf8 || !utf8_len) - return 0; - - for (i = 0; i < utf8_len; i++) { - if ((utf8[i] & 0x80) == 0x00) { - charval = utf8[i] & 0x7f; - } else if ((utf8[i] & 0xe0) == 0xc0) { - if (utf8_len < 2) - return 0; - - if ((utf8[i + 1] & 0xc0) != 0x80) - return 0; - - charval = (utf8[i++] & 0x1f) << 6; - charval |= utf8[i] & 0x3f; - if (charval < 0x80) - return 0; - } else if ((utf8[i] & 0xf0) == 0xe0) { - if (utf8_len < 3) - return 0; - - if (((utf8[i + 1] & 0xc0) != 0x80) || - ((utf8[i + 2] & 0xc0) != 0x80)) - return 0; - - charval = (utf8[i++] & 0xf) << 12; - charval |= (utf8[i++] & 0x3f) << 6; - charval |= utf8[i] & 0x3f; - if (charval < 0x800) - return 0; - } else if ((utf8[i] & 0xf8) == 0xf0) { - if (utf8_len < 4) - return 0; - - if (((utf8[i + 1] & 0xc0) != 0x80) || - ((utf8[i + 2] & 0xc0) != 0x80) || - ((utf8[i + 3] & 0xc0) != 0x80)) - return 0; - - charval = ((SilcUInt32)(utf8[i++] & 0x7)) << 18; - charval |= (utf8[i++] & 0x3f) << 12; - charval |= (utf8[i++] & 0x3f) << 6; - charval |= utf8[i] & 0x3f; - if (charval < 0x10000) - return 0; - } else if ((utf8[i] & 0xfc) == 0xf8) { - if (utf8_len < 5) - return 0; - - if (((utf8[i + 1] & 0xc0) != 0x80) || - ((utf8[i + 2] & 0xc0) != 0x80) || - ((utf8[i + 3] & 0xc0) != 0x80) || - ((utf8[i + 4] & 0xc0) != 0x80)) - return 0; - - charval = ((SilcUInt32)(utf8[i++] & 0x3)) << 24; - charval |= ((SilcUInt32)(utf8[i++] & 0x3f)) << 18; - charval |= ((SilcUInt32)(utf8[i++] & 0x3f)) << 12; - charval |= (utf8[i++] & 0x3f) << 6; - charval |= utf8[i] & 0x3f; - if (charval < 0x200000) - return 0; - } else if ((utf8[i] & 0xfe) == 0xfc) { - if (utf8_len < 6) - return 0; - - if (((utf8[i + 1] & 0xc0) != 0x80) || - ((utf8[i + 2] & 0xc0) != 0x80) || - ((utf8[i + 3] & 0xc0) != 0x80) || - ((utf8[i + 4] & 0xc0) != 0x80) || - ((utf8[i + 5] & 0xc0) != 0x80)) - return 0; - - charval = ((SilcUInt32)(utf8[i++] & 0x1)) << 30; - charval |= ((SilcUInt32)(utf8[i++] & 0x3f)) << 24; - charval |= ((SilcUInt32)(utf8[i++] & 0x3f)) << 18; - charval |= ((SilcUInt32)(utf8[i++] & 0x3f)) << 12; - charval |= (utf8[i++] & 0x3f) << 6; - charval |= utf8[i] & 0x3f; - if (charval < 0x4000000) - return 0; - } else { - return 0; - } + int i; + int slen1; + int slen2; + char *tmpstr1, *tmpstr2; + + if (!string1 || !string2) + return FALSE; + + slen1 = strlen(string1); + slen2 = strlen(string2); + + /* See if they are same already */ + if (!strncmp(string1, string2, slen2) && slen2 == slen1) + return TRUE; + + if (slen2 < slen1) + if (!strchr(string1, '*')) + return FALSE; + + /* Take copies of the original strings as we will change them */ + tmpstr1 = silc_calloc(slen1 + 1, sizeof(char)); + memcpy(tmpstr1, string1, slen1); + tmpstr2 = silc_calloc(slen2 + 1, sizeof(char)); + memcpy(tmpstr2, string2, slen2); + + for (i = 0; i < slen1; i++) { + + /* * wildcard. Only one * wildcard is possible. */ + if (tmpstr1[i] == '*') + if (!strncmp(tmpstr1, tmpstr2, i)) { + memset(tmpstr2, 0, slen2); + strncpy(tmpstr2, tmpstr1, i); + break; + } - switch (bin_encoding) { - case SILC_STRING_ASCII: - if (bin) { - if (enclen + 1 > bin_size) - return 0; + /* ? wildcard */ + if (tmpstr1[i] == '?') { + if (!strncmp(tmpstr1, tmpstr2, i)) { + if (!(slen1 < i + 1)) + if (tmpstr1[i + 1] != '?' && + tmpstr1[i + 1] != tmpstr2[i + 1]) + continue; - bin[enclen] = (unsigned char)charval; + if (!(slen1 < slen2)) + tmpstr2[i] = '?'; } - enclen++; - break; - case SILC_STRING_ASCII_ESC: - return 0; - break; - case SILC_STRING_BMP: - return 0; - break; - case SILC_STRING_UNIVERSAL: - return 0; - break; } } - return enclen; -} + /* if using *, remove it */ + if (strchr(tmpstr1, '*')) + *strchr(tmpstr1, '*') = 0; -/* Returns the length of UTF-8 encoded string if the `bin' of - encoding of `bin_encoding' is encoded with silc_utf8_encode. */ + if (!strcmp(tmpstr1, tmpstr2)) { + memset(tmpstr1, 0, slen1); + memset(tmpstr2, 0, slen2); + silc_free(tmpstr1); + silc_free(tmpstr2); + return TRUE; + } -SilcUInt32 silc_utf8_encoded_len(const unsigned char *bin, SilcUInt32 bin_len, - SilcStringEncoding bin_encoding) -{ - return silc_utf8_encode(bin, bin_len, bin_encoding, NULL, 0); + memset(tmpstr1, 0, slen1); + memset(tmpstr2, 0, slen2); + silc_free(tmpstr1); + silc_free(tmpstr2); + return FALSE; } -/* Returns TRUE if the `utf8' string of length of `utf8_len' is valid - UTF-8 encoded string, FALSE if it is not UTF-8 encoded string. */ +/* Splits a string containing separator `ch' and returns an array of the + splitted strings. */ -bool silc_utf8_valid(const unsigned char *utf8, SilcUInt32 utf8_len) +char **silc_string_split(const char *string, char ch, int *ret_count) { - return silc_utf8_decode(utf8, utf8_len, 0, NULL, 0) != 0; + char **splitted = NULL, sep[1], *item, *cp; + int i = 0, len; + + if (!string) + return NULL; + if (!ret_count) + return NULL; + + splitted = silc_calloc(1, sizeof(*splitted)); + if (!splitted) + return NULL; + + if (!strchr(string, ch)) { + splitted[0] = silc_memdup(string, strlen(string)); + *ret_count = 1; + return splitted; + } + + sep[0] = ch; + cp = (char *)string; + while(cp) { + len = strcspn(cp, sep); + item = silc_memdup(cp, len); + if (!item) { + silc_free(splitted); + return NULL; + } + + cp += len; + if (strlen(cp) == 0) + cp = NULL; + else + cp++; + + splitted = silc_realloc(splitted, (i + 1) * sizeof(*splitted)); + if (!splitted) + return NULL; + splitted[i++] = item; + } + *ret_count = i; + + return splitted; }