Source for file mbox.php
Documentation is available at mbox.php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2004 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 3.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available through the world-wide-web at the following url: |
// | http://www.php.net/license/3_0.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Roberto Berto <darkelder.php.net> |
// +----------------------------------------------------------------------+
// $Id: mbox.php,v 1.11 2004/10/07 14:04:55 darkelder Exp $
* Mbox PHP class to Unix MBOX parsing and using
* int resource mbox->open(string file)
* open a mbox and return a resource id
* bool mbox->close(resource)
* close a mbox resource id
* int mbox->size(resource)
* return mbox number of messages
* string mbox->get(int resource, messageNumber)
* return the message number of the resource
* bool mbox->update(int resource, int messageNumber, string message)
* update the message offset to message (need write permission)
* bool mbox->remove(int resource, int messageNumber)
* remove the message messageNumber (need write permission)
* bool mbox->insert(int resource, string message[, $offset = null])
* add message to the end of the mbox. Offset == 0 message will
* be append at first message. If after == null will be the last
* one message. (need write permission)
* - CPAN Perl Mail::Folder::Mbox Module
* Used as a start point to create this class.
* http://search.cpan.org/author/KJOHNSON/MailFolder-0.07/Mail/Folder/Mbox.pm
* - PHP Mime Decode PEAR Module
* Use it to parse headers and body.
* http://pear.php.net/package-info.php?pacid=21
From Foo@example.com Fri Dec 27 14:31:10 2002
Received: from [unix socket] by campos.example.com (LMTP); Fri, 27 Dec
2002 14:31:10 -0200 (BRST)
Date: Fri, 27 Dec 2002 14:31:21 -0500
Message-Id: <200212271931.gBRJVL012289@example.com>
Received: from pcp128525pcs.foo.example.com (
pcp128525pcs.example.com [99.99.99.99]) by/
serjolen6com.example.com (v64.19) with ESMTP id
MAILRELAYINZA98-3601058302; Fri, 08 Nov 2002 06:39:05 -0500
Subject: This is A SPAM!!
// uncomment to see lots of things
$mid = $mbox->open("mbox");
// uncomment to see internal vars
// deleting a message (uncomment to test)
#$res1 = $mbox->remove($mid,0);
if (PEAR::isError($res1))
print $res1->getMessage();
// changing a message (uncomment to test)
#$res2 = $mbox->update($mid,0,$content);
if (PEAR::isError($res2))
print $res2->getMessage();
// adding a message (uncomment to test)
$res3 = $mbox->insert($mid,$content,0);
if (PEAR::isError($res3))
print $res3->getMessage();
require_once "Mail/mimeDecode.php";
// showing current messages with Mail Mime
for ($x = 0; $x < $mbox->size($mid); $x++)
printf("Message: %08d<pre>",$x);
$thisMessage = $mbox->get($mid,$x);
$decode = new Mail_mimeDecode($thisMessage, "\r\n");
$structure = $decode->decode();
print "</pre><hr /><hr /><hr />";
* @author Roberto Berto <darkelder@php.net>
* Resources data like file name, file resource, mbox number, and other
* cacheds things are stored here.
* Note that it isnt really a valid resource type. It is of array type.
* Set to true to turn on debug mode
* Open the Mbox file and return an resource identificator.
* Also, this function will process the Mbox and create a cache
* that tells each message start and end bytes.
* @param int $file Mbox file to open
* @return mixed ResourceID on success else pear error class
// check if file exists else return pear error
return PEAR ::raiseError ("Cannot open the mbox file: file doesnt exists.");
// getting next resource it to set
$resourceId = sizeof($this->_resources) + 1;
// setting filename to the resource id
$this->_resources[$resourceId]["filename"] = $file;
$this->_resources[$resourceId]["fresource"] = fopen($file, "r");
if (!is_resource($this->_resources[$resourceId]["fresource"])) {
return PEAR ::raiseError ("Cannot open the mbox file: maybe without permission.");
// process the file and get the messages bytes offsets
$this->_process ($resourceId);
* Close the Mbox file opened by open()
* @param int $resourceId Mbox resouce id created by open
* @return mixed true on success else pear error class
function close($resourceId)
if (!is_resource($this->_resources[$resourceId]["fresource"])) {
return PEAR ::raiseError ("Cannot close the mbox file because it wanst open.");
if (!fclose($this->_resources[$resourceId]["fresource"])) {
return PEAR ::raiseError ("Cannot close the mbox, maybe file is being used (?)");
* Get Mbox Number of Messages
* @param int $resourceId Mbox resouce id created by open
* @return int Number of messages on Mbox (starting on 1,
* 0 if no message exists)
function size($resourceId)
return sizeof($this->_resources[$resourceId]["messages"]);
* Get a Message from Mbox
* Note: Message number start from 0.
* @param int $resourceId Mbox resouce id created by open
* @param int $message The number of Message
* @return string Return the message else pear error class
function get($resourceId, $message)
// checking if we have bytes locations for this message
if (!is_array($this->_resources[$resourceId]["messages"][$message])) {
return PEAR ::raiseError ("Message doesnt exists.");
// getting bytes locations
$bytesStart = $this->_resources[$resourceId]["messages"][$message][0 ];
$bytesEnd = $this->_resources[$resourceId]["messages"][$message][1 ];
// a debug feature to show the bytes locations
printf("%08d=%08d<br />", $bytesStart, $bytesEnd);
// seek to start of message
if (@fseek($this->_resources[$resourceId]["fresource"], $bytesStart) == -1 ) {
return PEAR ::raiseError ("Cannot read message bytes");
if ($bytesEnd - $bytesStart > 0 ) {
// reading and returning message (bytes to read = difference of bytes locations)
$msg = fread($this->_resources[$resourceId]["fresource"],
$bytesEnd - $bytesStart) . "\n";
* Remove a message from Mbox and save it.
* Note: messages start with 0.
* @param int $resourceId Mbox resouce id created by open
* @param int $message The number of Message to remove, or
* array of message ids to remove
* @return mixed Return true else pear error class
function remove($resourceId, $message)
// convert single message to array
$message = array ($message);
// checking if we have bytes locations for this message
foreach ($message as $msg) {
if (!is_array($this->_resources[$resourceId]["messages"][$msg])) {
return PEAR ::raiseError (" Message $msg doesn't exist." );
// changing umask for security reasons
// returning to old umask
$ftemp = fopen($ftempname, "w");
return PEAR ::raiseError ("Cannot create a temp file. Cannot handle this error.");
// writing only undeleted messages
$messages = $this->size($resourceId);
for ($x = 0; $x < $messages; $x++ ) {
$messageThis = $this->get($resourceId, $x);
$filename = $this->_resources[$resourceId]["filename"];
$this->close($resourceId);
return $this->_move ($resourceId, $ftempname, $filename);
* Note: Mail_Mbox auto adds \n\n at end of the message
* Note: messages start with 0.
* @param int $resourceId Mbox resouce id created by open
* @param int $message The number of Message to updated
* @param string $content The new content of the Message
* @return mixed Return true else pear error class
function update($resourceId, $message, $content)
// checking if we have bytes locations for this message
if (!is_array($this->_resources[$resourceId]["messages"][$message])) {
return PEAR ::raiseError ("Message doesnt exists.");
$ftemp = fopen($ftempname, "w");
return PEAR ::raiseError ("Cannot create a temp file. Cannot handle this error.");
// writing only undeleted messages
$messages = $this->size($resourceId);
for ($x = 0; $x < $messages; $x++ ) {
$messageThis = $content . "\n\n";
$messageThis = $this->get($resourceId, $x);
$filename = $this->_resources[$resourceId]["filename"];
$this->close($resourceId);
return $this->_move ($resourceId, $ftempname, $filename);
* PEAR::Mail_Mbox will insert the message according its offset.
* 0 means before the actual message 0. 3 means before the message 3
* (Remember: message 3 is the forth message). The default is put
* AFTER the last message.
* Note: PEAR::Mail_Mbox auto adds \n\n at end of the message
* @param int $resourceId Mbox resouce id created by open
* @param string $content The content of the new Message
* @param int offset Before the offset. Default: last message
* @return mixed Return true else pear error class
function insert($resourceId, $content, $offset = NULL )
// checking if we have bytes locations for this message
if (!is_array($this->_resources[$resourceId])) {
return PEAR ::raiseError ("ResourceId doesnt exists.");
$ftemp = fopen($ftempname, "w");
return PEAR ::raiseError ("Cannot create a temp file. Cannot handle this error.");
// writing only undeleted messages
$messages = $this->size($resourceId);
if ($messages == 0 && $offset !== NULL ) {
for ($x = 0; $x < $messages; $x++ ) {
if ($offset !== NULL && $x == $offset) {
$messageThis = $this->get($resourceId, $x);
$filename = $this->_resources[$resourceId]["filename"];
$this->close($resourceId);
return $this->_move ($resourceId, $ftempname, $filename);
* Used internally to copy the content of the temp file to the mbox file
* @parm int $resourceId Resource file
* @parm string $ftempname Source file - will be removed
* @param string $filename Output file
function _move ($resourceId, $ftempname, $filename)
$ftemp = fopen($ftempname, "r");
return PEAR ::raiseError ("Cannot open temp file.");
$fp = @fopen($filename, "w");
return PEAR ::raiseError ("Cannot write on mbox file.");
while (feof($ftemp) != true ) {
$strings = fread($ftemp, 4096 );
return PEAR ::raiseError ("Cannot write to file.");
// open another resource and substitute it to the old one
$mid = $this->open($filename);
$this->_resources[$resourceId] = $this->_resources[$mid];
unset ($this->_resources[$mid]);
* - Get start bytes and end bytes of each messages
* @param int $resourceId Mbox resouce id created by open
function _process ($resourceId)
if (!is_resource($this->_resources[$resourceId]["fresource"])) {
return PEAR ::raiseError ("Resource isn't valid.");
if (@fseek($this->_resources[$resourceId]["fresource"], 0 ) == -1 ) {
return PEAR ::raiseError ("Cannot read mbox");
while (feof($this->_resources[$resourceId]["fresource"]) != true ) {
$c = fgetc($this->_resources[$resourceId]["fresource"]);
// each \n we will check things
// checking if start with From
if (substr($lineThis, 0 , 5 ) === "From ") {
// this line byte count is last line more 1 byte
$bytesStart = $bytesEnd + 1;
// last line byte count is this line bytes minus this line length
$bytesEnd = $bytes - strlen($lineThis);
// we will check messages after they end
printf("#################### from byte %08d to byte %08d ################### <br />", $bytesStart, $bytesEnd);
// setting new message points
$messagesCount = $this->size($resourceId);
$this->_resources[$resourceId]["messages"][$messagesCount][0 ] = $bytesStart;
$this->_resources[$resourceId]["messages"][$messagesCount][1 ] = $bytesEnd;
// increasing number of lines (doesn't matter)
// last line is this line
// this line is blank now
printf("%08d:%08d %s<br/>", $lines, $bytes, $lineLast);
// last message must be made here - again same things -
// this line byte count is last line more 1 byte
$bytesStart = $bytesEnd + 1;
// last line byte count is this line bytes minus this line length
$bytesEnd = $bytes - strlen($lineThis) - 2;
// we will check messages after they end
$messagesCount = $this->size($resourceId);
$this->_resources[$resourceId]["messages"][$messagesCount][0 ] = $bytesStart;
$this->_resources[$resourceId]["messages"][$messagesCount][1 ] = $bytesEnd;
Documentation generated on Mon, 11 Mar 2019 13:57:03 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|