|
Packit |
b53373 |
|
|
Packit |
b53373 |
"http://www.w3.org/TR/html4/strict.dtd">
|
|
Packit |
b53373 |
<html>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<head>
|
|
Packit |
b53373 |
<meta name="description" content="LuaSocket: SMTP support">
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Library, Support">
|
|
Packit |
b53373 |
<title>LuaSocket: SMTP support</title>
|
|
Packit |
b53373 |
<link rel="stylesheet" href="reference.css" type="text/css">
|
|
Packit |
b53373 |
</head>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<body>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<center>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Network support for the Lua language
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
home ·
|
|
Packit |
b53373 |
download ·
|
|
Packit |
b53373 |
installation ·
|
|
Packit |
b53373 |
introduction ·
|
|
Packit |
b53373 |
reference
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
</center>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
SMTP
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
The <tt>smtp</tt> namespace provides functionality to send e-mail
|
|
Packit |
b53373 |
messages. The high-level API consists of two functions: one to
|
|
Packit |
b53373 |
define an e-mail message, and another to actually send the message.
|
|
Packit |
b53373 |
Although almost all users will find that these functions provide more than
|
|
Packit |
b53373 |
enough functionality, the underlying implementation allows for even more
|
|
Packit |
b53373 |
control (if you bother to read the code).
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
The implementation conforms to the Simple Mail Transfer Protocol,
|
|
Packit |
b53373 |
RFC 2821.
|
|
Packit |
b53373 |
Another RFC of interest is
|
|
Packit |
b53373 |
href="http://www.ietf.org/rfc/rfc2822.txt">RFC 2822,
|
|
Packit |
b53373 |
which governs the Internet Message Format.
|
|
Packit |
b53373 |
Multipart messages (those that contain attachments) are part
|
|
Packit |
b53373 |
of the MIME standard, but described mainly
|
|
Packit |
b53373 |
in RFC 2046
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
In the description below, good understanding of
|
|
Packit |
b53373 |
href="http://lua-users.org/wiki/FiltersSourcesAndSinks"> LTN012, Filters
|
|
Packit |
b53373 |
sources and sinks and the MIME module is
|
|
Packit |
b53373 |
assumed. In fact, the SMTP module was the main reason for their
|
|
Packit |
b53373 |
creation.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
To obtain the <tt>smtp</tt> namespace, run:
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
-- loads the SMTP module and everything it requires
|
|
Packit |
b53373 |
local smtp = require("socket.smtp")
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
MIME headers are represented as a Lua table in the form:
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<tt>
|
|
Packit |
b53373 |
headers = {
|
|
Packit |
b53373 |
field-1-name = field-1-value,
|
|
Packit |
b53373 |
field-2-name = field-2-value,
|
|
Packit |
b53373 |
field-3-name = field-3-value,
|
|
Packit |
b53373 |
...
|
|
Packit |
b53373 |
field-n-name = field-n-value
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
</tt>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Field names are case insensitive (as specified by the standard) and all
|
|
Packit |
b53373 |
functions work with lowercase field names (but see
|
|
Packit |
b53373 |
<tt>socket.headers.canonic</tt>).
|
|
Packit |
b53373 |
Field values are left unmodified.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Note: MIME headers are independent of order. Therefore, there is no problem
|
|
Packit |
b53373 |
in representing them in a Lua table.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
The following constants can be set to control the default behavior of
|
|
Packit |
b53373 |
the SMTP module:
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<tt>DOMAIN</tt>: domain used to greet the server;
|
|
Packit |
b53373 |
<tt>PORT</tt>: default port used for the connection;
|
|
Packit |
b53373 |
<tt>SERVER</tt>: default server used for the connection;
|
|
Packit |
b53373 |
<tt>TIMEOUT</tt>: default timeout for all I/O operations;
|
|
Packit |
b53373 |
<tt>ZONE</tt>: default time zone.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
smtp.send{
|
|
Packit |
b53373 |
from = string,
|
|
Packit |
b53373 |
rcpt = string or string-table,
|
|
Packit |
b53373 |
source = LTN12 source,
|
|
Packit |
b53373 |
[user = string,]
|
|
Packit |
b53373 |
[password = string,]
|
|
Packit |
b53373 |
[server = string,]
|
|
Packit |
b53373 |
[port = number,]
|
|
Packit |
b53373 |
[domain = string,]
|
|
Packit |
b53373 |
[step = LTN12 pump step,]
|
|
Packit |
b53373 |
[create = function]
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Sends a message to a recipient list. Since sending messages is not as
|
|
Packit |
b53373 |
simple as downloading an URL from a FTP or HTTP server, this function
|
|
Packit |
b53373 |
doesn't have a simple interface. However, see the
|
|
Packit |
b53373 |
<tt>message</tt> source factory for
|
|
Packit |
b53373 |
a very powerful way to define the message contents.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
The sender is given by the e-mail address in the <tt>from</tt> field.
|
|
Packit |
b53373 |
<tt>Rcpt</tt> is a Lua table with one entry for each recipient e-mail
|
|
Packit |
b53373 |
address, or a string
|
|
Packit |
b53373 |
in case there is just one recipient.
|
|
Packit |
b53373 |
The contents of the message are given by a simple
|
|
Packit |
b53373 |
LTN12
|
|
Packit |
b53373 |
<tt>source</tt>. Several arguments are optional:
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<tt>user</tt>, <tt>password</tt>: User and password for
|
|
Packit |
b53373 |
authentication. The function will attempt LOGIN and PLAIN authentication
|
|
Packit |
b53373 |
methods if supported by the server (both are unsafe);
|
|
Packit |
b53373 |
<tt>server</tt>: Server to connect to. Defaults to "localhost";
|
|
Packit |
b53373 |
<tt>port</tt>: Port to connect to. Defaults to 25;
|
|
Packit |
b53373 |
<tt>domain</tt>: Domain name used to greet the server; Defaults to the
|
|
Packit |
b53373 |
local machine host name;
|
|
Packit |
b53373 |
<tt>step</tt>:
|
|
Packit |
b53373 |
LTN12
|
|
Packit |
b53373 |
pump step function used to pass data from the
|
|
Packit |
b53373 |
source to the server. Defaults to the LTN12 <tt>pump.step</tt> function;
|
|
Packit |
b53373 |
<tt>create</tt>: An optional function to be used instead of
|
|
Packit |
b53373 |
<tt>socket.tcp</tt> when the communications socket is created.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
If successful, the function returns 1. Otherwise, the function returns
|
|
Packit |
b53373 |
<tt>nil</tt> followed by an error message.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Note: SMTP servers can be very picky with the format of e-mail
|
|
Packit |
b53373 |
addresses. To be safe, use only addresses of the form
|
|
Packit |
b53373 |
"<tt><fulano@example.com></tt>" in the <tt>from</tt> and
|
|
Packit |
b53373 |
<tt>rcpt</tt> arguments to the <tt>send</tt> function. In headers, e-mail
|
|
Packit |
b53373 |
addresses can take whatever form you like.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Big note: There is a good deal of misconception with the use of the
|
|
Packit |
b53373 |
destination address field headers, i.e., the '<tt>To</tt>', '<tt>Cc</tt>',
|
|
Packit |
b53373 |
and, more importantly, the '<tt>Bcc</tt>' headers. Do not add a
|
|
Packit |
b53373 |
'<tt>Bcc</tt>' header to your messages because it will probably do the
|
|
Packit |
b53373 |
exact opposite of what you expect.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Only recipients specified in the <tt>rcpt</tt> list will receive a copy of the
|
|
Packit |
b53373 |
message. Each recipient of an SMTP mail message receives a copy of the
|
|
Packit |
b53373 |
message body along with the headers, and nothing more. The headers
|
|
Packit |
b53373 |
are part of the message and should be produced by the
|
|
Packit |
b53373 |
LTN12
|
|
Packit |
b53373 |
<tt>source</tt> function. The <tt>rcpt</tt> list is not
|
|
Packit |
b53373 |
part of the message and will not be sent to anyone.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
RFC 2822
|
|
Packit |
b53373 |
has two important and short sections, "3.6.3. Destination address
|
|
Packit |
b53373 |
fields" and "5. Security considerations", explaining the proper
|
|
Packit |
b53373 |
use of these headers. Here is a summary of what it says:
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<tt>To</tt>: contains the address(es) of the primary recipient(s)
|
|
Packit |
b53373 |
of the message;
|
|
Packit |
b53373 |
<tt>Cc</tt>: (where the "Cc" means "Carbon Copy" in the sense of
|
|
Packit |
b53373 |
making a copy on a typewriter using carbon paper) contains the
|
|
Packit |
b53373 |
addresses of others who are to receive the message, though the
|
|
Packit |
b53373 |
content of the message may not be directed at them;
|
|
Packit |
b53373 |
<tt>Bcc</tt>: (where the "Bcc" means "Blind Carbon
|
|
Packit |
b53373 |
Copy") contains addresses of recipients of the message whose addresses are not to be revealed to other recipients of the message.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
The LuaSocket <tt>send</tt> function does not care or interpret the
|
|
Packit |
b53373 |
headers you send, but it gives you full control over what is sent and
|
|
Packit |
b53373 |
to whom it is sent:
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
If someone is to receive the message, the e-mail address has
|
|
Packit |
b53373 |
to be in the recipient list. This is the only parameter that controls who
|
|
Packit |
b53373 |
gets a copy of the message;
|
|
Packit |
b53373 |
If there are multiple recipients, none of them will automatically
|
|
Packit |
b53373 |
know that someone else got that message. That is, the default behavior is
|
|
Packit |
b53373 |
similar to the <tt>Bcc</tt> field of popular e-mail clients;
|
|
Packit |
b53373 |
It is up to you to add the <tt>To</tt> header with the list of primary
|
|
Packit |
b53373 |
recipients so that other recipients can see it;
|
|
Packit |
b53373 |
It is also up to you to add the <tt>Cc</tt> header with the
|
|
Packit |
b53373 |
list of additional recipients so that everyone else sees it;
|
|
Packit |
b53373 |
Adding a header <tt>Bcc</tt> is nonsense, unless it is
|
|
Packit |
b53373 |
empty. Otherwise, everyone receiving the message will see it and that is
|
|
Packit |
b53373 |
exactly what you don't want to happen!
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
I hope this clarifies the issue. Otherwise, please refer to
|
|
Packit |
b53373 |
RFC 2821
|
|
Packit |
b53373 |
and
|
|
Packit |
b53373 |
RFC 2822.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
-- load the smtp support
|
|
Packit |
b53373 |
local smtp = require("socket.smtp")
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
-- Connects to server "localhost" and sends a message to users
|
|
Packit |
b53373 |
-- "fulano@example.com", "beltrano@example.com",
|
|
Packit |
b53373 |
-- and "sicrano@example.com".
|
|
Packit |
b53373 |
-- Note that "fulano" is the primary recipient, "beltrano" receives a
|
|
Packit |
b53373 |
-- carbon copy and neither of them knows that "sicrano" received a blind
|
|
Packit |
b53373 |
-- carbon copy of the message.
|
|
Packit |
b53373 |
from = "<luasocket@example.com>"
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
rcpt = {
|
|
Packit |
b53373 |
"<fulano@example.com>",
|
|
Packit |
b53373 |
"<beltrano@example.com>",
|
|
Packit |
b53373 |
"<sicrano@example.com>"
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
mesgt = {
|
|
Packit |
b53373 |
headers = {
|
|
Packit |
b53373 |
to = "Fulano da Silva <fulano@example.com>",
|
|
Packit |
b53373 |
cc = '"Beltrano F. Nunes" <beltrano@example.com>',
|
|
Packit |
b53373 |
subject = "My first message"
|
|
Packit |
b53373 |
},
|
|
Packit |
b53373 |
body = "I hope this works. If it does, I can send you another 1000 copies."
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
r, e = smtp.send{
|
|
Packit |
b53373 |
from = from,
|
|
Packit |
b53373 |
rcpt = rcpt,
|
|
Packit |
b53373 |
source = smtp.message(mesgt)
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
smtp.message(mesgt)
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
Returns a simple
|
|
Packit |
b53373 |
LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep).
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
The only parameter of the function is a table describing the message.
|
|
Packit |
b53373 |
<tt>Mesgt</tt> has the following form (notice the recursive structure):
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<tt>
|
|
Packit |
b53373 |
mesgt = {
|
|
Packit |
b53373 |
headers = header-table,
|
|
Packit |
b53373 |
body = LTN12 source or string or
|
|
Packit |
b53373 |
multipart-mesgt
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
multipart-mesgt = {
|
|
Packit |
b53373 |
[preamble = string,]
|
|
Packit |
b53373 |
[1] = mesgt,
|
|
Packit |
b53373 |
[2] = mesgt,
|
|
Packit |
b53373 |
...
|
|
Packit |
b53373 |
[n] = mesgt,
|
|
Packit |
b53373 |
[epilogue = string,]
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
</tt>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
For a simple message, all that is needed is a set of <tt>headers</tt>
|
|
Packit |
b53373 |
and the <tt>body</tt>. The message <tt>body</tt> can be given as a string
|
|
Packit |
b53373 |
or as a simple
|
|
Packit |
b53373 |
LTN12
|
|
Packit |
b53373 |
source. For multipart messages, the body is a table that
|
|
Packit |
b53373 |
recursively defines each part as an independent message, plus an optional
|
|
Packit |
b53373 |
<tt>preamble</tt> and <tt>epilogue</tt>.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
The function returns a simple
|
|
Packit |
b53373 |
LTN12
|
|
Packit |
b53373 |
source that produces the
|
|
Packit |
b53373 |
message contents as defined by <tt>mesgt</tt>, chunk by chunk.
|
|
Packit |
b53373 |
Hopefully, the following
|
|
Packit |
b53373 |
example will make things clear. When in doubt, refer to the appropriate RFC
|
|
Packit |
b53373 |
as listed in the introduction.
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
-- load the smtp support and its friends
|
|
Packit |
b53373 |
local smtp = require("socket.smtp")
|
|
Packit |
b53373 |
local mime = require("mime")
|
|
Packit |
b53373 |
local ltn12 = require("ltn12")
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
-- creates a source to send a message with two parts. The first part is
|
|
Packit |
b53373 |
-- plain text, the second part is a PNG image, encoded as base64.
|
|
Packit |
b53373 |
source = smtp.message{
|
|
Packit |
b53373 |
headers = {
|
|
Packit |
b53373 |
-- Remember that headers are *ignored* by smtp.send.
|
|
Packit |
b53373 |
from = "Sicrano de Oliveira <sicrano@example.com>",
|
|
Packit |
b53373 |
to = "Fulano da Silva <fulano@example.com>",
|
|
Packit |
b53373 |
subject = "Here is a message with attachments"
|
|
Packit |
b53373 |
},
|
|
Packit |
b53373 |
body = {
|
|
Packit |
b53373 |
preamble = "If your client doesn't understand attachments, \r\n" ..
|
|
Packit |
b53373 |
"it will still display the preamble and the epilogue.\r\n" ..
|
|
Packit |
b53373 |
"Preamble will probably appear even in a MIME enabled client.",
|
|
Packit |
b53373 |
-- first part: no headers means plain text, us-ascii.
|
|
Packit |
b53373 |
-- The mime.eol low-level filter normalizes end-of-line markers.
|
|
Packit |
b53373 |
[1] = {
|
|
Packit |
b53373 |
body = mime.eol(0, [[
|
|
Packit |
b53373 |
Lines in a message body should always end with CRLF.
|
|
Packit |
b53373 |
The smtp module will *NOT* perform translation. However, the
|
|
Packit |
b53373 |
send function *DOES* perform SMTP stuffing, whereas the message
|
|
Packit |
b53373 |
function does *NOT*.
|
|
Packit |
b53373 |
]])
|
|
Packit |
b53373 |
},
|
|
Packit |
b53373 |
-- second part: headers describe content to be a png image,
|
|
Packit |
b53373 |
-- sent under the base64 transfer content encoding.
|
|
Packit |
b53373 |
-- notice that nothing happens until the message is actually sent.
|
|
Packit |
b53373 |
-- small chunks are loaded into memory right before transmission and
|
|
Packit |
b53373 |
-- translation happens on the fly.
|
|
Packit |
b53373 |
[2] = {
|
|
Packit |
b53373 |
headers = {
|
|
Packit |
b53373 |
["content-type"] = 'image/png; name="image.png"',
|
|
Packit |
b53373 |
["content-disposition"] = 'attachment; filename="image.png"',
|
|
Packit |
b53373 |
["content-description"] = 'a beautiful image',
|
|
Packit |
b53373 |
["content-transfer-encoding"] = "BASE64"
|
|
Packit |
b53373 |
},
|
|
Packit |
b53373 |
body = ltn12.source.chain(
|
|
Packit |
b53373 |
ltn12.source.file(io.open("image.png", "rb")),
|
|
Packit |
b53373 |
ltn12.filter.chain(
|
|
Packit |
b53373 |
mime.encode("base64"),
|
|
Packit |
b53373 |
mime.wrap()
|
|
Packit |
b53373 |
)
|
|
Packit |
b53373 |
)
|
|
Packit |
b53373 |
},
|
|
Packit |
b53373 |
epilogue = "This might also show up, but after the attachments"
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
-- finally send it
|
|
Packit |
b53373 |
r, e = smtp.send{
|
|
Packit |
b53373 |
from = "<sicrano@example.com>",
|
|
Packit |
b53373 |
rcpt = "<fulano@example.com>",
|
|
Packit |
b53373 |
source = source,
|
|
Packit |
b53373 |
}
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<center>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
home ·
|
|
Packit |
b53373 |
download ·
|
|
Packit |
b53373 |
installation ·
|
|
Packit |
b53373 |
introduction ·
|
|
Packit |
b53373 |
reference
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
<small>
|
|
Packit |
b53373 |
Last modified by Diego Nehab on
|
|
Packit |
b53373 |
Thu Apr 20 00:25:51 EDT 2006
|
|
Packit |
b53373 |
</small>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
</center>
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
|
|
Packit |
b53373 |
</body>
|
|
Packit |
b53373 |
</html>
|