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.2 2006/06/25 09:27:36 cweiske Exp $
* Class to read mbox mail files.
class Mail_Mbox extends PEAR
* Timestamp at which the file has been modified last
var $_lastModified = null;
* Set to true to turn on debug mode
* Directory in which the temporary mbox files are created.
* Even if it's a unix directory, it does work on windows as
* the only function it's used in is tempnam which automatically
* chooses the right temp directory if this here doesn't exist.
* So this variable is for special needs only.
* Create a new Mbox class instance.
* After creating it, you should use open().
* @param string $file Filename to open.
function Mail_Mbox ($file)
* Also, this function will process the Mbox and create a cache
* that tells each message start and end bytes.
// check if file exists else return pear error
return PEAR ::raiseError ('Cannot open the mbox file "' . $this->_file . '": file does not exist.');
$this->_lastModified = filemtime($this->_file);
$this->_resource = fopen($this->_file, 'r');
return PEAR ::raiseError ('Cannot open the mbox file: maybe without permission.');
// process the file and get the messages bytes offsets
* Close the Mbox file opened by open()
* @return mixed true on success, else PEAR_Error
return PEAR ::raiseError ('Cannot close the mbox file because it was not open.');
if (!fclose($this->_resource)) {
return PEAR ::raiseError ('Cannot close the mbox, maybe file is being used (?)');
* Get number of messages in this mbox
* @return int Number of messages on Mbox (starting on 1,
* 0 if no message exists)
if ($this->_index !== null ) {
* Get a message from the mbox
* Note: Message number start from 0.
* @param int $message The number of Message
* @return string Return the message, PEAR_Error on error
// checking if we have bytes locations for this message
if (!is_array($this->_index[$message])) {
return PEAR ::raiseError ('Message does not exist.');
// getting bytes locations
$bytesStart = $this->_index[$message][0 ];
$bytesEnd = $this->_index[$message][1 ];
// a debug feature to show the bytes locations
printf("%08d=%08d<br />", $bytesStart, $bytesEnd);
// seek to start of message
if (fseek($this->_resource, $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->_resource, $bytesEnd - $bytesStart) . "\n";
* Remove a message from Mbox and save it.
* Note: messages start with 0.
* @param int $message The number of the message to remove, or
* array of message ids to remove
* @return mixed Return true else PEAR_Error
function remove ($message)
if ($this->hasBeenModified ()) {
return PEAR ::raiseError ('File has been modified since loading. Re-open the file.');
// convert single message to array
$message = array ($message);
// checking if we have bytes locations for this message
foreach ($message as $msg) {
if (!isset ($this->_index[$msg]) || !is_array($this->_index[$msg])) {
return PEAR ::raiseError ('Message ' . $msg . 'does not exist.');
// changing umask for security reasons
$ftempname = tempnam($this->tmpdir, 'Mail_Mbox');
// returning to old umask
$ftemp = fopen($ftempname, 'w');
return PEAR ::raiseError ('Cannot create a temp file "' . $ftempname . '". Cannot handle this error.');
// writing only undeleted messages
$messages = $this->size ();
for ($x = 0; $x < $messages; $x++ ) {
$messageThis = $this->get ($x);
return $this->_move ($ftempname, $this->_file);
* Note: Mail_Mbox auto adds \n\n at end of the message
* Note: messages start with 0.
* @param int $message The number of Message to updated
* @param string $content The new content of the Message
* @return mixed Return true if all is ok, else PEAR_Error
function update ($message, $content)
if ($this->hasBeenModified ()) {
return PEAR ::raiseError ('File has been modified since loading. Re-open the file.');
// checking if we have bytes locations for this message
if (!is_array($this->_index[$message])) {
return PEAR ::raiseError ('Message does not exists.');
$ftempname = tempnam($this->tmpdir, 'Mail_Mbox');
$ftemp = fopen($ftempname, 'w');
return PEAR ::raiseError ('Cannot create temp file "' . $ftempname . '" . Cannot handle this error.');
$messages = $this->size ();
for ($x = 0; $x < $messages; $x++ ) {
$messageThis = $content . "\n\n";
$messageThis = $this->get ($x);
return $this->_move ($ftempname, $this->_file);
* 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 (offset = null).
* Note: PEAR::Mail_Mbox auto adds \n\n at end of the message
* @param string $content The content of the new message
* @param int offset Before the offset. Default: last message (null)
* @return mixed Return true else pear error class
function insert ($content, $offset = null )
if ($this->hasBeenModified ()) {
return PEAR ::raiseError ('File has been modified since loading. Re-open the file.');
$ftempname = tempnam($this->tmpdir, 'Mail_Mbox');
$ftemp = fopen($ftempname, 'w');
return PEAR ::raiseError ('Cannot create temp file "' . $ftempname . '". Cannot handle this error.');
// writing only undeleted messages
$messages = $this->size ();
if ($messages == 0 && $offset !== null ) {
for ($x = 0; $x < $messages; $x++ ) {
if ($offset !== null && $x == $offset) {
$messageThis = $this->get ($x);
return $this->_move ($ftempname, $this->_file);
* Used internally to copy the content of the temp file to the mbox file
* @parm string $ftempname Source file - will be removed
* @param string $filename Output file
function _move ($ftempname, $filename)
$ftemp = fopen($ftempname, 'r');
return PEAR ::raiseError ('Cannot open temp file "' . $ftempname . '".');
$fp = fopen($filename, 'w');
return PEAR ::raiseError ('Cannot write on mbox file "' . $filename . '".');
while (feof($ftemp) != true ) {
$strings = fread($ftemp, 4096 );
return PEAR ::raiseError ('Cannot write to file "' . $filename . '".');
// open another resource and substitute it to the old one
$this->_file = $filename;
* - Get start bytes and end bytes of each messages
return PEAR ::raiseError ('Resource is not valid. Maybe the file has not be opened?');
if (fseek($this->_resource, 0 ) == -1 ) {
return PEAR ::raiseError ('Cannot read mbox');
// current start byte position
// last start byte position
// there aren't any message
while ($line = fgets($this->_resource, 4096 )) {
// if line start with "From ", it is a new message
if (0 === strncmp($line, 'From ', 5 )) {
// save last start byte position
// new start byte position is the start of the line
// if it is not the first message add message positions
$this->_index[] = array ($laststart, $start - 1 );
// tell that there is really a message on the file
// if there are just one message, or if it's the last one,
// add it to messages positions
if (($start == 0 && $hasmessage === true ) || ($start > 0 )) {
$this->_index[] = array ($start, ftell($this->_resource));
* Checks if the file was modified since it has been loaded.
* If this is true, the file needs to be re-opened.
* @return boolean True if it has been modified.
function hasBeenModified ()
return filemtime($this->_file) > $this->_lastModified;
Documentation generated on Mon, 11 Mar 2019 14:41:28 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|