1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Search routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include "cgi-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include <regex.h>
17*5e7646d2SAndroid Build Coastguard Worker
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker /*
20*5e7646d2SAndroid Build Coastguard Worker * 'cgiCompileSearch()' - Compile a search string.
21*5e7646d2SAndroid Build Coastguard Worker */
22*5e7646d2SAndroid Build Coastguard Worker
23*5e7646d2SAndroid Build Coastguard Worker void * /* O - Search context */
cgiCompileSearch(const char * query)24*5e7646d2SAndroid Build Coastguard Worker cgiCompileSearch(const char *query) /* I - Query string */
25*5e7646d2SAndroid Build Coastguard Worker {
26*5e7646d2SAndroid Build Coastguard Worker regex_t *re; /* Regular expression */
27*5e7646d2SAndroid Build Coastguard Worker char *s, /* Regular expression string */
28*5e7646d2SAndroid Build Coastguard Worker *sptr, /* Pointer into RE string */
29*5e7646d2SAndroid Build Coastguard Worker *sword; /* Pointer to start of word */
30*5e7646d2SAndroid Build Coastguard Worker size_t slen; /* Allocated size of RE string */
31*5e7646d2SAndroid Build Coastguard Worker const char *qptr, /* Pointer into query string */
32*5e7646d2SAndroid Build Coastguard Worker *qend; /* End of current word */
33*5e7646d2SAndroid Build Coastguard Worker const char *prefix; /* Prefix to add to next word */
34*5e7646d2SAndroid Build Coastguard Worker int quoted; /* Word is quoted */
35*5e7646d2SAndroid Build Coastguard Worker size_t wlen; /* Word length */
36*5e7646d2SAndroid Build Coastguard Worker char *lword; /* Last word in query */
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker
39*5e7646d2SAndroid Build Coastguard Worker /*
40*5e7646d2SAndroid Build Coastguard Worker * Range check input...
41*5e7646d2SAndroid Build Coastguard Worker */
42*5e7646d2SAndroid Build Coastguard Worker
43*5e7646d2SAndroid Build Coastguard Worker if (!query)
44*5e7646d2SAndroid Build Coastguard Worker return (NULL);
45*5e7646d2SAndroid Build Coastguard Worker
46*5e7646d2SAndroid Build Coastguard Worker /*
47*5e7646d2SAndroid Build Coastguard Worker * Allocate a regular expression storage structure...
48*5e7646d2SAndroid Build Coastguard Worker */
49*5e7646d2SAndroid Build Coastguard Worker
50*5e7646d2SAndroid Build Coastguard Worker if ((re = (regex_t *)calloc(1, sizeof(regex_t))) == NULL)
51*5e7646d2SAndroid Build Coastguard Worker return (NULL);
52*5e7646d2SAndroid Build Coastguard Worker
53*5e7646d2SAndroid Build Coastguard Worker /*
54*5e7646d2SAndroid Build Coastguard Worker * Allocate a buffer to hold the regular expression string, starting
55*5e7646d2SAndroid Build Coastguard Worker * at 1024 bytes or 3 times the length of the query string, whichever
56*5e7646d2SAndroid Build Coastguard Worker * is greater. We'll expand the string as needed...
57*5e7646d2SAndroid Build Coastguard Worker */
58*5e7646d2SAndroid Build Coastguard Worker
59*5e7646d2SAndroid Build Coastguard Worker slen = strlen(query) * 3;
60*5e7646d2SAndroid Build Coastguard Worker if (slen < 1024)
61*5e7646d2SAndroid Build Coastguard Worker slen = 1024;
62*5e7646d2SAndroid Build Coastguard Worker
63*5e7646d2SAndroid Build Coastguard Worker if ((s = (char *)malloc(slen)) == NULL)
64*5e7646d2SAndroid Build Coastguard Worker {
65*5e7646d2SAndroid Build Coastguard Worker free(re);
66*5e7646d2SAndroid Build Coastguard Worker return (NULL);
67*5e7646d2SAndroid Build Coastguard Worker }
68*5e7646d2SAndroid Build Coastguard Worker
69*5e7646d2SAndroid Build Coastguard Worker /*
70*5e7646d2SAndroid Build Coastguard Worker * Copy the query string to the regular expression, handling basic
71*5e7646d2SAndroid Build Coastguard Worker * AND and OR logic...
72*5e7646d2SAndroid Build Coastguard Worker */
73*5e7646d2SAndroid Build Coastguard Worker
74*5e7646d2SAndroid Build Coastguard Worker prefix = ".*";
75*5e7646d2SAndroid Build Coastguard Worker qptr = query;
76*5e7646d2SAndroid Build Coastguard Worker sptr = s;
77*5e7646d2SAndroid Build Coastguard Worker lword = NULL;
78*5e7646d2SAndroid Build Coastguard Worker
79*5e7646d2SAndroid Build Coastguard Worker while (*qptr)
80*5e7646d2SAndroid Build Coastguard Worker {
81*5e7646d2SAndroid Build Coastguard Worker /*
82*5e7646d2SAndroid Build Coastguard Worker * Skip leading whitespace...
83*5e7646d2SAndroid Build Coastguard Worker */
84*5e7646d2SAndroid Build Coastguard Worker
85*5e7646d2SAndroid Build Coastguard Worker while (isspace(*qptr & 255))
86*5e7646d2SAndroid Build Coastguard Worker qptr ++;
87*5e7646d2SAndroid Build Coastguard Worker
88*5e7646d2SAndroid Build Coastguard Worker if (!*qptr)
89*5e7646d2SAndroid Build Coastguard Worker break;
90*5e7646d2SAndroid Build Coastguard Worker
91*5e7646d2SAndroid Build Coastguard Worker /*
92*5e7646d2SAndroid Build Coastguard Worker * Find the end of the current word...
93*5e7646d2SAndroid Build Coastguard Worker */
94*5e7646d2SAndroid Build Coastguard Worker
95*5e7646d2SAndroid Build Coastguard Worker if (*qptr == '\"' || *qptr == '\'')
96*5e7646d2SAndroid Build Coastguard Worker {
97*5e7646d2SAndroid Build Coastguard Worker /*
98*5e7646d2SAndroid Build Coastguard Worker * Scan quoted string...
99*5e7646d2SAndroid Build Coastguard Worker */
100*5e7646d2SAndroid Build Coastguard Worker
101*5e7646d2SAndroid Build Coastguard Worker quoted = *qptr ++;
102*5e7646d2SAndroid Build Coastguard Worker for (qend = qptr; *qend && *qend != quoted; qend ++);
103*5e7646d2SAndroid Build Coastguard Worker
104*5e7646d2SAndroid Build Coastguard Worker if (!*qend)
105*5e7646d2SAndroid Build Coastguard Worker {
106*5e7646d2SAndroid Build Coastguard Worker /*
107*5e7646d2SAndroid Build Coastguard Worker * No closing quote, error out!
108*5e7646d2SAndroid Build Coastguard Worker */
109*5e7646d2SAndroid Build Coastguard Worker
110*5e7646d2SAndroid Build Coastguard Worker free(s);
111*5e7646d2SAndroid Build Coastguard Worker free(re);
112*5e7646d2SAndroid Build Coastguard Worker
113*5e7646d2SAndroid Build Coastguard Worker if (lword)
114*5e7646d2SAndroid Build Coastguard Worker free(lword);
115*5e7646d2SAndroid Build Coastguard Worker
116*5e7646d2SAndroid Build Coastguard Worker return (NULL);
117*5e7646d2SAndroid Build Coastguard Worker }
118*5e7646d2SAndroid Build Coastguard Worker }
119*5e7646d2SAndroid Build Coastguard Worker else
120*5e7646d2SAndroid Build Coastguard Worker {
121*5e7646d2SAndroid Build Coastguard Worker /*
122*5e7646d2SAndroid Build Coastguard Worker * Scan whitespace-delimited string...
123*5e7646d2SAndroid Build Coastguard Worker */
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker quoted = 0;
126*5e7646d2SAndroid Build Coastguard Worker for (qend = qptr + 1; *qend && !isspace(*qend); qend ++);
127*5e7646d2SAndroid Build Coastguard Worker }
128*5e7646d2SAndroid Build Coastguard Worker
129*5e7646d2SAndroid Build Coastguard Worker wlen = (size_t)(qend - qptr);
130*5e7646d2SAndroid Build Coastguard Worker
131*5e7646d2SAndroid Build Coastguard Worker /*
132*5e7646d2SAndroid Build Coastguard Worker * Look for logic words: AND, OR
133*5e7646d2SAndroid Build Coastguard Worker */
134*5e7646d2SAndroid Build Coastguard Worker
135*5e7646d2SAndroid Build Coastguard Worker if (wlen == 3 && !_cups_strncasecmp(qptr, "AND", 3))
136*5e7646d2SAndroid Build Coastguard Worker {
137*5e7646d2SAndroid Build Coastguard Worker /*
138*5e7646d2SAndroid Build Coastguard Worker * Logical AND with the following text...
139*5e7646d2SAndroid Build Coastguard Worker */
140*5e7646d2SAndroid Build Coastguard Worker
141*5e7646d2SAndroid Build Coastguard Worker if (sptr > s)
142*5e7646d2SAndroid Build Coastguard Worker prefix = ".*";
143*5e7646d2SAndroid Build Coastguard Worker
144*5e7646d2SAndroid Build Coastguard Worker qptr = qend;
145*5e7646d2SAndroid Build Coastguard Worker }
146*5e7646d2SAndroid Build Coastguard Worker else if (wlen == 2 && !_cups_strncasecmp(qptr, "OR", 2))
147*5e7646d2SAndroid Build Coastguard Worker {
148*5e7646d2SAndroid Build Coastguard Worker /*
149*5e7646d2SAndroid Build Coastguard Worker * Logical OR with the following text...
150*5e7646d2SAndroid Build Coastguard Worker */
151*5e7646d2SAndroid Build Coastguard Worker
152*5e7646d2SAndroid Build Coastguard Worker if (sptr > s)
153*5e7646d2SAndroid Build Coastguard Worker prefix = ".*|.*";
154*5e7646d2SAndroid Build Coastguard Worker
155*5e7646d2SAndroid Build Coastguard Worker qptr = qend;
156*5e7646d2SAndroid Build Coastguard Worker }
157*5e7646d2SAndroid Build Coastguard Worker else
158*5e7646d2SAndroid Build Coastguard Worker {
159*5e7646d2SAndroid Build Coastguard Worker /*
160*5e7646d2SAndroid Build Coastguard Worker * Add a search word, making sure we have enough room for the
161*5e7646d2SAndroid Build Coastguard Worker * string + RE overhead...
162*5e7646d2SAndroid Build Coastguard Worker */
163*5e7646d2SAndroid Build Coastguard Worker
164*5e7646d2SAndroid Build Coastguard Worker wlen = (size_t)(sptr - s) + 2 * 4 * wlen + 2 * strlen(prefix) + 11;
165*5e7646d2SAndroid Build Coastguard Worker if (lword)
166*5e7646d2SAndroid Build Coastguard Worker wlen += strlen(lword);
167*5e7646d2SAndroid Build Coastguard Worker
168*5e7646d2SAndroid Build Coastguard Worker if (wlen > slen)
169*5e7646d2SAndroid Build Coastguard Worker {
170*5e7646d2SAndroid Build Coastguard Worker /*
171*5e7646d2SAndroid Build Coastguard Worker * Expand the RE string buffer...
172*5e7646d2SAndroid Build Coastguard Worker */
173*5e7646d2SAndroid Build Coastguard Worker
174*5e7646d2SAndroid Build Coastguard Worker char *temp; /* Temporary string pointer */
175*5e7646d2SAndroid Build Coastguard Worker
176*5e7646d2SAndroid Build Coastguard Worker
177*5e7646d2SAndroid Build Coastguard Worker slen = wlen + 128;
178*5e7646d2SAndroid Build Coastguard Worker temp = (char *)realloc(s, slen);
179*5e7646d2SAndroid Build Coastguard Worker if (!temp)
180*5e7646d2SAndroid Build Coastguard Worker {
181*5e7646d2SAndroid Build Coastguard Worker free(s);
182*5e7646d2SAndroid Build Coastguard Worker free(re);
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker if (lword)
185*5e7646d2SAndroid Build Coastguard Worker free(lword);
186*5e7646d2SAndroid Build Coastguard Worker
187*5e7646d2SAndroid Build Coastguard Worker return (NULL);
188*5e7646d2SAndroid Build Coastguard Worker }
189*5e7646d2SAndroid Build Coastguard Worker
190*5e7646d2SAndroid Build Coastguard Worker sptr = temp + (sptr - s);
191*5e7646d2SAndroid Build Coastguard Worker s = temp;
192*5e7646d2SAndroid Build Coastguard Worker }
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker /*
195*5e7646d2SAndroid Build Coastguard Worker * Add the prefix string...
196*5e7646d2SAndroid Build Coastguard Worker */
197*5e7646d2SAndroid Build Coastguard Worker
198*5e7646d2SAndroid Build Coastguard Worker memcpy(sptr, prefix, strlen(prefix) + 1);
199*5e7646d2SAndroid Build Coastguard Worker sptr += strlen(sptr);
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker /*
202*5e7646d2SAndroid Build Coastguard Worker * Then quote the remaining word characters as needed for the
203*5e7646d2SAndroid Build Coastguard Worker * RE...
204*5e7646d2SAndroid Build Coastguard Worker */
205*5e7646d2SAndroid Build Coastguard Worker
206*5e7646d2SAndroid Build Coastguard Worker sword = sptr;
207*5e7646d2SAndroid Build Coastguard Worker
208*5e7646d2SAndroid Build Coastguard Worker while (qptr < qend)
209*5e7646d2SAndroid Build Coastguard Worker {
210*5e7646d2SAndroid Build Coastguard Worker /*
211*5e7646d2SAndroid Build Coastguard Worker * Quote: ^ . [ $ ( ) | * + ? { \
212*5e7646d2SAndroid Build Coastguard Worker */
213*5e7646d2SAndroid Build Coastguard Worker
214*5e7646d2SAndroid Build Coastguard Worker if (strchr("^.[$()|*+?{\\", *qptr))
215*5e7646d2SAndroid Build Coastguard Worker *sptr++ = '\\';
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker *sptr++ = *qptr++;
218*5e7646d2SAndroid Build Coastguard Worker }
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker *sptr = '\0';
221*5e7646d2SAndroid Build Coastguard Worker
222*5e7646d2SAndroid Build Coastguard Worker /*
223*5e7646d2SAndroid Build Coastguard Worker * For "word1 AND word2", add reciprocal "word2 AND word1"...
224*5e7646d2SAndroid Build Coastguard Worker */
225*5e7646d2SAndroid Build Coastguard Worker
226*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(prefix, ".*") && lword)
227*5e7646d2SAndroid Build Coastguard Worker {
228*5e7646d2SAndroid Build Coastguard Worker char *lword2; /* New "last word" */
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker
231*5e7646d2SAndroid Build Coastguard Worker if ((lword2 = strdup(sword)) == NULL)
232*5e7646d2SAndroid Build Coastguard Worker {
233*5e7646d2SAndroid Build Coastguard Worker free(lword);
234*5e7646d2SAndroid Build Coastguard Worker free(s);
235*5e7646d2SAndroid Build Coastguard Worker free(re);
236*5e7646d2SAndroid Build Coastguard Worker return (NULL);
237*5e7646d2SAndroid Build Coastguard Worker }
238*5e7646d2SAndroid Build Coastguard Worker
239*5e7646d2SAndroid Build Coastguard Worker memcpy(sptr, ".*|.*", 6);
240*5e7646d2SAndroid Build Coastguard Worker sptr += 5;
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker memcpy(sptr, lword2, strlen(lword2) + 1);
243*5e7646d2SAndroid Build Coastguard Worker sptr += strlen(sptr);
244*5e7646d2SAndroid Build Coastguard Worker
245*5e7646d2SAndroid Build Coastguard Worker memcpy(sptr, ".*", 3);
246*5e7646d2SAndroid Build Coastguard Worker sptr += 2;
247*5e7646d2SAndroid Build Coastguard Worker
248*5e7646d2SAndroid Build Coastguard Worker memcpy(sptr, lword, strlen(lword) + 1);
249*5e7646d2SAndroid Build Coastguard Worker sptr += strlen(sptr);
250*5e7646d2SAndroid Build Coastguard Worker
251*5e7646d2SAndroid Build Coastguard Worker free(lword);
252*5e7646d2SAndroid Build Coastguard Worker lword = lword2;
253*5e7646d2SAndroid Build Coastguard Worker }
254*5e7646d2SAndroid Build Coastguard Worker else
255*5e7646d2SAndroid Build Coastguard Worker {
256*5e7646d2SAndroid Build Coastguard Worker if (lword)
257*5e7646d2SAndroid Build Coastguard Worker free(lword);
258*5e7646d2SAndroid Build Coastguard Worker
259*5e7646d2SAndroid Build Coastguard Worker lword = strdup(sword);
260*5e7646d2SAndroid Build Coastguard Worker }
261*5e7646d2SAndroid Build Coastguard Worker
262*5e7646d2SAndroid Build Coastguard Worker prefix = ".*|.*";
263*5e7646d2SAndroid Build Coastguard Worker }
264*5e7646d2SAndroid Build Coastguard Worker
265*5e7646d2SAndroid Build Coastguard Worker /*
266*5e7646d2SAndroid Build Coastguard Worker * Advance to the next string...
267*5e7646d2SAndroid Build Coastguard Worker */
268*5e7646d2SAndroid Build Coastguard Worker
269*5e7646d2SAndroid Build Coastguard Worker if (quoted)
270*5e7646d2SAndroid Build Coastguard Worker qptr ++;
271*5e7646d2SAndroid Build Coastguard Worker }
272*5e7646d2SAndroid Build Coastguard Worker
273*5e7646d2SAndroid Build Coastguard Worker if (lword)
274*5e7646d2SAndroid Build Coastguard Worker free(lword);
275*5e7646d2SAndroid Build Coastguard Worker
276*5e7646d2SAndroid Build Coastguard Worker if (sptr > s)
277*5e7646d2SAndroid Build Coastguard Worker memcpy(sptr, ".*", 3);
278*5e7646d2SAndroid Build Coastguard Worker else
279*5e7646d2SAndroid Build Coastguard Worker {
280*5e7646d2SAndroid Build Coastguard Worker /*
281*5e7646d2SAndroid Build Coastguard Worker * No query data, return NULL...
282*5e7646d2SAndroid Build Coastguard Worker */
283*5e7646d2SAndroid Build Coastguard Worker
284*5e7646d2SAndroid Build Coastguard Worker free(s);
285*5e7646d2SAndroid Build Coastguard Worker free(re);
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker return (NULL);
288*5e7646d2SAndroid Build Coastguard Worker }
289*5e7646d2SAndroid Build Coastguard Worker
290*5e7646d2SAndroid Build Coastguard Worker /*
291*5e7646d2SAndroid Build Coastguard Worker * Compile the regular expression...
292*5e7646d2SAndroid Build Coastguard Worker */
293*5e7646d2SAndroid Build Coastguard Worker
294*5e7646d2SAndroid Build Coastguard Worker if (regcomp(re, s, REG_EXTENDED | REG_ICASE))
295*5e7646d2SAndroid Build Coastguard Worker {
296*5e7646d2SAndroid Build Coastguard Worker free(re);
297*5e7646d2SAndroid Build Coastguard Worker free(s);
298*5e7646d2SAndroid Build Coastguard Worker
299*5e7646d2SAndroid Build Coastguard Worker return (NULL);
300*5e7646d2SAndroid Build Coastguard Worker }
301*5e7646d2SAndroid Build Coastguard Worker
302*5e7646d2SAndroid Build Coastguard Worker /*
303*5e7646d2SAndroid Build Coastguard Worker * Free the RE string and return the new regular expression we compiled...
304*5e7646d2SAndroid Build Coastguard Worker */
305*5e7646d2SAndroid Build Coastguard Worker
306*5e7646d2SAndroid Build Coastguard Worker free(s);
307*5e7646d2SAndroid Build Coastguard Worker
308*5e7646d2SAndroid Build Coastguard Worker return ((void *)re);
309*5e7646d2SAndroid Build Coastguard Worker }
310*5e7646d2SAndroid Build Coastguard Worker
311*5e7646d2SAndroid Build Coastguard Worker
312*5e7646d2SAndroid Build Coastguard Worker /*
313*5e7646d2SAndroid Build Coastguard Worker * 'cgiDoSearch()' - Do a search of some text.
314*5e7646d2SAndroid Build Coastguard Worker */
315*5e7646d2SAndroid Build Coastguard Worker
316*5e7646d2SAndroid Build Coastguard Worker int /* O - Number of matches */
cgiDoSearch(void * search,const char * text)317*5e7646d2SAndroid Build Coastguard Worker cgiDoSearch(void *search, /* I - Search context */
318*5e7646d2SAndroid Build Coastguard Worker const char *text) /* I - Text to search */
319*5e7646d2SAndroid Build Coastguard Worker {
320*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
321*5e7646d2SAndroid Build Coastguard Worker regmatch_t matches[100]; /* RE matches */
322*5e7646d2SAndroid Build Coastguard Worker
323*5e7646d2SAndroid Build Coastguard Worker
324*5e7646d2SAndroid Build Coastguard Worker /*
325*5e7646d2SAndroid Build Coastguard Worker * Range check...
326*5e7646d2SAndroid Build Coastguard Worker */
327*5e7646d2SAndroid Build Coastguard Worker
328*5e7646d2SAndroid Build Coastguard Worker if (!search || !text)
329*5e7646d2SAndroid Build Coastguard Worker return (0);
330*5e7646d2SAndroid Build Coastguard Worker
331*5e7646d2SAndroid Build Coastguard Worker /*
332*5e7646d2SAndroid Build Coastguard Worker * Do a lookup...
333*5e7646d2SAndroid Build Coastguard Worker */
334*5e7646d2SAndroid Build Coastguard Worker
335*5e7646d2SAndroid Build Coastguard Worker if (!regexec((regex_t *)search, text, sizeof(matches) / sizeof(matches[0]),
336*5e7646d2SAndroid Build Coastguard Worker matches, 0))
337*5e7646d2SAndroid Build Coastguard Worker {
338*5e7646d2SAndroid Build Coastguard Worker /*
339*5e7646d2SAndroid Build Coastguard Worker * Figure out the number of matches in the string...
340*5e7646d2SAndroid Build Coastguard Worker */
341*5e7646d2SAndroid Build Coastguard Worker
342*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < (int)(sizeof(matches) / sizeof(matches[0])); i ++)
343*5e7646d2SAndroid Build Coastguard Worker if (matches[i].rm_so < 0)
344*5e7646d2SAndroid Build Coastguard Worker break;
345*5e7646d2SAndroid Build Coastguard Worker
346*5e7646d2SAndroid Build Coastguard Worker return (i);
347*5e7646d2SAndroid Build Coastguard Worker }
348*5e7646d2SAndroid Build Coastguard Worker else
349*5e7646d2SAndroid Build Coastguard Worker return (0);
350*5e7646d2SAndroid Build Coastguard Worker }
351*5e7646d2SAndroid Build Coastguard Worker
352*5e7646d2SAndroid Build Coastguard Worker
353*5e7646d2SAndroid Build Coastguard Worker /*
354*5e7646d2SAndroid Build Coastguard Worker * 'cgiFreeSearch()' - Free a compiled search context.
355*5e7646d2SAndroid Build Coastguard Worker */
356*5e7646d2SAndroid Build Coastguard Worker
357*5e7646d2SAndroid Build Coastguard Worker void
cgiFreeSearch(void * search)358*5e7646d2SAndroid Build Coastguard Worker cgiFreeSearch(void *search) /* I - Search context */
359*5e7646d2SAndroid Build Coastguard Worker {
360*5e7646d2SAndroid Build Coastguard Worker regfree((regex_t *)search);
361*5e7646d2SAndroid Build Coastguard Worker free(search);
362*5e7646d2SAndroid Build Coastguard Worker }
363