5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 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; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * These are general utility functions that doesn't belong to any specific
27 * Revision 1.4 2000/07/19 07:04:04 priikone
28 * Minor bug fix in silc_encode_pem
30 * Revision 1.3 2000/07/10 05:34:40 priikone
31 * Added PEM encoding/decoding functions.
33 * Revision 1.2 2000/07/05 06:06:12 priikone
34 * Added file saving with specific mode.
36 * Revision 1.1.1.1 2000/06/27 11:36:55 priikone
37 * Imported from internal CVS/Added Log headers.
42 #include "silcincludes.h"
44 /* Reads a file to a buffer. The allocated buffer is returned. Length of
45 the file read is returned to the return_len argument. */
47 char *silc_file_read(const char *filename, int *return_len)
53 fd = open(filename, O_RDONLY);
55 SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
59 filelen = lseek(fd, (off_t)0L, SEEK_END);
62 if (lseek(fd, (off_t)0L, SEEK_SET) < 0)
66 SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
70 buffer = silc_calloc(filelen + 1, sizeof(char));
72 if ((read(fd, buffer, filelen)) == -1) {
73 memset(buffer, 0, sizeof(buffer));
75 SILC_LOG_ERROR(("Cannot read from file %s: %s", filename,
81 buffer[filelen] = EOF;
83 *return_len = filelen;
87 /* Writes a buffer to the file. */
89 int silc_file_write(const char *filename, const char *buffer, int len)
93 if ((fd = creat(filename, 0644)) == -1) {
94 SILC_LOG_ERROR(("Cannot open file %s for writing: %s", strerror(errno)));
98 if ((write(fd, buffer, len)) == -1) {
99 SILC_LOG_ERROR(("Cannot write to file %s: %s", strerror(errno)));
108 /* Writes a buffer to the file. If the file is created specific mode is
111 int silc_file_write_mode(const char *filename, const char *buffer,
116 if ((fd = creat(filename, mode)) == -1) {
117 SILC_LOG_ERROR(("Cannot open file %s for writing: %s", strerror(errno)));
121 if ((write(fd, buffer, len)) == -1) {
122 SILC_LOG_ERROR(("Cannot write to file %s: %s", strerror(errno)));
131 /* Gets line from a buffer. Stops reading when a newline or EOF occurs.
132 This doesn't remove the newline sign from the destination buffer. The
133 argument begin is returned and should be passed again for the function. */
135 int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin)
137 static int start = 0;
140 memset(dest, 0, destlen);
146 for ( ; start <= srclen; i++, start++) {
150 dest[i] = src[start];
163 /* Checks line for illegal characters. Return -1 when illegal character
164 were found. This is used to check for bad lines when reading data from
165 for example a configuration file. */
167 int silc_check_line(char *buf)
169 /* Illegal characters in line */
170 if (strchr(buf, '#')) return -1;
171 if (strchr(buf, '\'')) return -1;
172 if (strchr(buf, '\\')) return -1;
173 if (strchr(buf, '\r')) return -1;
174 if (strchr(buf, '\a')) return -1;
175 if (strchr(buf, '\b')) return -1;
176 if (strchr(buf, '\f')) return -1;
185 /* Returns current time as string. */
187 char *silc_get_time()
192 curtime = time(NULL);
193 return_time = ctime(&curtime);
194 return_time[strlen(return_time) - 1] = '\0';
199 /* Converts string to capital characters */
201 char *silc_to_upper(char *string)
204 char *ret = silc_calloc(strlen(string) + 1, sizeof(char));
206 for (i = 0; i < strlen(string); i++)
207 ret[i] = toupper(string[i]);
212 /* Compares two strings. Strings may include wildcards * and ?.
213 Returns TRUE if strings match. */
215 int silc_string_compare(char *string1, char *string2)
218 int slen1 = strlen(string1);
219 int slen2 = strlen(string2);
220 char *tmpstr1, *tmpstr2;
222 if (!string1 || !string2)
225 /* See if they are same already */
226 if (!strncmp(string1, string2, strlen(string2)))
230 if (!strchr(string1, '*'))
233 /* Take copies of the original strings as we will change them */
234 tmpstr1 = silc_calloc(slen1 + 1, sizeof(char));
235 memcpy(tmpstr1, string1, slen1);
236 tmpstr2 = silc_calloc(slen2 + 1, sizeof(char));
237 memcpy(tmpstr2, string2, slen2);
239 for (i = 0; i < slen2; i++) {
241 /* * wildcard. Only one * wildcard is possible. */
242 if (tmpstr1[i] == '*')
243 if (!strncmp(tmpstr1, tmpstr2, i)) {
244 memset(tmpstr2, 0, slen2);
245 strncpy(tmpstr2, tmpstr1, i);
250 if (tmpstr1[i] == '?') {
251 if (!strncmp(tmpstr1, tmpstr2, i)) {
252 if (!(slen1 < i + 1))
253 if (tmpstr1[i + 1] != '?' &&
254 tmpstr1[i + 1] != tmpstr2[i + 1])
257 if (!(slen1 < slen2))
262 if (strncmp(tmpstr1, tmpstr2, i))
263 strncpy(tmpstr2, string2, slen2);
268 /* if using *, remove it */
269 if (strchr(tmpstr1, '*'))
270 *strchr(tmpstr1, '*') = 0;
272 if (!strcmp(tmpstr1, tmpstr2)) {
273 memset(tmpstr1, 0, slen1);
274 memset(tmpstr2, 0, slen2);
280 memset(tmpstr1, 0, slen1);
281 memset(tmpstr2, 0, slen2);
287 unsigned char pem_enc[64] =
288 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
290 /* Encodes data into PEM encoding. Returns NULL terminated PEM encoded
291 data string. Note: This is originally public domain code and is
294 char *silc_encode_pem(unsigned char *data, unsigned int len)
297 unsigned int bits, c, char_count;
304 pem = silc_calloc(((len * 8 + 5) / 6) + 5, sizeof(*pem));
306 for (i = 0; i < len; i++) {
311 if (char_count == 3) {
312 pem[j++] = pem_enc[bits >> 18];
313 pem[j++] = pem_enc[(bits >> 12) & 0x3f];
314 pem[j++] = pem_enc[(bits >> 6) & 0x3f];
315 pem[j++] = pem_enc[bits & 0x3f];
323 if (char_count != 0) {
324 bits <<= 16 - (8 * char_count);
325 pem[j++] = pem_enc[bits >> 18];
326 pem[j++] = pem_enc[(bits >> 12) & 0x3f];
328 if (char_count == 1) {
332 pem[j++] = pem_enc[(bits >> 6) & 0x3f];
340 /* Same as above but puts newline ('\n') every 72 characters. */
342 char *silc_encode_pem_file(unsigned char *data, unsigned int data_len)
345 unsigned int len, cols;
348 pem = silc_encode_pem(data, data_len);
351 pem2 = silc_calloc(len + (len / 72) + 1, sizeof(*pem2));
353 for (i = 0, j = 0, cols = 1; i < len; i++, cols++) {
367 /* Decodes PEM into data. Returns the decoded data. Note: This is
368 originally public domain code and is still PD. */
370 unsigned char *silc_decode_pem(unsigned char *pem, unsigned int pem_len,
371 unsigned int *ret_len)
374 unsigned int len, c, char_count, bits;
376 static char ialpha[256], decoder[256];
378 for (i = 64 - 1; i >= 0; i--) {
379 ialpha[pem_enc[i]] = 1;
380 decoder[pem_enc[i]] = i;
392 data = silc_calloc(((len * 6) / 8), sizeof(*data));
394 for (i = 0; i < len; i++) {
400 if (c > 127 || !ialpha[c])
406 if (char_count == 4) {
407 data[j++] = bits >> 16;
408 data[j++] = (bits >> 8) & 0xff;
409 data[j++] = bits & 0xff;
423 data[j++] = bits >> 10;
426 data[j++] = bits >> 16;
427 data[j++] = (bits >> 8) & 0xff;