Commit a907b415 authored by Frank Bergmann's avatar Frank Bergmann

- Updated to OpenACS 5.9.1

parent cd0f4f92
......@@ -6,23 +6,25 @@
<pretty-plural>ACS Messaging Services</pretty-plural>
<initial-install-p>t</initial-install-p>
<singleton-p>t</singleton-p>
<implements-subsite-p>f</implements-subsite-p>
<inherit-templates-p>t</inherit-templates-p>
<version name="5.9.0" url="http://openacs.org/repository/download/apm/acs-messaging-5.9.0.apm">
<version name="5.9.1" url="http://openacs.org/repository/download/apm/acs-messaging-5.9.1.apm">
<owner url="mailto:akk+@cs.cmu.edu">Anukul Kapoor</owner>
<owner url="mailto:prevost@maya.com">John Prevost</owner>
<owner url="mailto:vinod@kurup.com">Vinod Kurup</owner>
<summary>General messaging for bboard and general comments.</summary>
<release-date>2015-10-04</release-date>
<maturity>3</maturity>
<release-date>2017-08-06</release-date>
<vendor url="http://openacs.org">OpenACS</vendor>
<license url="http://www.gnu.org/copyleft/gpl.html">GPL</license>
<description format="text/html">Provides generic message services, with email sending. acs-mail-lite and notifications are the
prefered packages for delivering this functionality and it is anticipated that this package will ultimately be deprecated.</description>
preferred packages for delivering this functionality and it is anticipated that this package will ultimately be deprecated.</description>
<license>GPL</license>
<maturity>3</maturity>
<provides url="acs-messaging" version="5.9.0"/>
<requires url="acs-content-repository" version="5.9.0"/>
<requires url="acs-kernel" version="5.9.0"/>
<requires url="acs-mail-lite" version="5.9.0"/>
<provides url="acs-messaging" version="5.9.1"/>
<requires url="acs-content-repository" version="5.9.1"/>
<requires url="acs-kernel" version="5.9.1"/>
<requires url="acs-mail-lite" version="5.9.1"/>
<callbacks>
</callbacks>
......@@ -32,7 +34,3 @@
</version>
</package>
......@@ -206,24 +206,35 @@ as
v_revision_id cr_revisions.revision_id%TYPE;
begin
-- generate a message id now so we can get an rfc822 message-id
if message_id is null then
select acs_object_id_seq.nextval into v_message_id from dual;
else
v_message_id := message_id;
end if;
-- this needs to be fixed up, but Oracle doesn't give us a way
-- to get the FQDN
-- -- generate a message id now so we can get an rfc822 message-id
-- if message_id is null then
-- select acs_object_id_seq.nextval into v_message_id from dual;
-- else
-- v_message_id := message_id;
-- end if;
-- -- this needs to be fixed up, but Oracle doesn't give us a way
-- -- to get the FQDN
-- if rfc822_id is null then
-- v_rfc822_id := sysdate || '.' || v_message_id || '@' ||
-- utl_inaddr.get_host_name || '.hate';
-- else
-- v_rfc822_id := rfc822_id;
-- end if;
-- Antonio Pisano 2016-09-20
-- rfc822_id MUST come from the tcl, no more
-- sql tricks to retrieve one if missing.
-- Motivations:
-- 1) duplication. We have same logics in acs_mail_lite::generate_message_id
-- 2) what if SystemURL is https?
-- 3) empty SystemURL would break General Comments
if rfc822_id is null then
v_rfc822_id := sysdate || '.' || v_message_id || '@' ||
utl_inaddr.get_host_name || '.hate';
else
v_rfc822_id := rfc822_id;
RAISE SELF_IS_NULL;
end if;
v_message_id := content_item.new (
name => v_rfc822_id,
name => rfc822_id,
parent_id => parent_id,
content_type => 'acs_message_revision',
item_id => message_id,
......@@ -238,7 +249,7 @@ as
insert into acs_messages
(message_id, reply_to, sent_date, sender, rfc822_id)
values
(v_message_id, reply_to, sent_date, sender, v_rfc822_id);
(v_message_id, reply_to, sent_date, sender, rfc822_id);
-- create an initial revision for the new message
v_revision_id := acs_message.edit (
......
......@@ -29,7 +29,6 @@ CREATE OR REPLACE FUNCTION acs_message__edit(
p_creation_user integer, -- default null
p_creation_ip varchar, -- default null
p_is_live boolean -- default 't'
) RETURNS integer AS $$
DECLARE
v_revision_id cr_revisions.revision_id%TYPE;
......@@ -38,28 +37,32 @@ BEGIN
if p_data is not null then
-- need to take care of blob?
v_revision_id := content_revision__new (
p_message_id, -- item_id
p_title, -- title
p_description, -- description
p_data, -- data
p_mime_type, -- mime_type
p_creation_date, -- creation_date
p_creation_user, -- creation_user
p_creation_ip -- creation_ip
p_title, -- title
p_description, -- description
now(), -- publish_date
p_mime_type, -- mime_type
null, -- nls_language
p_data, -- data
p_message_id, -- item_id
p_creation_date, -- creation_date
p_creation_user, -- creation_user
p_creation_ip -- creation_ip
);
else if p_title is not null or p_text is not null then
v_revision_id := content_revision__new (
p_title, -- title
p_description, -- description
now(), -- publish_date
p_mime_type, -- mime_type
null, -- nls_language
p_text, -- text
p_message_id, -- item_id
null, -- revision_id
p_creation_date, -- creation_date
p_creation_user, -- creation_user
p_creation_ip -- creation_ip
p_title, -- title
p_description, -- description
now(), -- publish_date
p_mime_type, -- mime_type
null, -- nls_language
p_text, -- text
p_message_id, -- item_id
null, -- revision_id
p_creation_date, -- creation_date
p_creation_user, -- creation_user
p_creation_ip, -- creation_ip
null, -- content_length
null -- package_id
);
end if;
end if;
......@@ -108,66 +111,73 @@ CREATE OR REPLACE FUNCTION acs_message__new(
p_creation_ip varchar, --default null,
p_object_type varchar, --default 'acs_message',
p_is_live boolean, --default 't'
p_package_id integer
p_package_id integer default null
) RETURNS integer AS $$
DECLARE
p_creation_date timestamptz := current_timestamp; -- alias for $13 --default sysdate,
v_message_id acs_messages.message_id%TYPE;
v_rfc822_id acs_messages.rfc822_id%TYPE;
v_revision_id cr_revisions.revision_id%TYPE;
v_system_url varchar;
v_domain_name varchar;
v_idx integer;
BEGIN
-- generate a message id now so we can get an rfc822 message-id
if p_message_id is null then
select nextval('t_acs_object_id_seq') into v_message_id;
else
v_message_id := p_message_id;
end if;
-- need to make this mandatory also - jg
-- this needs to be fixed up, but Oracle doesn't give us a way
-- to get the FQDN
-- vk: get SystemURL parameter and use it to extract domain name
select apm__get_value(package_id, 'SystemURL') into v_system_url
from apm_packages where package_key='acs-kernel';
v_idx := position('http://' in v_system_url);
v_domain_name := trim (substr(v_system_url, v_idx + 7));
if p_rfc822_id is null then
v_rfc822_id := current_date || '.' || v_message_id || '@' ||
v_domain_name || '.hate';
else
v_rfc822_id := p_rfc822_id;
-- -- generate a message id now so we can get an rfc822 message-id
-- if p_message_id is null then
-- select nextval('t_acs_object_id_seq') into v_message_id;
-- else
-- v_message_id := p_message_id;
-- end if;
-- -- need to make this mandatory also - jg
-- -- this needs to be fixed up, but Oracle doesn't give us a way
-- -- to get the FQDN
-- -- vk: get SystemURL parameter and use it to extract domain name
-- select apm__get_value(package_id, 'SystemURL') into v_system_url
-- from apm_packages where package_key='acs-kernel';
-- v_idx := position('http://' in v_system_url);
-- v_domain_name := trim (substr(v_system_url, v_idx + 7));
-- if p_rfc822_id is null then
-- v_rfc822_id := current_date || '.' || v_message_id || '@' ||
-- v_domain_name || '.hate';
-- else
-- v_rfc822_id := p_rfc822_id;
-- end if;
-- Antonio Pisano 2016-09-20
-- rfc822_id MUST come from the tcl, no more
-- sql tricks to retrieve one if missing.
-- Motivations:
-- 1) duplication. We have same logics in acs_mail_lite::generate_message_id
-- 2) what if SystemURL is https?
-- 3) empty SystemURL would break General Comments
if p_rfc822_id is null then
RAISE null_value_not_allowed;
end if;
v_message_id := content_item__new (
v_rfc822_id, -- name
p_parent_id, -- parent_id
p_message_id, -- item_id
null, -- locale
p_creation_date, -- creation_date
p_creation_user, -- creation_user
p_context_id, -- context_id
p_creation_ip, -- creation_ip
p_object_type, -- item_subtype
'acs_message_revision', -- content_type
null, -- title
null, -- description
'text/plain', -- mime_type
null, -- nls_language
null, -- text
'text', -- storage_type
p_package_id
p_rfc822_id, -- 1 name
p_parent_id, -- 2 parent_id
p_message_id, -- 3 item_id
null, -- 4 locale
p_creation_date, -- 5 creation_date
p_creation_user, -- 6 creation_user
p_context_id, -- 7 context_id
p_creation_ip, -- 8 creation_ip
p_object_type, -- 9 item_subtype
'acs_message_revision', -- 10 content_type
null, -- 11 title
null, -- 12 description
'text/plain', -- 13 mime_type
null, -- 14 nls_language
null, -- 15 text
'text', -- 16 storage_type
p_package_id -- 17 package_id
);
insert into acs_messages
(message_id, reply_to, sent_date, sender, rfc822_id)
values
(v_message_id, p_reply_to, p_sent_date, p_sender, v_rfc822_id);
(v_message_id, p_reply_to, p_sent_date, p_sender, p_rfc822_id);
-- create an initial revision for the new message
v_revision_id := acs_message__edit (
......@@ -188,55 +198,6 @@ END;
$$ LANGUAGE plpgsql;
--
-- procedure acs_message__new/16
--
CREATE OR REPLACE FUNCTION acs_message__new(
p_message_id integer, --default null,
p_reply_to integer, --default null,
p_sent_date timestamptz, --default sysdate,
p_sender integer, --default null,
p_rfc822_id varchar, --default null,
p_title varchar, --default null,
p_description varchar, --default null,
p_mime_type varchar, --default 'text/plain',
p_text text, --default null,
p_data integer, --default null,
p_parent_id integer, --default 0,
p_context_id integer,
p_creation_user integer, --default null,
p_creation_ip varchar, --default null,
p_object_type varchar, --default 'acs_message',
p_is_live boolean --default 't'
) RETURNS integer AS $$
DECLARE
p_creation_date timestamptz := current_timestamp; -- alias for $13 --default sysdate,
BEGIN
return acs_message__new (p_message_id,
p_reply_to,
p_sent_date,
p_sender,
p_rfc822_id,
p_title,
p_description,
p_mime_type,
p_text,
p_data,
p_parent_id,
p_context_id,
p_creation_user,
p_creation_ip,
p_object_type,
p_is_live,
null::integer
);
END;
$$ LANGUAGE plpgsql;
-- added
select define_function_args('acs_message__delete','message_id');
......@@ -370,9 +331,6 @@ $$ LANGUAGE plpgsql stable strict;
-- functions will migrate to another PL/SQL package or be replaced
-- by direct calls to CR code in the near future.
-- added
select define_function_args('acs_message__new_file','message_id,file_id;null,file_name,title;null,description;null,mime_type;text/plain,data;null,creation_date;sysdate,creation_user;null,creation_ip;null,is_live;t,storage_type;file,package_id;null');
--
......@@ -380,19 +338,19 @@ select define_function_args('acs_message__new_file','message_id,file_id;null,fil
--
CREATE OR REPLACE FUNCTION acs_message__new_file(
p_message_id integer,
p_file_id integer, -- default null
p_file_id integer, -- default null
p_file_name varchar,
p_title varchar, -- default null
p_description text, -- default null
p_mime_type varchar, -- default 'text/plain'
p_data integer, -- default null
p_creation_date timestamptz, -- default sysdate
p_creation_user integer, -- default null
p_creation_ip varchar, -- default null
p_is_live boolean, -- default 't'
p_storage_type varchar, -- default 'file'
p_package_id integer -- default null
p_title varchar, -- default null
p_description text, -- default null
p_mime_type varchar, -- default 'text/plain'
p_data integer, -- default null
p_creation_date timestamptz, -- default sysdate
p_creation_user integer, -- default null
p_creation_ip varchar, -- default null
p_is_live boolean, -- default 't'
p_storage_type cr_items.storage_type%TYPE, -- default 'file'
p_package_id integer default null
) RETURNS integer AS $$
DECLARE
v_file_id cr_items.item_id%TYPE;
......@@ -407,15 +365,19 @@ BEGIN
p_creation_user, -- creation_user
null, -- context_id
p_creation_ip, -- creation_ip
'content_item', -- item_subtype
'content_item', -- item_subtype
'content_revision', -- content_type
null, -- title
null, -- description
'text/plain', -- mime_type
null, -- nls_language
null, -- text
null, -- data
null, -- relation_tag
false, -- is_live
p_storage_type, -- storage_type
p_package_id -- package_id
p_package_id, -- package_id
true -- with_child_rels
);
-- create an initial revision for the new attachment
......@@ -437,45 +399,6 @@ $$ LANGUAGE plpgsql;
--
-- procedure acs_message__new_file/12
--
CREATE OR REPLACE FUNCTION acs_message__new_file(
p_message_id integer,
p_file_id integer, -- default null
p_file_name varchar,
p_title varchar, -- default null
p_description text, -- default null
p_mime_type varchar, -- default 'text/plain'
p_data integer, -- default null
p_creation_date timestamptz, -- default sysdate
p_creation_user integer, -- default null
p_creation_ip varchar, -- default null
p_is_live boolean, -- default 't'
p_storage_type varchar -- default 'file'
) RETURNS integer AS $$
DECLARE
BEGIN
return acs_message__new_file (p_message_id,
p_file_id,
p_file_name,
p_title,
p_description,
p_mime_type,
p_data,
p_creation_date,
p_creation_user,
p_creation_ip,
p_is_live,
p_storage_type,
null
);
END;
$$ LANGUAGE plpgsql;
-- added
select define_function_args('acs_message__edit_file','file_id,title;null,description;null,mime_type;text/plain,data;null,creation_date;sysdate,creation_user;null,creation_ip;null,is_live;t');
......@@ -548,20 +471,20 @@ select define_function_args('acs_message__new_image','message_id,image_id;null,f
--
CREATE OR REPLACE FUNCTION acs_message__new_image(
p_message_id integer,
p_image_id integer, -- default null
p_image_id integer, -- default null
p_file_name varchar,
p_title varchar, -- default null
p_description text, -- default null
p_mime_type varchar, -- default 'text/plain'
p_data integer, -- default null
p_width integer, -- default null
p_height integer, -- default null
p_creation_date timestamptz, -- default sysdate
p_creation_user integer, -- default null
p_creation_ip varchar, -- default null
p_is_live boolean, -- default 't'
p_storage_type varchar, -- default 'file'
p_package_id integer -- default null
p_title varchar, -- default null
p_description text, -- default null
p_mime_type varchar, -- default 'text/plain'
p_data integer, -- default null
p_width integer, -- default null
p_height integer, -- default null
p_creation_date timestamptz, -- default sysdate
p_creation_user integer, -- default null
p_creation_ip varchar, -- default null
p_is_live boolean, -- default 't'
p_storage_type cr_items.storage_type%TYPE, -- default 'file'
p_package_id integer default null
) RETURNS integer AS $$
DECLARE
......@@ -581,10 +504,10 @@ BEGIN
'content_revision', -- content_type
null, -- title
null, -- description
'text/plain', -- mime_type
'text/plain', -- mime_type
null, -- nls_language
null, -- text
'file', -- storage_type
p_storage_type, -- storage_type
p_package_id -- package_id
);
......@@ -608,50 +531,6 @@ END;
$$ LANGUAGE plpgsql;
--
-- procedure acs_message__new_image/14
--
CREATE OR REPLACE FUNCTION acs_message__new_image(
p_message_id integer,
p_image_id integer, -- default null
p_file_name varchar,
p_title varchar, -- default null
p_description text, -- default null
p_mime_type varchar, -- default 'text/plain'
p_data integer, -- default null
p_width integer, -- default null
p_height integer, -- default null
p_creation_date timestamptz, -- default sysdate
p_creation_user integer, -- default null
p_creation_ip varchar, -- default null
p_is_live boolean, -- default 't'
p_storage_type varchar -- default 'file'
) RETURNS integer AS $$
DECLARE
BEGIN
return acs_message__new_image (p_message_id,
p_image_id,
p_file_name,
p_title,
p_description,
p_mime_type,
p_data,
p_width,
p_height,
p_creation_date,
p_creation_user,
p_creation_ip,
p_is_live,
p_storage_type,
null
);
END;
$$ LANGUAGE plpgsql;
-- added
select define_function_args('acs_message__edit_image','image_id,title;null,description;null,mime_type;text/plain,data;null,width;null,height;null,creation_date;sysdate,creation_user;null,creation_ip;null,is_live;t');
......@@ -675,7 +554,7 @@ CREATE OR REPLACE FUNCTION acs_message__edit_image(
DECLARE
v_revision_id cr_revisions.revision_id%TYPE;
BEGIN
-- not sure which __new to use
-- not sure which __new to use
v_revision_id := content_revision__new (
p_title, -- title
NULL, -- description
......
......@@ -11,11 +11,7 @@ ad_proc -public acs_message_p {
} {
Check if an integer is a valid OpenACS message id.
} {
return [string equal [db_exec_plsql acs_message_p {
begin
:1 := acs_message.message_p(:message_id);
end;
}] "t"]
return [string equal [db_exec_plsql acs_message_p {}] "t"]
}
ad_page_contract_filter acs_message_id { name value } {
......@@ -63,9 +59,7 @@ ad_proc -public acs_messaging_first_ancestor {
the message_id of the first ancestor message (i.e. the message
that originated the thread).
} {
db_1row acs_message_first_ancestor {
select acs_message.first_ancestor(:message_id) as ancestor_id from dual
}
db_1row acs_message_first_ancestor {}
return $ancestor_id
}
......
<property name="context">{/doc/acs-messaging {Messaging}} {ACS Messaging Design}</property>
<property name="context">{/doc/acs-messaging {ACS Messaging}} {ACS Messaging Design}</property>
<property name="doc(title)">ACS Messaging Design</property>
<master>
<h2>ACS Messaging Design</h2>
......@@ -28,25 +28,26 @@ simple procedures that do the right thing when sending email.
Another example: if we built the IMAP server functionality 3.4
webmail provides against acs-messaging, then bboard forums, pages
of comments, and webmail folders could be viewed uniformly through
your email client. The IMAP mapping isn't quite trivial, but you
can see the idea.To reiterate, if applications are storing the same
sort of data (a text-ish messages with optional attachments and
replies), they should store them the same way. Then code from
your email client. The IMAP mapping isn&#39;t quite trivial, but
you can see the idea.To reiterate, if applications are storing the
same sort of data (a text-ish messages with optional attachments
and replies), they should store them the same way. Then code from
particular applications can possibly be refactored into generic
functionality.spam/general alerts/etc isn't meant to be replaced by
ACS Messaging, at least not with what is there currently. Currently
it is just a store; but we intend it to be the canonical store for
messages that need to be stored in the database. If messages are
automatically generated from other user objects, they might need to
be queue'd up or archived in the RDBMS. If so this should be done
in the acs-messaging tables. We can implement the generic incoming
email system by stashing messages in acs-messaging, then
dispatching the message id to package specific code for
processing.Currently (11/2000), ACS Messaging is very slim; it just
supports bboard. We intend to add attachments (most likely
implemented as content repository items that are children of the
message), extensible headers (just like the webmail datamodel), and
versioning as provided by the content repository.
functionality.spam/general alerts/etc isn&#39;t meant to be
replaced by ACS Messaging, at least not with what is there
currently. Currently it is just a store; but we intend it to be the
canonical store for messages that need to be stored in the
database. If messages are automatically generated from other user
objects, they might need to be queue&#39;d up or archived in the
RDBMS. If so this should be done in the acs-messaging tables. We
can implement the generic incoming email system by stashing
messages in acs-messaging, then dispatching the message id to
package specific code for processing.Currently (11/2000), ACS
Messaging is very slim; it just supports bboard. We intend to add
attachments (most likely implemented as content repository items
that are children of the message), extensible headers (just like
the webmail datamodel), and versioning as provided by the content
repository.
<h2>API</h2>
ACS Messaging provides the <code>acs_messages_all</code>
......
<property name="context">{/doc/acs-messaging {Messaging}} {ACS Messaging Documentation}</property>
<property name="context">{/doc/acs-messaging {ACS Messaging}} {ACS Messaging Documentation}</property>
<property name="doc(title)">ACS Messaging Documentation</property>
<master>
<h1>ACS Messaging Documentation</h1>
......
<property name="context">{/doc/acs-messaging {Messaging}} {ACS Messaging Requirements}</property>
<property name="context">{/doc/acs-messaging {ACS Messaging}} {ACS Messaging Requirements}</property>
<property name="doc(title)">ACS Messaging Requirements</property>
<master>
<h1>ACS Messaging Requirements</h1>
......@@ -7,7 +7,7 @@
by <a href="mailto:akk\@arsdigita.com">Anukul Kapoor</a>
and
<a href="mailto:akk\@arsdigita.com">Pete Su</a>
<i>This is only a DRAFT</i>
<em>This is only a DRAFT</em>
<h3>I. Introduction</h3>
<p>In ACS 3.x, each messaging application (e.g. bboard, general
comments, spam, ticket tracker and so on) used its own specialized
......@@ -46,9 +46,9 @@ search.</li>
<h3>IV. Use-cases and User Scenarios</h3>
<p>ACS Messaging is generally not used directly by users, so there
are no user interface level scenarios to consider at this point.
It's possible that in the future we will want to extend the system
with generic administrative user interfaces, but this is not clear
right now.</p>
It&#39;s possible that in the future we will want to extend the
system with generic administrative user interfaces, but this is not
clear right now.</p>
<p>We scenarios that we should consider are the kinds of
applications that we mean to support with this package, and what
the developers of those applications would like to see in the data
......@@ -59,8 +59,8 @@ implemented using this package:</p>
<li>BBoard</li><li>Webmail</li><li>General Comments</li><li>Spam</li><li>Various parts of the ticket tracker.</li>
</ul>
<p>Each of these applications requires a message store and each
defines it's own high level organization for messages whithin that
store.</p>
defines it&#39;s own high level organization for messages whithin
that store.</p>
<ul>
<li>Bboard organizes messages into forums and categories and
threads. It also allows users to send and reply to messages via
......@@ -84,7 +84,7 @@ representing messages.</p>
<p><strong>20.0 Message Content</strong></p>
<p>A message should have a primary content body consisting of a
specified MIME type and a block of storage holding the content. In
addition, applications may store one or more seperate revisions of
addition, applications may store one or more separate revisions of
a message.</p>
<p><strong>30.0 Attachments</strong></p>
<p>Messages may be composed of additional attachments. Each
......@@ -130,9 +130,9 @@ types, although initial implementations may be more limited.</p>
<p><strong>100.0 Messages and E-Mail</strong></p>
<p>The system should provide the following interfaces for
integrating with existing E-mail systems. Note that these
requirements only deal with <i>sending</i> mail. Our feeling that a
seperate package should be implemented to deal with
<i>receiving</i> mail that would use ACS Messages for storage of
requirements only deal with <em>sending</em> mail. Our feeling that
a separate package should be implemented to deal with
<em>receiving</em> mail that would use ACS Messages for storage of
incoming messages.</p>
<blockquote>
<p><strong>100.10 Sending Single Messages</strong></p><p>The system should provide a mechanism for specifying that a
......@@ -156,5 +156,5 @@ bboard thread could be sent to a user as a digest.</p>
<hr>
<address><a href="mailto:kapoor\@maya.com"></a></address>
Last modified: $&zwnj;Id: requirements.html,v 1.1.1.1 2001/03/13 22:59:26
ben Exp $
Last modified: $&zwnj;Id: requirements.html,v 1.1.1.1.30.1 2017/04/21
16:14:09 gustafn Exp $
......@@ -160,7 +160,7 @@
A message should have a primary content
body consisting of a specified MIME type and a block of storage
holding the content. In addition, applications may store one or
more seperate revisions of a message.
more separate revisions of a message.
</p>
<p><strong>30.0 Attachments</strong> <p> Messages may be composed
......@@ -250,7 +250,7 @@
<p>
The system should provide the following interfaces for integrating
with existing E-mail systems. Note that these requirements only
deal with <i>sending</i> mail. Our feeling that a seperate package
deal with <i>sending</i> mail. Our feeling that a separate package
should be implemented to deal with <i>receiving</i> mail that
would use ACS Messages for storage of incoming messages.
</p>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment