Alternc  latest
Alternc logiel libre pour l'hébergement
procmail_to_sieve.php File Reference

Go to the source code of this file.

Functions

 procmail2sieve ()
 MAIN FUNCTION Read all the mail folders and search for .procmailrc's. More...
 
 parseOneProcmail ($user)
 Parse ONE procmailrc, and write its sieve rules. More...
 
 readrules ($user="")
 Read rules, fill an array from m_procmail.php original file yeah I know, ereg() is deprecated ;) More...
 
 describe ($rule)
 Take ONE rule array, extract properly returns one array with the conditions (which are arrays with Condition Type and Value) and the action parameter. More...
 

Variables

 $acriteria
 
 $aactions
 
 $ROOT =$L_ALTERNC_MAIL
 
 $SIEVEROOT ="/var/lib/dovecot/sieve"
 

Function Documentation

◆ describe()

describe (   $rule)

Take ONE rule array, extract properly returns one array with the conditions (which are arrays with Condition Type and Value) and the action parameter.

Definition at line 277 of file procmail_to_sieve.php.

277  {
278 
279  // Lecture des conditions :
280  $cond=array();
281  switch ($rule["type"]) {
282  case 5:
283  $i=1;
284  while ($rule["rule"][$i]!="* !^FROM_DAEMON" && $rule["rule"][$i]!="") {
285  $cond[]=$rule["rule"][$i];
286  $i++;
287  }
288  break;
289  default:
290  $i=1;
291  while (substr($rule["rule"][$i],0,1)=="*") {
292  $cond[]=$rule["rule"][$i];
293  $i++;
294  }
295  break;
296  }
297 
298  // $cond is an array of conditions
299  // let's parse the condition : (see arrays at the top of this file)
300  $conds=array();
301 
302  for($i=0;$i<count($cond);$i++) {
303  if (ereg("^\\* \\^Subject\\.\\*(.*)$",$cond[$i],$t)) {
304  $conds[]=array( 0, $t[1] );
305  }
306  if (ereg("^\\* \\^From\\.\\*(.*)$",$cond[$i],$t)) {
307  $conds[]=array( 1, $t[1] );
308  }
309  if (ereg("^\\* \\^TO_(.*)$",$cond[$i],$t)) {
310  $conds[]=array( 2, $t[1] );
311  }
312  if (ereg("^\\* \\^List-Post: (.*)$",$cond[$i],$t)) {
313  $conds[]=array( 3, $t[1] );
314  }
315  if (ereg("^\\* \\^List-Id: (.*)$",$cond[$i],$t)) {
316  $conds[]=array( 4, $t[1] );
317  }
318  if (ereg("^\\* \\^X-Spam-Status: Yes$",$cond[$i])) {
319  $conds[]=array( 5 );
320  }
321  if (ereg("^\\* \\^Delivered-To:\\.\\*(.*)$",$cond[$i],$t)) {
322  $conds[]=array( 6, $t[1] );
323  }
324  }
325 
326  // Action :
327  $actionparam=false;
328  switch ($rule["type"]) {
329  case 1:
330  $actionparam=$rule["rule"][count($rule["rule"])-2]; /* Folder */
331  break;
332  case 4:
333  $actionparam = substr($rule["rule"][count($rule["rule"])-2],0,15); /* Recipient */
334  break;
335  }
336  return array($conds,$actionparam);
337 }
foreach($domaines_user as $domaine) $t
$i

References $i, and $t.

Referenced by parseOneProcmail().

◆ parseOneProcmail()

parseOneProcmail (   $user)

Parse ONE procmailrc, and write its sieve rules.

Parameters
string$user

Definition at line 69 of file procmail_to_sieve.php.

