diff options
Diffstat (limited to 'maildrop/search.C')
| -rw-r--r-- | maildrop/search.C | 404 | 
1 files changed, 102 insertions, 302 deletions
| diff --git a/maildrop/search.C b/maildrop/search.C index 33a5792..d2756bb 100644 --- a/maildrop/search.C +++ b/maildrop/search.C @@ -32,8 +32,6 @@ void Search::cleanup()  int	Search::init(const char *expr, const char *opts)  { -	int	dummy; -  	match_header=0;  	match_body=0;  	weight1=1; @@ -49,84 +47,67 @@ int	Search::init(const char *expr, const char *opts)  		if (strchr(opts, 'w'))	match_body=1;  	} -	Buffer b; - -	b="MAILDROP_OLD_REGEXP"; - -	const char *p=GetVarStr(b); - -	if (atoi(p ? p:"0") == 0) -	{ -		const char *errptr; - -		cleanup(); +	const char *errptr; -		if (strchr(opts, 'w')) -		{ -			b="Pattern option 'w' is valid only when MAILDROP_OLD_REGEXP is set\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} +	cleanup(); -		int errindex; +	int errindex; -		pcre_regexp=pcre_compile(expr, -					 strchr(opts, 'D') ? 0:PCRE_CASELESS, -					 &errptr, -					 &errindex, 0); +	pcre_regexp=pcre_compile(expr, +				 strchr(opts, 'D') ? 0:PCRE_CASELESS, +				 &errptr, +				 &errindex, 0); -		if (!pcre_regexp) -		{ -			b="Invalid regular expression, offset "; -			b.append((unsigned long)errindex); -			b += " of: "; -			b += expr; -			b += ": "; -			b += errptr; -			b += "\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} +	if (!pcre_regexp) +	{ +		Buffer b; + +		b="Invalid regular expression, offset "; +		b.append((unsigned long)errindex); +		b += " of: "; +		b += expr; +		b += ": "; +		b += errptr; +		b += "\n"; +		b += '\0'; +		merr.write(b); +		return -1; +	} -		pcre_regexp_extra=pcre_study(pcre_regexp, 0, -					     &errptr); +	pcre_regexp_extra=pcre_study(pcre_regexp, 0, &errptr); -		if (errptr) -		{ -			b="Error parsing regular expression: "; -			b += expr; -			b += ": "; -			b += errptr; -			b += "\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} +	if (errptr) +	{ +		Buffer b; + +		b="Error parsing regular expression: "; +		b += expr; +		b += ": "; +		b += errptr; +		b += "\n"; +		b += '\0'; +		merr.write(b); +		return -1; +	} -		int cnt=0; +	int cnt=0; -		pcre_fullinfo(pcre_regexp, pcre_regexp_extra, -			      PCRE_INFO_CAPTURECOUNT, &cnt); +	pcre_fullinfo(pcre_regexp, pcre_regexp_extra, +		      PCRE_INFO_CAPTURECOUNT, &cnt); -		pcre_vector_count=(cnt+1)*3; +	pcre_vector_count=(cnt+1)*3; -		pcre_vectors=(int *)malloc(pcre_vector_count*sizeof(int)); +	pcre_vectors=(int *)malloc(pcre_vector_count*sizeof(int)); -		if (!pcre_vectors) -		{ -			b=strerror(errno); -			b += "\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} -	}				 -	else +	if (!pcre_vectors)  	{ -		if (regexp.Compile(expr, strchr(opts, 'D') ? 1:0, dummy)) -			return (-1); +		Buffer b; + +		b=strerror(errno); +		b += "\n"; +		b += '\0'; +		merr.write(b); +		return -1;  	}  	while (*opts) @@ -157,8 +138,7 @@ int Search::find(Message &msg, MessageInfo &,  	if (init(expr, opts))	return (-1);  	msg.Rewind(); -	return (strchr(opts, 'w') ? findinsection(msg, expr, foreachp): -		findinline(msg, expr, foreachp)); +	return (findinline(msg, expr, foreachp));  }  int Search::find(const char *str, const char *expr, const char *opts, @@ -185,57 +165,26 @@ int Search::find(const char *str, const char *expr, const char *opts,  	for (;;)  	{ -		if (pcre_regexp) -		{ -			match_count=pcre_exec(pcre_regexp, pcre_regexp_extra, -					      orig_str, strlen(orig_str), -					      startoffset, -					      0, -					      pcre_vectors, -					      pcre_vector_count); -			if (match_count <= 0) -				break; -			startoffset=pcre_vectors[1]; - -			score += weight1; -			weight1 *= weight2; - -			if (!scoring_match || foreachp) -			{ -				init_match_vars(orig_str, match_count, -						pcre_vectors, foreachp); -				if (!foreachp) -					break; -			} -			continue; -		} - -		ReMatchStr match(str); - -		if ( regexp.Match(match))	break; +		match_count=pcre_exec(pcre_regexp, pcre_regexp_extra, +				      orig_str, strlen(orig_str), +				      startoffset, +				      0, +				      pcre_vectors, +				      pcre_vector_count); +		if (match_count <= 0) +			break; +		startoffset=pcre_vectors[1];  		score += weight1;  		weight1 *= weight2;  		if (!scoring_match || foreachp)  		{ -			match.SetCurrentPos(0); -			init_match_vars(match, foreachp); +			init_match_vars(orig_str, match_count, +					pcre_vectors, foreachp);  			if (!foreachp) -				break;	// No need for more. -		} - -	Re *p; -	off_t	c=0; - -		for (p= ®exp; p; ) -			c += p->MatchCount( &p ); -		if (c == 0) -		{ -			if (!*str)	break; -			++c; +				break;  		} -		str += c;  	}  	return (0);  } @@ -291,85 +240,6 @@ int	eof;  				merr.write(msg);  			} -			if (pcre_regexp) -			{ -				const char *orig_str=current_line; -				int match_count; - -				match_count=pcre_exec(pcre_regexp, -						      pcre_regexp_extra, -						      orig_str, -						      strlen(orig_str), -						      0, -						      0, -						      pcre_vectors, -						      pcre_vector_count); - -				if (match_count > 0) -				{ -					score += weight1; -					weight1 *= weight2; - -					if (!scoring_match || foreachp) -					{ -						init_match_vars(orig_str, -								match_count, -								pcre_vectors, -								foreachp); -						if (!foreachp) -							return (0); -					} -				} -				else	if (VerboseLevel() > 2) -					merr.write("Not matched.\n"); -			} -			else -			{ -				ReMatchStr match(current_line); - -				if (regexp.Match(match) == 0) -				{ -					score += weight1; -					weight1 *= weight2; -					if (!scoring_match || foreachp) -					{ -						match.SetCurrentPos(0); -						init_match_vars(match, -								foreachp); -						if (!foreachp) -							return (0); -					} -				} -				else	if (VerboseLevel() > 2) -					merr.write("Not matched.\n"); -			} -		} -		if ( c == '\n')	break; -		current_line=next_line; -	} -	if (!match_body || eof)	return (0); - -	while (current_line.reset(), msg.appendline(current_line) == 0) -	{ -		current_line.pop(); -		current_line += '\0'; - -		if (VerboseLevel() > 2) -		{ -		Buffer	msg; - -			msg="Matching /"; -			msg.append(expr); -			msg.append("/ against "); -			msg += current_line; -			msg.pop();	// Trailing null byte. -			msg += '\n'; -			msg += '\0'; -			merr.write(msg); -		} - -		if (pcre_regexp) -		{  			const char *orig_str=current_line;  			int match_count; @@ -399,93 +269,61 @@ int	eof;  			}  			else	if (VerboseLevel() > 2)  				merr.write("Not matched.\n"); +		} +		if ( c == '\n')	break; +		current_line=next_line; +	} +	if (!match_body || eof)	return (0); -			continue; +	while (current_line.reset(), msg.appendline(current_line) == 0) +	{ +		current_line.pop(); +		current_line += '\0'; + +		if (VerboseLevel() > 2) +		{ +		Buffer	msg; + +			msg="Matching /"; +			msg.append(expr); +			msg.append("/ against "); +			msg += current_line; +			msg.pop();	// Trailing null byte. +			msg += '\n'; +			msg += '\0'; +			merr.write(msg);  		} -		ReMatchStr match(current_line); +		const char *orig_str=current_line; +		int match_count; -		if (regexp.Match(match) == 0) +		match_count=pcre_exec(pcre_regexp, +				      pcre_regexp_extra, +				      orig_str, +				      strlen(orig_str), +				      0, +				      0, +				      pcre_vectors, +				      pcre_vector_count); + +		if (match_count > 0)  		{  			score += weight1;  			weight1 *= weight2; +  			if (!scoring_match || foreachp)  			{ -				match.SetCurrentPos(0); -				init_match_vars(match, foreachp); +				init_match_vars(orig_str, +						match_count, +						pcre_vectors, +						foreachp);  				if (!foreachp)  					return (0);  			}  		}  		else	if (VerboseLevel() > 2) -				merr.write("Not matched.\n"); -	} -	return (0); -} - -/////////////////////////////////////////////////////////////////////////// -// -// Search anchored in the entire message. -// -/////////////////////////////////////////////////////////////////////////// +			merr.write("Not matched.\n"); -int Search::findinsection(Message &msg, const char *expr, Buffer *foreachp) -{ -	if (!match_header && !match_body)	return (0);	// Huh? - -	if (VerboseLevel() > 2) -	{ -	Buffer	m; - -		m="Matching /"; -		m.append(expr); -		m.append("/ against"); -		if (match_header) -			m.append(" header"); -		if (match_body) -			m.append(" body"); -		m += '\n'; -		m += '\0'; -		merr.write(m); -	} - -	if (!match_header) -	{ -	Buffer	dummy; - -		do -		{ -			dummy.reset(); -			if (msg.appendline(dummy) < 0)	return (0); -						// No message body, give up. -		} while (dummy.Length() != 1 || -				*(const char *)dummy != '\n'); -	} - -off_t start_pos=msg.tell(); -ReMatchMsg	match_msg(&msg, !match_body, match_header); - -	while ( match_msg.CurrentChar() >= 0 && regexp.Match(match_msg) == 0) -	{ -		score += weight1; -		weight1 *= weight2; - -		if (!scoring_match || foreachp) -		{ -			match_msg.SetCurrentPos(start_pos); -			init_match_vars(match_msg, foreachp); -			if (!foreachp) -				break;	// No need for more. -		} - -	Re *p; -	off_t c=0; - -		for (p= ®exp; p; ) -			c += p->MatchCount( &p ); -		if (c == 0)	++c; -		start_pos += c; -		match_msg.SetCurrentPos(start_pos);  	}  	return (0);  } @@ -533,41 +371,3 @@ void Search::init_match_vars(const char *str, int nranges, int *offsets,  		SetVar(varname, v);  	}  } - -void Search::init_match_vars(ReMatch &m, Buffer *foreachp) -{ -Re	*p; -Buffer	buf; -Buffer	varname; -unsigned long varnamecount=1; - -	varname="MATCH"; -	for (p= ®exp; p; ) -	{ -	Re	*q=p; -	unsigned	count=p->MatchCount(&p); - -		buf.reset(); -		while (count) -		{ -			buf.push( m.NextChar() ); -			count--; -		} - -		if ( !q->IsDummy()) -		{ -			if (foreachp) -			{ -				*foreachp += buf; -				*foreachp += '\0'; -			} -			else -			{ -				SetVar(varname, buf); -				++varnamecount; -				varname="MATCH"; -				varname.append(varnamecount); -			} -		} -	} -} | 
