
=head1 NAME

Mail::Box::Mbox - handle folders in Mbox format

=head1 CLASS INHERITANCE

 Mail::Box::Mbox
   is a Mail::Box::File
   is a Mail::Box
   is a Mail::Reporter

=head1 SYNOPSIS

 use Mail::Box::Mbox;
 my $folder = Mail::Box::Mbox->new(folder => $ENV{MAIL}, ...);

=head1 DESCRIPTION

This documentation describes how Mbox mailboxes work, and also describes
what you can do with the Mbox folder object Mail::Box::Mbox.

=head1 METHODS

=head2 Initiation

=over 4

=item B<new> OPTIONS

(Class method)

 OPTION               DEFAULT
 access               'r'
 body_delayed_type    'Mail::Message::Body::Delayed'
 body_type            <see description>
 coerce_options       []
 create               <false>
 extract              10240
 field_type           undef
 fix_headers          <false>
 folder               $ENV{MAIL}
 folderdir            $ENV{HOME}.'/Mail'
 head_delayed_type    'Mail::Message::Head::Delayed'
 head_type            'Mail::Message::Head::Complete'
 keep_dups            <false>
 lock_extension       '.lock'
 lock_file            <foldername>.<lock-extension>
 lock_timeout         1 hour
 lock_type            'Mail::Box::Locker::DotLock'
 lock_wait            10 seconds
 locker               undef
 log                  'WARNINGS'
 manager              undef
 message_type         'Mail::Box::Mbox::Message'
 multipart_type       'Mail::Message::Body::Multipart'
 remove_when_empty    <true>
 save_on_exit         <true>
 subfolder_extension  '.d'
 trace                'WARNINGS'
 trusted              <depends on folder location>
 write_policy         undef

=over 4

=item B<access> =E<gt> MODE

See Mail::Box::new(access)

=item B<body_delayed_type> =E<gt> CLASS

See Mail::Box::new(body_delayed_type)

=item B<body_type> =E<gt> CLASS|CODE

See Mail::Box::File::new(body_type)

=item B<coerce_options> =E<gt> ARRAY

See Mail::Box::new(coerce_options)

=item B<create> =E<gt> BOOLEAN

See Mail::Box::new(create)

=item B<extract> =E<gt> INTEGER | CODE | METHOD | 'LAZY'|'ALWAYS'

See Mail::Box::new(extract)

=item B<field_type> =E<gt> CLASS

See Mail::Box::new(field_type)

=item B<fix_headers> =E<gt> BOOLEAN

See Mail::Box::new(fix_headers)

=item B<folder> =E<gt> FOLDERNAME

See Mail::Box::new(folder)

=item B<folderdir> =E<gt> DIRECTORY

See Mail::Box::new(folderdir)

=item B<head_delayed_type> =E<gt> CLASS

See Mail::Box::new(head_delayed_type)

=item B<head_type> =E<gt> CLASS

See Mail::Box::new(head_type)

=item B<keep_dups> =E<gt> BOOLEAN

See Mail::Box::new(keep_dups)

=item B<lock_extension> =E<gt> FILENAME|STRING

See Mail::Box::File::new(lock_extension)

=item B<lock_file> =E<gt> FILENAME

See Mail::Box::new(lock_file)

=item B<lock_timeout> =E<gt> SECONDS

See Mail::Box::new(lock_timeout)

=item B<lock_type> =E<gt> CLASS|STRING

See Mail::Box::new(lock_type)

=item B<lock_wait> =E<gt> SECONDS

See Mail::Box::new(lock_wait)

=item B<locker> =E<gt> OBJECT

See Mail::Box::new(locker)

=item B<log> =E<gt> LEVEL

See Mail::Reporter::new(log)

=item B<manager> =E<gt> MANAGER

See Mail::Box::new(manager)

=item B<message_type> =E<gt> CLASS

See Mail::Box::new(message_type)

=item B<multipart_type> =E<gt> CLASS

See Mail::Box::new(multipart_type)

=item B<remove_when_empty> =E<gt> BOOLEAN

See Mail::Box::new(remove_when_empty)

=item B<save_on_exit> =E<gt> BOOLEAN

See Mail::Box::new(save_on_exit)

=item B<subfolder_extension> =E<gt> STRING

Mbox folders do not support sub-folders.  However, this module can
simulate sub-directories if the user wants it to.  When a subfolder of
folder C<xyz> is created, we create a directory which is called C<xyz.d>
to contain them.  This extension C<.d> can be changed using this option.

