5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
22 #include "silcstrutil.h"
24 static unsigned char pem_enc[64] =
25 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
27 /* Encodes data into Base 64 encoding. Returns NULL terminated base 64 encoded
30 char *silc_base64_encode(unsigned char *data, SilcUInt32 len)
33 SilcUInt32 bits, c, char_count;
40 pem = silc_calloc(((len * 8 + 5) / 6) + 5, sizeof(*pem));
42 for (i = 0; i < len; i++) {
47 if (char_count == 3) {
48 pem[j++] = pem_enc[bits >> 18];
49 pem[j++] = pem_enc[(bits >> 12) & 0x3f];
50 pem[j++] = pem_enc[(bits >> 6) & 0x3f];
51 pem[j++] = pem_enc[bits & 0x3f];
59 if (char_count != 0) {
60 bits <<= 16 - (8 * char_count);
61 pem[j++] = pem_enc[bits >> 18];
62 pem[j++] = pem_enc[(bits >> 12) & 0x3f];
64 if (char_count == 1) {
68 pem[j++] = pem_enc[(bits >> 6) & 0x3f];
76 /* Same as above but puts newline ('\n') every 72 characters. */
78 char *silc_base64_encode_file(unsigned char *data, SilcUInt32 data_len)
84 pem = silc_base64_encode(data, data_len);
87 pem2 = silc_calloc(len + (len / 72) + 1, sizeof(*pem2));
89 for (i = 0, j = 0, cols = 1; i < len; i++, cols++) {
104 /* Decodes Base 64 into data. Returns the decoded data. */
106 unsigned char *silc_base64_decode(unsigned char *base64,
107 SilcUInt32 base64_len,
111 SilcUInt32 len, c, char_count, bits;
113 static char ialpha[256], decoder[256];
115 for (i = 64 - 1; i >= 0; i--) {
116 ialpha[pem_enc[i]] = 1;
117 decoder[pem_enc[i]] = i;
125 len = strlen(base64);
129 data = silc_calloc(((len * 6) / 8), sizeof(*data));
131 for (i = 0; i < len; i++) {
137 if (c > 127 || !ialpha[c])
143 if (char_count == 4) {
144 data[j++] = bits >> 16;
145 data[j++] = (bits >> 8) & 0xff;
146 data[j++] = bits & 0xff;
160 data[j++] = bits >> 10;
163 data[j++] = bits >> 16;
164 data[j++] = (bits >> 8) & 0xff;
174 /* Concatenates the `src' into `dest'. If `src_len' is more than the
175 size of the `dest' (minus NULL at the end) the `src' will be
178 char *silc_strncat(char *dest, SilcUInt32 dest_size,
179 const char *src, SilcUInt32 src_len)
183 dest[dest_size - 1] = '\0';
185 len = dest_size - 1 - strlen(dest);
188 strncat(dest, src, len);
190 strncat(dest, src, src_len);
196 /* Compares two strings. Strings may include wildcards '*' and '?'.
197 Returns TRUE if strings match. */
199 int silc_string_compare(char *string1, char *string2)
204 char *tmpstr1, *tmpstr2;
206 if (!string1 || !string2)
209 slen1 = strlen(string1);
210 slen2 = strlen(string2);
212 /* See if they are same already */
213 if (!strncmp(string1, string2, slen2) && slen2 == slen1)
217 if (!strchr(string1, '*'))
220 /* Take copies of the original strings as we will change them */
221 tmpstr1 = silc_calloc(slen1 + 1, sizeof(char));
222 memcpy(tmpstr1, string1, slen1);
223 tmpstr2 = silc_calloc(slen2 + 1, sizeof(char));
224 memcpy(tmpstr2, string2, slen2);
226 for (i = 0; i < slen1; i++) {
228 /* * wildcard. Only one * wildcard is possible. */
229 if (tmpstr1[i] == '*')
230 if (!strncmp(tmpstr1, tmpstr2, i)) {
231 memset(tmpstr2, 0, slen2);
232 strncpy(tmpstr2, tmpstr1, i);
237 if (tmpstr1[i] == '?') {
238 if (!strncmp(tmpstr1, tmpstr2, i)) {
239 if (!(slen1 < i + 1))
240 if (tmpstr1[i + 1] != '?' &&
241 tmpstr1[i + 1] != tmpstr2[i + 1])
244 if (!(slen1 < slen2))
250 /* if using *, remove it */
251 if (strchr(tmpstr1, '*'))
252 *strchr(tmpstr1, '*') = 0;
254 if (!strcmp(tmpstr1, tmpstr2)) {
255 memset(tmpstr1, 0, slen1);
256 memset(tmpstr2, 0, slen2);
262 memset(tmpstr1, 0, slen1);
263 memset(tmpstr2, 0, slen2);
269 /* Splits a string containing separator `ch' and returns an array of the
272 char **silc_string_split(const char *string, char ch, int *ret_count)
274 char **splitted = NULL, sep[1], *item, *cp;
282 splitted = silc_calloc(1, sizeof(*splitted));
286 if (!strchr(string, ch)) {
287 splitted[0] = silc_memdup(string, strlen(string));
295 len = strcspn(cp, sep);
296 item = silc_memdup(cp, len);
308 splitted = silc_realloc(splitted, (i + 1) * sizeof(*splitted));
311 splitted[i++] = item;