Penguin

This consists of 3 parts;

  • Exim config change
  • PHP script to process bounces
  • A change to the From: header from which you send email

The config change is as follows;

/etc/exim4/virtualDomains/<domain> (or however you've setup your virtual domains)

^bounce.*:|/var/bounce_processing.php

I also needed to change my Exim config to allow regexp in an alias, as per http://www.acmelabs.co.uk/?p=4

/etc/exim4/conf.d/router/400_exim4-config_system_aliases:

data = ${lookup{$local_part}lsearch{/etc/aliases}}

becomes

data = ${lookup{$local_part}wildlsearch{/etc/aliases}}

The PHP script is as follows;

#!/usr/bin/php

<?php

  /*
    *** Script to process bounces

    Mike Bordignon
    16 Jan 2009
  */

  require('bounce_dbconn.php');


  # Get stdin

  $fp = fopen('php://stdin', 'r');
  while ( !feof($fp) ) { $buff .= fread($fp, 4096); }
  fclose($fp);
  unset($fp);
  $email_data = $buff;
  unset($buff);
  $email_data2 = explode(chr(10), $email_data);

  foreach ($email_data2 as $v) {

    // Find to address
    if ( substr($v, 0, 10) == 'To: bounce' ) {

      list(, $email) = explode(':', $v);
      list($mailbox, $domain) = explode('@', $email);
      list(, $bounce_id_sha) = explode('+', $mailbox);

      $q = "SELECT id FROM addresses WHERE sha1Hash = '$bounce_id_sha'";
      $r = mysql_query($q) or die(mysql_error());
      if ( !mysql_num_rows($r) ) { break; }
      else { $data = mysql_fetch_array($r); $bounce_id = $data['id']; }

      mysql_select_db('database');
      $q = "UPDATE addresses SET active = 0 WHERE id = $bounce_id";
      mysql_query($q);

      break;

    }

  }

You'll obviously need to send your emails from a different From: address to identify them in the event they bounce. I use bounce+<sha1 or similar hash>@domain.co.nz. To create the hash I've used the database id concatenated with a secret.