=item B<trace> =E<gt> LEVEL

See Mail::Reporter::new(trace)

=item B<trusted> =E<gt> BOOLEAN

See Mail::Box::new(trusted)

=item B<write_policy> =E<gt> 'REPLACE'|'INPLACE'|undef

See Mail::Box::File::new(write_policy)

=back

=back

=head2 Opening folders

=over 4

=item B<clone> OPTIONS

See Mail::Box::clone()

=item B<create> FOLDERNAME, OPTIONS

 OPTION               DEFAULT
 folderdir            undef
 subfolder_extension  undef

=over 4

=item B<folderdir> =E<gt> DIRECTORY

See Mail::Box::create(folderdir)

=item B<subfolder_extension> =E<gt> STRING

If a directory is found on the location of the folder to be created, this
STRING is used to extend that directory name with.  This will cause the
directory to be seen as sub-folder for the created folder.  This argument
is passed to dirToSubfolder().

=back

=item B<folderdir> [DIRECTORY]

See Mail::Box::folderdir()

=item B<foundIn> [FOLDERNAME], [OPTIONS]

If no FOLDERNAME is specified, then the C<folder> option is taken.

 OPTION               DEFAULT
 folder               undef
 folderdir            undef
 subfolder_extension  <from object>

=over 4

=item B<folder> =E<gt> FOLDERNAME

=item B<folderdir> =E<gt> DIRECTORY

See Mail::Box::foundIn(folderdir)

=item B<subfolder_extension> =E<gt> STRING

=back

=back

=head2 On open folders

=over 4

=item B<addMessage> MESSAGE

See Mail::Box::addMessage()

=item B<addMessages> MESSAGE [, MESSAGE, ...]

See Mail::Box::addMessages()

=item B<copyTo> FOLDER, OPTIONS

See Mail::Box::copyTo()

=item B<filename> 

See Mail::Box::File::filename()

=item B<isModified> 

See Mail::Box::isModified()

=item B<modified> [BOOLEAN]

See Mail::Box::modified()

=item B<name> 

See Mail::Box::name()

=item B<organization> 

See Mail::Box::organization()

=item B<type> 

See Mail::Box::type()

=item B<update> OPTIONS

See Mail::Box::update()

=item B<url> 

See Mail::Box::url()

=item B<writable> 

See Mail::Box::writable()

=back

=head2 Closing the folder

=over 4

=item B<DESTROY> 

See Mail::Box::DESTROY()

=item B<close> OPTIONS

See Mail::Box::close()

=item B<delete> 

See Mail::Box::delete()

=back

=head2 The messages

=over 4

=item B<current> [NUMBER|MESSAGE|MESSAGE-ID]

See Mail::Box::current()

=item B<find> MESSAGE-ID

See Mail::Box::find()

=item B<message> INDEX [,MESSAGE]

See Mail::Box::message()

=item B<messageId> MESSAGE-ID [,MESSAGE]

See Mail::Box::messageId()

=item B<messageIds> 

See Mail::Box::messageIds()

=item B<messages> ['ALL',RANGE,'ACTIVE','DELETED',LABEL,!LABEL,FILTER]

See Mail::Box::messages()

=item B<scanForMessages> MESSAGE, MESSAGE-IDS, TIMESTAMP, WINDOW

See Mail::Box::scanForMessages()

=back

=head2 Sub-folders

=over 4

=item B<listSubFolders> OPTIONS

 OPTION               DEFAULT
 check                <false>
 folder               <obligatory>
 folderdir            <from folder>
 skip_empty           <false>
 subfolder_extension  <from object>

=over 4

=item B<check> =E<gt> BOOLEAN

See Mail::Box::listSubFolders(check)

=item B<folder> =E<gt> FOLDERNAME

See Mail::Box::listSubFolders(folder)

=item B<folderdir> =E<gt> DIRECTORY

See Mail::Box::listSubFolders(folderdir)

=item B<skip_empty> =E<gt> BOOL

See Mail::Box::listSubFolders(skip_empty)

=item B<subfolder_extension> =E<gt> STRING

When the method is called on an open folder, the extension defined by it is
used to detect sub-folders by default.  Otherwise, C<'.d'> is taken.

=back

=item B<nameOfSubfolder> NAME

See Mail::Box::nameOfSubfolder()

=item B<openRelatedFolder> OPTIONS

See Mail::Box::openRelatedFolder()

=item B<openSubFolder> NAME, OPTIONS

See Mail::Box::openSubFolder()

=back

=head2 Message threads [internals]

=over 4

