JAMES-1736 Introduce MessageParser which retrieve the list of attachments of a message
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5a76eee3 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5a76eee3 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5a76eee3 Branch: refs/heads/master Commit: 5a76eee3d40f50115ecbef39906b3065d5f7585b Parents: de15440 Author: Antoine Duprat <[email protected]> Authored: Thu May 12 16:54:20 2016 +0200 Committer: Raphael Ouazana <[email protected]> Committed: Wed May 18 16:36:18 2016 +0200 ---------------------------------------------------------------------- .../mailbox/store/mail/model/Attachment.java | 37 + .../store/mail/model/impl/MessageParser.java | 76 ++ .../store/mail/model/AttachmentTest.java | 52 + .../mail/model/impl/MessageParserTest.java | 81 ++ .../eml/embeddedAttachmentWithAttachment.eml | 131 ++ .../eml/embeddedAttachmentWithInline.eml | 1261 ++++++++++++++++++ mailbox/store/src/test/resources/eml/gimp.png | Bin 0 -> 3071 bytes .../src/test/resources/eml/noAttachment.eml | 14 + .../eml/oneAttachmentAndSomeInlined.eml | 39 + .../src/test/resources/eml/twoAttachments.eml | 73 + 10 files changed, 1764 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/5a76eee3/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Attachment.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Attachment.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Attachment.java new file mode 100644 index 0000000..f422f12 --- /dev/null +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/Attachment.java @@ -0,0 +1,37 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store.mail.model; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class Attachment { + + private final byte[] bytes; + + public Attachment(byte[] bytes) { + this.bytes = bytes; + } + + public InputStream getStream() throws IOException { + return new ByteArrayInputStream(bytes); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/5a76eee3/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java new file mode 100644 index 0000000..83987b3 --- /dev/null +++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/mail/model/impl/MessageParser.java @@ -0,0 +1,76 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store.mail.model.impl; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.apache.james.mailbox.store.mail.model.Attachment; +import org.apache.james.mime4j.MimeException; +import org.apache.james.mime4j.dom.Body; +import org.apache.james.mime4j.dom.Entity; +import org.apache.james.mime4j.dom.MessageWriter; +import org.apache.james.mime4j.dom.Multipart; +import org.apache.james.mime4j.dom.field.ContentDispositionField; +import org.apache.james.mime4j.message.DefaultMessageBuilder; +import org.apache.james.mime4j.message.DefaultMessageWriter; + +import com.google.common.collect.ImmutableList; + +public class MessageParser { + + public List<Attachment> retrieveAttachments(InputStream fullContent) throws MimeException, IOException { + Body body = new DefaultMessageBuilder() + .parseMessage(fullContent) + .getBody(); + try { + if (body instanceof Multipart) { + return listAttachments((Multipart)body); + } else { + return ImmutableList.of(); + } + } finally { + body.dispose(); + } + } + + private List<Attachment> listAttachments(Multipart multipart) throws IOException { + ImmutableList.Builder<Attachment> attachments = ImmutableList.builder(); + MessageWriter messageWriter = new DefaultMessageWriter(); + for (Entity entity : multipart.getBodyParts()) { + if (isAttachment(entity)) { + attachments.add(createAttachment(messageWriter, entity.getBody())); + } + } + return attachments.build(); + } + + private boolean isAttachment(Entity part) { + return ContentDispositionField.DISPOSITION_TYPE_ATTACHMENT.equalsIgnoreCase(part.getDispositionType()); + } + + private Attachment createAttachment(MessageWriter messageWriter, Body body) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + messageWriter.writeBody(body, out); + return new Attachment(out.toByteArray()); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/5a76eee3/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentTest.java new file mode 100644 index 0000000..9c91c93 --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/AttachmentTest.java @@ -0,0 +1,52 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + + +package org.apache.james.mailbox.store.mail.model; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.InputStream; + +import org.apache.commons.io.IOUtils; +import org.junit.Test; + +public class AttachmentTest { + + @Test + public void streamShouldBeConsumedOneTime() throws Exception { + String input = "mystream"; + Attachment attachment = new Attachment(input.getBytes()); + + InputStream stream = attachment.getStream(); + assertThat(stream).isNotNull(); + assertThat(IOUtils.toString(stream)).isEqualTo(input); + } + + @Test + public void streamShouldBeConsumedMoreThanOneTime() throws Exception { + String input = "mystream"; + Attachment attachment = new Attachment(input.getBytes()); + + attachment.getStream(); + InputStream stream = attachment.getStream(); + assertThat(stream).isNotNull(); + assertThat(IOUtils.toString(stream)).isEqualTo(input); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/5a76eee3/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java new file mode 100644 index 0000000..719ca77 --- /dev/null +++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/mail/model/impl/MessageParserTest.java @@ -0,0 +1,81 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailbox.store.mail.model.impl; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.apache.james.mailbox.store.mail.model.Attachment; +import org.junit.Before; +import org.junit.Test; + +public class MessageParserTest { + + private MessageParser testee; + + @Before + public void setup() { + testee = new MessageParser(); + } + + @Test + public void getAttachmentsShouldBeEmptyWhenNone() throws Exception { + List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/noAttachment.eml")); + + assertThat(attachments).isEmpty(); + } + + @Test + public void getAttachmentsShouldRetrieveAttachmentsWhenOne() throws Exception { + List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeInlined.eml")); + + assertThat(attachments).hasSize(1); + } + + @Test + public void getAttachmentsShouldReturnTheExpectedAttachment() throws Exception { + List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/oneAttachmentAndSomeInlined.eml")); + + Attachment attachment = attachments.get(0); + assertThat(attachment.getStream()).hasContentEqualTo(ClassLoader.getSystemResourceAsStream("eml/gimp.png")); + } + + @Test + public void getAttachmentsShouldRetrieveAttachmentsWhenTwo() throws Exception { + List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/twoAttachments.eml")); + + assertThat(attachments).hasSize(2); + } + + @Test + public void getAttachmentsShouldNotRetrieveEmbeddedAttachmentsWhenSome() throws Exception { + List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithInline.eml")); + + assertThat(attachments).hasSize(1); + } + + @Test + public void getAttachmentsShouldNotRetrieveInlineAttachmentsWhenSome() throws Exception { + List<Attachment> attachments = testee.retrieveAttachments(ClassLoader.getSystemResourceAsStream("eml/embeddedAttachmentWithAttachment.eml")); + + assertThat(attachments).hasSize(1); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/5a76eee3/mailbox/store/src/test/resources/eml/embeddedAttachmentWithAttachment.eml ---------------------------------------------------------------------- diff --git a/mailbox/store/src/test/resources/eml/embeddedAttachmentWithAttachment.eml b/mailbox/store/src/test/resources/eml/embeddedAttachmentWithAttachment.eml new file mode 100644 index 0000000..0bd3e87 --- /dev/null +++ b/mailbox/store/src/test/resources/eml/embeddedAttachmentWithAttachment.eml @@ -0,0 +1,131 @@ +Return-Path: <[email protected]> +Received: from alderaan.linagora.com (smtp.linagora.dc1 [172.16.18.53]) + by imap (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; + Thu, 12 May 2016 16:09:40 +0200 +X-Sieve: CMU Sieve 2.2 +Received: from [10.69.0.107] (mne69-10-88-173-78-196.fbx.proxad.net [88.173.78.196]) + (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) + (No client certificate requested) + by alderaan.linagora.com (Postfix) with ESMTPSA id 233CA267F + for <[email protected]>; Thu, 12 May 2016 16:09:40 +0200 (CEST) +References: <[email protected]> +Subject: Fwd: EmbeddedAttachment +To: Antoine DUPRAT <[email protected]> +From: Antoine DUPRAT <[email protected]> +X-Forwarded-Message-Id: <[email protected]> +Message-ID: <[email protected]> +Date: Thu, 12 May 2016 16:09:39 +0200 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 + Thunderbird/38.5.1 +MIME-Version: 1.0 +In-Reply-To: <[email protected]> +Content-Type: multipart/mixed; + boundary="------------040807010700040800000502" + +This is a multi-part message in MIME format. +--------------040807010700040800000502 +Content-Type: text/plain; charset=utf-8; format=flowed +Content-Transfer-Encoding: 7bit + +forwarded + +--------------040807010700040800000502 +Content-Type: message/rfc822; + name="EmbeddedAttachment.eml" +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; + filename="EmbeddedAttachment.eml" + +Return-Path: <[email protected]> +Received: from alderaan.linagora.com (smtp.linagora.dc1 [172.16.18.53]) + by imap (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; + Thu, 12 May 2016 16:08:35 +0200 +X-Sieve: CMU Sieve 2.2 +Received: from [10.69.0.107] (mne69-10-88-173-78-196.fbx.proxad.net [88.173.78.196]) + (using TLSv1 with cipher DHE-RSA-AES128-SHA (128/128 bits)) + (No client certificate requested) + by alderaan.linagora.com (Postfix) with ESMTPSA id 0FC992683 + for <[email protected]>; Thu, 12 May 2016 16:08:35 +0200 (CEST) +To: Antoine DUPRAT <[email protected]> +From: Antoine DUPRAT <[email protected]> +Subject: EmbeddedAttachment +Message-ID: <[email protected]> +Date: Thu, 12 May 2016 16:08:34 +0200 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 + Thunderbird/38.5.1 +MIME-Version: 1.0 +Content-Type: multipart/mixed; + boundary="------------000805010206020807030208" + +This is a multi-part message in MIME format. +--------------000805010206020807030208 +Content-Type: text/plain; charset=utf-8; format=flowed +Content-Transfer-Encoding: 7bit + + + +--------------000805010206020807030208 +Content-Type: image/png; + name="delete_mailboxes.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="delete_mailboxes.png" + +iVBORw0KGgoAAAANSUhEUgAAAroAAABHCAYAAADobuT3AAAABHNCSVQICAgIfAhkiAAAABl0 +RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dvz4AAAsmSURBVHic7dx7TNX1H8fxFye6 +IFnciRg2Zoql82i4aKstNiKhRpetyyaa/9CwOJHJGotNBpmxOZctDhpI03Dyh5AlK8VQF4KR +q9PiMpytsSxxiQcyWrA1POf3R/P8OFzOBZBz+vZ8/Pc9n8v3fd5fna99/Z5vyKDd7hQAAABg +MKZAFwAAAADcCARdAAAAGBJBFwAAAIZE0AUAAIAhEXQBAABgSARdAAAAGBJBFwAAAIZE0AUA +AIAhEXQBAABgSARdAAAAGBJBFwAAAIZE0AUAAIAhEXQBAABgSARdAAAAGBJBFwAAAIZE0AUA +AIAhEXQBAABgSARdAAAAGBJBFwAAAIZE0AUAAIAhEXQBAABgSARdAAAAGBJBFwAAAIZE0AUA +AIAhEXQBAABgSKGBLiAY1R04oIMHD8rhcAS6FAAAgFkxmUzasGGD1ufmBrqUeRcyaLc7A11E +sFmblUXIBQAAhmEymXS8uTnQZcw7Hl2YAiEXAAAYyX812xB0AQAAYEgEXQAAABgSQRcAAACG +RNAFAACAIRF0AQAAYEgEXQAAABgSQRcAAACGRNAFAACAIRF0AQAAYEgEXQAAABgSQRcAAACG +RNAFAACAIRF0AQAAYEgEXQAAABgSQRcAAACGRNAFAADwQ3x8/JzMwY1H0P0Xa21t1WOPPRbo +MvyWnZ2to0eP6osvvpjR+ESe+pCenq729vYZ1+qvlpYWPfHEEz7NDaa658tsvpdRewLg32X9 ++vVqbGzUqlWrpp1jNpvV2NiojRs3zmNlmApBN4AOHz4sm80mm82mr776SlVVVR7/4swVk8mk +rKws3XrrrTf8XBNFRkaqtLRU+/fv10svveT3eKCtWbNGtbW1am9v17Fjx7R161ZFRkb6tDaQ +fQcAzI3Ozk5JUmVl5ZT/ZpvNZlmtVknSDz/8MK+1YTKCboDV1tYqIyNDeXl56urq0p49e/TI +I4/M6TlycnJ07Ngx13FERISKioq0aNGiOT2PL5YtWyZJamho0ODgoN/jgZSWliar1apvvvlG +ubm52rJli5KSkrRr1y7ddNNNXtcHsu8AgLnR3d2tgoICSf+EXbPZ7BobH3ItFosrFCNwQgNd +wH/d6Oiorl69qqtXr+qnn36Sw+HQW2+9pZycHDkcjhtyzqGhIWVmZt6Qvb1ZuHChRkdH5XQ6 +ZzQeSK+//rqamppUW1vr+qykpETNzc164IEH9O2333pcH8i+AwDmTldXlwoKClRVVSWr1SqL +xSJJhNwgxB3dIPPpp5/qrrvu0n333SdJWrJkiWpqanTmzBkdPnxY2dnZU66bbp7ValVZWZni +4uJks9mUlpam6Oho2Ww2LV68WJIUHR2tiooKnT59Wi0tLSovL1dERIRr75aWFr388sv66KOP +1N7ervr6eqWkpExZh6e9Xn31VVVUVOjOO++UzWZTfn6+29rpxr3VN158fLw++OADtbW1qbGx +cdLdcU/9PHXqlIqLi3XkyBGVl5e7rYuMjFRKSopOnDjh9rndbldRUZEGBgbczjFVryb23Z+6 +x0tPT9ehQ4fU0dGhhoYGZWRkuMZaW1uVnp7uOn7mmWf0+eefu47NZrP279+vr7/+Wk1NTXru +ued8GvPUN09js7ke/vQEAOZbV1eXW8Al5AYngm6Qsdvt+vvvv5WQkKDIyEhVV1ers7NTTz31 +lHbt2qWtW7fq/vvvd1vjaZ7FYlFZWZkGBgaUmpqqs2fPuq01mUyqrKxUeHi41q9fr7y8PMXG +xmrnzp0KCQlxzcvJydH777+vF198Ub///ru2bNkyqXZve+3evVslJSX6448/lJqaqurqarf1 +U437Wt91O3bsUGhoqDZu3KjS0lItWbLEpz5d9/DDD2v37t3at2+f275RUVGS5BZor2ttbdWF +CxdcxxkZGV575U/dE+vYsWOH6urqlJ2drYMHD6qiokJJSUlezxEfHy+r1aqOjg49/fTT2r59 +uwoLC5Wenu5xzFPfvPV0NtfD154AQKB0dnbKarVqwYIFWrBggaxWKyE3yBB0g8z48JaVlaXh +4WFVVVVpcHBQbW1tOn36tNauXeu2xtd5U1m5cqWWLl2qsrIy/fLLL7pw4YJKS0u1evVqLV26 +1DWvpqZG3d3d6u/v19GjR5WcnDzjvfzhz56LFi3SihUrVFFRob6+PvX29urAgQN+9WnPnj06 +fvy4fv75Z7e9r18XXx6p8KVX/tQ9kcPhUHJysqKiovTZZ5+pqKhIIyMjXuvKzMyU3W5XdXW1 +rly5orNnz6qyslIxMTEexzz1zdPYbK6Hvz0BgEAwm82yWCwaGRnRyMiILBaL2zO7CDye0Q0y +cXFxuuWWW/Tbb79p5cqVSkpKks1mc5sz8b/PExISfJo3lfj4eA0PD2toaMj1md1u119//aWk +pCSdP39ektyeFx4bG1No6OQ/Or7u5Q9/9oyNjZXD4dDFixen3MuXPk33XPT188fFxbndvZWk +Bx98UP39/erv75+0x3S9Gs9b3RPryM/P17p167R3715du3ZNhw4d0pkzZ7yujY6O1qVLl9w+ +a2hokPTP88fTjV3/0d1UfQsJCZl2bDbXw5+eAEAgTPzhmfT/Rxh4fCF4EHSDzAsvvKCBgQH1 +9vbKbDbr/PnzysvLc5szNjbmdnz58mWf5k2lv79fCxcu1B133KHh4WFJUkxMjMLDw3X58mW/ +ap/LvWay58DAgEwmkxISEiaFNml2fRoaGlJfX58yMjLcfnQWFRWlqqoqFRQUuIKuv7zVPd7i +xYuVkJCg4uJihYSEyGw2q6qqSn19fTp16pTGxsZ08803T7n20qVLevTRR90+e+ihhxQaGupx +zFPfnn/++WnH4uPjZ3w9vK0FgECa7u0KFovFFXZfe+01Xi8WBHh0IcDCwsIUERGhlJQUFRYW +at26dXr33XflcDjU0tKixMRE5ebm6rbbblNsbKw2b96s1atXu+3hbd7o6KgiIiJ0zz33KCws +zG1tb2+vzp07p7KyMiUmJioxMVGlpaU6d+6cenp6/Pouc7nXTPb89ddf1d3drZKSEiUnJ2v5 +8uVuL+v2tZ/TsVqtevbZZ7VhwwYlJiZq2bJleuedd9TT0zPprqQ/vNU9XlhYmN5++21lZmYq +PDxcTqdTTqdTo6OjkqS+vj49+eSTuvvuu5Wamur2LuKTJ08qOjpaeXl5ioyM1KpVq7Rt2zbd +fvvtHsc89c3T2Gyuhz89AYD55OkVYp2dna5Xj1mt1nl5Nz48I+gGWF5enk6ePKkPP/xQ9957 +rzZt2qS2tjZJ/9zp27Rpk9asWaMjR45o3759MplM6u7udtvD27yOjg79+OOPqq+vn/TskMPh +0ObNmzUyMqKPP/5Y9fX1+vPPP1VYWOj3K77mcq+Z7llcXCyn06m6ujqVl5fru+++c4352s/p +tLa2qri4WNnZ2frkk0/03nvv6eLFi3rjjTd07dq1GX0/X+oer6enR6WlpcrPz9eJEye0fft2 +7d27Vx0dHZKknTt3Ki4uTo2NjXrzzTf1/fffu9YODQ3plVdeUVpampqamrRt2zbV1NSoubnZ +45invnnr6Wyuh689AYD5tHz5cknTv13h+qvHnE6nVqxYMd/lYYKQQbs9+F5YGmCZjz8e6BIA +AECQiomJkd1u9zgnNjZWV65cmaeKfNPy5ZeBLmHecUcXAADAD95CrqSgC7n/VQRdAAAAGBJB +FwAAAIZE0AUAAIAhEXQBAABgSARdAAAAGBJBFwAAAIZE0AUAAIAhEXQBAABgSARdAAAAGBJB +FwAAAIZE0AUAAIAhEXQBAABgSARdAAAAGNL/AGfuNVyaBg5YAAAAAElFTkSuQmCC +--------------000805010206020807030208-- + +--------------040807010700040800000502-- --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
