On Fri, 2018-12-07 at 08:21 +0000, Tim Streater wrote: On 07 Dec 2018, at 01:56, John <john.iliffe@xxxxxxxxx> wrote:
> I am trying to get e-mails one at a time from a pop3 mail server. I can open > the pop3 socket on port 110 using > > fsockopen(tcp://127.0.0.1, 110, $errno, $errstr) > > and I have no problem logging on to the mail account and issuing the LIST and > RETR commands. > > BUT getting the actual email has me stumped. Using fgets() works OK IF I can > tell it how many lines to expect. If not, it runs off the end of the file and > I > have to cancel the job manually. If I use the code in the fread() > documentation > it does the same thing: > > $message = ""; > while (! feof($mail_sock)) > { > $message .= fread($mail_sock, 8192); > } > > hangs at the end of the email and I need to cancel manually. Putting an echo > command right after the fread() statement shows that the entire message > arrives > correctly before it hangs. > > I have tried checking for the ".\r\n" standard pop3 EOF indicator and breaking > out of the while loop when I find it but that is unstable, that combination > occurred during testing in a random email. Same thing happened using fgets() > before I started trying fread().
You need to rtrim() each input line, and stop when you find a line consisting of just a full-stop (.)
Also, use fgets() to get the lines. Much easier.
$message = ''; while (true) { $line = rtrim (fgets ($mail_sock); if ($line=='.') break; // (Well, I think it's "break;" I should use to exit this loop :-) $message .= $line; }
I've had no problems doing this. See here:
<http://www.iletter.org.uk>
for a practical example (you want v2, not v2).
=========================================================== Thank you to all who replied. Very much appreciated. I think I will stop trying to reinvent the wheel and use the suggested IMAP functions, even though it calls for installing another PHP library. About time I updated to 7.3.x anyway!
Tim, FYI, the problem I encountered during testing using a few hundred emails randomly grabbed off the server, was that someone had sent an e-mail where they delimited a copy/paste operation with a string of dots. Since these were all alone on the line they matched the ./n/r sequence when I tested for end of e-mail.
The problem with any approach that relies on testing the received data is likely to be ambiguities like this. The server, based on looking at the received stream, just sends until it gets to EOF, sends the . delimiter and stops. fgets() and fread() don't seem to spot this until the socket times out.
Thanks again to all who replied.
John ===============================
|