Initial revision
[silc.git] / lib / silccore / silcutil.c
1 /*
2
3   silcutil.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 Pekka Riikonen
8
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.
13   
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.
18
19 */
20 /*
21  * These are general utility functions that doesn't belong to any specific
22  * group of routines.
23  */
24 /*
25  * $Id$
26  * $Log$
27  * Revision 1.1  2000/06/27 11:36:55  priikone
28  * Initial revision
29  *
30  *
31  */
32
33 #include "silcincludes.h"
34
35 /* Reads a file to a buffer. The allocated buffer is returned. Length of
36    the file read is returned to the return_len argument. */
37
38 char *silc_file_read(const char *filename, int *return_len)
39 {
40   int fd;
41   char *buffer;
42   int filelen;
43
44   fd = open(filename, O_RDONLY);
45   if (fd < 0) {
46     SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
47     return NULL;
48   }
49
50   filelen = lseek(fd, (off_t)0L, SEEK_END);
51   lseek(fd, (off_t)0L, SEEK_SET);  
52
53   if (filelen < 0) {
54     SILC_LOG_ERROR(("Cannot open file %s: %s", filename, strerror(errno)));
55     return NULL;
56   }
57   
58   buffer = silc_calloc(filelen + 1, sizeof(char));
59   
60   if ((read(fd, buffer, filelen)) == -1) {
61     memset(buffer, 0, sizeof(buffer));
62     close(fd);
63     SILC_LOG_ERROR(("Cannot read from file %s: %s", filename,
64                     strerror(errno)));
65     return NULL;
66   }
67
68   close(fd);
69   buffer[filelen] = EOF;
70   
71   *return_len = filelen;
72   return buffer;
73 }
74
75 /* Writes a buffer to the file. */
76
77 int silc_file_write(const char *filename, const char *buffer, int len)
78 {
79   int fd;
80         
81   if ((fd = creat(filename, 0644)) == -1) {
82     SILC_LOG_ERROR(("Cannot open file %s for writing: %s", strerror(errno)));
83     return -1;
84   }
85   
86   if ((write(fd, buffer, len)) == -1) {
87     SILC_LOG_ERROR(("Cannot write to file %s: %s", strerror(errno)));
88     return -1;
89   }
90
91   close(fd);
92   
93   return 0;
94 }
95
96 /* Gets line from a buffer. Stops reading when a newline or EOF occurs.
97    This doesn't remove the newline sign from the destination buffer. The
98    argument begin is returned and should be passed again for the function. */
99
100 int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin)
101 {
102   static int start = 0;
103   int i;
104   
105   memset(dest, 0, destlen);
106   
107   if (begin != start)
108     start = 0;
109   
110   i = 0;
111   for ( ; start <= srclen; i++, start++) {
112     if (i > destlen)
113       return -1;
114     
115     dest[i] = src[start];
116     
117     if (dest[i] == EOF) 
118       return EOF;
119     
120     if (dest[i] == '\n') 
121       break;
122   }
123   start++;
124   
125   return start;
126 }
127
128 /* Checks line for illegal characters. Return -1 when illegal character
129    were found. This is used to check for bad lines when reading data from
130    for example a configuration file. */
131
132 int silc_check_line(char *buf) 
133 {
134   /* Illegal characters in line */
135   if (strchr(buf, '#')) return -1;
136   if (strchr(buf, '\'')) return -1;
137   if (strchr(buf, '\\')) return -1;
138   if (strchr(buf, '\r')) return -1;
139   if (strchr(buf, '\a')) return -1;
140   if (strchr(buf, '\b')) return -1;
141   if (strchr(buf, '\f')) return -1;
142   
143   /* Empty line */
144   if (buf[0] == '\n')
145     return -1;
146   
147   return 0;
148 }
149
150 /* Returns current time as string. */
151
152 char *silc_get_time()
153 {
154   time_t curtime;
155   char *return_time;
156
157   curtime = time(NULL);
158   return_time = ctime(&curtime);
159   return_time[strlen(return_time) - 1] = '\0';
160
161   return return_time;
162 }
163
164 /* Converts string to capital characters */
165
166 char *silc_to_upper(char *string)
167 {
168   int i;
169   char *ret = silc_calloc(strlen(string) + 1, sizeof(char));
170
171   for (i = 0; i < strlen(string); i++)
172     ret[i] = toupper(string[i]);
173
174   return ret;
175 }
176
177 /* Compares two strings. Strings may include wildcards * and ?.
178    Returns TRUE if strings match. */
179
180 int silc_string_compare(char *string1, char *string2)
181 {
182   int i;
183   int slen1 = strlen(string1);
184   int slen2 = strlen(string2);
185   char *tmpstr1, *tmpstr2;
186
187   if (!string1 || !string2)
188     return FALSE;
189
190   /* See if they are same already */
191   if (!strncmp(string1, string2, strlen(string2)))
192     return TRUE;
193
194   if (slen2 < slen1)
195     if (!strchr(string1, '*'))
196       return FALSE;
197   
198   /* Take copies of the original strings as we will change them */
199   tmpstr1 = silc_calloc(slen1 + 1, sizeof(char));
200   memcpy(tmpstr1, string1, slen1);
201   tmpstr2 = silc_calloc(slen2 + 1, sizeof(char));
202   memcpy(tmpstr2, string2, slen2);
203   
204   for (i = 0; i < slen2; i++) {
205     
206     /* * wildcard. Only one * wildcard is possible. */
207     if (tmpstr1[i] == '*')
208       if (!strncmp(tmpstr1, tmpstr2, i)) {
209         memset(tmpstr2, 0, slen2);
210         strncpy(tmpstr2, tmpstr1, i);
211         break;
212       }
213     
214     /* ? wildcard */
215     if (tmpstr1[i] == '?') {
216       if (!strncmp(tmpstr1, tmpstr2, i)) {
217         if (!(slen1 < i + 1))
218           if (tmpstr1[i + 1] != '?' &&
219               tmpstr1[i + 1] != tmpstr2[i + 1])
220             continue;
221         
222         if (!(slen1 < slen2))
223           tmpstr2[i] = '?';
224       }
225 #if 0
226     } else {
227       if (strncmp(tmpstr1, tmpstr2, i))
228         strncpy(tmpstr2, string2, slen2);
229 #endif
230     }
231   }
232   
233   /* if using *, remove it */
234   if (strchr(tmpstr1, '*'))
235     *strchr(tmpstr1, '*') = 0;
236   
237   if (!strcmp(tmpstr1, tmpstr2)) {
238     memset(tmpstr1, 0, slen1);
239     memset(tmpstr2, 0, slen2);
240     silc_free(tmpstr1);
241     silc_free(tmpstr2);
242     return TRUE;
243   }
244   
245   memset(tmpstr1, 0, slen1);
246   memset(tmpstr2, 0, slen2);
247   silc_free(tmpstr1);
248   silc_free(tmpstr2);
249   return FALSE;
250 }