Search code examples
phpemailpermissionspiping

PHP script can not write to file with email piping


I have a simple script written to process received email. Here are the tested scenarios:

A. Script function is to send an email indicating an email was received at piped address.

-tested by browser - Success

-tested by CLI - Success

-tested by piping - Success

B. Script function is to parse and write files to folder, AND send email indicating email was received at piped address

-tested by browser - Files written and email sent.

-tested by CLI - Files written and email sent.

-tested by piping - Files NOT written, BUT email is sent.

I have simplified the script to the basic function of reading and writing the piped message. I suspect the issue is a permission problem, but I can not find any supporting evidence.

I am not fluent in CLI, but can perform some task. I am not sure where to look for log files for the piped scenario.

Piping works just fine in all tested scenarios. Here is the simplified code that fails when invoked by piping:

#!/usr/bin/php -q
<?php
/* Read the message from STDIN */
$fd = fopen("php://stdin", "r"); 
$email = ""; // This will be the variable holding the data.
while (!feof($fd)) {
$email .= fread($fd, 1024);
}
fclose($fd);
/* Saves the data into a file */
$fdw = fopen("/my/folder/mail.txt", "w");
fwrite($fdw, $email);
fclose($fdw);
/* Script End */

Thanks for any help.

Modified code to:

#!/usr/bin/php -q
<?php
/* Read the message from STDIN */
$email = file_get_contents('php://stdin');

/* Saves the data into a file */
$fdw = fopen("/Volumes/Cobra/Sites/email/mail.txt", "w+");
if (! $fdw) {
    error_log("Unable to open mail.txt for output.", 1, "myemail@mydomain.com", "From: admin@mydomain.com");
} else {
    fwrite($fdw, $email);
}

fclose($fdw);

/* Script End */

Error message was emailed. Now what? What user does the pipe-invoked script run as?


Solution

  • If it's a permissions problem, then either fopen will return FALSE on failure. You're not checking for that case, and assumes everything worked. Try

    $fd = fopen('php://stdin', 'r');
    if (!$fd) {
       die("Unable to open stdin for input");
    }
    
    $fdw = fopen(...);
    if (!$fdw) {
       die("Unable to open mail.txt for output");
    }
    

    If neither die() triggers, then it's not a permissions issue.

    As one stylistic thing, unless your real code is much more complicated and does want to process stdin in chunks, you could just do:

    $email = file_get_contents('php://stdin');