1 /*:ts=8*/
2 /*****************************************************************************
3 * FIDOGATE --- Gateway UNIX Mail/News <-> FTN NetMail/EchoMail
4 *
5 * $Id: rematch.c,v 4.10 2004/08/22 20:19:11 n0ll Exp $
6 *
7 * Regular expression (POSIX functions) handling for FIDOGATE
8 *
9 *****************************************************************************
10 * Copyright (C) 1990-2004
11 * _____ _____
12 * | |___ | Martin Junius <mj.at.n0ll.dot.net>
13 * | | | | | | Radiumstr. 18
14 * |_|_|_|@home| D-51069 Koeln, Germany
15 *
16 * This file is part of FIDOGATE.
17 *
18 * FIDOGATE is free software; you can redistribute it and/or modify it
19 * under the terms of the GNU General Public License as published by the
20 * Free Software Foundation; either version 2, or (at your option) any
21 * later version.
22 *
23 * FIDOGATE is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with FIDOGATE; see the file COPYING. If not, write to the Free
30 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
31 *****************************************************************************/
32
33 #include "fidogate.h"
34
35
36 #ifdef HAS_POSIX_REGEX /******************************************************/
37
38 #include <regex.h>
39
40
41
42 /*
43 * List of regular expressions
44 */
45 typedef struct st_regex {
46 struct st_regex *next;
47 char *re_s;
48 regex_t re_c;
49 } Regex;
50
51
52 static Regex *regex_list = NULL;
53 static Regex *regex_last = NULL;
54
55
56
57 /*
58 * Alloc and init new Regex struct
59 */
regex_new(void)60 static Regex *regex_new(void)
61 {
62 Regex *p;
63
64 p = (Regex *)xmalloc(sizeof(Regex));
65
66 /* Init */
67 p->next = NULL;
68 p->re_s = NULL;
69
70 return p;
71 }
72
73
74
75 /*
76 * Create new Regex struct for string
77 */
regex_parse_line(char * s)78 static Regex *regex_parse_line(char *s)
79 {
80 Regex *p;
81 int err;
82
83 /* New regex entry */
84 p = regex_new();
85
86 p->re_s = strsave(s);
87 err = regcomp(&p->re_c, p->re_s, REG_EXTENDED|REG_ICASE);
88 if(err) {
89 logit("WARNING: error compiling regex %s", p->re_s);
90 xfree(p);
91 return NULL;
92 }
93
94 debug(15, "regex: pattern=%s", p->re_s);
95
96 return p;
97 }
98
99
100
101 /*
102 * Put regex into linked list
103 */
regex_do_entry(char * s)104 static int regex_do_entry(char *s)
105 {
106 Regex *p;
107
108 p = regex_parse_line(s);
109 if(!p)
110 return ERROR;
111
112 /* Put into linked list */
113 if(regex_list)
114 regex_last->next = p;
115 else
116 regex_list = p;
117 regex_last = p;
118
119 return OK;
120 }
121
122
123
124 /*
125 * Match string against regex list
126 */
127 #define MAXREGMATCH 10
128
129 static regmatch_t regex_pmatch[MAXREGMATCH];
130
131
regex_match(const char * s)132 int regex_match(const char *s)
133 {
134 Regex *p;
135
136 for(p=regex_list; p; p=p->next)
137 {
138 if(regexec(&p->re_c, s, MAXREGMATCH, regex_pmatch, 0) == OK)
139 return TRUE;
140 }
141 return FALSE;
142 }
143
144
145
146 /*
147 * Get i'th sub-expression from regex match
148 */
regex_match_sub(int i)149 static regmatch_t *regex_match_sub(int i)
150 {
151 return i<0 || i>=MAXREGMATCH ? NULL : ®ex_pmatch[i];
152 }
153
154
155
156 /*
157 * Copy i'th sub-expression to string buffer
158 */
str_regex_match_sub(char * buf,size_t len,int idx,const char * s)159 char *str_regex_match_sub(char *buf, size_t len, int idx, const char *s)
160 {
161 regmatch_t *p;
162 int i, j;
163
164 p = regex_match_sub(idx);
165 if(p == NULL)
166 {
167 buf[0] = 0;
168 return NULL;
169 }
170
171 for(i=0, j=p->rm_so; i<len-1 && j<p->rm_eo; i++, j++)
172 buf[i] = s[j];
173 buf[i] = 0;
174
175 return buf;
176 }
177
178
179
180 /*
181 * Initialize regex list
182 */
regex_init(void)183 void regex_init(void)
184 {
185 char *s;
186
187 /* regex patterns from fidogate.conf */
188 for(s = cf_get_string("Regex1stLine",TRUE);
189 s;
190 s = cf_get_string("Regex1stLine",FALSE) )
191 regex_do_entry(s);
192 }
193
194
195 #endif /**HAS_POSIX_REGEX*****************************************************/
196
197
198
199
200 /***** TEST ******************************************************************/
201
202 #ifdef TEST
203
204 #ifdef HAS_POSIX_REGEX
debug_subs(void)205 void debug_subs(void)
206 {
207 int i;
208
209 printf("pmatch[]:");
210 for(i=0; i<MAXREGMATCH; i++)
211 if(regex_pmatch[i].rm_so != -1)
212 printf(" %d-%d", regex_pmatch[i].rm_so, regex_pmatch[i].rm_eo);
213 printf("\n");
214 }
215 #endif
216
217
218 /*
219 * Function test
220 */
main(int argc,char * argv[])221 int main(int argc, char *argv[])
222 {
223 #ifdef HAS_POSIX_REGEX
224 char buf[MAXINETADDR];
225
226 regex_init();
227
228 # if 0
229 do
230 {
231 printf("Enter regex pattern [ENTER=end of list]: ");
232 fflush(stdout);
233 fgets(buffer, sizeof(buffer), stdin);
234 strip_crlf(buffer);
235 if(buffer[0])
236 regex_do_entry(buffer);
237 }
238 while(buffer[0]);
239
240 printf("\n");
241 # endif
242
243 /* Read strings to match */
244 do
245 {
246 printf("Enter string [ENTER=end]: ");
247 fflush(stdout);
248 fgets(buffer, sizeof(buffer), stdin);
249 strip_crlf(buffer);
250 if(buffer[0])
251 {
252 if(regex_match(buffer))
253 {
254 printf("MATCH, ");
255 debug_subs();
256 str_regex_match_sub(buf, sizeof(buf), 1, buffer);
257 printf(" (1) = \"%s\"\n", buf);
258 }
259 else
260 {
261 printf("NO MATCH\n");
262 }
263 }
264 }
265 while(buffer[0]);
266 #endif
267
268 exit(0);
269 }
270
271 #endif /**TEST**/
272