Alternc  3.2
Alternc logiel libre pour l'hébergement
 All Data Structures Namespaces Files Functions Variables Pages
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.
 parseOneProcmail ($user)
 Parse ONE procmailrc, and write its sieve rules.
 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 Condition Type and Value) and the action parameter.

Variables

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

Function Documentation

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 276 of file procmail_to_sieve.php.

References $i, and $t.

Referenced by parseOneProcmail().

{
// Lecture des conditions :
$cond=array();
switch ($rule["type"]) {
case 5:
$i=1;
while ($rule["rule"][$i]!="* !^FROM_DAEMON" && $rule["rule"][$i]!="") {
$cond[]=$rule["rule"][$i];
$i++;
}
break;
default:
$i=1;
while (substr($rule["rule"][$i],0,1)=="*") {
$cond[]=$rule["rule"][$i];
$i++;
}
break;
}
// $cond is an array of conditions
// let's parse the condition : (see arrays at the top of this file)
$conds=array();
for($i=0;$i<count($cond);$i++) {
if (ereg("^\\* \\^Subject\\.\\*(.*)$",$cond[$i],$t)) {
$conds[]=array( 0, $t[1] );
}
if (ereg("^\\* \\^From\\.\\*(.*)$",$cond[$i],$t)) {
$conds[]=array( 1, $t[1] );
}
if (ereg("^\\* \\^TO_(.*)$",$cond[$i],$t)) {
$conds[]=array( 2, $t[1] );
}
if (ereg("^\\* \\^List-Post: (.*)$",$cond[$i],$t)) {
$conds[]=array( 3, $t[1] );
}
if (ereg("^\\* \\^List-Id: (.*)$",$cond[$i],$t)) {
$conds[]=array( 4, $t[1] );
}
if (ereg("^\\* \\^X-Spam-Status: Yes$",$cond[$i])) {
$conds[]=array( 5 );
}
if (ereg("^\\* \\^Delivered-To:\\.\\*(.*)$",$cond[$i],$t)) {
$conds[]=array( 6, $t[1] );
}
}
// Action :
$actionparam=false;
switch ($rule["type"]) {
case 1:
$actionparam=$rule["rule"][count($rule["rule"])-2]; /* Folder */
break;
case 4:
$actionparam = substr($rule["rule"][count($rule["rule"])-2],0,15); /* Recipient */
break;
}
return array($conds,$actionparam);
}
parseOneProcmail (   $user)

Parse ONE procmailrc, and write its sieve rules.

Definition at line 68 of file procmail_to_sieve.php.

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

Referenced by procmail2sieve().

{
global $SIEVEROOT;
$email=preg_replace("#_([^_]*)$#","@$1",$user);
if ($rules=readrules($user)) { /* ################## SUB FUNCTION ###################### */
for($i=0; $i<count($rules); $i++) {
list($rules[$i]["conds"],$rules[$i]["actionparam"])=describe($rules[$i]); /* ################## SUB FUNCTION ###################### */
}
// Now we have $rule["type"] = the ACTION to accomplish + (if 1 or 4) $actionparam
// and a list of $rule["conds"][0]=condition type & $rule["conds"][1]=condition parameter (if not 5)
// Let's write a sieve script :)
$u=substr($u,0,1);
@mkdir($SIEVEROOT."/".$u."/".$user."/sieve");
@mkdir($SIEVEROOT."/".$u."/".$user."/sieve/tmp");
$uid=fileowner($SIEVEROOT."/".$u."/".$user);
chown($SIEVEROOT."/".$u."/".$user."/sieve",$uid);
chgrp($SIEVEROOT."/".$u."/".$user."/sieve","vmail");
chown($SIEVEROOT."/".$u."/".$user."/sieve/tmp",$uid);
chgrp($SIEVEROOT."/".$u."/".$user."/sieve/tmp","vmail");
$f=fopen($SIEVEROOT."/".$u."/".$user."/sieve/tmp/phpscript.sieve","wb");
if (!$f) {
echo "ERROR: Can't open '$user' in '$SIEVEROOT' for writing\n";
} else {
echo "OK: writing sieve script for $user (".count($rules)." rules)\n";
$avelsieveversion=array("major" => 1, "minor"=>9, "release" => 9, "string" => "1.9.9");
fputs($f,'# This script has been automatically generated by avelsieve
# (Sieve Mail Filters Plugin for Squirrelmail)
# Warning: If you edit this manually, then the changes will not
# be reflected in the users\' front-end!
#AVELSIEVE_VERSION'.urlencode(base64_encode(serialize($avelsieveversion))).'
#AVELSIEVE_CREATED'.time().'
#AVELSIEVE_MODIFIED'.time().'
require ["fileinto","envelope","reject","vacation","imap4flags","relational","comparator-i;ascii-numeric","regex","body","date"];
');
foreach($rules as $rule) {
if ($rule["type"]==2) continue; // IGNORE "Filter the message through SpamAssassin"
// Create the avelsieve array:
$avelrule=array();
// And sieve script:
$script="if ";
$avelrule["condition"]="and";
$avelrule["type"]=1;
if (!count($rule["conds"])) {
// no conditions
$script.="true\n";
$avelrule["cond"][]=array("kind" => "message", "type" => "all");
} else { // have conditions
$script.="allof (";
$first=true;
foreach($conds as $cond) {
if (!$first) $script.=",\n";
$first=false;
// What kind of condition?
switch($cond[0]) {
case 0: // subject
$script.='header :contains "Subject" "'.str_replace('"','\\"',$cond[1]).'"';
$avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "Subject", "matchtype" => "contains", "headermatch" => $cond[1] );
break;
case 1: // sender
$script.='header :contains "From" "'.str_replace('"','\\"',$cond[1]).'"';
$avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "From", "matchtype" => "contains", "headermatch" => $cond[1] );
break;
case 2: // recipient
$script.='address :contains ["to", "cc"] "'.str_replace('"','\\"',$cond[1]).'"';
$avelrule["cond"][]=array("kind" => "message", "type" => "address", "address" => "toorcc", "matchtype" => "contains", "addressmatch" => $cond[1] );
break;
case 3: // List-Post
$script.='header :contains "List-Post" "'.str_replace('"','\\"',$cond[1]).'"';
$avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "List-Post", "matchtype" => "contains", "headermatch" => $cond[1] );
break;
case 4: // List-Id
$script.='header :contains "List-Id" "'.str_replace('"','\\"',$cond[1]).'"';
$avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "List-Id", "matchtype" => "contains", "headermatch" => $cond[1] );
break;
case 5: // Spamassassin
$script.='header :contains "X-Spam-Status" "Yes"';
$avelrule["cond"][]=array("kind" => "message", "type" => "header", "header" => "X-Spam-Status", "matchtype" => "contains", "headermatch" => "Yes" );
break;
case 6: // Delivered-To
$script.='envelope :contains "to" "'.str_replace('"','\\"',$cond[1]).'"';
$avelrule["cond"][]=array("kind" => "message", "type" => "envelope", "envelope" => "to", "matchtype" => "contains", "envelopematch" => $cond[1] );
break;
}
}
$script.=")\n{\n";
}
// Now the ACTION:
switch($rule["type"]) {
case 1: // move to
$script.='fileinto "'.str_replace('"','\\"',$rule["actionparam"]).'";
stop;
';
$avelrule["action"] = 5;
$avelrule["folder"] = $rule["actionparam"];
$avelrule["stop"] = "on";
break;
case 3: // Discard (for good)
$script.='discard;
stop;
';
$avelrule["action"] = 2;
$avelrule["stop"] = "on";
break;
case 4: // Forward To (copy)
$script.='redirect "'.str_replace('"','\\"',$rule["actionparam"]).'";
';
$avelrule["action"] = 4;
$avelrule["redirectemail"] = $rule["actionparam"];
break;
case 5: // Auto-Reply
$script.='vacation :days 7 :addresses ["'.$email.'"@ :subject "Auto Reply" text:
'.str_replace("\\'","'",@file_get_contents($ROOT."/".$u."/".$user."/".$user.".txt")).'
.
;
';
$avelrule["action"] = 6;
$avelrule["vac_addresses"] = $email;
$avelrule["vac_subject"] = "Auto Reply";
$avelrule["vac_days"] = 7;
$avelrule["vac_message"] = @file_get_contents($ROOT."/".$u."/".$user."/".$user.".txt");
break;
}
$script.="}\n";
// Now put it into the script file :
fputs($f,"#START_SIEVE_RULE".urlencode(base64_encode(serialize($avelrule)))."END_SIEVE_RULE\n");
fputs($f,$script);
/*
if allof (header :contains "From" "expediteur@coin.pan",
header :contains "To" "destinataire@coin.pan")
{
fileinto "INBOX.test";
stop;
}
*/
} /* for each rule */
fclose($f);
// Then Move it to the right place
@unlink($SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve");
rename(
$SIEVEROOT."/".$u."/".$user."/sieve/tmp/phpscript.sieve",
$SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve"
);
chown($SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve",$uid);
chgrp($SIEVEROOT."/".$u."/".$user."/sieve/phpscript.sieve","vmail");
}
} else {
echo "ERROR: can't read rules for $user\n";
}
} /* parseOneProcmauil */
procmail2sieve ( )

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

