Re: Need to override mail function
- From: petersprc <petersprc@xxxxxxxxx>
- Date: Tue, 27 May 2008 08:41:05 -0700 (PDT)
Hi,
You can do this on unix by replacing the default sendmail command with
sendmail-filter script below. Add a line like this to your virtual
host definition:
php_admin_value sendmail_path
"/opt/site/util/sendmail-filter
-field set X-Domain www.test.example"
You can define arbitrary header fields using the "-field set NAME
VALUE" option. For more options, run sendmail-filter -help.
[sendmail-filter]
#!/usr/bin/php5 -q
<?php
error_reporting(E_ALL | E_STRICT);
class MailFilter
{
function run()
{
$this->status = 0;
if ($this->parseArgs() && !$this->help) {
$this->send();
}
return $this->status;
}
function parseArgs()
{
$ok = true;
global $argc;
global $argv;
$this->prog = $argv[0];
$this->help = false;
$this->fields = array();
$this->fieldDict = array();
$this->cmd = '/usr/sbin/sendmail -t -i';
$this->lineTerm = "\r\n";
$this->defaultHeaderTerm = "\r\n";
for ($i = 1; $i < $argc; $i++) {
$str = $argv[$i];
if ($str == '-help') {
if ($argc != 2) {
$this->error('Parameter -help may not be ' .
'used with any other parameters.');
$ok = false;
} else {
$this->help = true;
}
} elseif ($str == '-field') {
if ($i >= $argc - 3) {
$this->error('The -field option requires an ' .
'action, name, and value.');
$ok = false;
} else {
$action = $argv[$i + 1];
if ($action != 'set' && $action != 'add' &&
$action != 'del' && $action != 'set-default') {
$this->error('Action must be ' .
'set, add, del, or set-default.');
$ok = false;
break;
} else {
$ln = strtolower(trim($argv[$i + 2]));
$item = array($argv[$i + 1],
$argv[$i + 2], $argv[$i + 3], $ln);
$this->fields[] = $item;
$this->fieldDict[$action][$ln] = $item;
$i += ($action == 'del' ? 2 : 3);
}
}
} elseif ($str == '--') {
break;
} elseif (substr($str, 0, 1) == '-') {
$this->error("Invalid parameter: \"$str\".");
$ok = false;
} else {
break;
}
}
if ($ok && $i < $argc) {
$this->cmd = '';
for ($j = $i; $j < $argc; $j++) {
if ($this->cmd != '') $this->cmd .= ' ';
$this->cmd .= $argv[$j];
}
}
if ($ok && $this->help) {
self::printUsage();
}
if (!$ok && $this->status == 0) {
$this->status = 1;
}
return $ok;
}
function send()
{
$ok = true;
$header = '';
$used = array();
$headerTerm = $this->defaultHeaderTerm;
$count = 0;
for ($n = 0; !feof(STDIN); $n++) {
if (($line = fgets(STDIN)) === false) {
break;
} elseif ($line == "\r\n" || $line == "\n") {
$headerTerm = $line;
break;
} else {
if (($p = strpos($line, ':')) === false) {
$name = $line;
$val = null;
} else {
$name = substr($line, 0, $p);
$val = substr($line, $p + 1);
}
$ln = strtolower(trim($name));
if (isset($this->fieldDict['set']) &&
isset($this->fieldDict['set'][$ln])) {
if (!isset($used[$ln])) {
$item = $this->fieldDict['set'][$ln];
$header .= $item[1] . ': ' . $item[2] .
$this->lineTerm;
$used[$ln] = $item;
$count++;
}
} elseif (!(isset($this->fieldDict['del']) &&
isset($this->fieldDict['del'][$ln]))) {
$header .= $line;
$used[$ln] = $val;
$count++;
}
}
}
if ($ok) {
foreach ($this->fields as $f) {
if ($f[0] == 'add' || (($f[0] == 'set' ||
$f[0] == 'set-default') &&
!isset($used[$f[3]]))) {
$header .= $f[1] . ': ' . $f[2] .
$this->lineTerm;
$count++;
}
}
if ($count) {
$header .= $headerTerm;
}
if (($pipe = popen($this->cmd, 'w')) === false) {
$this->error("Failed to execute mail command.");
$ok = false;
} else {
if (fwrite($pipe, $header) === false) {
$this->error("Failed to write to mail pipe.");
$ok = false;
} else {
while (!feof(STDIN)) {
if (($buf = fread(STDIN, 16284)) === false) {
$this->error("Failed to read input.");
$ok = false;
break;
}
if (fwrite($pipe, $buf) === false) {
$this->error("Failed to write to mail pipe.");
$ok = false;
break;
}
}
}
if (($pr = pclose($pipe)) === false) {
$this->error("Failed to close pipe.");
$ok = false;
} elseif ($pr != 0) {
$this->error("Mail command \"$this->cmd\" " .
"returned error status $pr.");
$this->status = $pr;
$ok = false;
}
}
}
if (!$ok && $this->status == 0) {
$this->status = 2;
}
return $ok;
}
function printUsage($fd = null)
{
fwrite((is_null($fd) ? STDOUT : STDERR),
$this->usageString());
}
function usageString()
{
$str = "Usage: $this->prog [OPTION]... [COMMAND]..." .
PHP_EOL . PHP_EOL;
$str .= 'Alters the sendmail header and body read from ' .
'standard input and' . PHP_EOL . 'passes the result to ' .
'the specified sendmail command.' . PHP_EOL . PHP_EOL;
$str .= 'COMMAND: An argument in ' .
'the sendmail command. Defauls to the list ' . PHP_EOL .
'/usr/lib/sendmail -t -v if no COMMAND is given.' .
PHP_EOL . PHP_EOL;
$str .= 'OPTION:' . PHP_EOL . PHP_EOL;
$str .= '-field set NAME VALUE: Set header field NAME to ' .
'VALUE.' . PHP_EOL;
$str .= '-field add NAME VALUE: Append header field NAME ' .
'with contents' . PHP_EOL . ' VALUE.' . PHP_EOL;
$str .= '-field del NAME: Remove header field NAME.' .
PHP_EOL;
$str .= '-field set-default NAME VALUE: Set header field ' .
'NAME to VALUE if' . PHP_EOL . ' not already defined.' .
PHP_EOL;
$str .= '-help: Print this help message.' . PHP_EOL;
return $str;
}
function error($str)
{
fwrite(STDERR, $this->prog . ': ' . $str . PHP_EOL);
}
}
$filter = new MailFilter;
exit($filter->run());
?>
If you have some way to map the request's current working directory
($ENV['PWD']) to the domain, you can add that logic. If an alias is
used though, that might not be what you expect in all cases.
Regards,
John Peters
On May 23, 5:25 pm, vizzz <andrea.visin...@xxxxxxxxx> wrote:
I need to override php mail function to append an extra header entry.
My first solution was to modify php source code in ext/standard/
mail.c, this is pretty simple but i need to append something like:
domain: customer-domain.tld, where customer-domain.tld is the domain
that call mail().
my goal is to have something completely transparent to my users, or to
disable mail() and tell them to use custom_mail().
which is the cleaner way to implement this? an extension? source code
modification (but how to have domain in mail.c ?).
Thanks Andrea
.
- Follow-Ups:
- Re: Need to override mail function
- From: vizzz
- Re: Need to override mail function
- References:
- Need to override mail function
- From: vizzz
- Need to override mail function
- Prev by Date: need to get rid og new line extra spaces
- Next by Date: Re: why _0 is translating to _00 ?
- Previous by thread: Need to override mail function
- Next by thread: Re: Need to override mail function
- Index(es):