69  {
70  global $SIEVEROOT;
71  $email=preg_replace("#_([^_]*)$#","@$1",$user);
72  if ($rules=readrules($user)) { /* ################## SUB FUNCTION ###################### */
73  for($i=0; $i<count($rules); $i++) {
74  list($rules[$i]["conds"],$rules[$i]["actionparam"])=describe($rules[$i]); /* ################## SUB FUNCTION ###################### */
75  }
76 
77  // Now we have $rule["type"] = the ACTION to accomplish + (if 1 or 4) $actionparam
78  // and a list of $rule["conds"][0]=condition type & $rule["conds"][1]=condition parameter (if not 5)
79  // Let's write a sieve script :)
80  $u=substr($u,0,1);
81  @mkdir($SIEVEROOT."/".$u."/".$user."/sieve");
82  @mkdir($SIEVEROOT."/".$u."/".$user."/sieve/tmp");
83  $uid=fileowner($SIEVEROOT."/".$u."/".$user);
84  chown($SIEVEROOT."/".$u."/".$user."/sieve",$uid);
85  chgrp($SIEVEROOT."/".$u."/".$user."/sieve","vmail");
86  chown($SIEVEROOT."/".$u."/".$user."/sieve/tmp",$uid);
87  chgrp($SIEVEROOT."/".$u."/".$user."/sieve/tmp","vmail");
88 
89  $f=fopen($SIEVEROOT."/".$u."/".$user."/sieve/tmp/phpscript.sieve","wb");
90  if (!$f) {
91  echo "ERROR: Can't open '$user' in '$SIEVEROOT' for writing\n";
92  } else {
93  echo "OK: writing sieve script for $user (".count($rules)." rules)\n";
94 
95  $avelsieveversion=array("major" => 1, "minor"=>9, "release" => 9, "string" => "1.9.9");
96  fputs($f,'# This script has been automatically generated by avelsieve
97 # (Sieve Mail Filters Plugin for Squirrelmail)
98 # Warning: If you edit this manually, then the changes will not
99 # be reflected in the users\' front-end!
100 #AVELSIEVE_VERSION'.urlencode(base64_encode(serialize($avelsieveversion))).'
101 #AVELSIEVE_CREATED'.time().'
102 #AVELSIEVE_MODIFIED'.time().'
103 require ["fileinto","envelope","reject","vacation","imap4flags","relational","comparator-i;ascii-numeric","regex","body","date"];
104 ');
105  foreach($rules as $rule) {
106  if ($rule["type"]==2) continue; // IGNORE "Filter the message through SpamAssassin"
107 
108  // Create the avelsieve array:
109  $avelrule=array();
110  // And sieve script:
111  $script="if ";
112  $avelrule["condition"]="and";
113  $avelrule["type"]=1;
114  if (!count($rule["conds"])) {
115  // no conditions
116  $script.="true\n";
117  $avelrule["cond"][]=array("kind" => "message", "type" => "all");
118  } else { // have conditions
119  $script.="allof (";
120  $first=true;
121  foreach($conds as $cond) {
122  if (!$first) $script.=",\n";
123  $first=false;
124  // What kind of condition?
125  switch($cond[0]) {
126  case 0: // subject
127  $script.='header :contains "Subject" "'.str_replace('"','\\"',$cond[1]).'"';
128  $avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "Subject", "matchtype" => "contains", "headermatch" => $cond[1] );
129  break;
130  case 1: // sender
131  $script.='header :contains "From" "'.str_replace('"','\\"',$cond[1]).'"';
132  $avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "From", "matchtype" => "contains", "headermatch" => $cond[1] );
133  break;
134  case 2: // recipient
135  $script.='address :contains ["to", "cc"] "'.str_replace('"','\\"',$cond[1]).'"';
136  $avelrule["cond"][]=array("kind" => "message", "type" => "address", "address" => "toorcc", "matchtype" => "contains", "addressmatch" => $cond[1] );
137  break;
138  case 3: // List-Post
139  $script.='header :contains "List-Post" "'.str_replace('"','\\"',$cond[1]).'"';
140  $avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "List-Post", "matchtype" => "contains", "headermatch" => $cond[1] );
141  break;
142  case 4: // List-Id
143  $script.='header :contains "List-Id" "'.str_replace('"','\\"',$cond[1]).'"';
144  $avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "List-Id", "matchtype" => "contains", "headermatch" => $cond[1] );
145  break;
146  case 5: // Spamassassin
147  $script.='header :contains "X-Spam-Status" "Yes"';
148  $avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "X-Spam-Status", "matchtype" => "contains", "headermatch" => "Yes" );
149  break;
150  case 6: // Delivered-To
151  $script.='envelope :contains "to" "'.str_replace('"','\\"',$cond[1]).'"';
152  $avelrule["cond"][]=array("kind" => "message", "type" => "envelope", "envelope" => "to", "matchtype" => "contains", "envelopematch" => $cond[1] );
153  break;
154 
155  }
156  }
157  $script.=")\n{\n";
158  }
159  // Now the ACTION:
160  switch($rule["type"]) {
161  case 1: // move to
162  $script.='fileinto "'.str_replace('"','\\"',$rule["actionparam"]).'";
163 stop;
164 ';
165  $avelrule["action"] = 5;
166  $avelrule["folder"] = $rule["actionparam"];
167  $avelrule["stop"] = "on";
168  break;
169  case 3: // Discard (for good)
170  $script.='discard;
171 stop;
172 ';
173  $avelrule["action"] = 2;
174  $avelrule["stop"] = "on";
175  break;
176  case 4: // Forward To (copy)
177  $script.='redirect "'.str_replace('"','\\"',$rule["actionparam"]).'";
178 ';
179  $avelrule["action"] = 4;
180  $avelrule["redirectemail"] = $rule["actionparam"];
181  break;
182  case 5: // Auto-Reply
183  $script.='vacation :days 7 :addresses ["'.$email.'"@ :subject "Auto Reply" text:
184 '.str_replace("\\'","'",@file_get_contents($ROOT."/".$u."/".$user."/".$user.".txt")).'
185 .
186 ;
187 ';
188  $avelrule["action"] = 6;
189  $avelrule["vac_addresses"] = $email;
190  $avelrule["vac_subject"] = "Auto Reply";
191  $avelrule["vac_days"] = 7;
192  $avelrule["vac_message"] = @file_get_contents($ROOT."/".$u."/".$user."/".$user.".txt");
193  break;
194  }
195  $script.="}\n";
196  // Now put it into the script file :
197  fputs($f,"#START_SIEVE_RULE".urlencode(base64_encode(serialize($avelrule)))."END_SIEVE_RULE\n");
198  fputs($f,$script);
199  /*
200 if allof (header :contains "From" "expediteur@coin.pan",
201 header :contains "To" "destinataire@coin.pan")
202 {
203 fileinto "INBOX.test";
204 stop;
205 }
206  */
207  } /* for each rule */
208 
209  fclose($f);
210 
211  // Then Move it to the right place
212  @unlink($SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve");
213  rename(
214  $SIEVEROOT."/".$u."/".$user."/sieve/tmp/phpscript.sieve",
215  $SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve"
216  );
217  chown($SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve",$uid);
218  chgrp($SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve","vmail");
219  }
220  } else {
221  echo "ERROR: can't read rules for $user\n";
222  }
223 
224 } /* parseOneProcmauil */
$uid
$user
Definition: bootstrap.php:84
readrules($user="")
Read rules, fill an array from m_procmail.php original file yeah I know, ereg() is deprecated ;)
describe($rule)
Take ONE rule array, extract properly returns one array with the conditions (which are arrays with Co...

References $f, $i, $ROOT, $SIEVEROOT, $uid, $user, describe(), and readrules().

Referenced by procmail2sieve().

◆ procmail2sieve()

procmail2sieve ( )

MAIN FUNCTION Read all the mail folders and search for .procmailrc's.

Definition at line 32 of file procmail_to_sieve.php.

32  {
33  global $ROOT;
34  $d=@opendir($ROOT);
35  if ($d) {
36  while ($c=readdir($d)) {
37  if (substr($c,0,1)==".") continue; // skip hidden files
38  if (is_dir($ROOT."/".$c)) {
39  // Go to level 2.
40  $e=@opendir($ROOT."/".$c);
41  if ($e) {
42  while ($f=readdir($e)) {
43  if (substr($f,0,1)==".") continue; // skip hidden files
44  if (is_file($ROOT."/".$c."/".$f."/.procmailrc")) {
45  // We found one .procmailrc, let's parse it on behalf of his user...
46  parseOneProcmail($f); /* ################## SUB FUNCTION ###################### */
47  }
48  }
49  closedir($e);
50  } else {
51  echo "ERROR: Cannot open ".$ROOT."/".$c."\n";
52  }
53 
54  }
55  }
56  closedir($d);
57  } else {
58  echo "FATAL: cannot open ".$ROOT."\n";
59  exit();
60  }
61 } /* procmail2sieve */
exit
Definition: adm_doadd.php:70
$c
Definition: bootstrap.php:47
$d
parseOneProcmail($user)
Parse ONE procmailrc, and write its sieve rules.

References $c, $d, $f, $ROOT, exit, and parseOneProcmail().

◆ readrules()

readrules (   $user = "")

Read rules, fill an array from m_procmail.php original file yeah I know, ereg() is deprecated ;)

