<?php
    
#require '/www/l-i-e.com/php/error.inc';
    
require '/www/l-i-e.com/php/globals.inc';
    require 
'/www/l-i-e.com/php/imap.inc';
    
    
$host '{localhost:143}';
    
    
$filters = array('example@yahoogroups.com'=>'Example',
                     
'friend@example.com'=>'Filtered'
                     
/* add many many many more filters here to pre-filter 'good' email where it belongs */
                    
);
    
$filtered = array();
    
$bodies = array();
    
    
$mailboxes imap_getmailboxes($imap$host'*') or trigger_error('Could not get mailboxes ' imap_alerts_errors(), E_USER_ERROR);
    
    while (
is_array($mailboxes) && (list($key$mailbox) = each($mailboxes))){
        
#echo "$key: <BR>\n";
        
$name $mailbox->name;
        
#echo imap_interesting($mailbox), '&nbsp;', $name, "<BR>\n";
        #imap_mailbox_attributes($mailbox->attributes);
        #echo "Delimiter: ", $mailbox->delimiter, "<BR>\n";
        
        
imap_subscribe($imap"$name") or trigger_error("Could not subscribe to $name " imap_alerts_errors(), E_USER_ERROR);
        
        
imap_reopen($imap$name) or trigger_error("Could not open $name " imap_alerts_errors(), E_USER_ERROR);
        
#echo "imap_num_msg: ", imap_num_msg($imap), "<BR>\n";
        
        
$spam_uid = array();
        
$subjects = array();
        
$trash = array();
        if (!
stristr($mailbox'Trash') && imap_interesting($mailbox) == '*'){
            
#echo "Checking $name\n";
            
$status imap_status($imap$nameSA_ALL);
            
#echo "Messages: " . $status->messages  . "<br />\n";
            #echo "Recent:  " . $status->recent   . "<br />\n";
            #echo "Unseen:  " . $status->unseen   . "<br />\n";
            #echo "UIDnext:  " . $status->uidnext  . "<br />\n";
            #echo "UIDvalidity:" . $status->uidvalidity . "<br />\n"; 
            
$uidvalidity $status->uidvalidity;
            
#echo "<PRE>";
            #var_dump($status);
            #echo "</PRE>";
            
imap_alerts_errors();
            for (
$i 1$i <= $status->messages$i++){
                
$uid imap_uid($imap$i);
                
#echo "uid: $uid<BR>";
                
$header imap_fetchheader($imap$uidFT_UID);
                
#echo "<PRE>$header</PRE><HR>\n";
                
$msg_headers[$i] = $header;
                
$subject explode('Subject:'$header);
                
$subject $subject[1];
                
$subject explode("\n"$subject);
                
$subject $subject[0];
                
$subjects[$uid] = $subject;
                if (
is_spam_header($header$subject)){
                    
$spam_uid[$uid] = $uid;
                }
                elseif ((
$i 1)){
                    
$message_id explode('Message-ID:'$header);
                    
$message_id $message_id[1];
                    
$message_id explode("\n"$message_id);
                    
$message_id $message_id[0];
                    
$message_id_1 explode('Message-ID:'$msg_headers[$i 1]);
                    
$message_id_1 $message_id_1[1];
                    
$message_id_1 explode("\n"$message_id_1);
                    
$message_id_1 $message_id_1[0];
                    
$headers_1 explode("\n"$header);
                    
$headers_2 explode("\n"$msg_headers[$i 1]);
                    
#echo "\nCOMPARING ", $i-1, " and $i\n";
                    
$diffcount 0;
                    while (list(
$k$l1) = each($headers_1)){
                        
$h_parts explode(':'$l1);
                        
$h_key $h_parts[0];
                        unset(
$h_parts[0]);
                        
$h_val implode($h_parts);
                        
$h1[$h_key] = $h_val;
                    }
                    while (list(
$k$l2) = each($headers_2)){
                        
$h_parts explode(':'$l2);
                        
$h_key $h_parts[0];
                        unset(
$h_parts[0]);
                        
$h_val implode($h_parts);
                        
$h2[$h_key] = $h_val;
                    }
                    
reset($h1);
                    while (
$diffcount && (list($k$l1) = each($h1))){
                        
$l2 $h2[$k];
                        if (
$l1 != $l2){
                            
$diffcount++;
                            
#printf("%10s: %70s | %70s\n", substr($k, 0, 10), substr($l1, 0, 70), substr($l2, 0, 70));
                        
}
                        else{
                            
#printf("%10s: %70s\n", substr($k, 0, 10), substr($l1, 0, 70));
                        
}
                    }
                    
reset($h2);
                    while (
$diffcount && (list($k$l2) = each($h2))){
                        
$l1 $h1[$k];
                        if (
$l1 != $l2){
                            
$diffcount++;
                            
#printf("%10s: %70s | %70s\n", substr($k, 0, 10), substr($l1, 0, 70), substr($l2, 0, 70));
                        
}
                        else{
                            
#printf("%10s: %70s\n", substr($k, 0, 10), substr($l1, 0, 70));
                        
}
                    }
                    
//Compare bodies, giving one point for any difference at all
                    //Skip anything that already 'passed':
                    
if ($diffcount 7){
                        
$body1 find_body($imap$i);
                        
$bodies[$i] = $body1;
                        
#echo "Body 1: $body1\n";
                        
$body2 $bodies[$i 1];
                        
#echo "Body 2: $body2\n";
                        
if (strlen($body1) && $body1 == $body2){
                            
#echo "Matching bodies $i and $i - 1 drops $diffcount by 1 to ", $diffcount - 1, "\n";
                            
$diffcount--;
                        }
                        if (!
strlen($body1)){
                            
#echo "Could not find body of message for $i ($uid)\n";
                            #echo "Here are its headers:\n";
                            #echo $header;
                            #echo "\n----------------------\n\n";
                        
}
                    }
                    if (
$diffcount 6){
                        
$spam_uid[$uid] = $uid;
                        
#echo "Removing duplicate: $uid ($subject)\n";
                        
if (strlen($message_id) && ($message_id == $message_id_1)){
                            
#echo "$subject\n sure looks like spam... Deleting the original as well\n";
                            
$old_uid imap_uid($imap$i 1);
                            
$spam_uid[$old_uid] = $old_uid;
                            
#echo "uid: $uid old_uid: $old_uid\n";
                        
}
                        else{
                            
#echo "Saving one copy of $i ($subject)\n";
                            #echo "because the message_id's are different, so it might be real...\n";
                        
}
                    }
                }
                
//Filters:
                
if (!isset($spam_uid[$uid])){
                    
reset($filters);
                    while (list(
$recipient$folder) = each($filters)){
                        
//The 'X-Spam-Level:' makes sure Spam Assassin has had a shot at labeling it as junk,
                        //BEFORE you go putting it in a folder of non-junk.
                        
if (strstr($header'X-Spam-Level:') && stristr($header$recipient)){
                            
#echo "Filter: $uid -> $folder\n";
                            
$filtered[$folder][$uid] = $uid;
                            continue 
2//stop filtering, stop processing this message, get out of Dodge.
                        
}
                    }
                    
//If we have made it to this line of code, then A. we don't think it's spam, and B. it didn't get filtered to another mailbox
                    //In that case, we should move it to the 'cleaned' box, so I can IGNORE the transitory Inbox
                    
if (strlen($subject)){
                        
//Sigh.  My filters aren't good enough yet.
                        //Need to De-Biff the subject and then use is_spam_header...
                        #echo "Would move $i ($uid) Subject: $subject to 'cleaned' box.\n";
                        #$filtered['AAAFiltered'][$uid] = $uid;
                    
}
                }
            }
            
            
$status imap_status($imap$nameSA_ALL);
            
#echo "original uidvalidity: $uidvalidity<BR>\n";
            #echo " current uidvalidity: ", $status->uidvalidity, "<BR>\n";
            
if ($uidvalidity == $status->uidvalidity){
                if (
count($spam_uid)){
                    
imap_delete($imapimplode(','$spam_uid), FT_UID);
                    
#echo "Deleted:\n", implode("\n", $subjects);
                
}
                else{
                    
#echo "No spam detected in $name\n";
                
}
                
//Apply filters
                
reset($filtered);
                while (list(
$folder$uids) = each($filtered)){
                    
$uid_list implode(','$uids);
                    
#echo "Moving ", count($uids), " messages ($uid_list) to $folder\n";
                    #echo "imap: $imap\n";
                    #echo "uid_list: $uid_list\n";
                    #echo "INBOX.folder: INBOX.$folder\n";
                    #echo "CP_UID: ", CP_UID, "\n";
                    #echo "FT_UID: ", FT_UID, "\n";
                    
imap_mail_move($imap$uid_list"INBOX.$folder"CP_UID) or trigger_error("Move $folder $uid_list failed " imap_alerts_errors(), E_USER_ERROR);
                }
                if (
count($spam_uid) || count($filtered)){
                    
imap_expunge($imap);
                }
            }
            else{
                echo 
"Unable to delete spam because uidvalidity changed from $uidvalidity to "$status->uidvalidity"\n";
            }
        }
        elseif (
stristr($name'Trash')){
            
$trash[] = $name;
        }
        while (list(, 
$t) = each($trash)){
            @
imap_reopen($imap$t) or trigger_error("Could not open trash: $t " imap_alerts_errors(), E_USER_ERROR);
            
imap_delete($imap'1:*') or trigger_error("Could not empty trash: $t " imap_alerts_errors(), E_USER_ERROR);
            
imap_expunge($imap) or trigger_error("Could not expunge trash: $t " imap_alerts_errors(), E_USER_ERROR);
        }
    }
    
    
