Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Dbx(3)		      User Contributed Perl Documentation		Dbx(3)

       Mail::Transport::Dbx - Parse Outlook Express mailboxes

	   use Mail::Transport::Dbx;

	   my $dbx = eval { Mail::Transport::Dbx->new("box.mbx") };
	   die $@ if $@;

	   for my $i (0	.. $dbx->msgcount - 1) {
	       my $msg = $dbx->get($i);
	       print $msg->subject;

	   # more convenient
	   for my $msg ($dbx->emails) {
	       print $msg->subject;

	   Read	dbx files (mailbox files of Outlook Express)

       Mail::Transport::Dbx gives you platform independent access to Outlook
       Express'	dbx files.  Extract subfolders,	messages etc. from those or
       use it to convert dbx archives into a more portable format (such	as
       standard	mbox format).

       It relies on LibDBX to do its job. The bad news:	LibDBX knows nothing
       about the endianness of your machine so it does not work	on big-endian
       machines	such as	Macintoshs or SUNs. The	good news: I made the
       appropriate patches so that it in fact does work	even on	machines with
       the 'wrong' byteorder (exception: machines with an even odder byteorder
       such as Crays are not suppored; exception from the exception: If	you
       buy me a	Cray I'll promise to fix it. :-).

       You have	to understand the structure of .dbx files to make proper use
       of this module. Outlook Express keeps a couple of those files on	your
       harddisk. For instance:


       The nasty thing about that is that there	are really two different kinds
       of such files: One that contains	the actual messages and	one that
       merely holds references to other	.dbx files. Folders.dbx	could be
       considered the toplevel file since it lists all other available .dbx
       files. As for folder1.dbx and comp.lang.perl.misc.dbx you can't yet
       know whether they contain messages or subfolders	(though
       comp.lang.perl.misc.dbx probably	contains newsgroup messages that are
       treated as mere emails).

       Fortunately this	module gives you the information you need. A common
       approach	would be the following:

	   1) create a new Mail::Transport::Dbx	object from "Folders.dbx"

	   2) iterate over its items using the get() method
	       2.1 if it returns a Mail::Transport::Dbx::Email
		   => a	message
	       2.2 if it returns a Mail::Transport::Dbx::Folder
		   => a	folder

	   3) if message
	       3.1 call	whatever method	from Mail::Transport::Dbx::Email
		   you need

	   4) if folder
	       4.1 call	whatever method	from Mail::Transport::Dbx::Folder
		   you need
	       4.2 call	dbx() on it to create a	new Mail::Transport::Dbx
		   4.2.1 if dbx() returned something defined
			 => rollback to	item 2)

       The confusing thing is that .dbx	files may contain references to	other
       folders that don't really exist!	If Outlook Express was used a
       newsclient this is a common scenario since Folders.dbx lists all
       newsgroups as separate "Mail::Transport::Dbx::Folder" objects no	matter
       whether you are subscribed to any of those or not. So in	essence
       calling "dbx()" on a folder will	only return a new object if the
       corresponding .dbx file exists.

       The following are methods for Mail::Transport::Dbx objects:

	   Passed either a string being	the filename or	an already opened and
	   readable filehandle ref, "new()" will construct a
	   Mail::Transport::Dbx	object from that.

	   This	happens	regardless of whether you open an ordinary dbx file or
	   the special Folders.dbx file	that contains an overview over all
	   available dbx subfolders.

	   If opening fails for	some reason your program will instantly
	   "die()" so be sure to wrap the constructor into an "eval()" and
	   check for $@:

	       my $dbx = eval {	Mail::Transport::Dbx->new( "file.dbx" )	};
	       die $@ if $@;

	   Be careful with using a filehandle, though. On Windows, you might
	   need	to use "binmode()" on your handle or otherwise the stream from
	   your	dbx file might get corrupted.

	   Returns the number of items stored in the dbx structure. If you
	   previously opened Folders.dbx "msgcount()" returns the number of
	   subfolders in it. Otherwise it returns the number of	messages.
	   "msgcount() - 1" is the index of the	last item.

	   In list context this	method returns all emails contained in the
	   file. In boolean (that is, scalar) context it returns a true	value
	   if the file contains	emails and false if it contains	subfolders.

	       if ($dbx->emails) {
		   print "I contain emails";
	       } else {
		   print "I contain subfolders";

	   This	is useful for iterations:

	       for my $msg ($dbx->emails) {

	   In list context this	method returns all subfolders of the current
	   file	as "Mail::Transport::Dbx::Folder" objects. In boolean (scalar)
	   context it returns true of the file contains	subfolders and false
	   if it contains emails.

	   Remember that you still have	to call	"dbx()"	on these subfolders if
	   you want to do something useful with	them:

	       for my $sub ($dbx->subfolders) {
		   if (my $d = $sub->dbx) {
		       # $d now	a proper Mail::Transport::Dbx object
		       # with content
		   } else {
		       print "Subfolder	referenced but non-existent";

	   Get the item	at the n-th position. First item is at position	0.
	   "get()" is actually a factory method	so it either returns a
	   "Mail::Transport::Dbx::Email" or "Mail::Transport::Dbx::Folder"
	   object. This	depends	on the folder you call this method upon:

	       my $dbx	= Mail::Transport::Dbx->new( "Folders.dbx" );
	       my $item	= $dbx->get(0);

	   $item will now definitely be	a "Mail::Transport::Dbx::Folder"
	   object since	Folders.dbx doesn't contain emails but references to

	   You can use the "is_email()"	and "is_folder()" method to check for
	   its type:

	       if ($item->is_email) {
		   print $item->subject;
	       } else {
		   # it's a subfolder

	   On an error,	this method returns an undefined value.	Check
	   "$dbx->errstr" to find out what went	wrong.

	   Whenever an error occurs, "errstr()"	will contain a string giving
	   you further help what went wrong.

	   WARNING: Internally it relies on a global variable so all objects
	   will	have the same error-string! That means it only makes sense to
	   use it after	an operation that potentially raises an	error:

	       # example 1
	       my $dbx = Mail::Transport::Dbx->new("box.dbx")
		   or die Mail::Transport::Dbx->errstr;

	       # example 2
	       my $msg = $dbx->get(5) or print $dbx->errstr;

	   Similar to "errstr()", only that it will return an error code. See
	   "Exportable constants/Error-Codes" under "EXPORT" for codes that
	   can be returned.

       The following are the methods for Mail::Transport::Dbx::Email objects:

	   Returns the whole message (header and body) as one large string.

	   Note	that the string	still contains the raw newlines	as used	by
	   DOSish systems (\015\012). If you want newlines to be represented
	   in the native format	of your	operating system, use the following:

	       my $email = $msg->as_string;
	       $email =~ s/\015\012/\n/g;

	   On Windows this is a	no-op so you can ommit this step.

	   Especially for news-articles	this method may	return "undef".	This
	   always happens when the particular articles was only	partially
	   downloaded (that is,	only header retrieved from the newsserver).
	   There is no way to retrieve this header literally with "header".
	   Methods like	"subject" etc. however do work.

	   Returns the header-portion of the whole email.

	   With	respect	to newlines the	same as	described under	"as_string()"

	   Returns "undef" under the same circumstances	as "as_string".

	   Returns the body-portion of the whole email.

	   With	respect	to newlines the	same as	described under	"as_string()"

	   Returns "undef" under the same circumstances	as "as_string".

	   Returns the subject of the email as a string.

	   Returns the processed subject of the	email as a string. 'Processed'
	   means that additions	such as	"Re:" etc. are cut off.

	   Returns the message-id of the message as a string.

	   Returns the message-ids of the parent messages as a string.

	   Returns the name of the sender of this email	as a string.

	   Returns the address of the sender of	this email as a	string.

	   Returns the name of the recipient of	this email as a	string.	This
	   might be your name. ;-)

	   Returns the address of the recipient	of this	email as a string.

	   Returns the Outlook Express account name this message was retrieved
	   with	as a string.

	   Outlook Express accounts also seem to have a	numerical
	   representation. This	method will return this	as a string (something
	   like	"0000001").

	   Returns the name of the POP server that this	message	was retrieved
	   from	as a string.

	   This	is the exact duplicate of Perl's builtin "localtime()" applied
	   to the date this message was	received. It returns a string in
	   scalar context and a	list with nine elements	in list	context. See
	   'perldoc -f localtime' for details.

	   Same	as "rcvd_localtime()" but returning a date conforming to GMT.

       date_received( [format, [len, [gmtime]]]	)
	   This	method returns the date	this message was received by you as a
	   string. The date returned is	calculated according to	"localtime()".

	   Without additional arguments, the string returned looks something

	       Sun Apr 14 02:27:57 2002

	   The optional	first argument is a string describing the format of
	   the date line. It is	passed unchanged to strftime(3). Please
	   consult your	system's documentation for strftime(3) to see how such
	   a string has	to look	like. The default string to render the date is
	   "%a %b %e %H:%M:%S %Y".

	   The optional	second argument	is the max string length to be
	   returned by "date_received()". This parameter is also passed
	   unaltered to	"strftime()". This method uses 25 as default

	   The third argument can be set to a true value if you	rather want to
	   get a date in GMT. So if you	want to	get the	GMT of the date	but
	   want	to use the default rendering settings, you will	have to
	   provide them	yourself:

	       print $msg->date_received("%a %b	%e %H:%M:%S %Y", 25, 1);

	   Returns a true value	if this	message	has already been seen. False

	   Always returns true for this	kind of	object.

	   Always returns false	for this kind of object.

       The following methods exist for Mail::Transport::Dbx::Folder objects:

       dbx This	is a convenience method. It creates a "Mail::Transport::Dbx"
	   object from the folder object. If the folder	is only	mentioned but
	   not physically existing on your hard-drive (either because you
	   deleted the .dbx file or it was actually never there	which
	   especially happens for newsgroup files) "dbx" returns an undefined

	   Please read "DESCRIPTION" again to learn why	"dbx()"	can return an
	   undefined value.

       num The index number of this folder. This is the	number you passed to
	   "$dbx->get()" to retrieve this folder.

	   According to	libdbx.h this returns one of "DBX_TYPE_FOLDER" or
	   "DBX_TYPE_EMAIL". Use it to check whether the folder	contains
	   emails or other folders.

	   The name of the folder.

	   The filename	of the folder. Use this, to create a new
	   "Mail::Transport::Dbx" object:

	       # $folder is a Mail::Transport::Dbx::Folder object
	       my $new_dbx = Mail::Transport::Dbx->new(	$folder->file );

	   Consider using the "dbx()" method instead.

	   This	method returns an undefined value if there is no .dbx file
	   belonging to	this folder.

       id  Numerical id	of the folder. Not sure	what this is useful for.

	   Numerical id	of the parent's	folder.

	   Returns the full folder name	of this	folder as a list of path
	   elements. It's then in your responsibility to join them together by
	   using a delimiter that doesn't show up in any of the	elements. ;-)

	       print join("/", $_->folder_path), "\n" for $dbx->subfolders;

	       # could for instance produce a long list, such as:
	       Outlook Express/
	       Outlook Express/
	       Outlook Express/Lokale Ordner/test/test1
	       Outlook Express/Lokale Ordner/test
	       Outlook Express/Lokale Ordner/EntwA1/4rfe
	       Outlook Express/Lokale Ordner/GelA<paragraph>schte Objekte
	       Outlook Express/Lokale Ordner/Gesendete Objekte
	       Outlook Express/Lokale Ordner/Postausgang
	       Outlook Express/Lokale Ordner/Posteingang
	       Outlook Express/Lokale Ordner
	       Outlook Express/Outlook Express

	   Note	that a slash (as any other character) might not	be a safe
	   choice as it	could show up in a folder name.

       None by default.

   Exportable constants
       If you intend to	use any	of the following constants, you	have to	import
       them when "use()"ing the	module.	You can	import them all	in one go

	   use Mail::Transport::Dbx qw(:all);

       Or you import only those	you need:

	   use Mail::Transport::Dbx qw(DBX_TYPE_EMAIL DBX_TYPE_FOLDER);

	   o	   DBX_NOERROR

		   No error occured.

	   o	   DBX_BADFILE

		   Dbx file operation failed (open or close)

	   o	   DBX_DATA_READ

		   Reading of data from	dbx file failed


		   Index out of	range


		   Request was made for	index reference	greater	than exists


		   Number of indexes read from dbx file	is less	than expected


		   Reading of Index Pointer from dbx file failed


		   Reading of Item Count from dbx file failed

	   o	   DBX_NEWS_ITEM

		   Item	is a news item not an email

       Dbx types
	   One of these	is returned by "$folder->type" so you can check
	   whether the folder contains emails or subfolders. Note that only
	   DBX_TYPE_EMAIL and DBX_TYPE_FOLDER are ever returned	so even
	   newsgroup postings are of the type DBX_TYPE_EMAIL.



	   o	   DBX_TYPE_NEWS

		   Don't use this one!

	   o	   DBX_TYPE_VOID

		   I have no idea what this is for.

       Miscellaneous constants

	   o	   DBX_FLAG_BODY

       You can't retrieve the internal state of	the objects using
       "Data::Dumper" or so since "Mail::Transport::Dbx" uses a	blessed	scalar
       to hold a reference to the respective C structures. That	means you have
       to use the provided methods for each object. Call that strong
       encapsultion if you need	an euphemism for that.

       There are currently no plans to implement write access to .dbx files. I
       leave that up to	the authors of libdbx.

       Other than that I don't know yet	of any.	This, of course, has never
       actually	been a strong indication for the absence of bugs.

SEE ALSO hosts the libdbx	package. It
       contains	the library backing this module	along with a description of
       the file	format for .dbx	files.

       Tassilo von Parseval, <>

       Copyright 2003-2005 by Tassilo von Parseval

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       Hey! The	above document had some	coding errors, which are explained

       Around line 450:
	   Non-ASCII character seen before =encoding in	'Ordner/EntwA1/4rfe'.
	   Assuming CP1252

perl v5.32.1			  2005-06-23				Dbx(3)


Want to link to this manual page? Use this URL:

home | help