2011-11-19 21:25:44 +01:00
/*
* rules . c , SJ
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <piler.h>
# include "rules.h"
2018-11-03 15:02:54 +01:00
void reset_rule_condition ( struct rule_cond * rule_cond ) {
memset ( rule_cond - > domain , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > from , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > to , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > subject , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > body , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > _size , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > attachment_name , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > attachment_type , 0 , SMALLBUFSIZE ) ;
memset ( rule_cond - > _attachment_size , 0 , SMALLBUFSIZE ) ;
rule_cond - > size = 0 ;
rule_cond - > attachment_size = 0 ;
rule_cond - > spam = 0 ;
rule_cond - > days = 0 ;
rule_cond - > folder_id = 0 ;
}
2018-09-29 08:43:50 +02:00
void load_rules ( struct session_data * sdata , struct node * xhash [ ] , char * table ) {
2011-11-19 21:25:44 +01:00
char s [ SMALLBUFSIZE ] ;
2015-08-28 22:50:28 +02:00
struct rule_cond rule_cond ;
2017-08-11 18:18:45 +02:00
struct sql sql ;
2013-05-05 11:57:14 +02:00
2018-11-03 15:02:54 +01:00
reset_rule_condition ( & rule_cond ) ;
2011-11-19 21:25:44 +01:00
2015-08-28 22:50:28 +02:00
snprintf ( s , sizeof ( s ) - 1 , " SELECT `domain`, `from`, `to`, `subject`, `body`, `_size`, `size`, `attachment_name`, `attachment_type`, `_attachment_size`, `attachment_size`, `spam`, `days`, `folder_id` FROM `%s` " , table ) ;
2011-11-19 21:25:44 +01:00
2017-08-11 18:18:45 +02:00
if ( prepare_sql_statement ( sdata , & sql , s ) = = ERR ) return ;
2013-05-05 11:57:14 +02:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2013-05-05 11:57:14 +02:00
2017-08-11 18:18:45 +02:00
if ( p_exec_stmt ( sdata , & sql ) = = OK ) {
2015-12-18 22:38:52 +01:00
2017-08-11 18:18:45 +02:00
p_bind_init ( & sql ) ;
2015-12-18 22:38:52 +01:00
2017-08-11 18:18:45 +02:00
sql . sql [ sql . pos ] = & rule_cond . domain [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . domain ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . from [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . from ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . to [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . to ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . subject [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . subject ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . body [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . body ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . _size [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . _size ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & rule_cond . size ; sql . type [ sql . pos ] = TYPE_LONG ; sql . len [ sql . pos ] = sizeof ( rule_cond . size ) ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . attachment_name [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . attachment_name ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . attachment_type [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . attachment_type ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = & rule_cond . _attachment_size [ 0 ] ; sql . type [ sql . pos ] = TYPE_STRING ; sql . len [ sql . pos ] = sizeof ( rule_cond . _attachment_size ) - 2 ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & rule_cond . attachment_size ; sql . type [ sql . pos ] = TYPE_LONG ; sql . len [ sql . pos ] = sizeof ( rule_cond . attachment_size ) ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & rule_cond . spam ; sql . type [ sql . pos ] = TYPE_LONG ; sql . len [ sql . pos ] = sizeof ( rule_cond . spam ) ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & rule_cond . days ; sql . type [ sql . pos ] = TYPE_LONG ; sql . len [ sql . pos ] = sizeof ( rule_cond . days ) ; sql . pos + + ;
sql . sql [ sql . pos ] = ( char * ) & rule_cond . folder_id ; sql . type [ sql . pos ] = TYPE_LONG ; sql . len [ sql . pos ] = sizeof ( rule_cond . folder_id ) ; sql . pos + + ;
2015-12-18 22:38:52 +01:00
2017-08-11 18:18:45 +02:00
p_store_results ( & sql ) ;
while ( p_fetch_results ( & sql ) = = OK ) {
append_rule ( xhash , & rule_cond ) ;
2018-11-03 15:02:54 +01:00
reset_rule_condition ( & rule_cond ) ;
2015-12-18 22:38:52 +01:00
}
2017-08-11 18:18:45 +02:00
p_free_results ( & sql ) ;
2013-05-05 11:57:14 +02:00
2011-11-19 21:25:44 +01:00
}
2017-08-11 18:18:45 +02:00
close_prepared_statement ( & sql ) ;
2011-11-19 21:25:44 +01:00
}
2017-08-11 18:18:45 +02:00
int append_rule ( struct node * xhash [ ] , struct rule_cond * rule_cond ) {
2013-08-14 14:24:30 +02:00
struct node * q , * Q = NULL , * node ;
struct rule * rule ;
int rc = 0 ;
2011-11-19 21:25:44 +01:00
2013-08-14 14:24:30 +02:00
if ( ( node = malloc ( sizeof ( struct node ) ) ) = = NULL ) return rc ;
2011-11-19 21:25:44 +01:00
2013-08-14 14:24:30 +02:00
memset ( node , 0 , sizeof ( struct node ) ) ;
node - > r = NULL ;
2017-08-11 18:18:45 +02:00
rule = create_rule_item ( rule_cond ) ;
2013-08-14 14:24:30 +02:00
if ( rule = = NULL ) {
free ( node ) ;
2015-08-28 22:50:28 +02:00
syslog ( LOG_INFO , " could not load rule=%s/%s/%s/%s/%s/%s,%d " , rule_cond - > domain , rule_cond - > from , rule_cond - > to , rule_cond - > subject , rule_cond - > body , rule_cond - > _size , rule_cond - > size ) ;
2013-08-14 14:24:30 +02:00
return rc ;
2011-11-19 21:25:44 +01:00
}
2013-08-14 14:24:30 +02:00
node - > str = rule ;
2011-11-19 21:25:44 +01:00
2013-08-14 14:24:30 +02:00
q = xhash [ 0 ] ;
while ( q ! = NULL ) {
Q = q ;
q = q - > r ;
2011-11-19 21:25:44 +01:00
}
2013-08-14 14:24:30 +02:00
if ( Q = = NULL ) xhash [ 0 ] = node ;
else {
Q - > r = node ;
}
rc = 1 ;
return rc ;
2011-11-19 21:25:44 +01:00
}
2017-08-11 18:18:45 +02:00
struct rule * create_rule_item ( struct rule_cond * rule_cond ) {
2011-11-19 21:25:44 +01:00
struct rule * h = NULL ;
int len ;
2015-12-28 14:50:37 +01:00
if ( rule_cond = = NULL ) return NULL ;
2011-11-19 21:25:44 +01:00
if ( ( h = malloc ( sizeof ( struct rule ) ) ) = = NULL )
return NULL ;
h - > compiled = 1 ;
2013-07-31 09:10:26 +02:00
h - > domain = NULL ;
2017-08-11 18:18:45 +02:00
h - > domainlen = strlen ( rule_cond - > domain ) ;
2013-07-31 09:10:26 +02:00
if ( h - > domainlen > 2 ) {
h - > domain = malloc ( h - > domainlen + 2 ) ;
2015-08-28 22:50:28 +02:00
if ( h - > domain ) snprintf ( h - > domain , h - > domainlen , " %s " , rule_cond - > domain ) ;
2013-07-31 09:10:26 +02:00
else {
h - > compiled = 0 ;
2015-08-28 22:50:28 +02:00
syslog ( LOG_INFO , " malloc error in create_rule_item() for '%s' " , rule_cond - > domain ) ;
2013-07-31 09:10:26 +02:00
}
}
2014-06-30 14:44:33 +02:00
h - > emptyfrom = h - > emptyto = h - > emptysubject = h - > emptyaname = h - > emptyatype = 0 ;
2021-04-18 20:19:26 +02:00
if ( rule_cond - > from [ 0 ] = = 0 ) { h - > emptyfrom = 1 ; }
2015-08-28 22:50:28 +02:00
if ( regcomp ( & ( h - > from ) , rule_cond - > from , REG_ICASE | REG_EXTENDED ) ) h - > compiled = 0 ;
2011-11-19 21:25:44 +01:00
2021-04-18 20:19:26 +02:00
if ( rule_cond - > to [ 0 ] = = 0 ) { h - > emptyto = 1 ; }
2015-08-28 22:50:28 +02:00
if ( regcomp ( & ( h - > to ) , rule_cond - > to , REG_ICASE | REG_EXTENDED ) ) h - > compiled = 0 ;
2011-11-19 21:25:44 +01:00
2021-04-18 20:19:26 +02:00
if ( rule_cond - > subject [ 0 ] = = 0 ) { h - > emptysubject = 1 ; }
2015-08-28 22:50:28 +02:00
if ( regcomp ( & ( h - > subject ) , rule_cond - > subject , REG_ICASE | REG_EXTENDED ) ) h - > compiled = 0 ;
2011-11-19 21:25:44 +01:00
2021-04-18 20:19:26 +02:00
if ( rule_cond - > body [ 0 ] = = 0 ) { h - > emptybody = 1 ; }
2015-08-28 22:50:28 +02:00
if ( regcomp ( & ( h - > body ) , rule_cond - > body , REG_ICASE | REG_EXTENDED ) ) h - > compiled = 0 ;
2015-03-11 12:54:31 +01:00
2015-08-28 22:50:28 +02:00
h - > spam = rule_cond - > spam ;
h - > days = rule_cond - > days ;
h - > folder_id = rule_cond - > folder_id ;
2012-02-19 22:59:47 +01:00
2015-08-28 22:50:28 +02:00
h - > size = rule_cond - > size ;
snprintf ( h - > _size , 3 , " %s " , rule_cond - > _size ) ;
2011-11-19 21:25:44 +01:00
2021-04-18 20:19:26 +02:00
if ( rule_cond - > attachment_name [ 0 ] = = 0 ) { h - > emptyaname = 1 ; }
2015-08-28 22:50:28 +02:00
if ( regcomp ( & ( h - > attachment_name ) , rule_cond - > attachment_name , REG_ICASE | REG_EXTENDED ) ) h - > compiled = 0 ;
2011-11-23 12:24:21 +01:00
2021-04-18 20:19:26 +02:00
if ( rule_cond - > attachment_type [ 0 ] = = 0 ) { h - > emptyatype = 1 ; }
2015-08-28 22:50:28 +02:00
if ( regcomp ( & ( h - > attachment_type ) , rule_cond - > attachment_type , REG_ICASE | REG_EXTENDED ) ) h - > compiled = 0 ;
2011-11-23 12:24:21 +01:00
2015-08-28 22:50:28 +02:00
h - > attachment_size = rule_cond - > attachment_size ;
snprintf ( h - > _attachment_size , 3 , " %s " , rule_cond - > _attachment_size ) ;
2011-11-23 12:24:21 +01:00
2015-08-28 22:50:28 +02:00
len = strlen ( rule_cond - > domain ) + 8 + strlen ( rule_cond - > from ) + 6 + strlen ( rule_cond - > to ) + 4 + strlen ( rule_cond - > subject ) + 9 + strlen ( rule_cond - > body ) + 6 + strlen ( rule_cond - > _size ) + 6 + strlen ( rule_cond - > attachment_name ) + 10 + strlen ( rule_cond - > attachment_type ) + 10 + strlen ( rule_cond - > _attachment_size ) + 10 + 9 + 15 + 15 ;
2011-11-19 21:25:44 +01:00
h - > rulestr = malloc ( len ) ;
2011-11-23 12:24:21 +01:00
2018-02-07 13:52:25 +01:00
if ( h - > rulestr ) {
snprintf ( h - > rulestr , len - 1 , " domain=%s,from=%s,to=%s,subject=%s,body=%s,size%s%d,att.name=%s,att.type=%s,att.size%s%d,spam=%d " , rule_cond - > domain , rule_cond - > from , rule_cond - > to , rule_cond - > subject , rule_cond - > body , rule_cond - > _size , rule_cond - > size , rule_cond - > attachment_name , rule_cond - > attachment_type , rule_cond - > _attachment_size , rule_cond - > attachment_size , rule_cond - > spam ) ;
syslog ( LOG_INFO , " adding rule: %s " , h - > rulestr ) ;
}
2011-11-19 21:25:44 +01:00
else h - > compiled = 0 ;
h - > r = NULL ;
return h ;
}
2018-11-03 21:54:44 +01:00
int count_match ( struct rule * p , struct parser_state * state , int size , int spam ) {
int ismatch = 0 ;
2011-11-19 21:25:44 +01:00
2018-11-03 17:12:07 +01:00
ismatch + = check_spam_rule ( spam , p - > spam ) ;
ismatch + = check_size_rule ( size , p - > size , p - > _size ) ;
ismatch + = check_attachment_rule ( state , p ) ;
2011-11-19 21:25:44 +01:00
2018-11-03 17:12:07 +01:00
if ( p - > compiled = = 1 ) {
2020-08-10 20:58:34 +02:00
size_t nmatch = 0 ;
2018-11-03 17:12:07 +01:00
if ( p - > emptyfrom = = 1 ) {
ismatch + = RULE_UNDEF ;
}
else if ( regexec ( & ( p - > from ) , state - > b_from , nmatch , NULL , 0 ) = = 0 ) ismatch + = RULE_MATCH ; else ismatch + = RULE_NO_MATCH ;
2011-11-19 21:25:44 +01:00
2018-11-03 17:12:07 +01:00
if ( p - > emptyto = = 1 ) {
ismatch + = RULE_UNDEF ;
}
else if ( regexec ( & ( p - > to ) , state - > b_to , nmatch , NULL , 0 ) = = 0 ) ismatch + = RULE_MATCH ; else ismatch + = RULE_NO_MATCH ;
2013-08-14 14:24:30 +02:00
2018-11-03 17:12:07 +01:00
if ( p - > emptysubject = = 1 ) {
ismatch + = RULE_UNDEF ;
}
else if ( regexec ( & ( p - > subject ) , state - > b_subject , nmatch , NULL , 0 ) = = 0 ) ismatch + = RULE_MATCH ; else ismatch + = RULE_NO_MATCH ;
2014-05-12 01:05:44 +02:00
2018-11-03 17:12:07 +01:00
if ( p - > emptybody = = 1 ) {
ismatch + = RULE_UNDEF ;
}
else if ( regexec ( & ( p - > body ) , state - > b_body , nmatch , NULL , 0 ) = = 0 ) ismatch + = RULE_MATCH ; else ismatch + = RULE_NO_MATCH ;
}
2014-05-12 01:05:44 +02:00
2018-11-03 17:12:07 +01:00
return ismatch ;
}
2014-06-30 14:44:33 +02:00
2019-01-13 16:12:14 +01:00
char * check_against_ruleset ( struct node * xhash [ ] , struct parser_state * state , int size , int spam ) {
2018-11-03 17:12:07 +01:00
struct rule * p ;
struct node * q ;
2015-03-11 12:54:31 +01:00
2018-11-03 17:12:07 +01:00
q = xhash [ 0 ] ;
2015-03-11 12:54:31 +01:00
2018-11-03 17:12:07 +01:00
while ( q ! = NULL ) {
2014-06-30 14:44:33 +02:00
2018-11-03 17:12:07 +01:00
if ( q - > str ) {
p = q - > str ;
2013-08-14 14:24:30 +02:00
2020-08-10 21:58:06 +02:00
if ( count_match ( p , state , size , spam ) > 0 ) {
2018-11-03 17:12:07 +01:00
return p - > rulestr ;
2013-08-14 14:24:30 +02:00
}
2011-11-19 21:25:44 +01:00
}
2013-08-14 14:24:30 +02:00
q = q - > r ;
2011-11-19 21:25:44 +01:00
}
return NULL ;
}
2017-08-08 15:34:45 +02:00
time_t query_retain_period ( struct data * data , struct parser_state * state , int size , int spam , struct config * cfg ) {
2012-02-19 22:59:47 +01:00
struct rule * p ;
2013-08-14 14:24:30 +02:00
struct node * q ;
q = data - > retention_rules [ 0 ] ;
2012-02-19 22:59:47 +01:00
2013-08-14 14:24:30 +02:00
while ( q ! = NULL ) {
2012-02-19 22:59:47 +01:00
2013-08-14 14:24:30 +02:00
if ( q - > str ) {
p = q - > str ;
2012-02-19 22:59:47 +01:00
2013-08-14 14:24:30 +02:00
if ( p - > domainlen > 2 ) {
if ( strcasestr ( state - > b_to_domain , p - > domain ) | | strcasestr ( state - > b_from_domain , p - > domain ) ) {
state - > retention = p - > days ;
2018-10-17 08:56:50 +02:00
return ( time_t ) ( state - > retention ) * ( time_t ) 86400 ;
2013-08-14 14:24:30 +02:00
}
}
2018-11-03 17:12:07 +01:00
else if ( count_match ( p , state , size , spam ) > 0 ) {
state - > retention = p - > days ;
return ( time_t ) ( state - > retention ) * ( time_t ) 86400 ;
2013-07-31 09:10:26 +02:00
}
2013-08-14 14:24:30 +02:00
2012-02-19 22:59:47 +01:00
}
2013-08-14 14:24:30 +02:00
q = q - > r ;
2012-02-19 22:59:47 +01:00
}
2013-08-14 14:24:30 +02:00
2013-07-31 10:06:05 +02:00
state - > retention = cfg - > default_retention_days ;
2018-10-17 08:47:43 +02:00
return ( time_t ) ( state - > retention ) * ( time_t ) 86400 ;
2012-02-19 22:59:47 +01:00
}
2017-08-08 15:34:45 +02:00
int get_folder_id_by_rule ( struct data * data , struct parser_state * state , int size , int spam , struct config * cfg ) {
2015-08-28 22:50:28 +02:00
struct rule * p ;
struct node * q ;
2016-01-24 15:23:47 +01:00
if ( cfg - > enable_folders = = 0 ) return 0 ;
2015-08-28 22:50:28 +02:00
q = data - > folder_rules [ 0 ] ;
while ( q ! = NULL ) {
if ( q - > str ) {
p = q - > str ;
if ( p - > domainlen > 2 ) {
if ( strcasestr ( state - > b_to_domain , p - > domain ) | | strcasestr ( state - > b_from_domain , p - > domain ) ) {
return p - > folder_id ;
}
}
2018-11-03 17:12:07 +01:00
else if ( count_match ( p , state , size , spam ) > 0 ) {
return p - > folder_id ;
2015-08-28 22:50:28 +02:00
}
}
q = q - > r ;
}
return 0 ; // default folder_id
}
2011-11-19 21:25:44 +01:00
int check_size_rule ( int message_size , int size , char * _size ) {
2014-05-12 01:05:44 +02:00
if ( size < = 0 ) return RULE_UNDEF ;
2011-11-19 21:25:44 +01:00
2014-05-12 01:05:44 +02:00
if ( strcmp ( _size , " > " ) = = 0 & & message_size > size ) return RULE_MATCH ;
if ( strcmp ( _size , " < " ) = = 0 & & message_size < size ) return RULE_MATCH ;
if ( strcmp ( _size , " = " ) = = 0 & & message_size = = size ) return RULE_MATCH ;
if ( ( strcmp ( _size , " <> " ) = = 0 | | strcmp ( _size , " != " ) = = 0 ) & & message_size ! = size ) return RULE_MATCH ;
2011-11-19 21:25:44 +01:00
2014-05-12 01:05:44 +02:00
return RULE_NO_MATCH ;
2011-11-19 21:25:44 +01:00
}
2012-02-19 22:59:47 +01:00
int check_spam_rule ( int is_spam , int spam ) {
2014-05-12 01:05:44 +02:00
if ( spam = = - 1 ) return RULE_UNDEF ;
if ( is_spam = = spam ) return RULE_MATCH ;
return RULE_NO_MATCH ;
2012-02-19 22:59:47 +01:00
}
2015-11-21 23:06:47 +01:00
int check_attachment_rule ( struct parser_state * state , struct rule * rule ) {
2011-11-23 12:24:21 +01:00
int i ;
size_t nmatch = 0 ;
2020-03-03 11:09:34 +01:00
// If no attachment rule, then return RULE_UNDEF
if ( rule - > emptyaname = = 1 & & rule - > emptyatype = = 1 & & rule - > attachment_size = = 0 ) return RULE_UNDEF ;
// If we have attachments, but no attachment rules, then return RULE_NO_MATCH
if ( state - > n_attachments = = 0 & & ( rule - > emptyaname = = 0 | | rule - > emptyatype = = 0 | | rule - > attachment_size ) ) return RULE_NO_MATCH ;
2012-01-28 20:52:13 +01:00
2014-06-30 14:44:33 +02:00
2011-11-23 12:24:21 +01:00
for ( i = 1 ; i < = state - > n_attachments ; i + + ) {
2020-08-10 20:58:34 +02:00
int ismatch = 0 ;
2014-06-30 14:44:33 +02:00
if ( rule - > emptyaname = = 0 ) {
if ( regexec ( & ( rule - > attachment_name ) , state - > attachments [ i ] . filename , nmatch , NULL , 0 ) = = 0 )
ismatch + = RULE_MATCH ;
else
ismatch + = RULE_NO_MATCH ;
}
if ( rule - > emptyatype = = 0 ) {
if ( regexec ( & ( rule - > attachment_type ) , state - > attachments [ i ] . type , nmatch , NULL , 0 ) = = 0 )
ismatch + = RULE_MATCH ;
else
ismatch + = RULE_NO_MATCH ;
2011-11-23 12:24:21 +01:00
}
2014-06-30 14:44:33 +02:00
ismatch + = check_size_rule ( state - > attachments [ i ] . size , rule - > attachment_size , rule - > _attachment_size ) ;
if ( ismatch > 0 ) return RULE_MATCH ;
2011-11-23 12:24:21 +01:00
}
2014-05-12 01:05:44 +02:00
return RULE_NO_MATCH ;
2011-11-23 12:24:21 +01:00
}
2013-08-14 14:24:30 +02:00
void initrules ( struct node * xhash [ ] ) {
xhash [ 0 ] = NULL ;
}
2011-11-19 21:25:44 +01:00
2013-08-14 14:24:30 +02:00
void clearrules ( struct node * xhash [ ] ) {
2020-08-10 20:58:34 +02:00
struct node * q ;
2013-08-14 14:24:30 +02:00
struct rule * rule ;
2011-11-19 21:25:44 +01:00
2013-08-14 14:24:30 +02:00
q = xhash [ 0 ] ;
while ( q ! = NULL ) {
2020-08-10 20:58:34 +02:00
struct node * p = q ;
2013-08-14 14:24:30 +02:00
q = q - > r ;
2011-11-19 21:25:44 +01:00
2020-08-10 20:58:34 +02:00
if ( p - > str ) {
rule = ( struct rule * ) p - > str ;
2013-08-14 14:24:30 +02:00
2020-08-10 20:58:34 +02:00
regfree ( & ( rule - > from ) ) ;
regfree ( & ( rule - > to ) ) ;
regfree ( & ( rule - > subject ) ) ;
regfree ( & ( rule - > body ) ) ;
regfree ( & ( rule - > attachment_name ) ) ;
regfree ( & ( rule - > attachment_type ) ) ;
2011-11-23 12:24:21 +01:00
2020-08-10 20:58:34 +02:00
free ( rule - > rulestr ) ;
2011-11-19 21:25:44 +01:00
2020-08-10 20:58:34 +02:00
if ( rule - > domain ) free ( rule - > domain ) ;
2013-07-31 09:10:26 +02:00
2020-08-10 20:58:34 +02:00
free ( rule ) ;
2011-11-19 21:25:44 +01:00
}
2020-08-10 20:58:34 +02:00
free ( p ) ;
2011-11-19 21:25:44 +01:00
}
2013-08-14 14:24:30 +02:00
xhash [ 0 ] = NULL ;
}