Provided by: libmail-bulkmail-perl_3.12-7_all bug

NAME

       Mail::Bulkmail - Platform independent mailing list module

AUTHOR

       Jim Thomason, jim@jimandkoka.com (http://www.jimandkoka.com)

SYNOPSIS

        use Mail::Bulkmail /path/to/conf.file

        my $bulk = Mail::Bulkmail->new(
               "LIST"          => "~/my.list.txt",
               "From"          => '"Jim Thomason"<jim@jimandkoka.com>',
               "Subject"       => "This is a test message",
               "Message"       => "Here is my test message"
        ) || die Mail::Bulkmail->error();

        $bulk->bulkmail() || die $bulk->error;

       Don't forget to set up your conf file!

DESCRIPTION

       Mail::Bulkmail gives a fairly complete set of tools for managing mass-mailing lists. I
       initially wrote it because the tools I was using at the time were just too damn slow for
       mailing out to thousands of recipients. I keep working on it because it's reasonably
       popular and I enjoy it.

       In a nutshell, it allows you to rapidly transmit a message to a mailing list by zipping
       out the information to them via an SMTP relay (your own, of course). Subclasses provide
       the ability to use mail merges, dynamic messages, and anything else you can think of.

       Mail::Bulkmail 3.00 is a major major major upgrade to the previous version (2.05), which
       was a major upgrade to the previous version (1.11). My software philosophy is that most
       code should be scrapped and re-written every 6-8 months or so. 2.05 was released in
       October of 2000, and I'm writing these docs for 3.00 in January of 2003. So I'm at least 3
       major re-writes behind.  (philosophy is referenced in the FAQ, below)

       But that's okay, because we're getting it done now.

       3.00 is about as backwards compatible to 2.00 as 2.00 is to 1.00. That is to say, sorta.
       I've tried to make a note of things where they changed, but I'm sure I missed things. Some
       things can no longer be done, lots are done differently, some are the same. You will need
       to change your code to update from 1.x or 2.x to 3.00, though. That's a given.

       So what's new for 3.00? Lots of stuff.

       Immediate changes are:

        * code compartmentalization
        * multi-server support
        * conf file

       The immediate change is that the code is now compartmentalized.  Mail::Bulkmail now just
       handles ordinary, non-dynamic mailings. See Mail::Bulkmail::Dynamic for the merging and
       dynamic text abilities from the prior versions.

       Server connections are no longer handled directly in Mail::Bulkmail (Smtp attribute, Port
       attribute, etc.), there is now a separate Mail::Bulkmail::Server object to handle all of
       that.

       And everything subclasses off of Mail::Bulkmail::Object, where I have my super-methods to
       define my objects, some helper stuff, and so on.

       It's just a lot easier for me to maintain, think about it, etc. if it's all separated.
       It's also easier for you, the user, if you want to make changes to things. Just subclass
       it, tweak it, and use it.  Very straightforward to modify and extend now. 2.x and below
       *could* do it, but it wasn't really that easy (unless you were making very trivial
       changes). This should rectify that.

       Another major change is the addition of multi-server support. See the docs in
       Mail::Bulkmail::Server for more information. You can still specify one SMTP relay if
       that's all you've got, but if you have multiple servers, Mail::Bulkmail can now load
       balance between them to help take the stress off. No matter what, the biggest bottleneck
       to all of this is network performance (both to the SMTP relay and then from the relay to
       the rest of the world), so i wanted to try and help alleviate that by using multiple
       servers.  I know that some people were doing that on there own with small changes, but
       this allows you to do it all invisibly.

       And finally, finally, finally there is a conf file. Documentation on the format is in
       Mail::Bulkmail::Object.  It's pretty easy to use. This is the conf file format that I
       designed for my own use (along with most of the rest of Mail::Bulkmail::Object). The
       software also has the ability to read multiple conf files, if so desired. So no more
       worrying about asking your sysadmin to tweak the values in your module somewhere up in
       /usr/lib/whatever

       Just have him create the conf file you want, or pass in your own as desired.

       conf_files are specified and further documented in Mail::Bulkmail::Object, in an internal
       array called @conf_files, right at the top of the module. To specify a universal conf
       file, put it in that array (or have your sysadmin do so).  Alternatively, you can also add
       a conf_file via the conf_files accessor.

        Mail::Bulkmail->conf_files('/path/to/conf_file', '/path/to/other/conf_file');  #, etc.

       But the recommended way is to specify your conf file upon module import.

        use Mail::Bulkmail 3.00 "/path/to/conf/file";

       In addition, there is the usual plethora of bug fixes, tweaks, clean-ups, and so on.

       And yes, the horrid long-standing bug in the Tz method is fixed! No, honest.

       I'm also trying a new documentation technique. The pod for a given method is now in the
       module by that method, as opposed to everything being bunched up at the bottom.
       Personally, I prefer everything being bunched up there for clarities sake. But from a
       maintenance point of view, spreading it all out makes my life much easier.

requires

        Perl 5.6.0, Socket
        (It probably can get by with less than 5.6.0, but I haven't tested it in such an environment)

ATTRIBUTES

       From       Stores the From address of this mailing. Must be a valid email address, unless
                  Trusting is set.  Really really should be a valid email address anyway.

                  From is no longer used as the Sender, as was the behavior in prior versions.
                  Now, Mail::Bulkmail first tries to use the Sender as the Sender, and failing
                  that, falls back on the from.

                   $bulk->From('"Jim Thomason"<jim@jimandkoka.com>');
                   print $bulk->From;

       To         Stores the To address of this mailing. Must be a valid email address, unless
                  Trusting is set.  Really should be a valid email address anyway.

                  To is used if you have use_envelope set to 1. See use_envelope, below. If you
                  are not using the envelope, then the actual email address that we are currently
                  on is used instead and ->To is never used at all.

                   $bulk->To('jimslist:;');
                   print $bulk->To;

                  As of 3.00, ->To may contain either a valid email address or a valid group
                  definition. A group definition is as follows (pseudo-regex):

                   Groupname:(address(,address)*)?;

                  i.e., "the group name", then a colon, then an optional list of email addresses,
                  then a semi-colon

                   $bulk->To('jim@jimandkoka.com');
                   $bulk->To('MyList:jim@jimandkoka.com');
                   $bulk->To('MyList:;');

                  Are all valid addresses. Only the ->To attribute may accept group syntax emails

       Sender     Stores the Sender address of this mailing. Must be a valid email address,
                  unless Trusting is set.  Really really should be a valid email address anyway.

                  Sender is mainly used when speaking SMTP to the server, specifically in the
                  RCPT TO command.  The spec defines "Sender" as "he who send the message"
                  (paraphrasing), which may not actually be who the message is from. 2.00 used
                  the From address as the Sender.

                  You should specify this, but if you don't then the From value is assumed to be
                  the sender.

                   $bulk->Sender('jim@jimandkoka.com');
                   print $bulk->Sender;

                  If this value is not set, then Mail::Bulkmail will place a Sender header equal
                  to the From value.

                  Note that the ultimate receiving SMTP server is expected to place a Return-Path
                  header in the message. This Return-Path value will be set to the value of the
                  sender of the message, either ->Sender or ->From. This, in turn, will be the
                  address that bounce backs go to. You should not set a Return-Path header
                  yourself, because bad things will result.

       ReplyTo    Stores the Reply-To address of this mailing. Must be a valid email address,
                  unless Trusting is set.  Really really should be a valid email address anyway.

                  Reply-To is used as the address that the user's email client should reply to,
                  if present. If this value is not set, then Mail::Bulkmail will place a Reply-To
                  header equal to the From value.

                  Note that even though the attribute is "ReplyTo", the header set is "Reply-To"

                   $bulk->ReplyTo('jim@jimandkoka.com');
                   print $bulk->ReplyTo;

       Subject    Boring old accessor that stores the subject of the message. It's really
                  recommended that this is set either at your object or in the conf file,
                  otherwise you'll send out a mailing list with no subject which will probably be
                  ignored.

                   $bulk->Subject("This is the list you signed up for");
                   print $bulk->Subject;

       HTML       Boolean flag. 1/0 only.

                  A lot of people, though obviously not you, because you're reading the pod, just
                  couldn't figure out how to send HTML messages. It's easy.

                   $bulk->header("Content-type", "text/html");

                  But it was just too hard for most people. So I added this flag.

                  Here's the order:

                   Check and see if ->header("Content-type") is set, if so then send it.
                   Otherwise, check and see if ->HTML is true, if so, then send a content-type of text/html
                     i.e., an HTML message
                   Otherwise, send a content-type of text/plain
                     i.e., a plaintext message

                   $bulk->HTML(1);
                   print $bulk->HTML();

       use_envelope
                  Boolean flag. 1/0 only.

                  use_envelope was the coolest thing I added to Bulkmail 2.00, and is arguably
                  still the best thing I've got here in terms of raw power in your lists.

                  Basically, it's like lasing a stick of dynamite. Mail::Bulkmail is fast.
                  Mail::Bulkmail with use_envelope is mind-numbingly fast.

                  For the uninformed, an email message contains two parts, the message itself and
                  the envelope.   Mail servers only care about the envelope (for the most part),
                  since that's where they find out who the message is to and from, and they don't
                  really need to know anything else.

                  A nifty feature of the envelope is that you can submit multiple addresses
                  within the envelope, and then your mail server will automagically send along
                  the message to everyone contained within the envelope.  You end up sending a
                  hell of a lot less data across your connection, your SMTP server has less work
                  to do, and everything ends up working out wonderfully.

                  There are two catches.  First of all, with envelope sending turned off, the
                  recipient will have their own email address in the "To" field (To:
                  jim@jimandkoka.com, fer instance).  With the envelope on, the recipient will
                  only receive a generic email address ("To: list@myserver.com", fer instance)
                  Most people don't care since that's how most email lists work, but you should
                  be aware of it.

                  Secondly, you MUST and I mean MUST sort your list by domain.  Envelopes can
                  only be bundled up by domain, so that we send all email to a domain in one
                  burst, all of the email to another domain in the next burst, and so on.  So you
                  need to have all of your domains clustered together in your list.  If you
                  don't, your list will still go out, but it will be a lot slower, since
                  Mail::Bulkmail has a fair amount more processing to do when you send with then
                  envelope.  This is normally more than offset by the gains received from sending
                  fewer messages.  But with an unsorted list, you never see the big gains and you
                  see a major slow down.  Sort your lists.

                   $bulk->use_envelope(0);
                   print $bulk->use_envelope;

       force80    Boolean flag 1/0

                  RFC 2822 recommends that all messages have no more than 80 characters in a line
                  (78 + CRLF), but doesn't require it. if force80 is 1, then it will force a
                  message to have only 80 characters per line. It will try to insert carriage
                  returns between word boundaries, but if it can't, then it will cut words in
                  half to force the limit.

                  Regardless of force80, be warned that RFC 2822 mandates that messages must have
                  no more than 1000 characters per line (998 + CRLF), and that wrapping will be
                  done no matter what. Again, it will try to wrap at word boundaries, but if it
                  can't, it will cut words in half to force the limit.

                  It is recommended that you just have your message with at most 78 characters +
                  CRLF for happiness' sake, and definitely at most 998 characters + CRLF. You may
                  end up with extra CRLFs in your message that you weren't expecting.

                  If your message is not guaranteed to have only < 78 characters + CRLF per line,
                  then it's recommended to have force80 on for full compatibility. Note that
                  force80 will be overridden by ->Trusting('wrapping');

       servers    arrayref of servers.

                  Okay, this is the first major change between 2.x and 3.x. 2.x had methods to
                  connect to one server (->Smtp, ->Port, etc.).  3.x doesn't have those, and the
                  relevant things are now in Mail::Bulkmail::Server, instead it has a list of
                  servers.

                  servers should contain an arrayref of server objects. You can either create
                  them externally yourself and pass them in in an arrayref,

                   $bulk->servers([\$server, \$server2, \$server3]);

                  or you can create them in your conf file. See the Mail::Bulkmail::Object for
                  more info on the format of the conf file, and Mail::Bulkmail::Server for the
                  attributes to specify.

                  servers will automatically be populated with a list of all servers in the
                  server_list in the conf file if you don't specify anything, so you really don't
                  need to worry about it.

                  If you'd rather use a different server_file, then pass the server_file flag to
                  the constructor:

                   $bulk = Mail::Bulkmail->new(
                          'server_file' => '/path/to/server_file'
                   );

                  That will override and ignore the server_file in any conf file, so use it with
                  caution.

                  Realistically, though, just let the program populate in the values of the
                  servers you specified in the conf file and don't worry about this.

                  Be warned that servers will be populated by the constructor if you do not
                  populate servers at object creation. You may still change servers later (before
                  you begin mailing), but there is the slight performance hit to initialize all
                  of the server objects and then throw them away. This doesn't affect mailing
                  speed in anyway, it'll just take a little longer to get started than it should.

       Message    This stores the message that you will send out to the recipients of your list.

                   $bulk->Message('Hi there. You're on my mailing list');
                   print $bulk->Message;

                  Don't put any headers in your Message, since they won't be transmitted as
                  headers. Instead they will show up in the body of your message text. Use the
                  ->header method instead for additional headers

                  This mutator is known to be able to return:

                   MB020 - could not open file for message
                   MB021 - could not close file for message
                   MB022 - invalid headers from message

       message_from_file
                  boolean flag. 1/0 only.

                  message_from_file allows you to load your message in from a file. If
                  message_from_file is set to 1, then the value passed to ->Message() will be
                  assumed to be a path to a file on disk.  That file will be opened in read mode
                  (if possible), read in, and stored as your message. Note that your entire
                  message text will be read into memory - no matter how large the message may be.

                  This is simply a shortcut so that you don't have to open and read in the
                  message yourself.

                  NOTE This is a bit picky, to put it mildly. No doubt you've read that the
                  constructor actually is taking in its arguments in an array, not a hash. So
                  they're parsed in order, which means you need pass in message_from_file before
                  Message. i.e., this will work:

                   $bulk = Mail::Bulkmail->new(
                          'message_from_file' => 1,
                          'Message'                       => '/path/to/message.txt',
                   );

                  But this will not:

                   $bulk = Mail::Bulkmail->new(
                          'Message'                       => '/path/to/message.txt',
                          'message_from_file' => 1,
                   );

                  Ditto for using the mutators. Turn on the flag, i<then> specify the Message.

       headers_from_message
                  boolean flag. 1/0 only.

                  headers_from_message allows you to specify mail headers inside your message
                  body. You may still specify additional headers in the traditional manner.

                  Note that if you change the value of ->Message (not recommended, but there are
                  times you may want to do so), then any headers that were previously set via
                  headers_from_message will be wiped out.

                  any headers specified in the message will be set when you call ->Message.

       LIST       LIST stores the list of addresses you're going to mail out to. LIST may be
                  either a coderef, globref, arrayref, or string literal.

                  If a string literal, then Mail::Bulkmail will attempt to open that file as your
                  list:

                   $bulk->LIST("/path/to/my/list");

                  If a globref, it is assumed to be an open filehandle:

                   open (L, "/path/to/my/list");
                   $bulk->LIST(\*L);

                  if a coderef, it is assumed to be a function to return your list, or undef when
                  it is done:

                   sub L {return $listquery->execute()};  #or whatever your code is
                   $bulk->LIST(\&L);

                  The coderef will receive the bulkmail object itself as an argument.

                  if an arrayref, it is assumed to be an array containing your list:

                   my $list = [qw(jim@jimandkoka.com thomasoniii@yahoo.com)];
                   $bulk->LIST($list);

                  Use whichever item is most convenient, and Mail::Bulkmail will take it from
                  there.

       BAD        This is an optional log file to keep track of the bad addresses you have, i.e.
                  banned, invalid, or duplicates.

                  BAD may be either a coderef, globref, arrayref, or string literal.

                  If a string literal, then Mail::Bulkmail will attempt to open that file (in
                  append mode) as your log:

                   $bulk->BAD("/path/to/my/bad.addresses");

                  If a globref, it is assumed to be an open filehandle in append mode:

                   open (B, ">>/path/to/my/bad.addresses");
                   $bulk->BAD(\*L);

                  if a coderef, it is assumed to be a function to call with the address as an
                  argument:

                   sub B { print "BAD ADDRESS : ", $_[1], "\n"};  #or whatever your code is
                   $bulk->BAD(\&B);

                  The coderef will receive two arguments. The first is the bulkmail object
                  itself, and the second is the data in the form that it was returned from the
                  LIST attribute.

                  if an arrayref, then bad addresses will be pushed on to the end of it

                   $bulk->BAD(\@bad);

                  Use whichever item is most convenient, and Mail::Bulkmail will take it from
                  there.

       GOOD       This is an optional log file to keep track of the good addresses you have, i.e.
                  the ones that Mail::Bulkmail could successfully transmit to the server. Note
                  that there is no guarantee that an email address in the GOOD file actually
                  received your mailing - it could have failed at a later point when out of
                  Mail::Bulkmail's control.

                  GOOD may be either a coderef, globref, arrayref, or string literal.

                  If a string literal, then Mail::Bulkmail will attempt to open that file (in
                  append mode) as your log:

                   $bulk->GOOD("/path/to/my/good.addresses");

                  If a globref, it is assumed to be an open filehandle in append mode:

                   open (B, ">>/path/to/my/good.addresses");
                   $bulk->GOOD(\*B);

                  if a coderef, it is assumed to be a function to call with the address as an
                  argument:

                   sub G { print "GOOD ADDRESS : ", $_[1], "\n"}; #or whatever your code is
                   $bulk->GOOD(\&G);

                  The coderef will receive two arguments. The first is the bulkmail object
                  itself, and the second is the data in the form that it was returned from the
                  LIST attribute.

                  if an arrayref, then bad addresses will be pushed on to the end of it

                   $bulk->GOOD(\@good);

                  Use whichever item is most convenient, and Mail::Bulkmail will take it from
                  there.

                  Please note that ->GOOD only says that the address was initially accepted for
                  delivery. It could later fail while transmitting the email address, or it could
                  be an valid but non-existent address that bounces later. It is up to the end
                  user to inspect your error logs to make sure no errors occurred, and look for
                  (and weed out) bounces or other failures later.

       server_class
                  server_class is a class method that MUST be specified in the conf file. You can
                  initialize it in your program if you really want, but it is strongly
                  recommended to be in the conf file so you don't forget it.

                  server_class is used by the constructor to create the server list to populate
                  into ->servers, ->servers is not populated in the constructor.

                  By default, this should probably be Mail::Bulkmail::Server, to allow mailing.
                  Another useful value is Mail::Bulkmail::Dummy See Mail::Bulkmail::Server and
                  Mail::Bulkmail::Dummy for more information on how to create those objects.

                  Also, if you write your own server implementation, this would be where you'd
                  hook it into Mail::Bulkmail

       Trusting   Trusting specifies your Trusting level. Mail::Bulkmail 3.00 will do its best to
                  make sure that your email addresses are valid and that your message conforms to
                  RFC 2822. But, there is a slight performance hit to doing that - it does have
                  to check things, do regexes, and so on. It's not very slow, but extrapolated
                  over a huge list, it can be noticeable.

                  So that's where Trusting comes in to play. If you set a Trusting value, then
                  certain tests will be skipped. Use this at your own risk. If you tell
                  Mail::Bulkmail to be Trusting, then it won't verify addresses or to make sure
                  your list is under 1,000 characters per line. So if you're Trusting and you
                  pass in bad data, it's your funeral. If there is any chance of invalid data,
                  then don't be Trusting. If you're *positive* there's nothing wrong, then you
                  may be Trusting.

                  Trusting values are set one as key/value pairs.

                   $bulk->Trusting("email" => 1);
                   $bulk->Trusting("wrapping" => 1);
                   $bulk->Trusting("default" => 1);

                  And read back with just the key:

                   $bulk->Trusting("email");
                   $bulk->Trusting("wrapping");
                   $bulk->Trusting("default");

                  default is used as a fall back. So if you didn't specify a Trusting value for
                  "email", for example, it will use the "default" value. Note that the default is
                  only used if a value is not specified.

                   $bulk->Trusting("default" => 1);
                   print $bulk->Trusting("email");        #prints 1
                   print $bulk->Trusting("default");      #prints 1
                   $bulk->Trusting("default" => 0);
                   print $bulk->Trusting("email");        #prints 0
                   print $bulk->Trusting("default");      #prints 0
                   $bulk->Trusting("email" => 1);
                   print $bulk->Trusting("email");        #prints 1
                   print $bulk->Trusting("default");      #prints 0
                   $bulk->Trusting("email" => 0);
                   $bulk->Trusting("default" => 0);
                   print $bulk->Trusting("email");        #prints 0
                   print $bulk->Trusting("default");      #prints 1

                  You may also directly set all values with the integer short cut.

                   $bulk->Trusting(1);    # everything is Trusting
                   $bulk->Trusting(0);    # nothing is Trusting

                  If you want to specify Trusting in the conf file, you may only directly specify
                  via the integer shortcut. Otherwise, you must use the list equation.

                   # all Trusting
                   Trusting = 1

                   #none Trusting
                   Trusting = 0

                   #email is trusting
                   Trusting @= email
                   Trusting @= wrapping

                  This will not work:

                   Trusting = email

                  If you use that syntax, it will internally do:

                   $bulk->Trusting('email');

                  which you know will only read the value, not set it. If you use the array
                  syntax, it will properly set the value.

                  Note that ->Trusting('default' => 0) is not equivalent to ->Trusting(0).
                  Consider:

                   $bulk->Trusting('email' => 1);
                   print $bulk->Trusting('email');        # prints 1
                   $bulk->Trusting("default' => 0);
                   print $bulk->Trusting('email');        # still prints 1
                   $bulk->Trusting(0);
                   print $bulk->Trusting('email');        # now prints 0

                  Currently, you may set:

                   email      - Trusting('email' => 1) will not check for valid email addresses
                   wrapping   - Trusting('wrapping' => 1) will not try to wrap the message to reach the 1,000 character per line limit
                   duplicates - Trusting('duplicates' => 1) will not do any duplicates checking
                       (this is the equivalent of allow_duplicates in older versions)
                   banned     - Trusting('banned' => 1) will not lowercase the local part of a domain in a banned or duplicates check
                       (this is the opposite of safe_banned in older versions. i.e. $bulk2_05->safe_banned(1) == $bulk_300->Trusting('banned' => 0);

                  It is recommended your conf file be:

                   Trusting @= duplicates

                  Since you're usually better off weeding duplicates out in advance. All other
                  Trusting values are recommended to be false.

       banned     banned stores the list of email addresses and domains that are banned. Only
                  store user@domain.com portions of email addresses, don't try to ban
                  "Jim"<jim@jimandkoka.com>, for instance. Only ban jim@jimandkoka.com

                  banned may be either a coderef, globref, arrayref, or string literal.

                  If a string literal, then Mail::Bulkmail will attempt to open that file (in
                  append mode) as your log:

                   $bulk->banned("/path/to/my/banned.addresses");

                  If a globref, it is assumed to be an open filehandle in append mode:

                   open (B, ">>/path/to/my/banned.addresses");
                   $bulk->banned(\*B);

                  files should contain one entry per line, each entry being an email address or a
                  domain. For example:

                   jim@jimandkoka.com
                   jimandkoka.com
                   foo@bar.com
                   bar.com

                  if a coderef, it is assumed to be a function to return your banned list:

                   sub B {return $bannedquery->execute()};        #or whatever your code is
                   $bulk->banned(\&B);

                  The function should return one entry per execution, either an address or a
                  domain.

                  if an arrayref, then it's an array of banned addresses and domains

                   $bulk->banned([qw(jim@jimandkoka.com jimandkoka.com)]);

                  The arrayref can contain email addresses and domains.

                  Use whichever item is most convenient, and Mail::Bulkmail will take it from
                  there.

                  Once banned has been populated, the values are stored internally in a hashref.

       Precedence Precedence is a validating accessor to validate the Precedence you have passed
                  for your mailing list.

                  Precedence must be either:

                   * list (default) - a mailing list
                   * bulk - bulk mailing of some type
                   * junk - worthless test message.

                  You can use an alternate Precedence if you set Trusting to 0. But seriously,
                  there's *no* reason to do that. Keeping the appropriate precedence will help
                  the servers on the internet route your message as well as the rest of the email
                  out there more efficiently. So don't be a jerk, and leave it as one of those
                  three.

                  This method is known to be able to return:

                   MB001 - invalid precedence

       Tz         Returns the timezone that you're in. You cannot set this value. You'll also
                  never need to worry about it.

       Date       Returns the date that this email is being sent, in valid RFC format. Note that
                  this will be stored in _cached_headers as the date that the first email is
                  sent.

                  Another thing you won't need to worry about.

METHODS

       new        The constructor, used to create new Mail::Bulkmail objects. See
                  Mail::Bulkmail::Object for more information on constructors.

                  In a nutshell, the constructor accepts a hash with name/value pairs
                  corresponding to attributes and attribute values.

                  So that:

                   my $bulk = Mail::Bulkmail->new(
                          'LIST' => './list.txt',
                          'Message' => "This is my message!",
                          'HTML' => 0
                   ) || die Mail::Bulkmail->error;

                  is the same as:

                   my $bulk = Mail::Bulkmail->new() || die Mail::Bulkmail->error;

                   $bulk->LIST("./list.txt");
                   $bulk->Message("This is my message!");
                   $bulk->HTML(0);

                  *technically* it's not exactly the same, since the constructor will fail with
                  an error if your attribute calls return undef, but it's close enough.

                  It is recommend to tack on an || die after your new() calls, to make sure
                  you're alerted if your object isn't created.

                   my $bulk = Mail::Bulkmail->new() || die Mail::Bulkmail->error();

                  Otherwise, you won't be alerted if your object isn't created.

                  Upon creation, Mail::Bulkmail will first iterate through the conf file and
                  populate all of the attributes defined in the conf file into your object. It
                  will then iterate through the values you passed to the constructor and mutate
                  the attributes to those values. If you don't pass any arguments to the
                  constructor, it still gets the default values in the conf file. Values passed
                  to the constructor always override values specified in the conf file

                  There is one special constructor flag, "server_file", which does not correspond
                  to an attribute or method. "server_file" is used to override the server_file
                  specified in the conf file.

                  If you pass a key/value pair to the constructor that doesn't have a
                  corresponding attribute, then it is assuming you are setting a new header.

                   my $bulk = Mail::Bulkmail->new('foo' => 'bar');

                   is the same as:

                   my $bulk = Mail::Bulkmail->new();
                   $bulk->header('foo' => 'bar');

                  This method is known to be able to return:

                   MB003 - could not use server class

       header     the header method is used to set additional headers for your object that don't
                  have their own methods (such as Subject) header expects the header and value to
                  act as a mutator, or the header to act as an accessor.

                   $bulk->header('X-Header', "My header value");
                   print $bulk->header('X-Header'); #prints "My header value"

                  Use this to set any additional headers that you would like.

                  Note that you can't use this to bypass validation checks.

                   $bulk->Header("Subject", "My Subject") will internally change into $bulk->Subject("My Subject");

                  There's no benefit to doing that, it'll just slow you down.

                  If you call header with no values, it returns the _headers hashref, containing
                  key value pairs of header => value

                  This method is known to be able to return:

                   MB004 - cannot set CC or BCC header
                   MB005 - invalid header

       valid_email
                  valid_email validates an email address and extracts the user@domain.com part of
                  an address

                   print $bulk->valid_email('jim@jimandkoka.com')->{'extracted'};                                 #prints jim@jimandkoka.com
                   print $bulk->valid_email('"Jim Thomason"<jim@jimandkoka.com>')->{'extracted'}; #prints jim@jimandkoka.com
                   print $bulk->valid_email('jim@jimandkoka.com')->{'extracted'};                                 #prints jim@jimandkoka.com
                   print $bulk->valid_email('jim@@jimandkoka.com');                                                               #prints nothing (invalid address)

                  Note that as of v3.10, valid_email returns a hash with two keys upon success.
                  'original' contains the address as you passed it in, 'extracted' is the address
                  person that was yanked out.

                   {
                          'original'      => 'Jim Thomason'<jim@jimandkoka.com',
                          'extracted'     => 'jim@jimandkoka.com',
                   }

                  Given an invalid address, returns undef and sets an error as always.

                  If Trusting is 1, then valid_email only removes comments and extracts the
                  address spec part of the email. i.e., if your address is

                   some name<some@address.com>

                  It'll just return some@address.com. This is required, because valid_email is
                  also where the address spec is validated.  As of 3.00, valid_email should be
                  fully RFC 2822 compliant, except where otherwise noted (such as forcing a valid
                  domain as per RFC 2821).  And also as of 3.00, Trusting is even more trusting
                  and has a faster return. There are speed reasons to have Trusting set to 1
                  (such as not having to check the validity of each email address), but if you do
                  that then you must be positive that all of your addresses are 100% valid. If
                  you have any addresses in your list that are invalid and Trusting is set to 1,
                  then you may have bad things happen. You have been warned.

                  This method is known to be able to return:

                   MB006 - no email address
                   MB007 - invalid email address

       lc_domain  given an email address, lowercases the domain. Mainly used internally, but I
                  thought it might be useful externally as well.

                   print $self->lc_domain('Jim@JimANDKoka.com');  #prints Jim@jimandkoka.com
                   print $self->lc_domain('JIM@JIMANDKOKA.com');  #prints JIM@jimandkoka.com
                   print $self->lc_domain('jim@jimandkoka.com');  #prints jim@jimandkoka.com

                  This method is known to be able to return:

                   MB009 - cannot lowercase domain w/o email

       setDuplicate
                  sets an email address as a duplicate.

                   $bulk->setDuplicate($email);

                  once an address is set as a duplicate, then isDuplicate will return a true
                  value for that address

                   print $bulk->isDuplicate($email2);     #prints 0
                   $bulk->setDuplicate($email2);
                   print $bulk->isDuplicate($email2);     #prints 1

                  This is mainly used internally, but I decided to make it external anyway.

                  setDuplicate will always return 1 if you have Trusting('duplicates') set.

                  Be warned that there is a performance hit to using this, since it will
                  eventually store your entire list inside an entire hashref in memory. You're in
                  much better shape if you weed out the duplicates in advance and then set
                  Trusting('duplicates' => 1) to skip the check and skip storing the values in
                  the hashref.

                  But if you have to use this to weed out values, go to town.

                  This method is known to be able to return:

                   MB010 - cannot set duplicate w/o email

       isDuplicate
                  returns a boolean value as to whether an email address is a duplicate

                   print $bulk->isDuplicate($email); #prints 0 or 1

                  once an address is set as a duplicate, then isDuplicate will return a true
                  value for that address

                   print $bulk->isDuplicate($email2);     #prints 0
                   $bulk->setDuplicate($email2);
                   print $bulk->isDuplicate($email2);     #prints 1

                  This is mainly used internally, but I decided to make it external anyway.

                  isDuplicate will always return 0 if you have Trusting('duplicates' => 1) set.

                  Be warned that there is a performance hit to using this, since it will
                  eventually store your entire list inside an entire hashref in memory. You're in
                  much better shape if you weed out the duplicates in advance and then set
                  Trusting('duplicates' => 1) to skip the check and skip storing the values in
                  the hashref.

                  But if you have to use this to weed out values, go to town.

       isBanned   returns a boolean value as to whether an email address (or domain) is banned or
                  not

                   $bulk->isBanned($email);       #prints 0 or 1
                   $bulk->isBanned($domain);      #prints 0 or 1

                  ->isBanned goes off of the values populated via the banned attribute

                  This is mainly used internally, but I decided to make it external anyway.

       nextServer Again, mainly used internally.

                  ->nextServer will iterate over the ->servers array and return the next valid,
                  connected server. If a server is not connected, ->nextServer will try to make
                  it connect. If the server cannot connect, it will go on to the next one.

                  Once all servers are exhausted, it returns undef.

                  nextServer is called if the present server object has reached one of its
                  internal limits. See Mail::Bulkmail::Server for more information on server
                  limits.

                  This method is known to be able to return:

                   MB011 - No servers (->servers array is empty)
                   MB012 - No available servers (cannot connect to any servers)

       extractEmail
                  The extract methods return results equivalent to the return of valid_email

                  extracts the email address from the data passed in the bulkmail object. Not
                  necessary in Mail::Bulkmail, since all it does in here is reflect through the
                  same value that is passed.

                  This will be very important in a subclass, though. getNextLine might return
                  values beyond just simple email addresses in subclasses, hashes, objects,
                  whatever. You name it. In that case, extractEmail is necessary to find the
                  actual email address out of whatever it is that was returned from
                  getNextLine().

                  But here? Nothing to worry about.

                  This method is known to be able to return:

                   MB013 - cannot extract email w/o email

       extractSender
                  The extract methods return results equivalent to the return of valid_email

                  extracts the sender of the message from the data passed in the bulkmail object.
                  Not necessary in Mail::Bulkmail, since all it does in here is return either the
                  Bulkmail object's Sender or its From field.

                  This will be very important in a subclass, though. getNextLine might return
                  values beyond just simple email addresses in subclasses - hashes, object,
                  whatever. You name it. In that case, extractEmail is necessary to find the
                  actual email address out of whatever it is that was returned from
                  getNextLine().

                  But here? Nothing to worry about.

       extractReplyTo
                  The extract methods return results equivalent to the return of valid_email

                  extracts the Reply-To of the message from the data passed in the bulkmail
                  object. Not necessary in Mail::Bulkmail, since all it does in here is return
                  either the Bulkmail object's Sender or its From field.

                  This will be very important in a subclass, though. getNextLine might return
                  values beyond just simple email addresses in subclasses - hashes, object,
                  whatever. You name it. In that case, extractEmail is necessary to find the
                  actual email address out of whatever it is that was returned from
                  getNextLine().

                  But here? Nothing to worry about.

       preprocess This is another method that'll do more in a subclass. When you had off data to
                  either ->mail or ->bulkmail, it gets preprocessed before it's actually used. In
                  Mail::Bulkmail itself, all it does is take a non-reference value and turn it
                  into a reference, or return a reference as is if that was passed.

                  Here, the whole method:

                   sub preprocess {
                          my $self        = shift;
                          my $val         = shift;

                          return ref $val ? $val : \$val;
                   };

                  But in a subclass, this may be much more important. Making sure that your data
                  is uniform or valid, that particular values are populated, additional tests,
                  whatever.

       buildHeaders
                  buildHeaders is mainly used internally, like its name implies, it builds the
                  headers for the message.

                  You'll never need to call buildHeaders unless you're subclassing, in which case
                  you may want to override this method with a new routine to build headers in a
                  different fashion.

                  This method is called internally by ->bulkmail and ->mail otherwise and is not
                  something you need to worry about.

                  The first time buildHeaders is called, it populates _cached_headers so as not
                  to have to go through the processing of rebuilding the headers for each address
                  in your list.

                  This method is known to be able to return:

                   MB014 - no From address
                   MB015 - no To address

       buildMessage
                  buildMessage is mainly used internally, like its name implies, it builds the
                  body of the message

                  You'll never need to call buildMessage unless you're subclassing, in which case
                  you may want to override this method with a new routine to build your message
                  in a different fashion.

                  This method is called internally by ->bulkmail and ->mail otherwise and is not
                  something you need to worry about.

                  This method is known to be able to return:

                   MB016 - ->Message is not defined

       bulkmail   This is the bread and butter of the whole set up, and it's easy as pie.

                   $bulk->bulkmail();

                  will take your list, iterate over it, build all your message headers, build
                  your message, and email to everyone on your list, iterating through all of your
                  servers, log all relevant information, and send you happily on your way.

                  Easy as pie. You don't even need to worry about it if you subclass things,
                  because you'd just need to override buildHeaders, buildMessage, getNextLine and
                  extractEmail at most.

                  This method is known to be able to return:

                   MB017 - duplicate email
                   MB018 - banned email
                   MB019 - invalid sender/from

       mail       Works the same as ->bulkmail, but only operates on one email address instead of
                  a list.

                   $bulk->mail('jim@jimandkoka.com');

                  Sends your Message as defined in ->Message to jim@jimandkoka.com. You can also
                  optionally pass in a server as the second argument.

                   $bulk->mail('jim@jimandkoka.com', $server);

                  is the same as above, but relays through that particular server. if you don't
                  pass a server, if tries to bring the next one in via ->nextServer

                  ->mail wants its first argument to be whatever would be normally returned by a
                  call to ->getNextLine($bulk->LIST); Right now, that's just a single email
                  address. But that may change in a subclass. So, if you're operating in a
                  subclass, just remember that you may be able (or required) to pass additional
                  information in your first argument.

                  This method is known to be able to return:

                   MB018 - banned email
                   MB019 - invalid sender/from address

FAQ

       So just how fast is this thing, anyway?>
            I don't know any more, I don't have access to the same gigantic lists I used to
            anymore.  :~(

            But, basically, Really fast.  Really stupendously incredibly fast.

            The last official big benchmark I ran was with v1.11. That list runs through to
            completion in about an hour and 43 minutes, which meant that Mail::Bulkmail 1.11
            could process (at least) 884 messages per minute or about 53,100 per hour.

            The last message sent out was 4,979 bytes.  4979 x 91,140 people is 453,786,060 bytes
            of data transferred, or about 453.786 megabytes in 1 hour and 43 minutes.  This is a
            sustained transfer rate of about 4.4 megabytes per minute, or 264.34 megabytes per
            hour.

            So then, that tells you how fast the software was back in 1999, 2 major revisions
            ago. But, invariably, you want to know what it's like *now*, right? Well, I'll do my
            best to guesstimate it. However, these tests were not run through an SMTP relay, they
            were run using DummyServer in v3.0 and a hacked 2.05 and (severely) hacked 1.11 to
            insert similar functionality. All data was sent to /dev/null.

            Tests were performed on a 5,000 recipient list.

            First of all, with envelope sending turned off (average times):

             v1.11......20 seconds  (1.00)
             v3.00......23 seconds  (1.15)
             v2.05......50 seconds  (2.5)

            1.11 was the speed champ in this case, but that's not surprising considering the fact
            that it did a lot less processing than the other 2. The fact that 3.00 almost catches
            it should speak to the improvement in the code in the 3.x release. 2.05 was...clunky.

            Now then, there's another thing to consider, envelope sending. With envelope sending
            turned on (average times):

             v3.00......12 seconds  (1.00)
             v2.05......19 seconds  (1.58)
             v1.11......22 seconds  (1.83)

            This is with an envelope_limit of 100. So the supposed speed gains that envelope
            sending were supposed to see in 2.05 never really materialized. While doing these
            tests, I discovered a bug in 2.05's use_envelope routine that would sometimes cause
            it to slow down substantially. 3.00, with a new routine, was never affected.
            Incidentally, Bulkmail 2.05 will be faster with trivially low envelope_limits.
            Bulkmail 3.00 becomes faster with an envelope_limit greater than 2.

            There is also mail merging (filemapping in 1.x) that should be considered. This was
            benchmarked with Mail::Bulkmail::Dynamic for 3.00.  A simple mail merge with one item
            was used, and one global item, read from a file, and split on a delimiter (since this
            was the only functionality that v1.x had). With mail merge turned on (average times):

             v1.11......20 seconds  (1.00)
             v3.00......35 seconds  (1.75)
             v2.05......40 seconds  (2.00)

            And finally, 2.x and 3.x have both had the capability to generate a dynamic message.
            This is a minimal test with one dynamic message element, one dynamic header, and a
            mail merge into the dynamic element:

             v3.00......36 seconds  (1.00)
             v2.05......44 seconds  (1.22)

            So 3.x is usually faster than 2.x, but sometimes slower than 1.x. Which makes sense,
            again due to the added features in 2.x and 3.x.

            These tests do not take into account the multi-server capability introduced in 3.00.

            Also note that these speeds are only measuring the time it takes to get from
            Mail::Bulkmail to your SMTP relay. There are no measurements reflecting how long it
            may take your SMTP relay to send the data on to the recipients on your list.

       Am I going to see speeds that fast?
            Maybe, maybe not.  It depends on how busy your SMTP server is.  If you have a
            relatively unused SMTP server with a fair amount of horsepower and a fast connection,
            you can easily get these speeds or beyond.  If you have a relatively busy and/or low
            powered SMTP server or slow connections, you're not going to reach speeds that fast.

       How much faster will Mail::Bulkmail be than my current system?
            This is a very tough question to answer, since it depends highly upon what your
            current system is.  For the sake of argument, let's assume that for your current
            system, you open an SMTP connection to your server, send a message, and close the
            connection.  And then repeat.  Open, send, close, etc.

            Mail::Bulkmail will always be faster than this approach since it opens one SMTP
            connection and sends every single message across on that one connection.  How much
            faster depends on how busy your server is as well as the size of your list. The
            connection will only be closed if you have an error or if you reach the max number of
            messages to send in a given server connection.

            Lets assume (for simplicity's sake) that you have a list of 100,000 people.  We'll
            also assume that you have a pretty busy SMTP server and it takes (on average) 25
            seconds for the server to respond to a connection request.  We're making 100,000
            connection requests (with your old system).  That means 100,000 x 25 seconds = almost
            29 days waiting just to make connections to the server!  Mail::Bulkmail makes one
            connection, takes 25 seconds for it, and ends up being 100,000x faster!

            But, now lets assume that you have a very unbusy SMTP server and it responds to
            connection requests in .003 seconds.  We're making 100,000 connection requests.  That
            means 100,000 x .0003 seconds = about 5 minutes waiting to make connections to the
            server.  Mail::Bulkmail makes on connection, takes .0003 seconds for it, and ends up
            only being 1666x faster.  But, even though being 1,666 times faster sounds
            impressive, the world won't stop spinning on its axis if you use your old system and
            take up an extra 5 minutes.

            And this doesn't even begin to take into account systems that don't open and close
            SMTP connections for each message.

            This also doesn't take into account the load balancing between multiple SMTP relays
            that 3.00 can perform.

            In short, there's no way for me to tell how much faster (if at all) it'll be. Try it
            and find out.

       Have you benchmarked it against anything else?
            Not scientifically.  I've heard that Mail::Bulkmail 1.10 is about 4-5x faster than
            Listcaster from Mustang Software, but I don't have any hard numbers.  But nothing
            beyond that.

            If you want to benchmark it against some other system and let me know the results,
            it'll be much appreciated.  :-)

       Can I send spam with this thing?
            No.  Don't be a jerk.

       SMTP relay? Wazzat?
            All Mail::Bulkmail does is provide you a quick way to relay information from your
            local machine through to your SMTP relay (which may be the same machine). Your SMTP
            relay then sends the messages on to the rest of the world.

            So your SMTP server must be configured properly to allow you to relay your messages
            out. It is recommended that this machine be kept behind a firewall for security
            reasons. Make sure that it's configured properly so it's not an open relay. Ask your
            SysAdmin for help.

       What about multi-part messages?
            Not yet supported. I'll definitely add internal support for multi-part/alternative in
            the future.

            Until then? You can always do the MIME encoding yourself, set your own headers, etc.
            It's perfectly fine to do it yourself, but you will have to do it yourself for now.

       Mail::Bulkmail is really cool, but what'd be even cooler is a front end for the thing! Do
       you have one of those?
            I don't. But check out Mojo Mail:

             http://mojo.skazat.com/

            Active community, developer, etc. Looks like a good product.

       You know, you re-invent a lot of wheels.
            Yeah, I do. Hey, c'mon, I write this stuff for the fun of it. And that means that I'm
            going to do it the way that I want to. :) Besides, I've never had any problem with
            re-inventing wheels. After all, if the wheel hadn't been re-invented a few times,
            we'd still be using solid plain wooden wheels. Not to say that I necessarily think
            that I've invented better things here than are available elsewhere, but I might
            eventually. Who knows.

            Anyway, you're more than free to subclass and over-ride things with "standard"
            modules if you'd like. ou can make your own server implementation using Net::SMTP, or
            your own dynamic message system using Text::Template, or whatever else. Feel free to
            use the standards if you'd prefer.

            Me? I enjoy re-inventing wheels, so I'll continue to do so.

       Dude! Warnings is on!
            That's by design. Nothing in the code ever should generate a warning, but if it does,
            then please please please let me know about it so I can patch it. You can always turn
            off warnings yourself if you're worried/annoyed.

       So what is it with these version numbers anyway?
            I'm going to try to be consistent in how I number the releases.

            The hundredths digit will indicate bug fixes, minor behind-the-scenes changes, etc.

            The tenths digit will indicate new and/or better functionality, as well as some minor
            new features.

            The ones digit will indicate a major new feature or re-write.

            Basically, if you have x.ab and x.ac comes out, you want to get it guaranteed.  Same
            for x.ad, x.ae, etc.

            If you have x.ac and x.ba comes out, you'll probably want to get it.  Invariably
            there will be bug fixes from the last "hundredths" release, but it'll also have
            additional features.  These will be the releases to be sure to read up on to make
            sure that nothing drastic has changes.

            If you have x.ac and y.ac comes out, you'll want to do research before upgrading. I
            break things, I lose backwards compatibility, I change stuff around a lot. Just my
            nature. Porting from one major release to the next is pretty straightforward, but
            there's still work to be done on your part - it won't just be a drop in replacement.
            And, depending upon your list and what options you're using, you may or may not see
            any benefit to upgrading. Read the docs, ask me questions, and test test test.

            Don't get me wrong, I'm not going to intentionally *try* to make things not backwards
            compatible, but if I come up with what I think is a better way of doing things, I'm
            going to go with it. And I don't like to pollute modules with a lot of cruft
            bridgeworks for backwards compatibility. This thing is huge enough as is without
            having to worry about making sure internal band-aids work.

            If this'll be a problem, then don't upgrade.

       Is anything missing vs. the old versions?
            Yes. You can't currently extract headers from the message you're sending. This will
            return in the future, probably.

            When using dynamic_header_data, you can no longer set a default header to be used if
            no header is defined for the individual user.  This will also probably return in the
            future.

            local merges no longer exist. You only have global merges and individual ones.

            It will now date all messages to the time of the first sent message.

            You can no longer externally load in a list of duplicates. Come on, did *anybody*
            ever actually do that?

       When I try to bulkmail, I get an error that says "Cannot bulkmail...no To address" How do
       I fix this?
            Ya know, I thought this error was self-explanatory, but considering the number of
            people that email me about it, I guess it's not.

            The issue here is that (say it with me now), you can't bulkmail because the To header
            hasn't been set.  If you're using envelope sending (on by default in Mail::Bulkmail),
            then you have to specify an address to set in the To: header of the message. This is
            specified via the ->To accessor.

             $bulk->To("mylist@mysite.com");

            So, specify the To header, and then you'll be fine.

       Wow, this module is really cool.  Have you contributed anything else to CPAN?
            Yes, Carp::Notify and Text::Flowchart

       Was that a shameless plug?
            Why, yes.  Yes it was.

       Anything else you want to tell me?
            Sure, anything you need to know.  Just drop me a message.

EXAMPLES

       #simple mailing with a list called "./list.txt"

        my $bulk = Mail::Bulkmail->new(
               "LIST"          => "./list.txt",
               "Subject"       => "A test message",
               "Message"       => "This is my test message",
               "From"          => 'me@mydomain.com',
               "To"            => 'somelist@mydomain.com',
               "Reply-To"      => 'replies@mydomain.com'
        ) || die Mail::Bulkmail->error();

        $bulk->bulkmail || die $bulk->error;

       #same thing, but turning off envelope sending

        my $bulk = Mail::Bulkmail->new(
               "LIST"                  => "./list.txt",
               "Subject"               => "A test message",
               "Message"               => "This is my test message",
               "From"                  => 'me@mydomain.com',
               "Reply-To"              => 'replies@mydomain.com',
               "use_envelope" => 0
        ) || die Mail::Bulkmail->error();

        $bulk->bulkmail || die $bulk->error;

       #Small example, with a miniature in memory list

        my $bulk = Mail::Bulkmail->new(
               "LIST"          => [qw(test@mydomain.com me@mydomain.com test2@mydomain.com)],
               "Subject"       => "A test message",
               "Message"       => "This is my test message",
               "From"          => 'me@mydomain.com',
               "To"            => 'somelist@mydomain.com',
               "Reply-To"      => 'replies@mydomain.com',
               "Sender"        => 'sender@mydomain.com'
        ) || die Mail::Bulkmail->error();

        $bulk->bulkmail || die $bulk->error;

       #Make sure our error logging is on in a different place, and set up a different server

        my $server = Mail::Bulkmail::Server->new(
               'Smtp' => "smtp.mydomain.com",
               "Port" => 25
        ) || die Mail::Bulkmail::Server->error();

        my $bulk = Mail::Bulkmail->new(
               "LIST"          => "./list.txt",
               "Subject"       => "A test message",
               "Message"       => "This is my test message",
               "From"          => 'me@mydomain.com',
               "To"            => 'somelist@mydomain.com',
               "Reply-To"      => 'replies@mydomain.com',
               "ERRFILE"       => '/etc/mb/error.file.txt',
               "servers"       => [$server]    #our new server
        ) || die Mail::Bulkmail->error();

        $bulk->bulkmail || die $bulk->error;

       #Make sure our error logging is on in a different place, and set up a different server
       #this time, we'll use a dummy server for debugging purposes

        my $dummy_server = Mail::Bulkmail::DummyServer->new(
               "dummy_file"    => "/etc/mb/dummy.server.output.txt"
        ) || die Mail::Bulkmail::DummyServer->error();

        my $bulk = Mail::Bulkmail->new(
               "LIST"          => "./list.txt",
               "Subject"       => "A test message",
               "Message"       => "This is my test message",
               "From"          => 'me@mydomain.com',
               "To'            => 'somelist@mydomain.com',
               "Reply-To"      => 'replies@mydomain.com',
               "ERRFILE"       => '/etc/mb/error.file.txt',
               "servers"       => [$dummy_server]      #our new server, which is a dummy server
        ) || die Mail::Bulkmail->error();

        $bulk->bulkmail || die $bulk->error;

       #mailing just to one address

        my $bulk = Mail::Bulkmail->new(
               "Subject"       => "A test message",
               "Message"       => "This is my test message",
               "From"          => 'me@mydomain.com',
               "Reply-To"      => 'replies@mydomain.com',
               "Sender"        => 'sender@mydomain.com'
        ) || die Mail::Bulkmail->error();

        $bulk->mail('test@yourdomain.com') || die $bulk->error;

       #here, a fun one. Use a coderef as our LIST

        my $query = "select email, domain from table order by domain";
        my $stmt = $dbh->prepare($query) || die;

        $stmt->execute || die;

        sub get_list {
               my $bulk = shift; #we always get our bulkmail object first

               my $data = $stmt->fetchrow_hashref();

               if ($data) {
                       return $data->{"email"};
               }
               else {
                       return undef;
               };
        };

        $bulk->LIST(\&get_list);

        #and now, logging to a coderef.

        my $query = ('insert into table good_addresses (email) values (?)');
        my $stmt = $dbh->prepare($query) || die;

        sub store_to_db {
               my $bulk        = shift; #always get our bulkmail object first
               my $email       = shift;

               $stmt->execute($email) || return $bulk->error("Could not store to DB!");
               return 1;
        };

        $bulk->GOOD(\&store_to_db);

SAMPLE CONFIG FILE

       This is my current conf file. It's about as close to one that you want to use as possible.
       Remember, you can set any values you'd like in the conf file, as long as they're scalars
       or arrayrefs of scalars. For example, if you want a default "From" value, then define it
       in the conf file.

       For more information on conf files, see Mail::Bulkmail::Object. For more information on
       the server file, see Mail::Bulkmail::Server. This file is also stored in the file
       "sample.cfg.file"

        define package Mail::Bulkmail

        #server_class stores the server object that we're going to use.
        #uncomment the DummyServer line and comment out the Server line for debugging

        server_class = Mail::Bulkmail::Server
        #server_class = Mail::Bulkmail::DummyServer

        #log our errors
        ERRFILE = /etc/mb/error.txt
        BAD    = /etc/mb/bad.txt
        GOOD   = /etc/mb/good.txt
        banned = /etc/mb/banned.txt

        #if we want a default From value, you can place it here.
        #From = me@mydomain.com

        define package Mail::Bulkmail::Server

        #set up the domain we use to say HELO to our relay
        Domain = mydomain.com

        #Most servers are going to connect on port 25, so we'll set this as the default port here
        Port = 25

        #We'll give it 5 tries to connect before we let ->connect fail
        Tries = 5

        #Lets try to reconnect to a server 5 times if ->connect fails.
        max_connection_attempts = 5

        #100 is a good number for the envelope_limit
        envelope_limit = 100

        #Send 1,000 messages to each server in the round before going to the next one.
        #set max_messages_per_robin to 0 if you're only using one server, otherwise you'll have needless
        #overhead
        max_messages_per_robin = 0

        #maximum number of messages per connection. Probably best to keep this 0 unless you have a reason
        #to do otherwise
        max_messages_per_connection = 0

        #maximum number of messages for the server. Probably best to keep this 0 unless you have a reason
        #to do otherwise
        max_messages= 0

        #maximum number of messages to send before sleeping, probably best to keep this 0 unless you need
        #to let your server relax and sleep
        max_messages_while_awake = 0

        #sleep for 10 seconds if we're sleeping. This line is commented out because we don't need it.
        #No harm in uncommenting it, though.
        #sleep_length = 10

        #our list of servers
        server_file = /etc/mb/servers.txt

        define package Mail::Bulkmail::Dynamic

        #it is highly recommended that quotemeta be 1
        quotemeta = 1

        #set up our default delimiters
        dynamic_message_delimiter                      = ;
        dynamic_message_value_delimiter        = =
        dynamic_header_delimiter                       = ;
        dynamic_header_value_delimiter         = =

        #we're going to assume that duplicates have been weeded out, so we'll allow them.
        Trusting       @= duplicates

        #By default, we'll turn on our envelope. Mail::Bulkmail might as well use it.
        #Mail::Bulkmail::Dynamic doesn't care about this value.
        use_envelope           = 1

        define package Mail::Bulkmail::DummyServer

        #Our dummy data file, for when we're using DummyServer. It's also useful to send the data to
        #/dev/null to test things if you don't care about the message output.
        dummy_file = /etc/mb/dummy.file
        #dummy_file = /dev/null

DIAGNOSTICS

       Bulkmail doesn't directly generate any errors.  If something fails, it will return undef
       and set the ->error property of the bulkmail object.  If you've provided an error log
       file, the error will be printed out to the log file.

       Check the return of your functions, if it's undef, check ->error to find out what
       happened.

       Be warned that isDuplicate and isBanned will return 0 if an address is not a duplicate or
       banned, respectively, but this is not an error condition.

SEE ALSO

       Mail::Bulkmail::Object, Mail::Bulkmail::Server, Mail::Bulkmail::Dummy

COPYRIGHT (again)

       Copyright and (c) 1999, 2000, 2001, 2002, 2003 James A Thomason III (jim@jimandkoka.com).
       All rights reserved.  Mail::Bulkmail is distributed under the terms of the Perl Artistic
       License.

CONTACT INFO

       So you don't have to scroll all the way back to the top, I'm Jim Thomason
       (jim@jimandkoka.com) and feedback is appreciated.  Bug reports/suggestions/questions/etc.
       Hell, drop me a line to let me know that you're using the module and that it's made your
       life easier.  :-)

       http://www.jimandkoka.com/jim/perl/ for more perl info, http://www.jimandkoka.com in
       general