Definition at line 233 of file procmail_to_sieve.php.

233  {
234  if (!$user) $user=$this->user;
235  $u=substr($user,0,1);
236  if (!file_exists(ALTERNC_MAIL."/$u/$user/.procmailrc")) {
237  return false;
238  }
239  $f=fopen(ALTERNC_MAIL."/$u/$user/.procmailrc","rb");
240  $state=0; $rulenum=0; $ligne=0;
241  $res=array();
242  while (!feof($f)) {
243  $found=false; // found allow us to know if we found something for each loop
244  $s=fgets($f,1024);
245  $s=trim($s);
246  if ($state==1 && !ereg("^# RuleEnd$",$s)) {
247  $res[$rulenum]["rule"][$res[$rulenum]["count"]++]=$s;
248  $found=true;
249  }
250  if ($state==1 && ereg("^# RuleEnd$",$s)) {
251  $state=0;
252  $rulenum++;
253  $found=true;
254  }
255  if ($state==0 && ereg("^# RuleType ([0-9][0-9]) -- (.*)?$",$s,$r)) {
256  $state=1;
257  $res[$rulenum]["type"]=$r[1];
258  $res[$rulenum]["name"]=$r[2];
259  $res[$rulenum]["count"]=0;
260  $found=true;
261  }
262  if (!$found && $state!=0) {
263  return false;
264  }
265  $ligne++;
266  }
267  fclose($f);
268  return $res;
269 }
const ALTERNC_MAIL
Definition: bootstrap.php:9
$r
Definition: aws_add.php:75
$found
Definition: aws_del.php:29
$res
Definition: index.php:111