Definition at line 32 of file procmail_to_sieve.php.

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

{
global $ROOT;
$d=@opendir($ROOT);
if ($d) {
while ($c=readdir($d)) {
if (substr($c,0,1)==".") continue; // skip hidden files
if (is_dir($ROOT."/".$c)) {
// Go to level 2.
$e=@opendir($ROOT."/".$c);
if ($e) {
while ($f=readdir($e)) {
if (substr($f,0,1)==".") continue; // skip hidden files
if (is_file($ROOT."/".$c."/".$f."/.procmailrc")) {
// We found one .procmailrc, let's parse it on behalf of his user...
parseOneProcmail($f); /* ################## SUB FUNCTION ###################### */
}
}
closedir($e);
} else {
echo "ERROR: Cannot open ".$ROOT."/".$c."\n";
}
}
}
closedir($d);
} else {
echo "FATAL: cannot open ".$ROOT."\n";
exit();
}
} /* procmail2sieve */
readrules (   $user = "")

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

Definition at line 232 of file procmail_to_sieve.php.

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

Referenced by parseOneProcmail().

{
$u=substr($user,0,1);
if (!file_exists(ALTERNC_MAIL."/$u/$user/.procmailrc")) {
return false;
}
$f=fopen(ALTERNC_MAIL."/$u/$user/.procmailrc","rb");
$state=0; $rulenum=0; $ligne=0;
$res=array();
while (!feof($f)) {
$found=false; // found allow us to know if we found something for each loop
$s=fgets($f,1024);
$s=trim($s);
if ($state==1 && !ereg("^# RuleEnd$",$s)) {
$res[$rulenum]["rule"][$res[$rulenum]["count"]++]=$s;
$found=true;
}
if ($state==1 && ereg("^# RuleEnd$",$s)) {
$state=0;
$rulenum++;
$found=true;
}
if ($state==0 && ereg("^# RuleType ([0-9][0-9]) -- (.*)?$",$s,$r)) {
$state=1;
$res[$rulenum]["type"]=$r[1];
$res[$rulenum]["name"]=$r[2];
$res[$rulenum]["count"]=0;
$found=true;
}
if (!$found && $state!=0) {
return false;
}
$ligne++;
}
fclose($f);
return $res;
}

Variable Documentation

$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 356 of file procmail_to_sieve.php.

$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 347 of file procmail_to_sieve.php.

$ROOT = $L_ALTERNC_MAIL

Definition at line 368 of file procmail_to_sieve.php.

Referenced by parseOneProcmail(), and procmail2sieve().

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

Definition at line 370 of file procmail_to_sieve.php.

Referenced by parseOneProcmail().