imap_close($imap);
    
    
    function 
find_body($imap$message_number$part_number '1'$structure 0){
        
#echo "MSG: $message_number - Currently in part: $part_number\n";
        
if (!$structure){
            
$structure = @imap_fetchstructure($imap$message_numberFT_PEEK);
            
#print_r($structure);
        
}
        
$result = @imap_fetchbody($imap$message_number$part_numberFT_PEEK);
        if (
strlen($result)) return $result;
        switch(
$structure->type){
            case 
TYPETEXT:
                
#echo "Found Body in: $part_number\n";
                
$result = @imap_fetchbody($imap$message_number$part_numberFT_PEEK);
                return 
$result;
            break;
            case 
TYPEMESSAGE:
                
#echo "\nStupid 'message' type:\n";
                #echo $part_number, "\n";
                #print_r($structure);
                
$result = @imap_fetchbody($imap$message_number$part_numberFT_PEEK);
                
#echo "maybe it's $result\n";
                
return $result;
            break;
            case 
TYPEMULTIPART:
                while ((list(
$no$part) = each($structure->parts))){
                    
#echo "PARTS is parts:\n";
                    #print_r($structure->parts);
                    
$next_part "$part_number." . ($no 1);
                    
#echo "Moving to '$next_part'\n";
                    
if ($result find_body($imap$message_number$next_part$part)){
                        
#echo "Found it in '$next_part'\n";
                        
return $result;
                    }
                }
                
//If it's not buried in part 1, dig into the other parts:
                
if (!strstr($part_number'.')){
                    for (
$i $part_number 1$i count($structure->parts); $i++){
                        
#echo "Trying part $i\n";
                        
if ($result find_body($imap$message_number$i$structure)){
                            
#echo "Found it in '$i'\n";
                            
return $result;
                        }
                    }
                }
            break;
            case 
TYPEAPPLICATION:
            case 
TYPEAUDIO:
            case 
TYPEIMAGE:
            case 
TYPEVIDEO:
                return 
'';
            break;
            case 
TYPEOTHER:
                
#echo "What the hell is TYPEOTHER anyway?\n";
                #print_r($structure);
            
break;
            default:
                
#echo "Some made-up Microsoft crap, no doubt:\n";
                #print_r($structure);
            
break;
        }
        return 
$result;
        
#echo "Having reached the end of find_body, I believe I cannot find the body:\n";
        #print_r($structure);
    
}
    
    function 
is_spam_header($headers$subject){
        return
            
stristr($headers'****SPAM***')
            || (
trim($subject) == '')
            || 
stristr($headers'webmillion')
            || 
stristr($headers'joao@ulele.com')
            || 
stristr($headers'Wicked screensaver')
            || 
stristr($headers'Reminder - Musicians Only Discussion Group')
            || 
stristr($headers'(no subject)')
      || 
stristr($headers'Big 5')
      || 
stristr($headers'BATISTA')
      || 
stristr($headers'HGH Myth')
      || 
stristr($headers'buy.com')
      || 
stristr($headers'Viagra')
      || 
stristr($headers'Vioxx')
      || 
stristr($headers'valium')
            || 
stristr($headers'your medicine')
            || 
stristr($headers'your pills')
            || 
stristr($headers'your medication')
            || 
stristr($headers'diploma')
            || 
stristr($headers'inexpensive software')
            || 
stristr($headers'low-priced software')
            || 
stristr($headers'ebay profits')
            || 
stristr($headers'Cialis')
            || 
stristr($headers'Levitra')
            || 
stristr($headers'erectile')
            || 
stristr($headers'pharmacy')
            || 
stristr($headers'prescription')
            || 
stristr($headers'darvon')
            || 
stristr($headers'casino')
            || 
stristr($headers'generic')
            || 
stristr($headers'doctor')
            || 
stristr($headers'get laid')
            || 
stristr($headers'freebie@l-i-e.com')
            || 
stristr($headers'Airline Promotions')
            || 
stristr($headers'Testers Needed')
            || 
stristr($subject'message subject')
            || 
stristr($subject'medication')
            || 
stristr($subject'phentermine')
            || 
stristr($subject'usbank')
            || 
stristr($subject'investor')
            || 
stristr($subject'xanax')
            || 
stristr($subject'roulette')
            || 
stristr($subject'office xp')
            || 
stristr($subject'hydrocodone')
            || 
stristr($subject'vicodin')
            || 
stristr($subject'homeowner')
            || 
stristr($subject'popular software')
            || 
stristr($subject'low-cost software')
            || 
stristr($subject'your request')
            || 
stristr($subject'we owe you $')
            || 
stristr($subject'we cannot cancel')
            || 
stristr($subject'sexually explicit')
            || 
stristr($subject'sexually-explicit')
            || 
stristr($subject'friend with benefits')
            || 
stristr($subject'adults only')
            || 
stristr($subject'=?iso-8859')
            || 
stristr($subject'this program')
            || 
stristr($subject'Rolex')
            || 
stristr($subject'Jet Out of Town')
            || 
stristr($subject'2 Round-Trip Worldwide AirlineTickets')
            || 
stristr($subject'Winter Airline Promotion')
            || 
stristr($subject'medical marvel')
            || 
stristr($subject'reduction in high blood pressure')
            || 
stristr($subject'diet pills')
            || 
stristr($subject'payment confirmation')
            || 
stristr($subject'I owe you one')
            || 
stristr($subject'did I send you this')
            || 
stristr($subject'did I sent you this')
            || 
stristr($subject'did I send this to you')
            || 
stristr($subject'v1agra')
            || 
stristr($subject'st0ck')
            || 
stristr($subject'microcap')
            || 
stristr($subject'smallcap')
            || 
stristr($subject'small cap')
            || 
stristr($subject'online drugs')
            || 
stristr($subject'prescríption')
            || 
stristr($subject'did you seen this')
            || 
stristr($subject'weight loss')
            || 
stristr($subject'regalis')
            || 
stristr($subject'tired of being fat')
            || 
stristr($subject'shipped overnight to your door')
            || 
stristr($subject'Vìagra'// accent-i
            
|| stristr($subject'need your tablets')
            || 
stristr($subject'want your tablets')
            || 
stristr($subject'want to surpriser her')
            || 
stristr($subject'mêdic')
            || 
stristr($subject'improve your muscle mass')
            || 
stristr($subject'get meds online')
            || 
stristr($subject"can't go to the beach")
            || 
stristr($subject"can't get it up")
            || 
stristr($subject'microsoft office')
            || 
stristr($subject'pay less for')
            || 
stristr($subject'legitimate software')
            || 
stristr($subject'information about rejected payment')
            || 
stristr($subject'I need your help')
            || 
stristr($subject'order confirmation')
            || 
stristr($subject'sexually - explicit')
            || 
stristr(str_replace('.'''$subject), 'investor')
            || (
strcasecmp(trim($subject), 'FWD:') === 0)
            || (
strcasecmp(trim($subject), 'FWD') === 0)
            || (
strcasecmp(trim($subject), 'RE:') === 0)
            || (
strcasecmp(trim($subject), 'RE') === 0)
            || (
strcasecmp(trim($subject), 'none') === 0)
            || (
strcasecmp(trim($subject), 'Re: hi') === 0)
            || (
strcasecmp(trim($subject), 'hi') === 0)
            || 
preg_match('/[Re: \\[\\]0-9]*(update[s]?|upgrade[s]?|please)/'$subject)
            || 
preg_match('/Status update for account [0-9A-Z]*/'$subject)
            || 
preg_match('/Payment N[0-9]*/'$subject)
            || 
preg_match('/Application # [0-9]*/'$subject)
        ;
    }
?>