References $f, $found, $r, $res, $user, and ALTERNC_MAIL.

Referenced by parseOneProcmail().

Variable Documentation

◆ $aactions

$aactions
Initial value:
=array(
1 => "Move the message to this folder",
2 => "Filter the message through SpamAssassin",
3 => "Discard the message (for good !)",
4 => "Forward the mail to",
5 => "Auto-reply",
)

Definition at line 357 of file procmail_to_sieve.php.

◆ $acriteria

$acriteria
Initial value:
=array(
0 => "Le sujet du message contient ...",
1 => "L'expediteur du message est contient ...",
2 => "L'un des destinataires du message contient ...",
3 => "L'en-tete 'List-Post' du message est ...",
4 => "L'en-tete 'List-Id' du message est ...",
5 => "SpamAssassin considere qu'il s'agit d'un Spam",
6 => "L'en-tete 'Delivered-To' du message contient ...",
)

Definition at line 348 of file procmail_to_sieve.php.

◆ $ROOT

$ROOT =$L_ALTERNC_MAIL

Definition at line 369 of file procmail_to_sieve.php.

Referenced by parseOneProcmail(), and procmail2sieve().

◆ $SIEVEROOT

$SIEVEROOT ="/var/lib/dovecot/sieve"

Definition at line 371 of file procmail_to_sieve.php.

Referenced by parseOneProcmail().