xref: /aosp_15_r20/external/libcups/cgi-bin/search.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
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