Document last updated: 8/3/2001 (samc) Using LAFcommon.SMTPMail ======================== LAFcommon.SMTPMail is an interface for programmatically sending email via SMTP. It is a "Mail Delivery Agent" (as opposed to a "Mail Transport Agent"), which means that it generates the mail message and hands it off to a server that is capable of more advanced processing. LAFcommon.SMTPMail is not capable of looking up DNS MX records to find remote mail hosts, it is not capable of bouncing messages if delivery is not possible and it does not present an SMTP interface for remote hosts to deliver mail to it. It only allows a programmer to send email from a program in much the same way that Outlook allows a user to send email from a computer. In general, LAFcommon.SMTPMail is intended to handle many messages, though it functions well for sending single messages as well. It is for this reason that some of the "environment" for message delivery is set seperately from the message content and is maintained even after a message has been delivered. LAFcommon.SMTPMail completely replaces the old LAFcommon.Sendmail interface, though LAFcommon.Sendmail still exists for backwards compatibility and just calls LAFcommon.SMTPMail internally. NOTE: While the following documentation is intended for VB/VBScript programmers using LAFcommon.SMTPMail, the files "reusables_SMTP.h" and "reusables_SMTP.cpp" in the LAFcommon project provide the C++ interface to the following functionality, in most cases through functions of the same or similar names. The two files can be directly included into other projects -- they only require that PROJECT_HELPSTRING be "#define"d to a short string appropriately describing the project, STRLEN_PROJECT_HELPSTRING be "#define"d to the length of PROJECT_HELPSTRING and the files "reusables_Queue.*" and "reusables_AVLTree.*" be included as well. LAFcommon.SMTPMail does most of its work through properties, especially when setting up the "environment" for message delivery. Some properties are "session-level", which means that they are stored on the current instantiation of LAFcommon.SMTPMail, not the currently selected queue. "Session-level" property values are often used to set values in new messages. "Queue-level" properties are stored on the queue and persist with the queue even after the current instantiation has been destroyed. The following properties are available: Accountability (read/write, Long) Accountability determines LAFcommon.SMTPMail's behavior after it attempts to deliver a message. The possible values are defined in the LAFcommon typelib and in the file "lafcommon_vbs.txt". The given values can be combined by bitwise ORing them together to produce the desired behavioral description. The values are as follows: LAFCOMMON_SMTPMAIL_discard_all The delivery results, the message IDs and the messages' content are discarded after delivery is attempted. This option cannot be specified with LAFCOMMON_SMTPMAIL_save_id or LAFCOMMON_SMTPMAIL_save_all. LAFCOMMON_SMTPMAIL_save_id The delivery results and message IDs are saved after delivery is attempted, but the messages' content is discarded. This option only has any effect when either LAFCOMMON_SMTPMAIL_act_on_success or LAFCOMMON_SMTPMAIL_act_on_failure (or both) are given. This option cannot be specified with LAFCOMMON_SMTPMAIL_discard_all or LAFCOMMON_SMTPMAIL_save_all. LAFCOMMON_SMTPMAIL_save_all The delivery results, message IDs and messages' content are saved after delivery is attempted. This option only has any effect when either LAFCOMMON_SMTPMAIL_act_on_success or LAFCOMMON_SMTPMAIL_act_on_failure (or both) are given. This option cannot be specified with LAFCOMMON_SMTPMAIL_discard_all or LAFCOMMON_SMTPMAIL_save_id. LAFCOMMON_SMTPMAIL_act_on_success The options LAFCOMMON_SMTPMAIL_save_id and LAFCOMMON_SMTPMAIL_save_all are considered when a message is successfully delivered. In other words, specifying both LAFCOMMON_SMTPMAIL_save_id and LAFCOMMON_SMTPMAIL_act_on_success will save all the message IDs of messages that are successfully delivered. LAFCOMMON_SMTPMAIL_act_on_failure The options LAFCOMMON_SMTPMAIL_save_id and LAFCOMMON_SMTPMAIL_save_all are considered when a message cannot be delivered. In other words, specifying both LAFCOMMON_SMTPMAIL_save_id and LAFCOMMON_SMTPMAIL_act_on_failure will save all the message IDs of messages that cannot be delivered. LAFCOMMON_SMTPMAIL_retry_failures All messages for which delivery fails will be retried after a predetermined period of time. This option can be given with any of the others, including LAFCOMMON_SMTPMAIL_discard_all. When this option is given, the properties MaxFailureRetries and RetryIntervalMinutes are used. LAFCOMMON_SMTPMAIL_process_batch_attempt_all An attempt will be made to deliver the message(s) to all addressees, even if some of them are rejected by the SMTP server. This option only has meaning for messages with multiple addressees. This option cannot be given with LAFCOMMON_SMTPMAIL_process_batch_stop_on_first_failure. LAFCOMMON_SMTPMAIL_process_batch_stop_on_first_failure A message will fail delivery as soon as one of its addressees is rejected by the SMTP server. NOTE: If one of a message's addressees is rejected and the message fails delivery, it is possible that some of the addressees may receive the message if their messages were accepted by the SMTP server before the error was encountered. This option only has meaning for messages with multiple addressees. This option cannot be given with LAFCOMMON_SMTPMAIL_process_batch_attempt_all. The default is: LAFCOMMON_SMTPMAIL_discard_all | LAFCOMMON_SMTPMAIL_process_batch_attempt_all Accountability is a queue-level setting. DeliveryMode (read/write, Long) DeliveryMode determines LAFcommon.SMTPMail's behavior after ProcessMessage() is called. The possible values are defined in the LAFcommon typelib and in the file "lafcommon_vbs.txt". They are as follows: LAFCOMMON_SMTPMAIL_deliver_synchronous All messages are delivered synchronously -- ProcessMessage() does not return until delivery is complete; its return code is the outcome of the message. This is the default. LAFCOMMON_SMTPMAIL_deliver_asynchronous All messages are delivered asynchronously -- ProcessMessage() returns immediately and worker threads deliver the messages in the background. NOTE: Asynchronous delivery has several advantages and disadvantages. In asynchronous mode, many worker threads can be attached to the queue to process many messages. This can result in faster processing in certain cases (see MaxWorkerThreads for details). Asynchronous delivery can provide an excellent workaround to the problem of ASP pages timing out before delivery is complete. However, asynchronous delivery will only work if worker threads can be started to process the messages in the queue. This is only possible if the calling process has initialized LAFcommon in an MTA (Multi-Threaded Apartment). IIS and the JRE do this but the Windows Scripting Host does not. Therefore, asynchronous delivery is not possible from the Scripting Host. Delivery in asynchronous mode masks the outcomes of the delivery attempts, making it much more difficult to determine if a message was delivered. The only way to circumvent this is to set the Accountability (above) to an appropriate value so the outcomes can be examined later. Lastly, when many messages are queued in asynchronous mode, the programmer must take great care to ensure the process does not exit before delivery is complete. While this is typically not a problem under IIS, command-line programs can easily terminate before delivery has finished, especially if mail delivery is their last action before exiting. Any messages remaining in the queue when the process exits are lost. See WaitUntilEmpty() for a solution to this problem. DeliveryMode is a session-level setting. ErrorMessage (read-only, String) ErrorMessage is a system-generated string that provides an English explanation of the outcome of the last action. If the last action was successful, ErrorMessage is an empty string. Reading from ErrorMessage does not reset ErrorMessage, but using any other method or property does. ErrorMessage is a session-level value. MaxFailureRetries (read/write, Integer) MaxFailureRetries determines the number of times an unsuccessful delivery is retried, if the Accountability dictates that failures should be retried. It must be a positive integer. The default value is 4. MaxFailureRetries is a queue-level setting. MaxRecipientsPerMessage (read/write, Integer) MaxRecipientsPerMessage determines the maximum number of addressees that each connection to the SMTP server can attempt to deliver to. For example, if a message has 1000 addressees and MaxRecipientsPerMessage is set to 100, LAFcommon.SMTPMail will only make 10 connections to the SMTP server, attempting to deliver a single message to 100 addressees each time. Use of this option can greatly reduce network traffic and processing time. The maximum value of MaxRecipientsPerMessage is determined by the SMTP server -- it is typically a configuration option set by the administrator. It must be a positive integer. The default value is 1. NOTE: MaxRecipientsPerMessage does not affect the number of addressees that can be given in a call to ProcessMessage, nor does it affect the "To:" line in the message header. MaxRecipientsPerMessage takes advantage of a feature in the SMTP protocol that was designed such that the recipient(s) of a message cannot determine it was used. MaxRecipientsPerMessage is a queue-level setting. MaxWorkerThreads (read/write, Integer) MaxWorkerThreads sets the upper limit for the number of threads that will attach to the current queue to attempt to deliver messages. The default value is 1. At first, this appears to be a case where "more is better", but that thinking is not true in most situations. There is only _one_ case where more worker threads is beneficial -- when reverse DNS of the sending machine's IP address is not setup correctly. There is a simple test for this: from the sending machine's console, use telnet to connect the SMTP server's SMTP port. If a greeting banner is displayed immediately, reverse DNS is working correctly and MaxWorkerThreads should be set to 1. If the greeting banner takes 30-90 seconds to appear, reverse DNS is not working correctly and increasing MaxWorkerThreads will speed message delivery. The reason for this is simple: message delivery can only go as fast as the slowest step in the procedure. If connecting to the mail server takes many seconds, a number of threads can be waiting for the greeting banner at once. However, if the greeting banner appears immediately, total message delivery may take no longer than 100 milliseconds. In this case, the slowest step is inside LAFcommon.SMTPMail -- the removal of messages from the queue. Because the queue is shared across threads, mutually exclusive locks are used to ensure data integrity. Only one thread can hold the lock at once and grabbing the lock is the slowest step. While many threads fight for the lock, one of them delivers a message. Because that message was delivered so fast, the delivering thread is fighting for the lock again before the next message is delivered. With this rapid-fire wrestling match going on, message delivery actually slows down. NOTE: Multiple processors only exacerbate this problem because the mutex dataspace must be stored in system RAM instead of processor cache. System RAM is thousands of times slower than processor cache, so the frantic lock contention slows down overall, which only delays message delivery even more. If increasing MaxWorkerThreads is beneficial, it is recommended that it be set no higher than 5 unless LAFcommon.SMTPMail is running in its own process space and a dedicated SMTP server is being used. There is a (small) upper limit to the number of threads a process can have. When running under a massively threaded process like IIS, a high number of LAFcommon.SMTPMail worker threads can cause segfaults if the parent process hits its thread limit and cannot spawn more when needed. Additionally, most SMTP servers have a (configurable) upper limit to the number of simultaneous incoming connections they can support. Consuming all of these connections by starting a high number of worker threads can be considered a Denial Of Service attack and is generally rude. MaxWorkerThreads is a queue-level setting. QueueName (read/write, String) The name of the mail queue being accessed by all of the queue-level methods and properties in this interface. By default, this is a GUID created when the session is started. This property allows an otherwise stateless environment (like ASP) to reconnect to a previously-used queue to check its status, pause or empty it. Queues are deleted after 20 minutes of inactivity. QueueName is a session-level setting. QueueSize (read-only, Long) Returns the number of messages in the queue waiting for delivery. QueueSize is a queue-level value. ReplyToAddress (write-only, String) ReplyToAddress is used to construct the message header. In a compliant mail reader, hitting "Reply" will send a new message to the address listed in the "Reply-To" field of the header, regardless of the contents of the "From" field. ReplyToAddress is optional and by default is empty. If set, it must be an email address. ReplyToAddress is a session-level setting. RetryIntervalMinutes (read/write, Integer) RetryIntervalMinutes is the number of minutes LAFcommon.SMTPMail will hold a message for which delivery failed before trying to deliver it again. By default, it is 15. RetryIntervalMinutes is a queue-level setting. ReturnPathAddress (write-only, String) ReturnPathAddress is used in the message header to specify an address the message should be returned to if it cannot be delivered. Without this field, the message is typically bounced to the address listed in the "From:" field. If the "apparently_from" feature of ProcessMessage() is used, this field may not contain a valid/appropriate address. ReturnPathAddress is optional and by default is empty. ReturnPathAddress is a session-level setting. SenderAddress (write-only, String) SenderAddress is used in two places: first in the SMTP protocol when LAFcommon.SMTPMail identifies itself to the SMTP server and second in the message header "From" field if an "apparently from" value is not given (see ProcessMessage() below). SenderAddress is required and must be an email address that the SMTP server will not deny for relaying. By default it is empty. SenderAddress is a session-level setting. SenderName (write-only, String) SenderName is used in the message header "From" field if an "apparently from" value is not given (see ProcessMessage() below). SenderName is optional and can be a free-form string, though it should be kept short (40 characters or less) because it is often displayed in mail clients with the understanding that it will be a person's name. By default it is empty. SenderName is a session-level setting. ServerIP (write-only, String) ServerIP is the IP address of the SMTP server. It must be in "dotted quad" notation (e.g. "111.222.111.222"). ServerIP should only be used when a DNS name for the server is not available and cannot be made available. Using an IP address requires someone to update the application if the mail server ever moves. Needless to say, if ServerIP is used, that fact should be widely advertised so the application will get updated if the server moves. Either ServerIP or ServerName must be supplied. By default, ServerIP is empty. ServerIP is a session-level setting. ServerName (write-only, String) ServerName is the DNS name of the SMTP server. An IP address is not acceptable for ServerName -- use ServerIP instead if a DNS name is not available. The DNS name is looked up when ServerName is called, not at message delivery time, so if the name cannot be found an error will immediately be available. Either ServerName or ServerIP must be supplied. By default, ServerName is empty. ServerName is a session-level setting. ServerPort (write-only, Integer) ServerPort is the SMTP port on the SMTP server that LAFcommon.SMTPMail should connect to. ServerPort is required and must be a positive integer no greater than 65535. By default it has no value. ServerPort is a session-level setting. ThrowErrors (write-only, Boolean) ThrowErrors has no effect on the behavior of LAFcommon.SMTPMail's mail delivery, only on the behavior of this interface. If ThrowErrors is set to True, ATL errors will be generated whenever ErrorMessage is set to a non-empty value. The ATL error will contain the text of ErrorMessage. On an ASP page, unless "On Error Resume Next" is specified, an ATL error will stop processing and display the error message. ThrowErrors is a session-level setting. LAFcommon.SMTPMail has the following methods available: Function AddSection(Integer section_type, String content, Optional String name) as Integer AddSection() adds the content to the current message. The possible values for section_type are found in the LAFcommon typelib and also in the file "lafcommon_vbs.txt". They are as follows: LAFCOMMON_SMTPMAIL_x_header Adds an extra header to the mail header, preceeded by "X-". "X" headers are ignored by mail clients except in very special circumstances, and most newer mail clients will not even display them to the user. They can be very handy for debugging, however. The name field is required for this section type. LAFCOMMON_SMTPMAIL_plain_text_message This is the standard message type, encoded as plain text. Any lines longer than 996 characters will be wrapped after character 996, even if that breaks a word across two lines. The name field is ignored for this section type. LAFCOMMON_SMTPMAIL_html_text_message Adds the ability to provide an HTML message that a compliant mail reader will display as an HTML document. Not all mail readers have this capability, so a plain text alternative should be provided (see below). LAFCOMMON_SMTPMAIL_plain_text_attachment Adds a text attachment whose content is provided in the content field. The name field is optional but will give the filename the attachment should be saved as when viewed in a compliant mail reader. NOTE: This section type does not require the attachment's extension to be "TXT", it only determines the encoding that is performed on the content before the message is sent. The recipient will be unable to tell that the attachment's content was not loaded from a file on disk. LAFCOMMON_SMTPMAIL_html_text_attachment Adds an HTML attachment whose content is provided in the content field. The name field is optional but will give the filename the attachment should be saved as when viewed in a compliant mail reader. NOTE: This section type does not require the attachment's extension to be "HTML", it only determines the encoding that is performed on the content before the message is sent. The recipient will be unable to tell that the attachment's content was not loaded from a file on disk. LAFCOMMON_SMTPMAIL_text_file_attachment Adds a text attachment whose content is loaded from disk. The name field is optional, but will give the filename the attachment should be saved as when viewed in a compliant mail reader. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "TXT", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_html_file_attachment Adds an HTML attachment whose content is loaded from disk. The name field is optional, but will give the filename the attachment should be saved as when viewed in a compliant mail reader. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "HTML", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_binary_file_attachment Adds a binary attachment whose content is loaded from disk. The name field is optional, but will give the filename the attachment should be saved as when viewed in a compliant mail reader. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to anything, it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_gif_file_attachment Adds a gif attachment whose content is loaded from disk. The name field is optional, but will give the filename the attachment should be saved as when viewed in a compliant mail reader. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "GIF", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_jpeg_file_attachment Adds a jpeg attachment whose content is loaded from disk. The name field is optional, but will give the filename the attachment should be saved as when viewed in a compliant mail reader. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "JPG", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_plain_text_inline Adds a plain text inline attachment whose content can be referenced from other sections in a MIME-compliant mail client. This section type requires a name, which is used both for the filename and for the content ID. NOTE: This section type does not force the attachment's extension to "TXT", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_html_text_inline Adds an HTML text inline attachment whose content can be referenced from other sections in a MIME-compliant mail client. This section type requires a name, which is used both for the filename and for the content ID. NOTE: This section type does not force the attachment's extension to "HTML", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_text_file_inline Adds a text inline attachment whose content is loaded from disk and that can be referenced from other sections in a MIME-compliant mail client. This section type requires a name, which is used both for the filename and for the content ID. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "GIF", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_html_file_inline Adds a text inline attachment whose content is loaded from disk and that can be referenced from other sections in a MIME-compliant mail client. This section type requires a name, which is used both for the filename and for the content ID. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "GIF", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_binary_file_inline Adds a binary inline attachment whose content is loaded from disk and that can be referenced from other sections in a MIME-compliant mail client. This section type requires a name, which is used both for the filename and for the content ID. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to anything, it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_gif_file_inline Adds a GIF inline attachment whose content is loaded from disk and that can be referenced from other sections in a MIME-compliant mail client. This section type requires a name, which is used both for the filename and for the content ID. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "GIF", it only determines the encoding that is performed on the content before the message is sent. LAFCOMMON_SMTPMAIL_jpeg_file_inline Adds a JPEG inline attachment whose content is loaded from disk and that can be referenced from other sections in a MIME-compliant mail client. This section type requires a name, which is used both for the filename and for the content ID. The content field should contain the source filename on the server's hard drive that the content is to be read from. NOTE: This file must be accessible by the owner of the process that is invoking LAFcommon.SMTPMail. Under an in-process IIS application, this is SYSTEM. Under an out-of-process IIS application, this is IUSR_machinename. NOTE: This section type does not force the attachment's extension to "JPG", it only determines the encoding that is performed on the content before the message is sent. Any number of sections can be added to a message. The order of the message sections is significant, however. The MIME specification dictates that the _last_ message section is the preferred one to show the recipient, if the mail reader can support it. If it cannot, the previous one should be used. If that one cannot be supported, the mail reader should continue backtracking through the sections until one is found that can be displayed. This means that in most cases, a plain text section should be added first, followed by an HTML section. If the recipient is using an HTML-capable mail client, it will display the HTML section. If the recipient is using a mail client that cannot handle HTML, it will display the plain text. X-* headers are always added to the message header in the order they were added by AddSection(); their order with respect to the message content sections is ignored. The difference between the *_attachment and *_inline section types is subtle but significant. The _only_ reason to use an *_inline section type is if email is to be sent out with attachment(s) that are to be displayed in the message. For example, if an HTML email is sent out with images that are to be shown when the message is read _instead_of_ having the HTML document reference images on a remote server, *_inline sections are the solution. The inline attachments should be referenced by their Content-IDs, which is the name supplied for the section when it was added. The special tag that tells the mail client to use the attachment is "cid" (analogous to "http"). For example, if the following code were executed: AddSection(LAFCOMMON_SMTPMAIL_gif_file_inline, "C:\foo.gif", "bar.gif") Then the following HTML document would display the image in the mail client: IMPORTANT NOTE: The above does not apply to Microsoft Outlook, which is not RFC 2387-compliant. In Outlook, the MIME type "multipart/related" is not recognized and is treated as "multipart/mixed" (in accordance with RFC 2045). This means that any *_inline sections will cause the message in Outlook to be blank with an attached message that displays correctly (with the *_inline sections in the document as intended). In addition, any *_attachment sections will appear as normal attachments in the initial blank message next to the "attached" message. However, Netscape Communicator _is_ RFC 2387-compliant, which means that *_attachment sections cannot be referenced using the "cid" tag; they must be added as *_inline sections. This means that Outlook and Communicator are completely incompatible in this respect. If a single message must be sent to both Outlook and Communicator users that must display the attachments in the document, the sections should be added as *_inline sections. Doing this, the Communicator users will see the intended result. The Outlook users will see the intended result after opening the "attached" message inside the initial blank one. If the attachments are added as *_attachment sections, the Communicator users will see broken images with no way to see the intended result. Whether other popular mail clients, such as Lotus Notes, Eudora Pro or Pegasus Mail are RFC 2387-compliant is left as an exercise for the reader. NOTE: None of the above applies if the content of the attachments is not intended to be viewed in the message. Both Outlook and Communicator can display an HTML document that references images stored on a remote server, so long as the client machine has a connection to the internet. Function Constant2Value(String constant_name) as Variant Constant2Value() is provided for environments that cannot read LAFcommon's typelib and that cannot import the file "lafcommon_vbs.txt". An example of this type of environment is Windows Scripting Host. Constant2Value() will accept the name of the constant as it is defined in "lafcommon_vbs.txt" and return its defined value. NOTE: Using this function is _much_ slower than using the values in the typelib or in "lafcommon_vbs.txt" and should only be used as a last resort. Function ProcessMessage(Variant addressee_array, String subject, Optional String apparently_to, Optional String apparently_from) as Integer ProcessMessage() packages the current message and either delivers it immediately or adds it to the queue for later delivery (depending on the value of DeliveryMode -- see above). The first parameter, addressee_array, can have two possible formats. It may be a String if only one addressee is is desired or it may be a single-dimensional array of Strings if many addressees are desired. NOTE: The latter is far more efficient for delivering to multiple addressees (as opposed to creating many separate identical messages) in terms of memory usage and delivery speed. The second parameter, subject, is the subject of the message. The third parameter, apparently_to, can be used as a substitute for the default "To" field in the message header if only one addressee is given. This is useful when the addressee's address should not be shown in the message header. This parameter is required when multiple addressees are given. From an ASP page, providing the keyword Empty for this parameter has the same effect as omitting it. The fourth parameter, apparently_from, is always optional and can be used as a substitute for the email address in the message header's "From" field. This is useful when SenderAddress was set to a value that would pass through the mail server's anti-relaying filters (see above) but is not an address that is suitable to be advertised or is not the address the recipient is expecting. From an ASP page, providing the keyword Empty for this parameter has the same effect as omitting it. The returned Integer is an LAFcommon.SMTPMail return code (see below). Function QueueFlush() as Integer QueueFlush() dumps all messages waiting to be delivered in the current queue. The returned Integer is an LAFcommon.SMTPMail return code (see below). Function QueuePause(Integer max_pause_seconds) as Integer QueuePause() prevents asynchronous delivery from the current queue for a minimum of max_pause_seconds seconds. This is useful if a great number of messages are to be loaded into the queue for asynchronous delivery -- pausing the queue before loading the messages will prevent the delivery worker threads from fighting for the queue lock until the loading is complete, thus speeding up both procedures. QueuePause() is also useful for preventing the queue from attempting to deliver messages if something is wrong with the mail server -- it can be paused until the problem is repaired. The returned Integer is an LAFcommon.SMTPMail return code (see below). Sub VersionInfo(ByRef Variant file_major, ByRef Variant file_minor, ByRef Variant file_revision, ByRef Variant file_build, ByRef Variant product_major, ByRef Variant product_minor, ByRef Variant product_revision, ByRef Variant product_build, ByRef Variant additional_info) VersionInfo() provides information on the version of LAFcommon that is running without requiring a visit to the server's console. The first eight parameters can be used to assemble the file version and the product version in the form W.X.Y.Z where W is the major version, X is the minor version, Y is the revision number and Z is the build number. The last parameter, additional_info, can be used to return other relevant information that the author saw fit to provide. Function WaitUntilEmpty(Integer max_wait_seconds) as Integer WaitUntilEmpty() is a function call that simply blocks until either (1) the current queue contains no messages to be delivered or (2) max_wait_seconds seconds have passed. If max_wait_seconds is equal to 0 (zero), WaitUntilEmpty() will never timeout -- it waits until the queue is empty. The returned Integer is an LAFcommon.SMTPMail return code (see below). LAFcommon.SMTPMail defines the following return codes in the LAFcommon typelib and in the text file "lafcommon_vbs.txt": LAFCOMMON_SMTPMAIL_success The function call was successful and no work remains to be done. LAFCOMMON_SMTPMAIL_success_remainder The function call was successful, but more work remains to be done. LAFCOMMON_SMTPMAIL_fail No errors were encountered, but the function call failed. LAFCOMMON_SMTPMAIL_error_internal An internal error occurred, possibly one that corrupted the memory space of the parent process. The author should probably be contacted. LAFCOMMON_SMTPMAIL_error_not_initialized The networking subsystem was not initialized when a network call was made. This error should never be seen. LAFCOMMON_SMTPMAIL_error_bad_parameter A parameter of the wrong type was given -- see above for the correct definitions of parameters the typelib declares as Variants. LAFCOMMON_SMTPMAIL_error_delivery_failure The message could not be delivered -- the SMTP server returned an unexpected response code. LAFCOMMON_SMTPMAIL_error_timeout A timeout occurred internally, preventing the call from succeeding. This may have been a network call or an attempt to grab the queue lock. LAFCOMMON_SMTPMAIL_error_bad_address The SMTP server address or SMTP port given was bad. LAFCOMMON_SMTPMAIL_error_invalid_accountability The accountability code given was not valid. Check to ensure a constant from the typelib or from "lafcommon_vbs.txt" is being used. LAFCOMMON_SMTPMAIL_error_cant_happen This error can't happen. Contact the author if you see it. LAFCOMMON_SMTPMAIL_error_connection_lost The connection to the SMTP server was lost. This may indicate a network problem (lost link, smoking equipment, etc). LAFCOMMON_SMTPMAIL_error_connection_refused The connection to the SMTP server was refused. The server may not be usable or it may just be busy. LAFCOMMON_SMTPMAIL_error_connection_failed The connection to the SMTP server failed. This most likely indicates a problem with the server's networking subsystem. LAFCOMMON_SMTPMAIL_error_network_down The server's networking subsystem is down -- no connections can be established. LAFCOMMON_SMTPMAIL_error_out_of_space No more memory (RAM) was available to allocate the buffers needed to complete the networking calls. LAFCOMMON_SMTPMAIL_error_host_not_found The SMTP host's DNS name could not be found. LAFCOMMON_SMTPMAIL_error_try_again_later An error occurred in the host's networking subsystem that will probably correct itself. Try again later. LAFCOMMON_SMTPMAIL_error_invalid_delivery_mode The delivery mode code given was not valid. Check to ensure a constant from the typelib or from "lafcommon_vbs.txt" is being used. LAFCOMMON_SMTPMAIL_error_invalid_max_worker_threads The maximum worker threads given was not valid. It must be a positive integer greater than or equal to 1. LAFCOMMON_SMTPMAIL_error_invalid_max_recipients_per_message The maximum number of recipients per message given was not valid. It must be a positive integer greater than or equal to 1. LAFCOMMON_SMTPMAIL_error_invalid_retry_interval_minutes The maximum number of minutes between delivery retries given was not valid. It must be a positive integer greater than or equal to 1. LAFCOMMON_SMTPMAIL_error_no_apparently_to Multiple addressees were given but no apparently_to parameter was provided. This is required when more than one addressee is specified. LAFCOMMON_SMTPMAIL_error_no_content No message content was provided. This is required. LAFCOMMON_SMTPMAIL_error_no_sender_address No sender address was provided. This is required. LAFCOMMON_SMTPMAIL_error_no_subject No subject was provided. This is required. LAFCOMMON_SMTPMAIL_error_no_addressees No recipients were provided. At least one recipient is required. LAFCOMMON_SMTPMAIL_error_invalid_max_failure_retries The maximum number of times to retry a message for which delivery failed given was invalid. It must be a positive integer greater than or equal to 1. LAFCOMMON_SMTPMAIL_error_invalid_section_type The section type code given was not valid. Check to ensure a constant from the typelib or from "lafcommon_vbs.txt" is being used. LAFCOMMON_SMTPMAIL_error_not_implemented The function called or property used has not been implemented yet. Contact the author if it is needed. LAFCOMMON_SMTPMAIL_error_cannot_open_file The file referenced as the source for an attachment could not be opened. Check to make sure that the process' owner has permission to open the file. LAFCOMMON_SMTPMAIL_error_section_name_required The section type specfied requires a name, but none was supplied.