=item B<toBeThreaded> MESSAGES

See Mail::Box::toBeThreaded()

=item B<toBeUnthreaded> MESSAGES

See Mail::Box::toBeUnthreaded()

=back

=head2 Reading and Writing [internals]

=over 4

=item B<appendMessages> OPTIONS

See Mail::Box::File::appendMessages()

=item B<coerce> MESSAGE

See Mail::Box::coerce()

=item B<determineBodyType> MESSAGE, HEAD

See Mail::Box::determineBodyType()

=item B<dirToSubfolder> DIRECTORY, EXTENSION

The DIRECTORY is renamed by appending the EXTENSION, which defaults to C<".d">,
to make place for a folder file on that specific location.  C<false> is
returned if this failed.

=item B<folderToFilename> FOLDERNAME, FOLDERDIR, [EXTENSION]

(Class or Instance method) 
Translate a folder name into a filename, using the
FOLDERDIR value to replace a leading C<=>.  If no EXTENSION is specified and
this method is called as instance method, new(subfolder_extension) is used.
Otherwise, the extension default to C<'.d'>.

=item B<lineSeparator> [STRING|'CR'|'LF'|'CRLF']

See Mail::Box::lineSeparator()

=item B<locker> 

See Mail::Box::locker()

=item B<parser> 

See Mail::Box::File::parser()

=item B<read> OPTIONS

See Mail::Box::read()

=item B<readMessages> OPTIONS

See Mail::Box::readMessages()

=item B<storeMessage> MESSAGE

See Mail::Box::storeMessage()

=item B<updateMessages> OPTIONS

See Mail::Box::updateMessages()

=item B<write> OPTIONS

See Mail::Box::File::write()

=item B<writeMessages> OPTIONS

See Mail::Box::writeMessages()

=back

=head2 Logging and Tracing

=over 4

=item B<defaultTrace> [LEVEL, [LEVEL]

See Mail::Reporter::defaultTrace()

=item B<errors> 

See Mail::Reporter::errors()

=item B<log> [LEVEL [,STRINGS]]

See Mail::Reporter::log()

=item B<report> [LEVEL]

See Mail::Reporter::report()

=item B<reportAll> [LEVEL]

See Mail::Reporter::reportAll()

=item B<trace> [LEVEL]

See Mail::Reporter::trace()

=item B<warnings> 

See Mail::Reporter::warnings()

=back

=head2 Other Methods

=over 4

=item B<AUTOLOAD> 

See Mail::Reporter::AUTOLOAD()

=item B<inGlobalDestruction> 

See Mail::Reporter::inGlobalDestruction()

=item B<logPriority> LEVEL

See Mail::Reporter::logPriority()

=item B<logSettings> 

See Mail::Reporter::logSettings()

=item B<notImplemented> 

See Mail::Reporter::notImplemented()

=item B<timespan2seconds> TIME

See Mail::Box::timespan2seconds()

=back

=head1 IMPLEMENTATION

=head2 How MBOX folders work

MBOX folders store many messages in one file.  Each message begins with a
line which starts with the string C<From >.  Lines inside a message which
accidentally start with C<From> are, in the file, preceded by `E<gt>'. This
character is stripped when the message is read.

In this respect must be noted that the format of the MBOX files is not
strictly defined.  The exact content of the separator lines differ between
Mail User Agents (MUA's).  Besides, some MUAs (like mutt) forget to encode
the C<From > lines within message bodies, breaking other parsers....

=head2 Simulation of sub-folders

MBOX folders do not have a sub-folder concept as directory based folders
do, but this MBOX module tries to simulate them.  In this implementation
a directory like

 Mail/subject1/

is taken as an empty folder C<Mail/subject1>, with the folders in that
directory as sub-folders for it.  You may also use

 Mail/subject1
 Mail/subject1.d/

where C<Mail/subject1> is the folder, and the folders in the
C<Mail/subject1.d> directory are used as sub-folders.  If your situation
is similar to the first example and you want to put messages in that empty
folder, the directory is automatically (and transparently) renamed, so
that the second situation is reached.

=head1 SEE ALSO

A good start to read is Mail::Box-Overview.
More documentation and a mailinglist are available from the project's
website at L<http://perl.overmeer.net/mailbox/>.

=head1 AUTHOR

Written by Mark Overmeer (L<mark@overmeer.net|mailto:mark@overmeer.net>)
with the help of many.  See the ChangeLog for details.

=head1 VERSION

This code is beta, version 2.037.

Copyright (c) 2001-2003 by the authors. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
