
=head1 NAME

Mail::Box::File - handle file-based folders

=head1 CLASS INHERITANCE

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

 Mail::Box::File is extended by
   Mail::Box::Mbox

=head1 SYNOPSIS


=head1 DESCRIPTION

Mail::Box::File is the base-class for all file-based folders: folders which
bundle multiple messages into one single file.  Usually, these messages are
separated by a special line which indicates the start of the next one.

=head1 METHODS

=head2 Initiation

=over 4

=item B<create> FOLDERNAME, OPTIONS

(Class method)

 OPTION               DEFAULT
 folderdir            undef

=over 4

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

See Mail::Box::create(folderdir)

=back

=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::File::Message'
 multipart_type       'Mail::Message::Body::Multipart'
 remove_when_empty    <true>
 save_on_exit         <true>
 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

The C<body_type> option for File folders defaults to

 sub determine_body_type($$)
 {   my $head = shift;
     my $size = shift || 0;
     'Mail::Message::Body::' . ($size > 10000 ? 'File' : 'Lines');
 }

which will cause messages larger than 10kB to be stored in files, and
smaller files in memory.

=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

When the dotlock locking mechanism is used, the lock is created with a
hardlink to the folder file.  For Mail::Box::File type of folders, this
file is by default named as the folder-file itself followed by
C<.lock>.  For example: the F<Mail/inbox> folder file will have a hardlink
made as F<Mail/inbox.lock>.

You may specify an absolute filename, a relative (to the folder's
directory) filename, or an extension (preceded by a dot).  So valid
examples are:

 .lock                  # appended to the folder's filename
 my_own_lockfile.test   # full filename, same dir
 /etc/passwd            # somewhere else

When the program runs with less priviledges (as normal user), often the
default inbox folder can not be locked with the lockfile name which is produced
by default.

=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<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

Sets the default write policy (see write(policy)).  With C<undef>, the best
policy is autodetected.

=back

=back

=head2 Opening folders

=over 4

=item B<clone> OPTIONS

See Mail::Box::clone()

=item B<folderdir> [DIRECTORY]

See Mail::Box::folderdir()

=item B<foundIn> [FOLDERNAME], OPTIONS

See Mail::Box::foundIn()

=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> 

Returns the filename for this folder, which may be an absolute or relative
path to the file.

Examples:

 print $folder->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

See Mail::Box::listSubFolders()

=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

(Class method)

 OPTION               DEFAULT
 folder               <obligatory>
 message              undef
 messages             undef

=over 4

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

See Mail::Box::appendMessages(folder)

=item B<message> =E<gt> MESSAGE

See Mail::Box::appendMessages(message)

=item B<messages> =E<gt> ARRAY-OF-MESSAGES

See Mail::Box::appendMessages(messages)

=back

=item B<coerce> MESSAGE

See Mail::Box::coerce()

=item B<determineBodyType> MESSAGE, HEAD

See Mail::Box::determineBodyType()

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

(Class or Instance method) 
Translate a folder name into a filename, using the
FOLDERDIR value to replace a leading C<=>.  SUBEXT is only used for MBOX
folders.

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

See Mail::Box::lineSeparator()

=item B<locker> 

See Mail::Box::locker()

=item B<parser> 

Create a parser for this mailbox.  The parser stays alive as long as
the folder is open.

=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

 OPTION               DEFAULT
 force                <false>
 policy               undef
 save_deleted         <false>

=over 4

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

See Mail::Box::write(force)

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

In what way will the mail folder be updated.  If not specified during the
write, the value of the C<write_policy> at folder creation is taken.

Valid values:

=over 4

=item * C<REPLACE>

First a new folder is written in the same directory as the folder which has
to be updated, and then a call to move will throw away the old immediately
replacing it by the new.  The name of the folder's temporary file is
produced in tmpNewFolder().

Writing in C<REPLACE> module is slightly optimized: messages which are not 
modified are copied from file to file, byte by byte.  This is much
faster than printing the data which is will be done for modified messages.

=item * C<INPLACE>

The original folder file will be opened read/write.  All message which where
not changed will be left untouched, until the first deleted or modified
message is detected.  All further messages are printed again.

=item * C<undef>

As default, or when C<undef> is explicitly specified, first C<REPLACE> mode
is tried.  Only when that fails, an C<INPLACE> update is performed.

=back

C<INPLACE> will be much faster than C<REPLACE> when applied on large
folders, however requires the C<truncate> function to be implemented on
your operating system.  It is also dangerous: when the program is interrupted
during the update process, the folder is corrupted.  Data may be lost.

However, in some cases it is not possible to write the folder with
C<REPLACE>.  For instance, the usual incoming mail folder on UNIX is
stored in a directory where a user can not write.  Of course, the
C<root> and C<mail> users can, but if you want to use this Perl module
with permission of a normal user, you can only get it to work in C<INPLACE>
mode.  Be warned that in this case folder locking via a lockfile is not
possible as well.

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

See Mail::Box::write(save_deleted)

=back

=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 file-based folders work

File-based folders store many messages in one file (let's call this a
`file-based' folder, in comparison to a `directory-based' folder types
like MH and Maildir).

=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.
