regex-match.c 4.62 KB
Newer Older
1
/*
2
 * $Id: regex-match.c,v 1.34 2003/07/12 22:26:34 ceder Exp $
Per Cederqvist's avatar
Per Cederqvist committed
3
 * Copyright (C) 1992-1999, 2001-2002  Lysator Academic Computer Association.
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *
 * This file is part of the LysKOM server.
 * 
 * LysKOM is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 1, or (at your option) 
 * any later version.
 * 
 * LysKOM is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LysKOM; see the file COPYING.  If not, write to
 * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
 * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
 * MA 02139, USA.
 *
 * Please mail bug reports to bug-lyskom@lysator.liu.se. 
 */

/*
 * Regexp matching
 */

David Byers's avatar
David Byers committed
30
31
32
33
34

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

Per Cederqvist's avatar
Per Cederqvist committed
35
36
#include <stdio.h>
#include <setjmp.h>
Per Cederqvist's avatar
Per Cederqvist committed
37
#include <sys/types.h>
38
#include "timewrap.h"
David Byers's avatar
David Byers committed
39
40
41
#ifdef HAVE_STDLIB_H
#  include <stdlib.h>
#endif
David Byers's avatar
Server  
David Byers committed
42
43
44
#ifdef HAVE_STRING_H
#  include <string.h>
#endif
45
46

#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
47
48
49
50
51
#include "misc-types.h"
#include "kom-types.h"
#include "services.h"
#include "regex.h"
#include "server/smalloc.h"
Per Cederqvist's avatar
Per Cederqvist committed
52
#include "cache.h"
Per Cederqvist's avatar
Per Cederqvist committed
53
#include "kom-errno.h"
Per Cederqvist's avatar
Per Cederqvist committed
54
#include "com.h"
55
#include "async.h"
Per Cederqvist's avatar
Per Cederqvist committed
56
#include "connections.h"
Per Cederqvist's avatar
Per Cederqvist committed
57
58
#include "manipulate.h"
#include "log.h"
David Byers's avatar
David Byers committed
59
60
#include "kom-config.h"
#include "param.h"
61
62

static Success
David Byers's avatar
Server  
David Byers committed
63
64
lookup_regexp (Connection        *conn,
               const String       regexp,
65
66
67
	       Conf_z_info_list  *result,
	       Bool	          want_persons,
	       Bool	          want_confs)
68
69
{
    struct re_pattern_buffer pat_buf;
Per Cederqvist's avatar
Per Cederqvist committed
70
71
    Conf_no conf_no;
    String name = EMPTY_STRING;
Per Cederqvist's avatar
Per Cederqvist committed
72
    const char *errmsg;
73
    Conf_type type;
74

75
76
    /* FIXME (bug 163): It is unnecessary to allocate this much if
       only one conference matches. */
77
78
    result->confs = tmp_alloc (cached_no_of_existing_conferences()
			       * sizeof(Conf_z_info));
79
80
    result->no_of_confs = 0;

Per Cederqvist's avatar
Per Cederqvist committed
81
82
    re_syntax_options = RE_SYNTAX_GREP;

83
    pat_buf.translate = NULL;
David Byers's avatar
David Byers committed
84

85
86
87
88
89
    /* We have to use malloc() instead of smalloc() when allocating
       the fastmap, since regfree will use free() to free the memory.
       If malloc fails here we simply continue without a fastmap.  The
       match will be a little slower, but that is not fatal.  */
    pat_buf.fastmap = malloc(256);
90
91
92
    pat_buf.allocated = 0;
    pat_buf.buffer = 0;

Per Cederqvist's avatar
Per Cederqvist committed
93
    if ((errmsg =
94
	 re_compile_pattern((char*)regexp.string, s_strlen(regexp), &pat_buf))
Per Cederqvist's avatar
Per Cederqvist committed
95
	!= NULL)
96
    {
Per Cederqvist's avatar
Per Cederqvist committed
97
	regfree(&pat_buf);
98
        err_stat = 0;
99
100
101
102
103
104
	kom_errno = KOM_REGEX_ERROR;
	return FAILURE;
    }

    for (conf_no = 0; (conf_no = traverse_conference(conf_no)) != 0;)
    {
105
106
	type = cached_get_conf_type(conf_no);
	if ((type.letter_box ? want_persons : want_confs)
107
	    &&  access_perm(conf_no, conn, read_protected) > none)
108
	{
Per Cederqvist's avatar
Per Cederqvist committed
109
	    name = cached_get_name(conf_no);
110
111
	    switch ( re_search (&pat_buf,
				(char*)name.string, s_strlen(name), 0,
112
113
114
115
116
				s_strlen(name), NULL) )
	    {
	    case -1:
		break;
	    case -2:
117
		kom_log("Internal error in regex.\n");
118
119
120
		break;
	    default:
		/* It matched. (Ignore where it matched). */
121
122
123
		result->confs[result->no_of_confs].conf_no = conf_no;
		result->confs[result->no_of_confs].name = name;
		result->confs[result->no_of_confs++].type = type;
124
125
126
127
128
		break;
	    }
	}
    }

Per Cederqvist's avatar
Per Cederqvist committed
129
130
131
    regfree(&pat_buf);

    return OK;
132
133
}

134
135
136
137
138
139
140
141
142
143
144
145
146
147
static void
downgrade(Conf_z_info_list *in,
	  Conf_no_list *out)
{
    int ix;

    out->conf_nos = tmp_alloc(sizeof(Conf_no) * in->no_of_confs);
    out->no_of_confs = in->no_of_confs;
    for (ix = 0; ix < in->no_of_confs; ix++)
    {
	out->conf_nos[ix] = in->confs[ix].conf_no;
    }
}

148
149
150
151
Success
re_lookup_person (const String  regexp,
		  Conf_no_list  *result)
{
152
153
154
    Conf_z_info_list tmp;
    Success retval;

David Byers's avatar
Server  
David Byers committed
155
156
    CHK_CONNECTION(FAILURE);
    retval = lookup_regexp(active_connection, regexp, &tmp, TRUE, FALSE);
157
158
159
    if (retval == OK)
	downgrade(&tmp, result);
    return retval;
160
161
162
163
164
165
166
}


Success
re_lookup_conf (const String  regexp,
		Conf_no_list  *result)
{
167
168
169
    Conf_z_info_list tmp;
    Success retval;

David Byers's avatar
Server  
David Byers committed
170
171
    CHK_CONNECTION(FAILURE);
    retval = lookup_regexp(active_connection, regexp, &tmp, FALSE, TRUE);
172
173
174
175
176
177
178
179
180
181
182
    if (retval == OK)
	downgrade(&tmp, result);
    return retval;
}

Success
re_z_lookup (const String  regexp,
	     int want_persons,
	     int want_confs,
	     Conf_z_info_list *result)
{
David Byers's avatar
Server  
David Byers committed
183
184
185
    CHK_CONNECTION(FAILURE);
    return lookup_regexp(active_connection, regexp, result,
                         want_persons, want_confs);
186
}