diff options
Diffstat (limited to 'src')
416 files changed, 33590 insertions, 2 deletions
diff --git a/src/address.cpp b/src/vmime/address.cpp index c6fa74f1..c6fa74f1 100644 --- a/src/address.cpp +++ b/src/vmime/address.cpp diff --git a/src/vmime/address.hpp b/src/vmime/address.hpp new file mode 100644 index 00000000..5eb510f9 --- /dev/null +++ b/src/vmime/address.hpp @@ -0,0 +1,87 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_ADDRESS_HPP_INCLUDED +#define VMIME_ADDRESS_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + + +namespace vmime +{ + + +/** Abstract class representing a mailbox or a group of mailboxes. + * + * This class define a common behaviour for the mailbox + * and mailboxGroup classes. + */ + +class VMIME_EXPORT address : public headerFieldValue +{ +protected: + + address(); + +public: + + /** Check whether this address is empty (no mailboxes specified + * if this is a mailboxGroup -or- no email specified if this is + * a mailbox). + * + * @return true if this address is empty + */ + virtual bool isEmpty() const = 0; + + /** Test whether this is object is a mailboxGroup. + * + * @return true if this is a mailboxGroup, false otherwise + */ + virtual bool isGroup() const = 0; + + virtual shared_ptr <component> clone() const = 0; + + /** Parse an address from an input buffer. + * + * @param ctx parsing context + * @param buffer input buffer + * @param position position in the input buffer + * @param end end position in the input buffer + * @param newPosition will receive the new position in the input buffer + * @param isLastAddressOfGroup will be set to true if this is the last address + * of a group (end delimiter was found), or false otherwise (may be set to NULL) + * @return a new address object, or null if no more address is available in the input buffer + */ + static shared_ptr <address> parseNext + (const parsingContext& ctx, const string& buffer, + const size_t position, const size_t end, + size_t* newPosition, bool *isLastAddressOfGroup); +}; + + +} // vmime + + +#endif // VMIME_ADDRESS_HPP_INCLUDED diff --git a/src/addressList.cpp b/src/vmime/addressList.cpp index 5c7d34ac..5c7d34ac 100644 --- a/src/addressList.cpp +++ b/src/vmime/addressList.cpp diff --git a/src/vmime/addressList.hpp b/src/vmime/addressList.hpp new file mode 100644 index 00000000..0df657d3 --- /dev/null +++ b/src/vmime/addressList.hpp @@ -0,0 +1,192 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_ADDRESSLIST_HPP_INCLUDED +#define VMIME_ADDRESSLIST_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + +#include "vmime/address.hpp" + + +namespace vmime +{ + + +class mailboxList; + + +/** A list of addresses. + */ + +class VMIME_EXPORT addressList : public headerFieldValue +{ +public: + + addressList(); + addressList(const addressList& addrList); + + ~addressList(); + + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + addressList& operator=(const addressList& other); + addressList& operator=(const mailboxList& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + + /** Add a address at the end of the list. + * + * @param addr address to append + */ + void appendAddress(shared_ptr <address> addr); + + /** Insert a new address before the specified address. + * + * @param beforeAddress address before which the new address will be inserted + * @param addr address to insert + * @throw std::out_of_range if the address is not in the list + */ + void insertAddressBefore(shared_ptr <address> beforeAddress, shared_ptr <address> addr); + + /** Insert a new address before the specified position. + * + * @param pos position at which to insert the new address (0 to insert at + * the beginning of the list) + * @param addr address to insert + * @throw std::out_of_range if the position is out of range + */ + void insertAddressBefore(const size_t pos, shared_ptr <address> addr); + + /** Insert a new address after the specified address. + * + * @param afterAddress address after which the new address will be inserted + * @param addr address to insert + * @throw std::out_of_range if the address is not in the list + */ + void insertAddressAfter(shared_ptr <address> afterAddress, shared_ptr <address> addr); + + /** Insert a new address after the specified position. + * + * @param pos position of the address before the new address + * @param addr address to insert + * @throw std::out_of_range if the position is out of range + */ + void insertAddressAfter(const size_t pos, shared_ptr <address> addr); + + /** Remove the specified address from the list. + * + * @param addr address to remove + * @throw std::out_of_range if the address is not in the list + */ + void removeAddress(shared_ptr <address> addr); + + /** Remove the address at the specified position. + * + * @param pos position of the address to remove + * @throw std::out_of_range if the position is out of range + */ + void removeAddress(const size_t pos); + + /** Remove all addresses from the list. + */ + void removeAllAddresses(); + + /** Return the number of addresses in the list. + * + * @return number of addresses + */ + size_t getAddressCount() const; + + /** Tests whether the list of addresses is empty. + * + * @return true if there is no address, false otherwise + */ + bool isEmpty() const; + + /** Return the address at the specified position. + * + * @param pos position + * @return address at position 'pos' + * @throw std::out_of_range if the position is out of range + */ + shared_ptr <address> getAddressAt(const size_t pos); + + /** Return the address at the specified position. + * + * @param pos position + * @return address at position 'pos' + * @throw std::out_of_range if the position is out of range + */ + const shared_ptr <const address> getAddressAt(const size_t pos) const; + + /** Return the address list. + * + * @return list of addresses + */ + const std::vector <shared_ptr <const address> > getAddressList() const; + + /** Return the address list. + * + * @return list of addresses + */ + const std::vector <shared_ptr <address> > getAddressList(); + + /** Return a list of mailboxes. + * If some addresses are actually groups, mailboxes are recursively + * extracted from these groups. + * + * @return list of mailboxes + */ + shared_ptr <mailboxList> toMailboxList() const; + +private: + + std::vector <shared_ptr <address> > m_list; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_ADDRESSLIST_HPP_INCLUDED diff --git a/src/vmime/attachment.hpp b/src/vmime/attachment.hpp new file mode 100644 index 00000000..9730bc6c --- /dev/null +++ b/src/vmime/attachment.hpp @@ -0,0 +1,118 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_ATTACHMENT_HPP_INCLUDED +#define VMIME_ATTACHMENT_HPP_INCLUDED + + +#include "vmime/base.hpp" + +#include "vmime/bodyPart.hpp" +#include "vmime/mediaType.hpp" +#include "vmime/text.hpp" +#include "vmime/contentHandler.hpp" +#include "vmime/encoding.hpp" + + +namespace vmime +{ + + +/** Base class for all types of attachment. + */ + +class VMIME_EXPORT attachment : public object +{ + friend class messageBuilder; + friend class messageParser; + friend class attachmentHelper; + +protected: + + attachment() { } + +public: + + virtual ~attachment() { } + + /** Return the media type of this attachment. + * + * @return content type of the attachment + */ + virtual const mediaType getType() const = 0; + + /** Return the description of this attachment. + * + * @return attachment description, or an empty text + * if no description is available + */ + virtual const text getDescription() const = 0; + + /** Return the (file) name of this attachment. + * + * @return attachment name, or an empty word if no + * name is available + */ + virtual const word getName() const = 0; + + /** Return the data contained in this attachment. + * + * @return attachment data + */ + virtual const shared_ptr <const contentHandler> getData() const = 0; + + /** Return the encoding used for this attachment. + * + * @return attachment data encoding + */ + virtual const encoding getEncoding() const = 0; + + /** Return the part in which the attachment has been found. + * This can be a vmime::bodyPart or a vmime::net::part object. + * + * @return attachment part or NULL if the attachment is not + * attached to a part + */ + virtual shared_ptr <const object> getPart() const = 0; + + /** Return the header of the attachment part. + * + * @return attachment part header or NULL if the attachment + * is not attached to a part + */ + virtual shared_ptr <const header> getHeader() const = 0; + +protected: + + /** Generate the attachment in the specified body part. + * + * @param parent body part in which to generate the attachment + */ + virtual void generateIn(shared_ptr <bodyPart> parent) const = 0; +}; + + +} // vmime + + +#endif // VMIME_ATTACHMENT_HPP_INCLUDED diff --git a/src/attachmentHelper.cpp b/src/vmime/attachmentHelper.cpp index 152daeed..152daeed 100644 --- a/src/attachmentHelper.cpp +++ b/src/vmime/attachmentHelper.cpp diff --git a/src/vmime/attachmentHelper.hpp b/src/vmime/attachmentHelper.hpp new file mode 100644 index 00000000..e03a4f7d --- /dev/null +++ b/src/vmime/attachmentHelper.hpp @@ -0,0 +1,121 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_ATTACHMENTHELPER_HPP_INCLUDED +#define VMIME_ATTACHMENTHELPER_HPP_INCLUDED + + +#include "vmime/config.hpp" + +#include "vmime/attachment.hpp" +#include "vmime/message.hpp" + + +namespace vmime +{ + + +/** Retrieve attachment information from message parts. + */ +class VMIME_EXPORT attachmentHelper +{ +public: + + /** Options for use with the following functions: + * findAttachmentsInMessage, + * getBodyPartAttachment, + * and isBodyPartAnAttachment. + */ + enum FindOptions + { + INLINE_OBJECTS = (1 << 0) /**< Recognize and return inline objects. The aim is to + consider MHTML objects (parts with a "Content-Id" or + a "Content-Location", such as inline images) as attachments. */ + }; + + /** Test whether a body part is an attachment. + * + * @param part message part to test + * @param options search options (see FindOptions) + * @return true if the part is an attachment, false otherwise + */ + static bool isBodyPartAnAttachment(shared_ptr <const bodyPart> part, const unsigned int options = 0); + + /** Return attachment information in the specified body part. + * If the specified body part does not contain attachment + * information (ie. is not an attachment), NULL is returned. + * + * @param part message part in which to search + * @param options search options (see FindOptions) + * @return attachment found in the part, or NULL + */ + static shared_ptr <const attachment> + getBodyPartAttachment(shared_ptr <const bodyPart> part, const unsigned int options = 0); + + /** Find all attachments contained in the specified part + * and all its children parts. + * This is simply a recursive call to getBodyPartAttachment(). + * + * @param part part in which to search + * @param options search options (see FindOptions) + * @return a list of attachments found + */ + static const std::vector <shared_ptr <const attachment> > + findAttachmentsInBodyPart(shared_ptr <const bodyPart> part, const unsigned int options = 0); + + /** Find all attachments contained in the specified message. + * This is simply a recursive call to getBodyPartAttachment(). + * + * @param msg message in which to search + * @param options search options (see FindOptions) + * @return a list of attachments found + */ + static const std::vector <shared_ptr <const attachment> > + findAttachmentsInMessage(shared_ptr <const message> msg, const unsigned int options = 0); + + /** Add an attachment to the specified message. + * + * @param msg message into which to add the attachment + * @param att attachment to add + */ + static void addAttachment(shared_ptr <message> msg, shared_ptr <attachment> att); + + /** Add a message attachment to the specified message. + * + * @param msg message into which to add the attachment + * @param amsg message to attach + */ + static void addAttachment(shared_ptr <message> msg, shared_ptr <message> amsg); + +protected: + + static shared_ptr <bodyPart> findBodyPart + (shared_ptr <bodyPart> part, const mediaType& type); +}; + + +} // vmime + + +#endif // VMIME_ATTACHMENTHELPER_HPP_INCLUDED + diff --git a/src/base.cpp b/src/vmime/base.cpp index 9f9a87be..9f9a87be 100644 --- a/src/base.cpp +++ b/src/vmime/base.cpp diff --git a/src/vmime/base.hpp b/src/vmime/base.hpp new file mode 100644 index 00000000..f6515794 --- /dev/null +++ b/src/vmime/base.hpp @@ -0,0 +1,258 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_BASE_HPP_INCLUDED +#define VMIME_BASE_HPP_INCLUDED + + +#include <string> +#include <vector> +#include <map> +#include <sstream> +#include <cctype> +#include <locale> + +#include "vmime/config.hpp" +#include "vmime/types.hpp" +#include "vmime/constants.hpp" + + +namespace vmime +{ + class text; + class word; + class charset; + + + // "Null" strings + extern VMIME_EXPORT const string NULL_STRING; + + extern VMIME_EXPORT const text NULL_TEXT; + extern VMIME_EXPORT const word NULL_WORD; + +#ifndef VMIME_BUILDING_DOC + + // Null pointer + struct nullPtrType + { + template<typename T> + operator shared_ptr <T>() { return shared_ptr <T>(); } + }; + + extern nullPtrType VMIME_EXPORT null; + +#endif // VMIME_BUILDING_DOC + + + // + // Library name and version + // + + const string VMIME_EXPORT libname(); + const string VMIME_EXPORT libversion(); + const string VMIME_EXPORT libapi(); + + + // + // Helpful functions used for array -> iterator conversion + // + + template <typename T, size_t N> + inline T const* cbegin(T const (&array)[N]) + { + return (array); + } + + template <typename T, size_t N> + inline T const* cend(T const (&array)[N]) + { + return (array + N); + } + + template <typename T, size_t N> + inline T* begin(T (&array)[N]) + { + return (array); + } + + template <typename T, size_t N> + inline T* end(T (&array)[N]) + { + return (array + N); + } + + template <typename T, size_t N> + inline size_t count(T const (&/* array */)[N]) + { + return (N); + } + + + // Copy one vector to another, with type conversion + + template <class T1, class T2> + void copy_vector(const T1& v1, T2& v2) + { + const typename T1::size_type count = v1.size(); + + v2.resize(count); + + for (typename T1::size_type i = 0 ; i < count ; ++i) + v2[i] = v1[i]; + } + + + /* + + RFC#2822 + 2.1.1. Line Length Limits + + There are two limits that this standard places on the number of + characters in a line. Each line of characters MUST be no more than + 998 characters, and SHOULD be no more than 78 characters, excluding + the CRLF. + + The 998 character limit is due to limitations in many implementations + which send, receive, or store Internet Message Format messages that + simply cannot handle more than 998 characters on a line. Receiving + implementations would do well to handle an arbitrarily large number + of characters in a line for robustness sake. However, there are so + many implementations which (in compliance with the transport + requirements of [RFC2821]) do not accept messages containing more + than 1000 character including the CR and LF per line, it is important + for implementations not to create such messages. + + The more conservative 78 character recommendation is to accommodate + the many implementations of user interfaces that display these + messages which may truncate, or disastrously wrap, the display of + more than 78 characters per line, in spite of the fact that such + implementations are non-conformant to the intent of this specification + (and that of [RFC2821] if they actually cause information to be lost). + Again, even though this limitation is put on messages, it is encumbant + upon implementations which display messages to handle an arbitrarily + large number of characters in a line (certainly at least up to the 998 + character limit) for the sake of robustness. + */ + + namespace lineLengthLimits + { + extern VMIME_EXPORT const size_t infinite; + + enum + { + max = 998, + convenient = 78 + }; + } + + + // New line sequence to be used when folding header fields. + extern VMIME_EXPORT const string NEW_LINE_SEQUENCE; + extern VMIME_EXPORT const size_t NEW_LINE_SEQUENCE_LENGTH; + + + // CR-LF sequence + extern VMIME_EXPORT const string CRLF; + + + // Mime version + extern VMIME_EXPORT const string SUPPORTED_MIME_VERSION; + + /** Utility classes. */ + namespace utility { } + + + /** Constant value with the greatest possible value for an element + * of type size_t. The meaning is "infinite" or "until the end". + */ + extern VMIME_EXPORT const size_t npos; + + + /** Clone helper (using a shared_ptr). + * This is an alias for dynamic_pointer_cast <T>(obj->clone()). + */ + template <class T> + shared_ptr <T> clone(shared_ptr <T> obj) + { + return dynamic_pointer_cast <T>(obj->clone()); + } + + /** Clone helper (using a const shared_ptr). + * This is an alias for dynamic_pointer_cast <T>(obj->clone()). + */ + template <class T> + shared_ptr <T> clone(shared_ptr <const T> obj) + { + return dynamic_pointer_cast <T>(obj->clone()); + } + + /** Clone helper (using a const reference). + * This is an alias for dynamic_pointer_cast <T>(obj.clone()). + */ + template <class T> + shared_ptr <T> clone(const T& obj) + { + return dynamic_pointer_cast <T>(obj.clone()); + } + + /** Downcast helper. + * Usage: vmime::dynamicCast <DerivedType>(obj), where 'obj' is of + * type Type, and DerivedType is derived from Type. + */ + template <class X, class Y> + shared_ptr <X> dynamicCast(shared_ptr <Y> obj) + { + return dynamic_pointer_cast <X, Y>(obj); + } + + /** Const cast helper. + */ + template <class X, class Y> + shared_ptr <X> constCast(const shared_ptr <Y>& obj) + { + return const_pointer_cast <X, Y>(obj); + } + + /** Inherit from this class to indicate the subclass is not copyable, + * ie. you want to prohibit copy construction and copy assignment. + */ + class VMIME_EXPORT noncopyable + { + protected: + + noncopyable() { } + virtual ~noncopyable() { } + + private: + + noncopyable(const noncopyable&); + void operator=(const noncopyable&); + }; + +} // vmime + + +#include "vmime/utility/stream.hpp" + + +#endif // VMIME_BASE_HPP_INCLUDED diff --git a/src/body.cpp b/src/vmime/body.cpp index 8f5401cf..8f5401cf 100644 --- a/src/body.cpp +++ b/src/vmime/body.cpp diff --git a/src/vmime/body.hpp b/src/vmime/body.hpp new file mode 100644 index 00000000..e47f97e9 --- /dev/null +++ b/src/vmime/body.hpp @@ -0,0 +1,344 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_BODY_HPP_INCLUDED +#define VMIME_BODY_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/component.hpp" + +#include "vmime/header.hpp" + +#include "vmime/mediaType.hpp" +#include "vmime/charset.hpp" +#include "vmime/encoding.hpp" + +#include "vmime/contentHandler.hpp" + + +namespace vmime +{ + + +class bodyPart; + + +/** Body section of a MIME part. + */ + +class VMIME_EXPORT body : public component +{ + friend class bodyPart; + +public: + + body(); + ~body(); + + /** Add a part at the end of the list. + * + * @param part part to append + */ + void appendPart(shared_ptr <bodyPart> part); + + /** Insert a new part before the specified part. + * + * @param beforePart part before which the new part will be inserted + * @param part part to insert + * @throw exceptions::no_such_part if the part is not in the list + */ + void insertPartBefore(shared_ptr <bodyPart> beforePart, shared_ptr <bodyPart> part); + + /** Insert a new part before the specified position. + * + * @param pos position at which to insert the new part (0 to insert at + * the beginning of the list) + * @param part part to insert + */ + void insertPartBefore(const size_t pos, shared_ptr <bodyPart> part); + + /** Insert a new part after the specified part. + * + * @param afterPart part after which the new part will be inserted + * @param part part to insert + * @throw exceptions::no_such_part if the part is not in the list + */ + void insertPartAfter(shared_ptr <bodyPart> afterPart, shared_ptr <bodyPart> part); + + /** Insert a new part after the specified position. + * + * @param pos position of the part before the new part + * @param part part to insert + */ + void insertPartAfter(const size_t pos, shared_ptr <bodyPart> part); + + /** Remove the specified part from the list. + * + * @param part part to remove + * @throw exceptions::no_such_part if the part is not in the list + */ + void removePart(shared_ptr <bodyPart> part); + + /** Remove the part at the specified position. + * + * @param pos position of the part to remove + */ + void removePart(const size_t pos); + + /** Remove all parts from the list. + */ + void removeAllParts(); + + /** Return the number of parts in the list. + * + * @return number of parts + */ + size_t getPartCount() const; + + /** Tests whether the list of parts is empty. + * + * @return true if there is no part, false otherwise + */ + bool isEmpty() const; + + /** Return the part at the specified position. + * + * @param pos position + * @return part at position 'pos' + */ + shared_ptr <bodyPart> getPartAt(const size_t pos); + + /** Return the part at the specified position. + * + * @param pos position + * @return part at position 'pos' + */ + const shared_ptr <const bodyPart> getPartAt(const size_t pos) const; + + /** Return the part list. + * + * @return list of parts + */ + const std::vector <shared_ptr <const bodyPart> > getPartList() const; + + /** Return the part list. + * + * @return list of parts + */ + const std::vector <shared_ptr <bodyPart> > getPartList(); + + /** Return the prolog text. + * + * @return prolog text + */ + const string& getPrologText() const; + + /** Set the prolog text. + * + * @param prologText new prolog text + */ + void setPrologText(const string& prologText); + + /** Return the epilog text. + * + * @return epilog text + */ + const string& getEpilogText() const; + + /** Set the epilog text. + * + * @param epilogText new epilog text + */ + void setEpilogText(const string& epilogText); + + /** Return a read-only reference to body contents. + * + * @return read-only body contents + */ + const shared_ptr <const contentHandler> getContents() const; + + /** Set the body contents. + * + * @param contents new body contents + */ + void setContents(shared_ptr <const contentHandler> contents); + + /** Set the body contents and type. + * + * @param contents new body contents + * @param type type of contents + */ + void setContents(shared_ptr <const contentHandler> contents, const mediaType& type); + + /** Set the body contents, type and charset. + * + * @param contents new body contents + * @param type type of contents + * @param chset charset of contents + */ + void setContents(shared_ptr <const contentHandler> contents, const mediaType& type, const charset& chset); + + /** Set the body contents, type, charset and encoding. + * + * @param contents new body contents + * @param type type of contents + * @param chset charset of contents + * @param enc contents encoding + */ + void setContents(shared_ptr <const contentHandler> contents, const mediaType& type, + const charset& chset, const encoding& enc); + + /** Set the MIME type and charset of contents. + * If a charset is defined, it will not be modified. + * + * @param type MIME media type of contents + * @param chset charset of contents + */ + void setContentType(const mediaType& type, const charset& chset); + + /** Set the MIME type of contents. + * + * @param type MIME media type of contents + */ + void setContentType(const mediaType& type); + + /** Return the media type of the data contained in the body contents. + * This is a shortcut for getHeader()->ContentType()->getValue() + * on the parent part. + * + * @return media type of body contents + */ + const mediaType getContentType() const; + + /** Set the charset of contents. + * If the type is not set, it will be set to default "text/plain" type. + * + * @param chset charset of contents + */ + void setCharset(const charset& chset); + + /** Return the charset of the data contained in the body contents. + * This is a shortcut for getHeader()->ContentType()->getCharset() + * on the parent part. + * + * @return charset of body contents + */ + const charset getCharset() const; + + /** Set the output encoding of contents. + * Contents will be encoded (or re-encoded) when this node is being generated. + * + * @param enc encoding of contents + */ + void setEncoding(const encoding& enc); + + /** Return the encoding used to encode the body contents. + * This is a shortcut for getHeader()->ContentTransferEncoding()->getValue() + * on the parent part. + * + * @return encoding of body contents + */ + const encoding getEncoding() const; + + /** Generate a new random boundary string. + * + * @return randomly generated boundary string + */ + static const string generateRandomBoundaryString(); + + /** Test a boundary string for validity (as defined in RFC #1521, page 19). + * + * @param boundary boundary string to test + * @return true if the boundary string is valid, false otherwise + */ + static bool isValidBoundary(const string& boundary); + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + body& operator=(const body& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + size_t getGeneratedSize(const generationContext& ctx); + +private: + + text getActualPrologText(const generationContext& ctx) const; + text getActualEpilogText(const generationContext& ctx) const; + + void setParentPart(bodyPart* parent); + + + string m_prologText; + string m_epilogText; + + shared_ptr <const contentHandler> m_contents; + + bodyPart* m_part; + + std::vector <shared_ptr <bodyPart> > m_parts; + + bool isRootPart() const; + + void initNewPart(shared_ptr <bodyPart> part); + +protected: + + /** Finds the next boundary position in the parsing buffer. + * + * @param parser parser object + * @param boundary boundary string (without "--" nor CR/LF) + * @param position start position + * @param end end position + * @param boundaryStart will hold the start position of the boundary (including any + * CR/LF and "--" before the boundary) + * @param boundaryEnd will hold the end position of the boundary (position just + * before the CRLF or "--" which follows) + * @return the position of the boundary string, or npos if not found + */ + size_t findNextBoundaryPosition + (shared_ptr <utility::parserInputStreamAdapter> parser, const string& boundary, + const size_t position, const size_t end, + size_t* boundaryStart, size_t* boundaryEnd); + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + shared_ptr <utility::parserInputStreamAdapter> parser, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_BODY_HPP_INCLUDED diff --git a/src/bodyPart.cpp b/src/vmime/bodyPart.cpp index 12896f84..12896f84 100644 --- a/src/bodyPart.cpp +++ b/src/vmime/bodyPart.cpp diff --git a/src/vmime/bodyPart.hpp b/src/vmime/bodyPart.hpp new file mode 100644 index 00000000..214cb208 --- /dev/null +++ b/src/vmime/bodyPart.hpp @@ -0,0 +1,155 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_BODYPART_HPP_INCLUDED +#define VMIME_BODYPART_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/component.hpp" + +#include "vmime/header.hpp" +#include "vmime/body.hpp" + + +namespace vmime +{ + + +/** A MIME part. + */ + +class VMIME_EXPORT bodyPart : public component +{ + friend class body; + +public: + + bodyPart(); + + /** Return the header section of this part. + * + * @return header section + */ + const shared_ptr <const header> getHeader() const; + + /** Return the header section of this part. + * + * @return header section + */ + shared_ptr <header> getHeader(); + + /** Replaces the header section of this part. + * + * @param header the new header of this part + */ + void setHeader(shared_ptr <header> header); + + /** Return the body section of this part. + * + * @return body section + */ + const shared_ptr <const body> getBody() const; + + /** Return the body section of this part. + * + * @return body section + */ + shared_ptr <body> getBody(); + + /** Replaces the body section of this part. + * + * @param body new body section + */ + void setBody(shared_ptr <body> body); + + /** Return the parent part of this part. + * + * @return parent part or NULL if not known + */ + bodyPart* getParentPart(); + + /** Return the parent part of this part (const version). + * + * @return parent part or NULL if not known + */ + const bodyPart* getParentPart() const; + + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + bodyPart& operator=(const bodyPart& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + size_t getGeneratedSize(const generationContext& ctx); + +private: + + shared_ptr <header> m_header; + mutable shared_ptr <body> m_body; + + // We can't use a weak_ptr<> here as the parent part may + // have been allocated on the stack + bodyPart* m_parent; + +protected: + + /** Creates and returns a new part and set this part as its + * parent. The newly created sub-part should then be added + * to this part by calling getBody()->appendPart(). Called + * by the body class. + * + * @return child part + */ + shared_ptr <bodyPart> createChildPart(); + + /** Detach the specified part from its current parent part (if + * any) and attach it to this part by setting this part as its + * new parent. The sub-part should then be added to this part + * by calling getBody()->appendPart(). Called by body class. + * + * @param part child part to attach + */ + void importChildPart(shared_ptr <bodyPart> part); + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + shared_ptr <utility::parserInputStreamAdapter> parser, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_BODYPART_HPP_INCLUDED diff --git a/src/bodyPartAttachment.cpp b/src/vmime/bodyPartAttachment.cpp index 0684a896..0684a896 100644 --- a/src/bodyPartAttachment.cpp +++ b/src/vmime/bodyPartAttachment.cpp diff --git a/src/vmime/bodyPartAttachment.hpp b/src/vmime/bodyPartAttachment.hpp new file mode 100644 index 00000000..e1a4a89a --- /dev/null +++ b/src/vmime/bodyPartAttachment.hpp @@ -0,0 +1,78 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_BODYPARTATTACHMENT_HPP_INCLUDED +#define VMIME_BODYPARTATTACHMENT_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC // implementation detail + + +#include "vmime/attachment.hpp" + +#include "vmime/contentDispositionField.hpp" +#include "vmime/contentTypeField.hpp" + + +namespace vmime +{ + + +/** An attachment related to a local body part. + */ +class VMIME_EXPORT bodyPartAttachment : public attachment +{ +public: + + bodyPartAttachment(shared_ptr <const bodyPart> part); + + const mediaType getType() const; + const word getName() const; + const text getDescription() const; + const encoding getEncoding() const; + + const shared_ptr <const contentHandler> getData() const; + + shared_ptr <const object> getPart() const; + shared_ptr <const header> getHeader() const; + +private: + + void generateIn(shared_ptr <bodyPart> parent) const; + + shared_ptr <const contentDispositionField> getContentDisposition() const; + shared_ptr <const contentTypeField> getContentType() const; + + + shared_ptr <const bodyPart> m_part; +}; + + +} // vmime + + +#endif // VMIME_BUILDING_DOC + + +#endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED + diff --git a/src/charset.cpp b/src/vmime/charset.cpp index 22bff301..22bff301 100644 --- a/src/charset.cpp +++ b/src/vmime/charset.cpp diff --git a/src/vmime/charset.hpp b/src/vmime/charset.hpp new file mode 100644 index 00000000..5bd50fdf --- /dev/null +++ b/src/vmime/charset.hpp @@ -0,0 +1,148 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CHARSET_HPP_INCLUDED +#define VMIME_CHARSET_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/utility/inputStream.hpp" +#include "vmime/utility/outputStream.hpp" +#include "vmime/charsetConverterOptions.hpp" +#include "vmime/component.hpp" + + +namespace vmime +{ + + +class encoding; // forward reference + + +/** Charset description (basic type). + */ + +class VMIME_EXPORT charset : public component +{ +public: + + charset(); + charset(const string& name); + charset(const char* name); // to allow creation from vmime::charsets constants + +public: + + /** Return the ISO name of the charset. + * + * @return charset name + */ + const string& getName() const; + + charset& operator=(const charset& other); + + bool operator==(const charset& value) const; + bool operator!=(const charset& value) const; + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Gets the recommended encoding for this charset. + * Note: there may be no recommended encoding. + * + * @param enc output parameter that will hold recommended encoding + * @return true if an encoding is recommended (the encoding is stored + * in the enc parameter), false otherwise (in this case, the enc + * parameter is not modified) + */ + bool getRecommendedEncoding(encoding& enc) const; + + /** Returns the default charset used on the system. + * + * This function simply calls <code>platformHandler::getLocalCharset()</code> + * and is provided for convenience. + * + * @return system default charset + */ + static const charset getLocalCharset(); + + /** Convert a string buffer from one charset to another + * charset (in-memory conversion) + * + * \deprecated Use the new convert() method, which takes + * an outputStream parameter. + * + * @param in input buffer + * @param out output buffer + * @param source input charset + * @param dest output charset + * @param opts conversion options + * @throws exceptions::charset_conv_error if an error occured during + * the conversion + */ + static void convert(const string& in, string& out, + const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); + + /** Convert the contents of an input stream in a specified charset + * to another charset and write the result to an output stream. + * + * @param in input stream to read data from + * @param out output stream to write the converted data + * @param source input charset + * @param dest output charset + * @param opts conversion options + * @throws exceptions::charset_conv_error if an error occured during + * the conversion + */ + static void convert(utility::inputStream& in, utility::outputStream& out, + const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + +private: + + string m_name; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_CHARSET_HPP_INCLUDED diff --git a/src/charsetConverter.cpp b/src/vmime/charsetConverter.cpp index 87886823..87886823 100644 --- a/src/charsetConverter.cpp +++ b/src/vmime/charsetConverter.cpp diff --git a/src/vmime/charsetConverter.hpp b/src/vmime/charsetConverter.hpp new file mode 100644 index 00000000..07f38d8f --- /dev/null +++ b/src/vmime/charsetConverter.hpp @@ -0,0 +1,119 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CHARSETCONVERTER_HPP_INCLUDED +#define VMIME_CHARSETCONVERTER_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/component.hpp" + +#include "vmime/charset.hpp" +#include "vmime/charsetConverterOptions.hpp" +#include "vmime/utility/filteredStream.hpp" + + +namespace vmime +{ + + +namespace utility +{ + + +/** A filtered output stream which applies a charset conversion + * to input bytes. + * + * May throw a exceptions::charset_conv_error if an error + * occured when initializing convert, or during charset conversion. + */ + +class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream +{ +}; + + +} // utility + + +/** Convert between charsets. + */ + +class VMIME_EXPORT charsetConverter : public object +{ +public: + + /** Construct and initialize an iconv charset converter. + * + * @param source input charset + * @param dest output charset + * @param opts conversion options + */ + static shared_ptr <charsetConverter> create + (const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); + + /** Convert a string buffer from one charset to another + * charset (in-memory conversion) + * + * \deprecated Use the new convert() method, which takes + * an outputStream parameter. + * + * @param in input buffer + * @param out output buffer + * @throws exceptions::charset_conv_error if an error occured during + * the conversion + */ + virtual void convert(const string& in, string& out) = 0; + + /** Convert the contents of an input stream in a specified charset + * to another charset and write the result to an output stream. + * + * @param in input stream to read data from + * @param out output stream to write the converted data + * @throws exceptions::charset_conv_error if an error occured during + * the conversion + */ + virtual void convert(utility::inputStream& in, utility::outputStream& out) = 0; + + /** Returns a filtered output stream which applies a charset + * conversion to input bytes. Please note that it may not be + * supported by the converter. + * + * @param os stream into which filtered data will be written + * @return a filtered output stream, or NULL if not supported + */ + virtual shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os) = 0; + +private: + + static shared_ptr <charsetConverter> createGenericConverter + (const charset& source, const charset& dest, + const charsetConverterOptions& opts); +}; + + +} // vmime + + +#endif // VMIME_CHARSETCONVERTER_HPP_INCLUDED diff --git a/src/charsetConverterOptions.cpp b/src/vmime/charsetConverterOptions.cpp index caeacd01..caeacd01 100644 --- a/src/charsetConverterOptions.cpp +++ b/src/vmime/charsetConverterOptions.cpp diff --git a/src/vmime/charsetConverterOptions.hpp b/src/vmime/charsetConverterOptions.hpp new file mode 100644 index 00000000..07e7a138 --- /dev/null +++ b/src/vmime/charsetConverterOptions.hpp @@ -0,0 +1,53 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CHARSETCONVERTEROPTIONS_HPP_INCLUDED +#define VMIME_CHARSETCONVERTEROPTIONS_HPP_INCLUDED + + +#include "vmime/base.hpp" + + +namespace vmime +{ + + +/** Options for charset conversion. + */ + +class VMIME_EXPORT charsetConverterOptions : public object +{ +public: + + charsetConverterOptions(); + + + /** Replace invalid sequences with this string. */ + string invalidSequence; +}; + + +} // vmime + + +#endif // VMIME_CHARSETCONVERTEROPTIONS_HPP_INCLUDED diff --git a/src/charsetConverter_iconv.cpp b/src/vmime/charsetConverter_iconv.cpp index 75d7b170..75d7b170 100644 --- a/src/charsetConverter_iconv.cpp +++ b/src/vmime/charsetConverter_iconv.cpp diff --git a/src/vmime/charsetConverter_iconv.hpp b/src/vmime/charsetConverter_iconv.hpp new file mode 100644 index 00000000..4167dc4e --- /dev/null +++ b/src/vmime/charsetConverter_iconv.hpp @@ -0,0 +1,135 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED +#define VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_CHARSETCONV_LIB_IS_ICONV + + +#include "vmime/charsetConverter.hpp" + + +namespace vmime +{ + + +/** A generic charset converter which uses iconv library. + */ + +class charsetConverter_iconv : public charsetConverter +{ +public: + + /** Construct and initialize an iconv charset converter. + * + * @param source input charset + * @param dest output charset + * @param opts conversion options + */ + charsetConverter_iconv(const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); + + ~charsetConverter_iconv(); + + void convert(const string& in, string& out); + void convert(utility::inputStream& in, utility::outputStream& out); + + shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os); + +private: + + void* m_desc; + + charset m_source; + charset m_dest; + + charsetConverterOptions m_options; +}; + + +namespace utility { + + +class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream +{ +public: + + /** Construct a new filter for the specified output stream. + * + * @param source input charset + * @param dest output charset + * @param os stream into which write filtered data + */ + charsetFilteredOutputStream_iconv + (const charset& source, const charset& dest, outputStream* os); + + ~charsetFilteredOutputStream_iconv(); + + + outputStream& getNextOutputStream(); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + // Maximum character width in any charset + enum { MAX_CHARACTER_WIDTH = 128 }; + + + void* m_desc; + + const charset m_sourceCharset; + const charset m_destCharset; + + outputStream& m_stream; + + // Buffer in which unconverted bytes are left until they can + // be converted (when more data arrives). The length should be + // large enough to contain any character in any charset. + byte_t m_unconvBuffer[MAX_CHARACTER_WIDTH]; + size_t m_unconvCount; + + // Buffer used for conversion. Avoids declaring it in write(). + // Should be at least MAX_CHARACTER_WIDTH * MAX_CHARACTER_WIDTH. + byte_t m_outputBuffer[32768]; +}; + + +} // utility + + +} // vmime + + +#endif // VMIME_CHARSETCONV_LIB_IS_ICONV + +#endif // VMIME_CHARSETCONVERTER_ICONV_HPP_INCLUDED diff --git a/src/charsetConverter_icu.cpp b/src/vmime/charsetConverter_icu.cpp index 3374d448..3374d448 100644 --- a/src/charsetConverter_icu.cpp +++ b/src/vmime/charsetConverter_icu.cpp diff --git a/src/vmime/charsetConverter_icu.hpp b/src/vmime/charsetConverter_icu.hpp new file mode 100644 index 00000000..5d054413 --- /dev/null +++ b/src/vmime/charsetConverter_icu.hpp @@ -0,0 +1,126 @@ +//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#ifndef VMIME_CHARSETCONVERTER_ICU_HPP_INCLUDED
+#define VMIME_CHARSETCONVERTER_ICU_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+
+#if VMIME_CHARSETCONV_LIB_IS_ICU
+
+
+#include "vmime/charsetConverter.hpp"
+
+
+struct UConverter;
+
+
+namespace vmime
+{
+
+
+/** A generic charset converter which uses ICU library.
+ */
+
+class charsetConverter_icu : public charsetConverter
+{
+public:
+
+ /** Construct and initialize an ICU charset converter.
+ *
+ * @param source input charset
+ * @param dest output charset
+ * @param opts conversion options
+ */
+ charsetConverter_icu(const charset& source, const charset& dest,
+ const charsetConverterOptions& opts = charsetConverterOptions());
+
+ ~charsetConverter_icu();
+
+ void convert(const string& in, string& out);
+ void convert(utility::inputStream& in, utility::outputStream& out);
+
+ shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os);
+
+private:
+
+ UConverter* m_from;
+ UConverter* m_to;
+
+ charset m_source;
+ charset m_dest;
+
+ charsetConverterOptions m_options;
+};
+
+
+namespace utility {
+
+
+class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream
+{
+public:
+
+ /** Construct a new filter for the specified output stream.
+ *
+ * @param source input charset
+ * @param dest output charset
+ * @param os stream into which write filtered data
+ */
+ charsetFilteredOutputStream_icu
+ (const charset& source, const charset& dest, outputStream* os);
+
+ ~charsetFilteredOutputStream_icu();
+
+
+ outputStream& getNextOutputStream();
+
+ void flush();
+
+protected:
+
+ void writeImpl(const byte_t* const data, const size_t count);
+
+private:
+
+ UConverter* m_from;
+ UConverter* m_to;
+
+ const charset m_sourceCharset;
+ const charset m_destCharset;
+
+ outputStream& m_stream;
+};
+
+
+} // utility
+
+
+} // vmime
+
+
+#endif // VMIME_CHARSETCONV_LIB_IS_ICU
+
+#endif // VMIME_CHARSETCONVERTER_ICU_HPP_INCLUDED
diff --git a/src/charsetConverter_idna.cpp b/src/vmime/charsetConverter_idna.cpp index aea6eca7..aea6eca7 100644 --- a/src/charsetConverter_idna.cpp +++ b/src/vmime/charsetConverter_idna.cpp diff --git a/src/vmime/charsetConverter_idna.hpp b/src/vmime/charsetConverter_idna.hpp new file mode 100644 index 00000000..874d6bf1 --- /dev/null +++ b/src/vmime/charsetConverter_idna.hpp @@ -0,0 +1,70 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CHARSETCONVERTER_IDNA_HPP_INCLUDED +#define VMIME_CHARSETCONVERTER_IDNA_HPP_INCLUDED + + +#include "vmime/charsetConverter.hpp" + + +namespace vmime +{ + + +/** A charset converter which can convert to and from Punycode (for IDNA). + */ + +class charsetConverter_idna : public charsetConverter +{ +public: + + /** Construct and initialize an IDNA charset converter. + * + * @param source input charset + * @param dest output charset + * @param opts conversion options + */ + charsetConverter_idna(const charset& source, const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()); + + ~charsetConverter_idna(); + + void convert(const string& in, string& out); + void convert(utility::inputStream& in, utility::outputStream& out); + + shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(utility::outputStream& os); + +private: + + charset m_source; + charset m_dest; + + charsetConverterOptions m_options; +}; + + +} // vmime + + +#endif // VMIME_CHARSETCONVERTER_IDNA_HPP_INCLUDED diff --git a/src/component.cpp b/src/vmime/component.cpp index 46ff4036..46ff4036 100644 --- a/src/component.cpp +++ b/src/vmime/component.cpp diff --git a/src/vmime/component.hpp b/src/vmime/component.hpp new file mode 100644 index 00000000..87d465e8 --- /dev/null +++ b/src/vmime/component.hpp @@ -0,0 +1,257 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_COMPONENT_HPP_INCLUDED +#define VMIME_COMPONENT_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/utility/inputStream.hpp" +#include "vmime/utility/seekableInputStream.hpp" +#include "vmime/utility/parserInputStreamAdapter.hpp" +#include "vmime/utility/outputStream.hpp" +#include "vmime/generationContext.hpp" +#include "vmime/parsingContext.hpp" + + +namespace vmime +{ + + +/** This abstract class is the base class for all the components of a message. + * It defines methods for parsing and generating a component. + */ + +class VMIME_EXPORT component : public object +{ +public: + + component(); + virtual ~component(); + + /** Parse RFC-822/MIME data for this component, using the default + * parsing context. + * + * @param buffer input buffer + */ + void parse(const string& buffer); + + /** Parse RFC-822/MIME data for this component. + * + * @param ctx parsing context + * @param buffer input buffer + */ + void parse(const parsingContext& ctx, const string& buffer); + + /** Parse RFC-822/MIME data for this component. If stream is not seekable, + * or if length is not specified, entire contents of the stream will + * be loaded into memory before parsing. + * + * @param inputStream stream from which to read data + * @param length data length, in bytes (0 = unknown/not specified) + */ + void parse(shared_ptr <utility::inputStream> inputStream, const size_t length); + + /** Parse RFC-822/MIME data for this component, using the default + * parsing context. + * + * @param buffer input buffer + * @param position current position in the input buffer + * @param end end position in the input buffer + * @param newPosition will receive the new position in the input buffer + */ + void parse + (const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + /** Parse RFC-822/MIME data for this component. + * + * @param ctx parsing context + * @param buffer input buffer + * @param position current position in the input buffer + * @param end end position in the input buffer + * @param newPosition will receive the new position in the input buffer + */ + void parse + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + /** Parse RFC-822/MIME data for this component. If stream is not seekable, + * or if end position is not specified, entire contents of the stream will + * be loaded into memory before parsing. The default parsing context + * will be used. + * + * @param inputStream stream from which to read data + * @param position current position in the input stream + * @param end end position in the input stream + * @param newPosition will receive the new position in the input stream + */ + void parse + (shared_ptr <utility::inputStream> inputStream, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + /** Parse RFC-822/MIME data for this component. If stream is not seekable, + * or if end position is not specified, entire contents of the stream will + * be loaded into memory before parsing. + * + * @param ctx parsing context + * @param inputStream stream from which to read data + * @param position current position in the input stream + * @param end end position in the input stream + * @param newPosition will receive the new position in the input stream + */ + void parse + (const parsingContext& ctx, + shared_ptr <utility::inputStream> inputStream, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + /** Generate RFC-2822/MIME data for this component. + * + * \deprecated Use the new generate() method, which takes an outputStream parameter. + * + * @param maxLineLength maximum line length for output + * @param curLinePos length of the current line in the output buffer + * @return generated data + */ + virtual const string generate + (const size_t maxLineLength = lineLengthLimits::infinite, + const size_t curLinePos = 0) const; + + /** Generate RFC-2822/MIME data for this component, using the default generation context. + * + * @param outputStream output stream + * @param curLinePos length of the current line in the output buffer + * @param newLinePos will receive the new line position (length of the last line written) + */ + virtual void generate + (utility::outputStream& outputStream, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; + + /** Generate RFC-2822/MIME data for this component, using the default generation context. + * + * @param ctx generation context + * @param outputStream output stream + * @param curLinePos length of the current line in the output buffer + * @param newLinePos will receive the new line position (length of the last line written) + */ + virtual void generate + (const generationContext& ctx, + utility::outputStream& outputStream, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; + + /** Clone this component. + * + * @return a copy of this component + */ + virtual shared_ptr <component> clone() const = 0; + + /** Replace data in this component by data in other component. + * Both components must be of the same type. + * + * @throw std::bad_cast_exception if the components are not + * of the same (dynamic) type + * @param other other component to copy data from + */ + virtual void copyFrom(const component& other) = 0; + + /** Return the start position of this component in the + * parsed message contents. Use for debugging only. + * + * @return start position in parsed buffer + * or 0 if this component has not been parsed + */ + size_t getParsedOffset() const; + + /** Return the length of this component in the + * parsed message contents. Use for debugging only. + * + * @return length of the component in parsed buffer + * or 0 if this component has not been parsed + */ + size_t getParsedLength() const; + + /** Return the list of children of this component. + * + * @return list of child components + */ + virtual const std::vector <shared_ptr <component> > getChildComponents() = 0; + + /** Get the number of bytes that will be used by this component when + * it is generated. This may be a heuristically-derived estimate, + * but such an estimated size should always be larger than the actual + * generated size. + * + * @param ctx generation context + * @return component size when generated + */ + virtual size_t getGeneratedSize(const generationContext& ctx); + +protected: + + void setParsedBounds(const size_t start, const size_t end); + + // AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class + virtual void parseImpl + (const parsingContext& ctx, + shared_ptr <utility::parserInputStreamAdapter> parser, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + virtual void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + virtual void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const = 0; + +private: + + void offsetParsedBounds(const size_t offset); + + size_t m_parsedOffset; + size_t m_parsedLength; +}; + + +} // vmime + + +#endif // VMIME_COMPONENT_HPP_INCLUDED diff --git a/src/constants.cpp b/src/vmime/constants.cpp index 3b0a54c0..3b0a54c0 100644 --- a/src/constants.cpp +++ b/src/vmime/constants.cpp diff --git a/src/vmime/constants.hpp b/src/vmime/constants.hpp new file mode 100644 index 00000000..8e6e3f83 --- /dev/null +++ b/src/vmime/constants.hpp @@ -0,0 +1,256 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free SOFTWARE; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software FOUNDATION; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// along with this PROGRAM; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CONSTANTS_HPP_INCLUDED +#define VMIME_CONSTANTS_HPP_INCLUDED + + +#include <string> + +#include "vmime/types.hpp" + + +// Remove Windows defines of ERROR and WARNING +#ifdef _WIN32 + #undef ERROR + #undef WARNING +#endif + + +namespace vmime +{ + /** Constants for media types. */ + namespace mediaTypes + { + // Types + extern VMIME_EXPORT const char* const TEXT; + extern VMIME_EXPORT const char* const MULTIPART; + extern VMIME_EXPORT const char* const MESSAGE; + extern VMIME_EXPORT const char* const APPLICATION; + extern VMIME_EXPORT const char* const IMAGE; + extern VMIME_EXPORT const char* const AUDIO; + extern VMIME_EXPORT const char* const VIDEO; + + // Sub-types + extern VMIME_EXPORT const char* const TEXT_PLAIN; + extern VMIME_EXPORT const char* const TEXT_HTML; + extern VMIME_EXPORT const char* const TEXT_RICHTEXT; + extern VMIME_EXPORT const char* const TEXT_ENRICHED; + extern VMIME_EXPORT const char* const TEXT_RFC822_HEADERS; // RFC-1892 + extern VMIME_EXPORT const char* const TEXT_DIRECTORY; // RFC-2426 + + extern VMIME_EXPORT const char* const MULTIPART_MIXED; + extern VMIME_EXPORT const char* const MULTIPART_RELATED; + extern VMIME_EXPORT const char* const MULTIPART_ALTERNATIVE; + extern VMIME_EXPORT const char* const MULTIPART_PARALLEL; + extern VMIME_EXPORT const char* const MULTIPART_DIGEST; + extern VMIME_EXPORT const char* const MULTIPART_REPORT; // RFC-1892 + + extern VMIME_EXPORT const char* const MESSAGE_RFC822; + extern VMIME_EXPORT const char* const MESSAGE_PARTIAL; + extern VMIME_EXPORT const char* const MESSAGE_EXTERNAL_BODY; + extern VMIME_EXPORT const char* const MESSAGE_DISPOSITION_NOTIFICATION; + + extern VMIME_EXPORT const char* const APPLICATION_OCTET_STREAM; + + extern VMIME_EXPORT const char* const IMAGE_JPEG; + extern VMIME_EXPORT const char* const IMAGE_GIF; + + extern VMIME_EXPORT const char* const AUDIO_BASIC; + + extern VMIME_EXPORT const char* const VIDEO_MPEG; + } + + + /** Constants for encoding types. */ + namespace encodingTypes + { + extern VMIME_EXPORT const char* const SEVEN_BIT; + extern VMIME_EXPORT const char* const EIGHT_BIT; + extern VMIME_EXPORT const char* const BASE64; + extern VMIME_EXPORT const char* const QUOTED_PRINTABLE; + extern VMIME_EXPORT const char* const BINARY; + extern VMIME_EXPORT const char* const UUENCODE; + } + + + /** Constants for content disposition types (RFC-2183). */ + namespace contentDispositionTypes + { + extern VMIME_EXPORT const char* const INLINE; + extern VMIME_EXPORT const char* const ATTACHMENT; + } + + + /** Constants for charsets. */ + namespace charsets + { + extern VMIME_EXPORT const char* const ISO8859_1; + extern VMIME_EXPORT const char* const ISO8859_2; + extern VMIME_EXPORT const char* const ISO8859_3; + extern VMIME_EXPORT const char* const ISO8859_4; + extern VMIME_EXPORT const char* const ISO8859_5; + extern VMIME_EXPORT const char* const ISO8859_6; + extern VMIME_EXPORT const char* const ISO8859_7; + extern VMIME_EXPORT const char* const ISO8859_8; + extern VMIME_EXPORT const char* const ISO8859_9; + extern VMIME_EXPORT const char* const ISO8859_10; + extern VMIME_EXPORT const char* const ISO8859_13; + extern VMIME_EXPORT const char* const ISO8859_14; + extern VMIME_EXPORT const char* const ISO8859_15; + extern VMIME_EXPORT const char* const ISO8859_16; + + extern VMIME_EXPORT const char* const CP_437; + extern VMIME_EXPORT const char* const CP_737; + extern VMIME_EXPORT const char* const CP_775; + extern VMIME_EXPORT const char* const CP_850; + extern VMIME_EXPORT const char* const CP_852; + extern VMIME_EXPORT const char* const CP_853; + extern VMIME_EXPORT const char* const CP_855; + extern VMIME_EXPORT const char* const CP_857; + extern VMIME_EXPORT const char* const CP_858; + extern VMIME_EXPORT const char* const CP_860; + extern VMIME_EXPORT const char* const CP_861; + extern VMIME_EXPORT const char* const CP_862; + extern VMIME_EXPORT const char* const CP_863; + extern VMIME_EXPORT const char* const CP_864; + extern VMIME_EXPORT const char* const CP_865; + extern VMIME_EXPORT const char* const CP_866; + extern VMIME_EXPORT const char* const CP_869; + extern VMIME_EXPORT const char* const CP_874; + extern VMIME_EXPORT const char* const CP_1125; + extern VMIME_EXPORT const char* const CP_1250; + extern VMIME_EXPORT const char* const CP_1251; + extern VMIME_EXPORT const char* const CP_1252; + extern VMIME_EXPORT const char* const CP_1253; + extern VMIME_EXPORT const char* const CP_1254; + extern VMIME_EXPORT const char* const CP_1255; + extern VMIME_EXPORT const char* const CP_1256; + extern VMIME_EXPORT const char* const CP_1257; + + extern VMIME_EXPORT const char* const US_ASCII; + + extern VMIME_EXPORT const char* const UTF_7; + extern VMIME_EXPORT const char* const UTF_8; + extern VMIME_EXPORT const char* const UTF_16; + extern VMIME_EXPORT const char* const UTF_32; + + extern VMIME_EXPORT const char* const WINDOWS_1250; + extern VMIME_EXPORT const char* const WINDOWS_1251; + extern VMIME_EXPORT const char* const WINDOWS_1252; + extern VMIME_EXPORT const char* const WINDOWS_1253; + extern VMIME_EXPORT const char* const WINDOWS_1254; + extern VMIME_EXPORT const char* const WINDOWS_1255; + extern VMIME_EXPORT const char* const WINDOWS_1256; + extern VMIME_EXPORT const char* const WINDOWS_1257; + extern VMIME_EXPORT const char* const WINDOWS_1258; + + extern VMIME_EXPORT const char* const IDNA; + } + + /** Constants for standard field names. */ + namespace fields + { + extern VMIME_EXPORT const char* const RECEIVED; + extern VMIME_EXPORT const char* const FROM; + extern VMIME_EXPORT const char* const SENDER; + extern VMIME_EXPORT const char* const REPLY_TO; + extern VMIME_EXPORT const char* const TO; + extern VMIME_EXPORT const char* const CC; + extern VMIME_EXPORT const char* const BCC; + extern VMIME_EXPORT const char* const DATE; + extern VMIME_EXPORT const char* const SUBJECT; + extern VMIME_EXPORT const char* const ORGANIZATION; + extern VMIME_EXPORT const char* const USER_AGENT; + extern VMIME_EXPORT const char* const DELIVERED_TO; + extern VMIME_EXPORT const char* const RETURN_PATH; + extern VMIME_EXPORT const char* const MIME_VERSION; + extern VMIME_EXPORT const char* const MESSAGE_ID; + extern VMIME_EXPORT const char* const CONTENT_TYPE; + extern VMIME_EXPORT const char* const CONTENT_TRANSFER_ENCODING; + extern VMIME_EXPORT const char* const CONTENT_DESCRIPTION; + extern VMIME_EXPORT const char* const CONTENT_DISPOSITION; + extern VMIME_EXPORT const char* const CONTENT_ID; + extern VMIME_EXPORT const char* const CONTENT_LOCATION; + extern VMIME_EXPORT const char* const IN_REPLY_TO; + extern VMIME_EXPORT const char* const REFERENCES; + + extern VMIME_EXPORT const char* const X_MAILER; + extern VMIME_EXPORT const char* const X_PRIORITY; + + // RFC-3798: Message Disposition Notification + extern VMIME_EXPORT const char* const ORIGINAL_MESSAGE_ID; + extern VMIME_EXPORT const char* const DISPOSITION_NOTIFICATION_TO; + extern VMIME_EXPORT const char* const DISPOSITION_NOTIFICATION_OPTIONS; + extern VMIME_EXPORT const char* const DISPOSITION; + extern VMIME_EXPORT const char* const FAILURE; + extern VMIME_EXPORT const char* const ERROR; + extern VMIME_EXPORT const char* const WARNING; + extern VMIME_EXPORT const char* const ORIGINAL_RECIPIENT; + extern VMIME_EXPORT const char* const FINAL_RECIPIENT; + extern VMIME_EXPORT const char* const REPORTING_UA; + extern VMIME_EXPORT const char* const MDN_GATEWAY; + } + + /** Constants for disposition action modes (RFC-3978). */ + namespace dispositionActionModes + { + /** User implicitely displayed or deleted the message (filter or + * any other automatic action). */ + extern VMIME_EXPORT const char* const AUTOMATIC; + + /** User explicitely displayed or deleted the message (manual action). */ + extern VMIME_EXPORT const char* const MANUAL; + } + + /** Constants for disposition sending modes (RFC-3798). */ + namespace dispositionSendingModes + { + /** The MDN was sent because the MUA had previously been configured + * to do so automatically. */ + extern VMIME_EXPORT const char* const SENT_AUTOMATICALLY; + + /** User explicitly gave permission for this particular MDN to be sent. */ + extern VMIME_EXPORT const char* const SENT_MANUALLY; + } + + /** Constants for disposition types (RFC-3798). */ + namespace dispositionTypes + { + /** Message has been displayed to the user. */ + extern VMIME_EXPORT const char* const DISPLAYED; + /** Message has been deleted without being displayed. */ + extern VMIME_EXPORT const char* const DELETED; + /** Message has been denied. */ + extern VMIME_EXPORT const char* const DENIED; + } + + /** Constants for disposition modifiers (RFC-3798). */ + namespace dispositionModifiers + { + extern VMIME_EXPORT const char* const ERROR; + } +} + + +#endif // VMIME_CONSTANTS_HPP_INCLUDED diff --git a/src/contentDisposition.cpp b/src/vmime/contentDisposition.cpp index 3cf92e27..3cf92e27 100644 --- a/src/contentDisposition.cpp +++ b/src/vmime/contentDisposition.cpp diff --git a/src/vmime/contentDisposition.hpp b/src/vmime/contentDisposition.hpp new file mode 100644 index 00000000..c934b81d --- /dev/null +++ b/src/vmime/contentDisposition.hpp @@ -0,0 +1,99 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CONTENTDISPOSITION_HPP_INCLUDED +#define VMIME_CONTENTDISPOSITION_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + + +namespace vmime +{ + + +/** Content disposition (basic type). + */ + +class VMIME_EXPORT contentDisposition : public headerFieldValue +{ +public: + + contentDisposition(); + contentDisposition(const string& name); + contentDisposition(const contentDisposition& disp); + + + /** Return the content disposition type. + * See the constants in vmime::dispositionTypes. + * + * @return name of the disposition type (eg. "inline") + */ + const string& getName() const; + + /** Set the content disposition type. + * See the constants in vmime::dispositionTypes. + * + * @param name name of the disposition type + */ + void setName(const string& name); + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + contentDisposition& operator=(const contentDisposition& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + + contentDisposition& operator=(const string& name); + + bool operator==(const contentDisposition& value) const; + bool operator!=(const contentDisposition& value) const; + +private: + + string m_name; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_CONTENTDISPOSITION_HPP_INCLUDED diff --git a/src/contentDispositionField.cpp b/src/vmime/contentDispositionField.cpp index 5a9c1212..5a9c1212 100644 --- a/src/contentDispositionField.cpp +++ b/src/vmime/contentDispositionField.cpp diff --git a/src/vmime/contentDispositionField.hpp b/src/vmime/contentDispositionField.hpp new file mode 100644 index 00000000..aac4c5de --- /dev/null +++ b/src/vmime/contentDispositionField.hpp @@ -0,0 +1,148 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CONTENTDISPOSITIONFIELD_HPP_INCLUDED +#define VMIME_CONTENTDISPOSITIONFIELD_HPP_INCLUDED + + +#include "vmime/parameterizedHeaderField.hpp" + +#include "vmime/contentDisposition.hpp" +#include "vmime/dateTime.hpp" +#include "vmime/word.hpp" + + +namespace vmime +{ + + +/** Describes presentation information, as per RFC-2183. + */ + +class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField +{ + friend class headerFieldFactory; + +protected: + + contentDispositionField(); + contentDispositionField(contentDispositionField&); + +public: + + /** Test whether the "creation-date" parameter is set. + * + * @return true if the "creation-date" parameter is set, or false otherwise + */ + bool hasCreationDate() const; + + /** Return the value of the "creation-date" parameter. + * + * @return value of the "creation-date" parameter + */ + const datetime getCreationDate() const; + + /** Set the value of the "creation-date" parameter. + * + * @param creationDate new value for the "creation-date" parameter + */ + void setCreationDate(const datetime& creationDate); + + /** Test whether the "modification-date" parameter is set. + * + * @return true if the "modification-date" parameter is set, or false otherwise + */ + bool hasModificationDate() const; + + /** Return the value of the "modification-date" parameter. + * + * @return value of the "modification-date" parameter + */ + const datetime getModificationDate() const; + + /** Set the value of the "modification-date" parameter. + * + * @param modificationDate new value for the "modification-date" parameter + */ + void setModificationDate(const datetime& modificationDate); + + /** Test whether the "read-date" parameter is set. + * + * @return true if the "read-date" parameter is set, or false otherwise + */ + bool hasReadDate() const; + + /** Return the value of the "read-date" parameter. + * + * @return value of the "read-date" parameter + */ + const datetime getReadDate() const; + + /** Set the value of the "read-date" parameter. + * + * @param readDate new value for the "read-date" parameter + */ + void setReadDate(const datetime& readDate); + + /** Test whether the "filename" parameter is set. + * + * @return true if the "filename" parameter is set, or false otherwise + */ + bool hasFilename() const; + + /** Return the value of the "filename" parameter. + * + * @return value of the "filename" parameter + */ + const word getFilename() const; + + /** Set the value of the "filename" parameter. + * + * @param filename new value for the "filename" parameter + */ + void setFilename(const word& filename); + + /** Test whether the "size" parameter is set. + * + * @return true if the "size" parameter is set, or false otherwise + */ + bool hasSize() const; + + /** Return the value of the "size" parameter. + * + * @return value of the "size" parameter + */ + const string getSize() const; + + /** Set the value of the "size" parameter. + * + * @param size new value for the "size" parameter + */ + void setSize(const string& size); +}; + + +} // vmime + + +#endif // VMIME_CONTENTDISPOSITIONFIELD_HPP_INCLUDED diff --git a/src/contentHandler.cpp b/src/vmime/contentHandler.cpp index 3afe4324..3afe4324 100644 --- a/src/contentHandler.cpp +++ b/src/vmime/contentHandler.cpp diff --git a/src/vmime/contentHandler.hpp b/src/vmime/contentHandler.hpp new file mode 100644 index 00000000..f62af166 --- /dev/null +++ b/src/vmime/contentHandler.hpp @@ -0,0 +1,139 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CONTENTHANDLER_HPP_INCLUDED +#define VMIME_CONTENTHANDLER_HPP_INCLUDED + + +#include <limits> + +#include "vmime/base.hpp" +#include "vmime/utility/stringProxy.hpp" +#include "vmime/utility/progressListener.hpp" +#include "vmime/encoding.hpp" +#include "vmime/mediaType.hpp" + + +namespace vmime +{ + + +class VMIME_EXPORT contentHandler : public object +{ +public: + + /** Used to specify that enclosed data is not encoded. */ + static const vmime::encoding NO_ENCODING; + + + virtual ~contentHandler(); + + /** Return a copy of this object. + * + * @return copy of this object + */ + virtual shared_ptr <contentHandler> clone() const = 0; + + /** Output the contents into the specified stream. Data will be + * encoded before being written into the stream. This is used internally + * by the body object to generate the message, you may not need to use + * this (see contentHandler::extract() if you want to get the contents). + * + * @param os output stream + * @param enc encoding for output + * @param maxLineLength maximum line length for output + */ + virtual void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const = 0; + + /** Extract the contents into the specified stream. If needed, data + * will be decoded before being written into the stream. + * + * @throw exceptions::no_encoder_available if the encoding is + * not supported + * @param os output stream + * @param progress progress listener, or NULL if you do not + * want to receive progress notifications + */ + virtual void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0; + + /** Extract the contents into the specified stream, without + * decoding it. It may be useful in case the encoding is not + * supported and you want to extract raw data. + * + * @param os output stream + * @param progress progress listener, or NULL if you do not + * want to receive progress notifications + */ + virtual void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0; + + /** Returns the actual length of data. WARNING: this can return 0 if no + * length was specified when setting data of this object, or if the + * length is not known). + * + * @return length of data + */ + virtual size_t getLength() const = 0; + + /** Returns 'true' if data managed by this object is encoded. + * + * @return true if data is encoded, false otherwise + */ + virtual bool isEncoded() const = 0; + + /** Returns the encoding used for data (or "binary" if not encoded). + * + * @return encoding used for data + */ + virtual const vmime::encoding& getEncoding() const = 0; + + /** Returns 'true' if there is no data set. + * + * @return true if no data is managed by this object, false otherwise + */ + virtual bool isEmpty() const = 0; + + /** Indicates whether the extract() method can be called multiple times. + * + * @return true if the data can be extracted multiple times, or false + * if not (ie. streamed data from socket) + */ + virtual bool isBuffered() const = 0; + + /** Gives a hint about the kind of data managed by this object. + * + * @param type content media type + */ + virtual void setContentTypeHint(const mediaType& type) = 0; + + /** Returns a hint about the kind of data managed by this object. + * + * @return type content media type + */ + virtual const mediaType getContentTypeHint() const = 0; +}; + + +} // vmime + + +#endif // VMIME_CONTENTHANDLER_HPP_INCLUDED diff --git a/src/contentTypeField.cpp b/src/vmime/contentTypeField.cpp index 9f38294a..9f38294a 100644 --- a/src/contentTypeField.cpp +++ b/src/vmime/contentTypeField.cpp diff --git a/src/vmime/contentTypeField.hpp b/src/vmime/contentTypeField.hpp new file mode 100644 index 00000000..8604c4a3 --- /dev/null +++ b/src/vmime/contentTypeField.hpp @@ -0,0 +1,114 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CONTENTTYPEFIELD_HPP_INCLUDED +#define VMIME_CONTENTTYPEFIELD_HPP_INCLUDED + + +#include "vmime/parameterizedHeaderField.hpp" + +#include "vmime/mediaType.hpp" +#include "vmime/charset.hpp" + + +namespace vmime +{ + + +class VMIME_EXPORT contentTypeField : public parameterizedHeaderField +{ + friend class headerFieldFactory; + +protected: + + contentTypeField(); + contentTypeField(contentTypeField&); + +public: + + /** Test whether the "boundary" parameter is set. + * + * @return true if the "boundary" parameter is set, or false otherwise + */ + bool hasBoundary() const; + + /** Return the value of the "boundary" parameter. Boundary is a + * random string used to separate body parts. + * + * @return value of the "boundary" parameter + */ + const string getBoundary() const; + + /** Set the value of the "boundary" parameter. Boundary is a + * random string used to separate body parts. Normally, the + * boundary is generated automatically by VMime, you should + * not need to call this. + * + * @param boundary new value for the "boundary" parameter + */ + void setBoundary(const string& boundary); + + /** Test whether the "charset" parameter is set. + * + * @return true if the "charset" parameter is set, or false otherwise + */ + bool hasCharset() const; + + /** Return the value of the "charset" parameter. It specifies the + * charset used in the body part contents. + * + * @return value of the "charset" parameter + */ + const charset getCharset() const; + + /** Set the value of the "charset" parameter. It specifies the + * charset used in the body part contents. + * + * @param ch new value for the "charset" parameter + */ + void setCharset(const charset& ch); + + /** Test whether the "report-type" parameter is set. + * + * @return true if the "report-type" parameter is set, or false otherwise + */ + bool hasReportType() const; + + /** Return the value of the "report-type" parameter (RFC-1892). + * + * @return value of the "report-type" parameter + */ + const string getReportType() const; + + /** Set the value of the "report-type" parameter (RFC-1892). + * + * @param reportType new value for the "report-type" parameter + */ + void setReportType(const string& reportType); +}; + + +} // vmime + + +#endif // VMIME_CONTENTTYPEFIELD_HPP_INCLUDED diff --git a/src/context.cpp b/src/vmime/context.cpp index 07fe4875..07fe4875 100644 --- a/src/context.cpp +++ b/src/vmime/context.cpp diff --git a/src/vmime/context.hpp b/src/vmime/context.hpp new file mode 100644 index 00000000..767ec05a --- /dev/null +++ b/src/vmime/context.hpp @@ -0,0 +1,122 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_CONTEXT_HPP_INCLUDED +#define VMIME_CONTEXT_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/charsetConverterOptions.hpp" + + +namespace vmime +{ + + +/** Holds configuration parameters used either for parsing or generating messages. + */ + +class VMIME_EXPORT context : public object +{ +public: + + virtual ~context(); + + /** Returns whether support for Internationalized Email Headers (RFC-6532) + * is enabled. + * + * @return true if RFC-6532 support is enabled, false otherwise + */ + bool getInternationalizedEmailSupport() const; + + /** Enables or disables support for Internationalized Email Headers (RFC-6532). + * This is disabled by default, and should be used only with servers + * which support it (eg. SMTP servers with SMTPUTF8 extension). + * + * @param support true if RFC-6532 support is enabled, false otherwise + */ + void setInternationalizedEmailSupport(const bool support); + + /** Returns options used currently for charset conversions by the parser and/or + * the generator. See charsetConverterOptions class for more information. + * + * @return current charset conversion options + */ + const charsetConverterOptions& getCharsetConversionOptions() const; + + /** Sets the options used currently for charset conversions by the parser and/or + * the generator. See charsetConverterOptions class for more information. + * + * @param opts new charset conversion options + */ + void setCharsetConversionOptions(const charsetConverterOptions& opts); + + /** Switches between contexts temporarily. + */ + template <typename CTX_CLASS> + class switcher + { + public: + + /** Switches to the specified context. + * Default context will temporarily use the data of the specified + * new context during the lifetime of this object. + * + * @param newCtx new context + */ + switcher(CTX_CLASS& newCtx) + : m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx) + { + CTX_CLASS::getDefaultContext().copyFrom(newCtx); + } + + /** Restores back saved context. + */ + ~switcher() + { + CTX_CLASS::getDefaultContext().copyFrom(m_oldCtxData); + } + + private: + + CTX_CLASS m_oldCtxData; + CTX_CLASS* m_newCtx; + }; + +protected: + + context(); + context(const context& ctx); + + virtual context& operator=(const context& ctx); + void copyFrom(const context& ctx); + + bool m_internationalizedEmail; + charsetConverterOptions m_charsetConvOptions; +}; + + +} // vmime + + +#endif // VMIME_CONTEXT_HPP_INCLUDED diff --git a/src/dateTime.cpp b/src/vmime/dateTime.cpp index eca8e785..eca8e785 100644 --- a/src/dateTime.cpp +++ b/src/vmime/dateTime.cpp diff --git a/src/vmime/dateTime.hpp b/src/vmime/dateTime.hpp new file mode 100644 index 00000000..7af63040 --- /dev/null +++ b/src/vmime/dateTime.hpp @@ -0,0 +1,263 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_DATETIME_HPP_INCLUDED +#define VMIME_DATETIME_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + +#include <ctime> + + +namespace vmime +{ + + +/** Date and time (basic type). + */ + +class VMIME_EXPORT datetime : public headerFieldValue +{ +public: + + // Constructors + datetime(); + datetime(const int year, const int month, const int day); + datetime(const int year, const int month, const int day, const int hour, const int minute, const int second, const int zone = GMT); + datetime(const datetime& d); + datetime(const string& date); + datetime(const time_t t, const int zone = GMT); + + // Destructor + ~datetime(); + + // Some time zones (in minutes) + enum TimeZones + { + GMT_12 = -720, // GMT-12h + GMT_11 = -660, // GMT-11h + GMT_10 = -600, // GMT-10h + GMT_9 = -540, // GMT-9h + GMT_8 = -480, // GMT-8h + GMT_7 = -420, // GMT-7h + GMT_6 = -360, // GMT-6h + GMT_5 = -300, // GMT-5h + GMT_4 = -240, // GMT-4h + GMT_3 = -180, // GMT-3h + GMT_2 = -120, // GMT-2h + GMT_1 = -60, // GMT-1h + GMT = 0, // GMT + GMT1 = 60, // GMT+1h + GMT2 = 120, // GMT+2h + GMT3 = 180, // GMT+3h + GMT4 = 240, // GMT+4h + GMT5 = 300, // GMT+5h + GMT6 = 360, // GMT+6h + GMT7 = 420, // GMT+7h + GMT8 = 480, // GMT+8h + GMT9 = 540, // GMT+9h + GMT10 = 600, // GMT+10h + GMT11 = 660, // GMT+11h + GMT12 = 720, // GMT+12h + + UT = GMT, // Universal Time + + EST = GMT_5, // Eastern + EDT = GMT_4, + CST = GMT_6, // Central + CDT = GMT_5, + MST = GMT_7, // Mountain + MDT = GMT_6, + PST = GMT_8, // Pacific + PDT = GMT_7, + + // Military time zones + A = GMT_1, + B = GMT_2, + C = GMT_3, + D = GMT_4, + E = GMT_5, + F = GMT_6, + G = GMT_7, + H = GMT_8, + I = GMT_9, // J not used + K = GMT_10, + L = GMT_11, + M = GMT_12, + + N = GMT1, + O = GMT2, + P = GMT3, + Q = GMT4, + R = GMT5, + S = GMT6, + T = GMT7, + U = GMT8, + V = GMT9, + W = GMT10, + X = GMT11, + Y = GMT12, + + Z = GMT + }; + + // Months list + enum Months + { + // Long + JANUARY = 1, + FEBRUARY = 2, + MARCH = 3, + APRIL = 4, + MAY = 5, + JUNE = 6, + JULY = 7, + AUGUST = 8, + SEPTEMBER = 9, + OCTOBER = 10, + NOVEMBER = 11, + DECEMBER = 12, + + // Short + JAN = 1, + FEB = 2, + MAR = 3, + APR = 4, + JUN = 6, + JUL = 7, + AUG = 8, + SEP = 9, + OCT = 10, + NOV = 11, + DEC = 12 + }; + + // Days of week list + enum DaysOfWeek + { + // Long + SUNDAY = 0, + MONDAY = 1, + TUESDAY = 2, + WEDNESDAY = 3, + THURSDAY = 4, + FRIDAY = 5, + SATURDAY = 6, + + // Short + SUN = 0, + MON = 1, + TUE = 2, + WED = 3, + THU = 4, + FRI = 5, + SAT = 6 + }; + +private: + + // Date components + int m_year; + int m_month; + int m_day; + + // Time components + int m_hour; + int m_minute; + int m_second; + int m_zone; + +public: + + // Get + int getYear() const; + int getMonth() const; + int getDay() const; + int getHour() const; + int getMinute() const; + int getSecond() const; + int getZone() const; + int getWeekDay() const; + int getWeek() const; + + void getTime(int& hour, int& minute, int& second, int& zone) const; + void getTime(int& hour, int& minute, int& second) const; + void getDate(int& year, int& month, int& day) const; + + // Set + void setYear(const int year); + void setMonth(const int month); + void setDay(const int day); + void setHour(const int hour); + void setMinute(const int minute); + void setSecond(const int second); + void setZone(const int zone); + + void setTime(const int hour = 0, const int minute = 0, const int second = 0, const int zone = GMT); + void setDate(const int year, const int month, const int day); + + // Assignment + datetime& operator=(const datetime& other); + datetime& operator=(const string& s); + + void copyFrom(const component& other); + + shared_ptr <component> clone() const; + + // Comparison + bool operator==(const datetime& other) const; + bool operator!=(const datetime& other) const; + bool operator<(const datetime& other) const; + bool operator<=(const datetime& other) const; + bool operator>(const datetime& other) const; + bool operator>=(const datetime& other) const; + + // Current date and time + static const datetime now(); + + const std::vector <shared_ptr <component> > getChildComponents(); + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_DATETIME_HPP_INCLUDED diff --git a/src/defaultAttachment.cpp b/src/vmime/defaultAttachment.cpp index 8f8ad453..8f8ad453 100644 --- a/src/defaultAttachment.cpp +++ b/src/vmime/defaultAttachment.cpp diff --git a/src/vmime/defaultAttachment.hpp b/src/vmime/defaultAttachment.hpp new file mode 100644 index 00000000..6eb0c5b6 --- /dev/null +++ b/src/vmime/defaultAttachment.hpp @@ -0,0 +1,88 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_DEFAULTATTACHMENT_HPP_INCLUDED +#define VMIME_DEFAULTATTACHMENT_HPP_INCLUDED + + +#include "vmime/attachment.hpp" +#include "vmime/encoding.hpp" + + +namespace vmime +{ + + +/** Default implementation for attachments. + */ + +class VMIME_EXPORT defaultAttachment : public attachment +{ +protected: + + // For use in derived classes. + defaultAttachment(); + +public: + + defaultAttachment(shared_ptr <const contentHandler> data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); + defaultAttachment(shared_ptr <const contentHandler> data, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD); + defaultAttachment(const defaultAttachment& attach); + + ~defaultAttachment(); + + defaultAttachment& operator=(const defaultAttachment& attach); + + const mediaType getType() const; + const text getDescription() const; + const word getName() const; + const shared_ptr <const contentHandler> getData() const; + const encoding getEncoding() const; + + shared_ptr <const object> getPart() const; + + shared_ptr <const header> getHeader() const; + +protected: + + mediaType m_type; /**< Media type (eg. "application/octet-stream") */ + text m_desc; /**< Description (eg. "The image you requested") */ + shared_ptr <const contentHandler> m_data; /**< Attachment data (eg. the file contents) */ + encoding m_encoding; /**< Encoding */ + word m_name; /**< Name/filename (eg. "sunset.jpg") */ + +private: + + // No need to override "generateIn", use "generatePart" instead (see below). + void generateIn(shared_ptr <bodyPart> parent) const; + +protected: + + virtual void generatePart(shared_ptr <bodyPart> part) const; +}; + + +} // vmime + + +#endif // VMIME_DEFAULTATTACHMENT_HPP_INCLUDED diff --git a/src/disposition.cpp b/src/vmime/disposition.cpp index 352d3251..352d3251 100644 --- a/src/disposition.cpp +++ b/src/vmime/disposition.cpp diff --git a/src/vmime/disposition.hpp b/src/vmime/disposition.hpp new file mode 100644 index 00000000..7322c21d --- /dev/null +++ b/src/vmime/disposition.hpp @@ -0,0 +1,159 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_DISPOSITION_HPP_INCLUDED +#define VMIME_DISPOSITION_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + +#include <vector> + + +namespace vmime +{ + + +/** Disposition - from RFC-3798 (basic type). + */ + +class VMIME_EXPORT disposition : public headerFieldValue +{ +public: + + disposition(); + disposition(const string& actionMode, const string& sendingMode, const string& type, const string& modifier); + + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + disposition& operator=(const disposition& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + + /** Set the disposition action mode. + * See the constants in vmime::dispositionActionModes. + * + * @param mode disposition action mode + */ + void setActionMode(const string& mode); + + /** Return the disposition action mode. + * See the constants in vmime::dispositionActionModes. + * + * @return disposition action mode + */ + const string& getActionMode() const; + + /** Set the disposition sending mode. + * See the constants in vmime::dispositionSendingModes. + * + * @param mode disposition sending mode + */ + void setSendingMode(const string& mode); + + /** Return the disposition sending mode. + * See the constants in vmime::dispositionSendingModes. + * + * @return disposition sending mode + */ + const string& getSendingMode() const; + + /** Set the disposition type. + * See the constants in vmime::dispositionTypes. + * + * @param type disposition type + */ + void setType(const string& type); + + /** Return the disposition type. + * See the constants in vmime::dispositionTypes. + * + * @return disposition type + */ + const string& getType() const; + + /** Add a disposition modifier if it does not exist. + * See the constants in vmime::dispositionModifiers. + * + * @param modifier modifier to add + */ + void addModifier(const string& modifier); + + /** Remove the specified disposition modifier. + * See the constants in vmime::dispositionModifiers. + * + * @param modifier modifier to remove + */ + void removeModifier(const string& modifier); + + /** Remove all disposition modifiers. + */ + void removeAllModifiers(); + + /** Test whether a disposition modifier is set. + * + * @param modifier modifier to test + * @return true if the specified modifier is set, false otherwise + */ + bool hasModifier(const string& modifier) const; + + /** Return the list of modifiers. + * + * @return list of modifiers + */ + const std::vector <string> getModifierList() const; + +private: + + string m_actionMode; + string m_sendingMode; + string m_type; + + std::vector <string> m_modifiers; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_DISPOSITION_HPP_INCLUDED + diff --git a/src/emailAddress.cpp b/src/vmime/emailAddress.cpp index e185b17b..e185b17b 100644 --- a/src/emailAddress.cpp +++ b/src/vmime/emailAddress.cpp diff --git a/src/vmime/emailAddress.hpp b/src/vmime/emailAddress.hpp new file mode 100644 index 00000000..30ee24ab --- /dev/null +++ b/src/vmime/emailAddress.hpp @@ -0,0 +1,135 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_EMAILADDRESS_HPP_INCLUDED +#define VMIME_EMAILADDRESS_HPP_INCLUDED + + +#include "vmime/component.hpp" +#include "vmime/text.hpp" + + +namespace vmime +{ + + +/** An email address: local name and domain name (basic type). + */ + +class VMIME_EXPORT emailAddress : public component +{ +public: + + emailAddress(); + emailAddress(const emailAddress& eml); + emailAddress(const string& email); + emailAddress(const char* email); + emailAddress(const string& localName, const string& domainName); + emailAddress(const word& localName, const word& domainName); + + /** Return the local name of the address. + * + * @return local name of the address + */ + const word& getLocalName() const; + + /** Set the local name of the address. + * + * @param localName local name of the address + */ + void setLocalName(const word& localName); + + /** Return the domain name of the address. + * + * @return domain name of the address + */ + const word& getDomainName() const; + + /** Set the domain name of the address. + * + * @param domainName domain name of the address + */ + void setDomainName(const word& domainName); + + /** Returns whether this email address is empty. + * Address is considered as empty if the local part is not specified. + * + * @return true if the address is empty, false otherwise + */ + bool isEmpty() const; + + /** Returns the email address as a string, by joining components. + * (ie. the local name, followed by a @ then the domain name.) + * + * @return email address as a string + */ + const string toString() const; + + /** Returns the email address as multibyte text, by joining components. + * (ie. the local name, followed by a @ then the domain name.) + * + * @return email address as multibyte text + */ + const text toText() const; + + // Comparison + bool operator==(const class emailAddress& eml) const; + bool operator!=(const class emailAddress& eml) const; + + // Assignment + void copyFrom(const component& other); + shared_ptr <component> clone() const; + emailAddress& operator=(const emailAddress& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + +protected: + + word m_localName; + word m_domainName; + +public: + + using component::parse; + using component::generate; + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_EMAILADDRESS_HPP_INCLUDED diff --git a/src/emptyContentHandler.cpp b/src/vmime/emptyContentHandler.cpp index e0f191f3..e0f191f3 100644 --- a/src/emptyContentHandler.cpp +++ b/src/vmime/emptyContentHandler.cpp diff --git a/src/vmime/emptyContentHandler.hpp b/src/vmime/emptyContentHandler.hpp new file mode 100644 index 00000000..369a4206 --- /dev/null +++ b/src/vmime/emptyContentHandler.hpp @@ -0,0 +1,70 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_EMPTYCONTENTHANDLER_HPP_INCLUDED +#define VMIME_EMPTYCONTENTHANDLER_HPP_INCLUDED + + +#include "vmime/contentHandler.hpp" + + +namespace vmime +{ + + +class VMIME_EXPORT emptyContentHandler : public contentHandler +{ +public: + + emptyContentHandler(); + + shared_ptr <contentHandler> clone() const; + + void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + + void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; + + size_t getLength() const; + + bool isEncoded() const; + + const vmime::encoding& getEncoding() const; + + bool isEmpty() const; + + bool isBuffered() const; + + void setContentTypeHint(const mediaType& type); + const mediaType getContentTypeHint() const; + +private: + + mediaType m_contentType; +}; + + +} // vmime + + +#endif // VMIME_EMPTYCONTENTHANDLER_HPP_INCLUDED diff --git a/src/encoding.cpp b/src/vmime/encoding.cpp index 26922395..26922395 100644 --- a/src/encoding.cpp +++ b/src/vmime/encoding.cpp diff --git a/src/vmime/encoding.hpp b/src/vmime/encoding.hpp new file mode 100644 index 00000000..3148f899 --- /dev/null +++ b/src/vmime/encoding.hpp @@ -0,0 +1,172 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_ENCODING_HPP_INCLUDED +#define VMIME_ENCODING_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime +{ + + +class contentHandler; + + +/** Content encoding (basic type). + */ + +class VMIME_EXPORT encoding : public headerFieldValue +{ +public: + + enum EncodingUsage + { + USAGE_UNKNOWN, + USAGE_TEXT, /**< Use for body text. */ + USAGE_BINARY_DATA /**< Use for attachment, image... */ + }; + + + encoding(); + explicit encoding(const string& name); + encoding(const string& name, const EncodingUsage usage); + encoding(const encoding& enc); + +public: + + /** Return the name of the encoding. + * See the constants in vmime::encodingTypes. + * + * @return name of the encoding (eg. "quoted-printable") + */ + const string& getName() const; + + /** Set the name of the encoding. + * See the constants in vmime::encodingTypes. + * + * @param name name of the encoding + */ + void setName(const string& name); + + /** Return the type of contents this encoding is used for. + * See the EncodingUsage enum. + */ + EncodingUsage getUsage() const; + + /** Set the type of contents this encoding is used for. + * See the EncodingUsage enum. + * + * @param usage type of contents + */ + void setUsage(const EncodingUsage usage); + + + encoding& operator=(const encoding& other); + encoding& operator=(const string& name); + + bool operator==(const encoding& value) const; + bool operator!=(const encoding& value) const; + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Decide which encoding to use based on the specified data. + * + * @param data data used to determine encoding + * @param usage context of use of data + * @return suitable encoding for specified data + */ + static const encoding decide(shared_ptr <const contentHandler> data, const EncodingUsage usage = USAGE_BINARY_DATA); + + /** Decide which encoding to use based on the specified data and charset. + * + * @param data data used to determine encoding + * @param chset charset of data + * @param usage context of use of data + * @return suitable encoding for specified data and charset + */ + static const encoding decide(shared_ptr <const contentHandler> data, const charset& chset, const EncodingUsage usage = USAGE_BINARY_DATA); + + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + + /** Use encoderFactory to obtain an encoder/decoder object + * for the current encoding type. + * + * @throw exceptions::no_encoder_available if no encoder + * is registered for the encoding + * @return a new encoder object for the encoding type + */ + shared_ptr <utility::encoder::encoder> getEncoder() const; + +private: + + string m_name; + EncodingUsage m_usage; + + /** Determine whether data encoded using this encoding should + * be re-encoded if needed. + * + * @return true if data should be re-encoded, false otherwise + */ + bool shouldReencode() const; + + /** Decide which encoding to use based on the specified data. + * + * Please note: this will read the whole buffer, so it should be used only + * for small amount of data (eg. text), and not large binary attachments. + * + * @param begin start iterator in buffer + * @param end end iterator in buffer + * @return suitable encoding for specified data + */ + static const encoding decideImpl(const string::const_iterator begin, const string::const_iterator end); + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_ENCODING_HPP_INCLUDED diff --git a/src/exception.cpp b/src/vmime/exception.cpp index 042ac4f4..042ac4f4 100644 --- a/src/exception.cpp +++ b/src/vmime/exception.cpp diff --git a/src/vmime/exception.hpp b/src/vmime/exception.hpp new file mode 100644 index 00000000..e2afcc62 --- /dev/null +++ b/src/vmime/exception.hpp @@ -0,0 +1,906 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_EXCEPTION_HPP_INCLUDED +#define VMIME_EXCEPTION_HPP_INCLUDED + + +#include <stdexcept> + +#include "vmime/config.hpp" +#include "vmime/base.hpp" +#include "vmime/utility/path.hpp" + + +namespace vmime +{ + + +/** Base class for VMime exceptions. + */ + +class VMIME_EXPORT exception : public std::exception +{ +private: + + string m_what; + exception* m_other; + + exception(); + +public: + + exception(const string& what, const exception& other = NO_EXCEPTION); + exception(const exception& e); + + virtual ~exception() throw(); + + /** Return a description of the error. + * + * @return error message + */ + const char* what() const throw(); + + /** Return a description of the error. + * + * @return error message + */ + const char* what() throw(); + + /** Return the next exception in the chain (encapsulated exception). + * + * @return next exception in the chain + */ + const exception* other() const throw(); + + /** Return a name identifying the exception. + * + * @return exception name + */ + virtual const char* name() const throw(); + + /** Clone this object. + * + * @return a new copy of this object + */ + virtual exception* clone() const; + +protected: + + static const exception NO_EXCEPTION; +}; + + + +/** List of all VMime exceptions. */ + +namespace exceptions +{ + + +class VMIME_EXPORT bad_field_value_type : public vmime::exception +{ +public: + + bad_field_value_type(const string& fieldName, const exception& other = NO_EXCEPTION); + ~bad_field_value_type() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT charset_conv_error : public vmime::exception +{ +public: + + charset_conv_error(const string& what = "", const exception& other = NO_EXCEPTION); + ~charset_conv_error() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** No encoder has been found for the specified encoding name. + */ + +class VMIME_EXPORT no_encoder_available : public vmime::exception +{ +public: + + no_encoder_available(const string& name, const exception& other = NO_EXCEPTION); + ~no_encoder_available() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** No algorithm has been found for the specified name. + */ + +class VMIME_EXPORT no_digest_algorithm_available : public vmime::exception +{ +public: + + no_digest_algorithm_available(const string& name, const exception& other = NO_EXCEPTION); + ~no_digest_algorithm_available() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT no_such_field : public vmime::exception +{ +public: + + no_such_field(const exception& other = NO_EXCEPTION); + ~no_such_field() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT no_such_part : public vmime::exception +{ +public: + + no_such_part(const exception& other = NO_EXCEPTION); + ~no_such_part() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT no_such_message_id : public vmime::exception +{ +public: + + no_such_message_id(const exception& other = NO_EXCEPTION); + ~no_such_message_id() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT open_file_error : public vmime::exception +{ +public: + + open_file_error(const exception& other = NO_EXCEPTION); + ~open_file_error() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT no_factory_available : public vmime::exception +{ +public: + + no_factory_available(const exception& other = NO_EXCEPTION); + ~no_factory_available() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT no_platform_handler : public vmime::exception +{ +public: + + no_platform_handler(const exception& other = NO_EXCEPTION); + ~no_platform_handler() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** No expeditor specified. + */ + +class VMIME_EXPORT no_expeditor : public vmime::exception +{ +public: + + no_expeditor(const exception& other = NO_EXCEPTION); + ~no_expeditor() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** No recipient specified. + */ + +class VMIME_EXPORT no_recipient : public vmime::exception +{ +public: + + no_recipient(const exception& other = NO_EXCEPTION); + ~no_recipient() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** There is no property with that name in the set. + */ + +class VMIME_EXPORT no_such_property : public vmime::exception +{ +public: + + no_such_property(const string& name, const exception& other = NO_EXCEPTION); + ~no_such_property() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Bad type specified when reading property. + */ + +class VMIME_EXPORT invalid_property_type : public vmime::exception +{ +public: + + invalid_property_type(const exception& other = NO_EXCEPTION); + ~invalid_property_type() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Bad argument was passed to the function. + */ + +class VMIME_EXPORT invalid_argument : public vmime::exception +{ +public: + + invalid_argument(const exception& other = NO_EXCEPTION); + ~invalid_argument() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Underlying operating system error. + */ + +class VMIME_EXPORT system_error : public vmime::exception +{ +public: + + system_error(const string& what, const exception& other = NO_EXCEPTION); + ~system_error() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** The URL is malformed. + */ + +class VMIME_EXPORT malformed_url : public vmime::exception +{ +public: + + malformed_url(const string& error, const exception& other = NO_EXCEPTION); + ~malformed_url() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +/** Base class for exceptions thrown by the networking module. + */ + +class VMIME_EXPORT net_exception : public vmime::exception +{ +public: + + net_exception(const string& what, const exception& other = NO_EXCEPTION); + ~net_exception() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Alias for 'net_exception' (compatibility with version <= 0.7.1); + * this is deprecated. + */ +typedef net_exception messaging_exception; + + +/** Socket error. + */ + +class VMIME_EXPORT socket_exception : public net_exception +{ +public: + + socket_exception(const string& what = "", const exception& other = NO_EXCEPTION); + ~socket_exception() throw(); + + exception* clone() const; + const char* name() const throw(); + +}; + + +/** Error while connecting to the server: this may be a DNS resolution error + * or a connection error (for example, time-out while connecting). + */ + +class VMIME_EXPORT connection_error : public socket_exception +{ +public: + + connection_error(const string& what = "", const exception& other = NO_EXCEPTION); + ~connection_error() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Server did not initiated the connection correctly. + */ + +class VMIME_EXPORT connection_greeting_error : public net_exception +{ +public: + + connection_greeting_error(const string& response, const exception& other = NO_EXCEPTION); + ~connection_greeting_error() throw(); + + const string& response() const; + + exception* clone() const; + const char* name() const throw(); + +private: + + string m_response; +}; + + +/** Error while giving credentials to the server (wrong username + * or password, or wrong authentication method). + */ + +class VMIME_EXPORT authentication_error : public net_exception +{ +public: + + authentication_error(const string& response, const exception& other = NO_EXCEPTION); + ~authentication_error() throw(); + + const string& response() const; + + exception* clone() const; + const char* name() const throw(); + +private: + + string m_response; +}; + + +/** Option not supported. + */ + +class VMIME_EXPORT unsupported_option : public net_exception +{ +public: + + unsupported_option(const exception& other = NO_EXCEPTION); + ~unsupported_option() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** The current state of the object does not permit to execute the + * operation (for example, you try to close a folder which is not open). + */ + +class VMIME_EXPORT illegal_state : public net_exception +{ +public: + + illegal_state(const string& state, const exception& other = NO_EXCEPTION); + ~illegal_state() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Folder not found (does not exist). + */ + +class VMIME_EXPORT folder_not_found : public net_exception +{ +public: + + folder_not_found(const exception& other = NO_EXCEPTION); + ~folder_not_found() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Folder is already open in the same session. + */ + +class VMIME_EXPORT folder_already_open : public net_exception +{ +public: + + folder_already_open(const exception& other = NO_EXCEPTION); + ~folder_already_open() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Message not found (does not exist). + */ + +class VMIME_EXPORT message_not_found : public net_exception +{ +public: + + message_not_found(const exception& other = NO_EXCEPTION); + ~message_not_found() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Operation not supported by the underlying protocol. + */ + +class VMIME_EXPORT operation_not_supported : public net_exception +{ +public: + + operation_not_supported(const exception& other = NO_EXCEPTION); + ~operation_not_supported() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** The operation timed out (time-out delay is elapsed). + */ + +class VMIME_EXPORT operation_timed_out : public net_exception +{ +public: + + operation_timed_out(const exception& other = NO_EXCEPTION); + ~operation_timed_out() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** The operation has been cancelled. + */ + +class VMIME_EXPORT operation_cancelled : public net_exception +{ +public: + + operation_cancelled(const exception& other = NO_EXCEPTION); + ~operation_cancelled() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Must call fetchMessage() or fetchHeader() before accessing + * the requested object. + */ + +class VMIME_EXPORT unfetched_object : public net_exception +{ +public: + + unfetched_object(const exception& other = NO_EXCEPTION); + ~unfetched_object() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** The service is not currently connected. + */ + +class VMIME_EXPORT not_connected : public net_exception +{ +public: + + not_connected(const exception& other = NO_EXCEPTION); + ~not_connected() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** The service is already connected (must disconnect before). + */ + +class VMIME_EXPORT already_connected : public net_exception +{ +public: + + already_connected(const exception& other = NO_EXCEPTION); + ~already_connected() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Illegal operation: cannot run this operation on the object. + */ + +class VMIME_EXPORT illegal_operation : public net_exception +{ +public: + + illegal_operation(const string& msg = "", const exception& other = NO_EXCEPTION); + ~illegal_operation() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Command error: operation failed (this is specific to the underlying protocol). + */ + +class VMIME_EXPORT command_error : public net_exception +{ +public: + + command_error(const string& command, const string& response, const string& desc = "", const exception& other = NO_EXCEPTION); + ~command_error() throw(); + + /** Return the name of the command which have thrown the exception. + * This is protocol-dependent. + * + * @return command name (protocol-dependent) + */ + const string& command() const; + + /** Return the invalid response line. + * The meaning is protocol-dependent. + * + * @return response line (protocol-dependent) + */ + const string& response() const; + + exception* clone() const; + const char* name() const throw(); + +private: + + string m_command; + string m_response; +}; + + +/** The server returned an invalid response. + */ + +class VMIME_EXPORT invalid_response : public net_exception +{ +public: + + invalid_response(const string& command, const string& response, const exception& other = NO_EXCEPTION); + ~invalid_response() throw(); + + /** Return the name of the command which have thrown the exception. + * This is protocol-dependent. + * + * @return command name (protocol-dependent) + */ + const string& command() const; + + /** Return the invalid response line. + * The meaning is protocol-dependent. + * + * @return response line (protocol-dependent) + */ + const string& response() const; + + exception* clone() const; + const char* name() const throw(); + +private: + + string m_command; + string m_response; +}; + + +/** Partial fetch is not supported by the underlying protocol. + */ + +class VMIME_EXPORT partial_fetch_not_supported : public net_exception +{ +public: + + partial_fetch_not_supported(const exception& other = NO_EXCEPTION); + ~partial_fetch_not_supported() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** Folder name is invalid. + */ + +class VMIME_EXPORT invalid_folder_name : public net_exception +{ +public: + + invalid_folder_name(const string& error = "", const exception& other = NO_EXCEPTION); + ~invalid_folder_name() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#if VMIME_HAVE_FILESYSTEM_FEATURES + + +/** Base class for exceptions thrown by the filesystem features. + */ + +class VMIME_EXPORT filesystem_exception : public vmime::exception +{ +public: + + filesystem_exception(const string& what, const utility::path& path, const exception& other = NO_EXCEPTION); + ~filesystem_exception() throw(); + + /** Return the full path of the file have thrown the exception. + * + * @return full path of the file/directory + */ + const utility::path& path() const; + + exception* clone() const; + const char* name() const throw(); + +private: + + const utility::path m_path; +}; + + +/** File is not a directory. + */ + +class VMIME_EXPORT not_a_directory : public filesystem_exception +{ +public: + + not_a_directory(const utility::path& path, const exception& other = NO_EXCEPTION); + ~not_a_directory() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** File not found. + */ + +class VMIME_EXPORT file_not_found : public filesystem_exception +{ +public: + + file_not_found(const utility::path& path, const exception& other = NO_EXCEPTION); + ~file_not_found() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +#endif // VMIME_HAVE_FILESYSTEM_FEATURES + + +/** Authentication exception. + */ + +class VMIME_EXPORT authentication_exception : public vmime::exception +{ +public: + + authentication_exception(const string& what, const exception& other = NO_EXCEPTION); + ~authentication_exception() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** The requested information cannot be provided. + */ + +class VMIME_EXPORT no_auth_information : public authentication_exception +{ +public: + + no_auth_information(const exception& other = NO_EXCEPTION); + ~no_auth_information() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +#if VMIME_HAVE_SASL_SUPPORT + + +/** Base class for exceptions thrown by SASL module. + */ + +class VMIME_EXPORT sasl_exception : public authentication_exception +{ +public: + + sasl_exception(const string& what, const exception& other = NO_EXCEPTION); + ~sasl_exception() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** No mechanism is registered with the specified name. + */ + +class VMIME_EXPORT no_such_mechanism : public sasl_exception +{ +public: + + no_such_mechanism(const string& name, const exception& other = NO_EXCEPTION); + ~no_such_mechanism() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +#endif // VMIME_HAVE_SASL_SUPPORT + + +#if VMIME_HAVE_TLS_SUPPORT + + +/** Base class for exceptions thrown by TLS module. + */ + +class VMIME_EXPORT tls_exception : public vmime::exception +{ +public: + + tls_exception(const string& what, const exception& other = NO_EXCEPTION); + ~tls_exception() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT certificate_exception : public tls_exception +{ +public: + + certificate_exception(const string& what, const exception& other = NO_EXCEPTION); + ~certificate_exception() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +class VMIME_EXPORT certificate_verification_exception : public certificate_exception +{ +public: + + certificate_verification_exception(const string& what, const exception& other = NO_EXCEPTION); + ~certificate_verification_exception() throw (); + + exception* clone() const; + const char* name() const throw (); +}; + + +class VMIME_EXPORT unsupported_certificate_type : public certificate_exception +{ +public: + + unsupported_certificate_type(const string& type, const exception& other = NO_EXCEPTION); + ~unsupported_certificate_type() throw (); + + exception* clone() const; + const char* name() const throw (); +}; + + +#endif // VMIME_HAVE_TLS_SUPPORT + + + +} // exceptions + + +} // vmime + + +#endif // VMIME_EXCEPTION_HPP_INCLUDED diff --git a/src/vmime/export.hpp b/src/vmime/export.hpp new file mode 100644 index 00000000..90f0cc3a --- /dev/null +++ b/src/vmime/export.hpp @@ -0,0 +1,36 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_EXPORT_HPP_INCLUDED +#define VMIME_EXPORT_HPP_INCLUDED + + +// Define VMIME_STATIC if you are linking with the static library +#ifdef VMIME_STATIC +# include "vmime/export-static.hpp" +#else +# include "vmime/export-shared.hpp" +#endif + + +#endif // VMIME_EXPORT_HPP_INCLUDED diff --git a/src/fileAttachment.cpp b/src/vmime/fileAttachment.cpp index 25a97fcc..25a97fcc 100644 --- a/src/fileAttachment.cpp +++ b/src/vmime/fileAttachment.cpp diff --git a/src/vmime/fileAttachment.hpp b/src/vmime/fileAttachment.hpp new file mode 100644 index 00000000..1e7a808a --- /dev/null +++ b/src/vmime/fileAttachment.hpp @@ -0,0 +1,197 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_FILEATTACHMENT_HPP_INCLUDED +#define VMIME_FILEATTACHMENT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_FILESYSTEM_FEATURES + + +#include "vmime/defaultAttachment.hpp" +#include "vmime/dateTime.hpp" +#include "vmime/contentHandler.hpp" +#include "vmime/utility/stream.hpp" + + +namespace vmime +{ + + +/** Attachment of type 'file'. + */ + +class VMIME_EXPORT fileAttachment : public defaultAttachment +{ +public: + + fileAttachment(const string& filepath, const mediaType& type); + fileAttachment(const string& filepath, const mediaType& type, const text& desc); + fileAttachment(const string& filepath, const mediaType& type, const text& desc, const encoding& enc); + + fileAttachment(shared_ptr <contentHandler> cts, const word& filename, const mediaType& type); + fileAttachment(shared_ptr <contentHandler> cts, const word& filename, const mediaType& type, const text& desc); + fileAttachment(shared_ptr <contentHandler> cts, const word& filename, const mediaType& type, const text& desc, const encoding& enc); + + /** Stores information about a file attachment. + */ + class fileInfo + { + public: + + fileInfo(); + ~fileInfo(); + + /** Check whether the 'filename' property is present. + * + * @return true if the 'filename' property is set, + * false otherwise + */ + bool hasFilename() const; + + /** Return the value of the 'filename' property. + * + * @return file name + */ + const word& getFilename() const; + + /** Set the value of the 'filename' property. + * + * @param name file name + */ + void setFilename(const string& name); + + /** Set the value of the 'filename' property. + * + * @param name file name + */ + void setFilename(const word& name); + + /** Check whether the 'creation-date' property is present. + * + * @return true if the 'creation-date' property is set, + * false otherwise + */ + bool hasCreationDate() const; + + /** Return the value of the 'creation-date' property. + * + * @return file creation time + */ + const datetime& getCreationDate() const; + + /** Set the value of the 'creation-date' property. + * + * @param date file creation time + */ + void setCreationDate(const datetime& date); + + /** Check whether the 'modification-date' property is present. + * + * @return true if the 'modification-date' property is set, + * false otherwise + */ + bool hasModificationDate() const; + + /** Return the value of the 'modification-date' property. + * + * @return file modification time + */ + const datetime& getModificationDate() const; + + /** Set the value of the 'modification-date' property. + * + * @param date file modification time + */ + void setModificationDate(const datetime& date); + + /** Check whether the 'read-date' property is set. + * + * @return true if the 'read-date' property is set, + * false otherwise + */ + bool hasReadDate() const; + + /** Return the value of the 'read-date' property. + * + * @return file access time + */ + const datetime& getReadDate() const; + + /** Set the value of the 'read-date' property. + * + * @param date file access time + */ + void setReadDate(const datetime& date); + + /** Check whether the value of the 'size' property is set. + * + * @return true if the 'size' property is set, + * false otherwise + */ + bool hasSize() const; + + /** Return the value of the 'size' property. + * + * @return file size + */ + size_t getSize() const; + + /** Set the value of the 'size' property. + * + * @param size file size + */ + void setSize(const size_t size); + + private: + + word* m_filename; + size_t * m_size; + datetime* m_creationDate; + datetime* m_modifDate; + datetime* m_readDate; + }; + + const fileInfo& getFileInfo() const; + fileInfo& getFileInfo(); + +private: + + void setData(const string& filepath); + void setData(shared_ptr <contentHandler> cts); + + fileInfo m_fileInfo; + + void generatePart(shared_ptr <bodyPart> part) const; +}; + + +} // vmime + + +#endif // VMIME_HAVE_FILESYSTEM_FEATURES + +#endif // VMIME_FILEATTACHMENT_HPP_INCLUDED diff --git a/src/fileContentHandler.cpp b/src/vmime/fileContentHandler.cpp index 53ec9f69..53ec9f69 100644 --- a/src/fileContentHandler.cpp +++ b/src/vmime/fileContentHandler.cpp diff --git a/src/vmime/fileContentHandler.hpp b/src/vmime/fileContentHandler.hpp new file mode 100644 index 00000000..68b4d396 --- /dev/null +++ b/src/vmime/fileContentHandler.hpp @@ -0,0 +1,93 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_FILECONTENTHANDLER_HPP_INCLUDED +#define VMIME_FILECONTENTHANDLER_HPP_INCLUDED + + +#include "vmime/streamContentHandler.hpp" +#include "vmime/utility/file.hpp" + + +namespace vmime +{ + + +/** A content handler which obtains its data from a file. + */ + +class VMIME_EXPORT fileContentHandler : public streamContentHandler +{ +public: + + /** Creates a new empty content handler. No data can be extracted until + * a file is attached using setData() function. + * + * @return a reference to a new content handler + */ + fileContentHandler(); + + /** Creates a new content handler using a file. + * + * @param file file from which data will be obtained + * @param enc set to anything other than NO_ENCODING if the data contained + * in the file is already encoded with the specified encoding + * + * @return a reference to a new content handler + */ + fileContentHandler + (shared_ptr <utility::file> file, + const vmime::encoding& enc = NO_ENCODING); + + ~fileContentHandler(); + + fileContentHandler(const fileContentHandler& cts); + fileContentHandler& operator=(const fileContentHandler& cts); + + shared_ptr <contentHandler> clone() const; + + /** Sets the data managed by this content handler. + * + * @param file file from which data will be obtained + * @param enc set to anything other than NO_ENCODING if the data contained + * in the file is already encoded with the specified encoding + */ + void setData + (shared_ptr <utility::file> file, + const vmime::encoding& enc = NO_ENCODING); + +private: + + // Equals to NO_ENCODING if data is not encoded, otherwise this + // specifies the encoding that have been used to encode the data. + vmime::encoding m_encoding; + + // Actual data + shared_ptr <utility::file> m_file; +}; + + +} // vmime + + +#endif // VMIME_FILECONTENTHANDLER_HPP_INCLUDED diff --git a/src/generatedMessageAttachment.cpp b/src/vmime/generatedMessageAttachment.cpp index 0473d247..0473d247 100644 --- a/src/generatedMessageAttachment.cpp +++ b/src/vmime/generatedMessageAttachment.cpp diff --git a/src/vmime/generatedMessageAttachment.hpp b/src/vmime/generatedMessageAttachment.hpp new file mode 100644 index 00000000..7137b22b --- /dev/null +++ b/src/vmime/generatedMessageAttachment.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED +#define VMIME_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC // implementation detail + + +#include "vmime/messageAttachment.hpp" +#include "vmime/bodyPartAttachment.hpp" + + +namespace vmime +{ + + +/** A message attachment that can be extracted from a message. + */ +class VMIME_EXPORT generatedMessageAttachment : public messageAttachment +{ +public: + + generatedMessageAttachment(shared_ptr <const bodyPart> part); + + const mediaType getType() const; + const text getDescription() const; + const word getName() const; + + const shared_ptr <const contentHandler> getData() const; + + const encoding getEncoding() const; + + shared_ptr <const object> getPart() const; + + shared_ptr <const header> getHeader() const; + + shared_ptr <message> getMessage() const; + +protected: + + void generateIn(shared_ptr <bodyPart> parent) const; + +private: + + shared_ptr <bodyPartAttachment> m_bpa; + mutable shared_ptr <message> m_msg; +}; + + +} // vmime + + +#endif // !VMIME_BUILDING_DOC + + +#endif // VMIME_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED + diff --git a/src/generationContext.cpp b/src/vmime/generationContext.cpp index e9662883..e9662883 100644 --- a/src/generationContext.cpp +++ b/src/vmime/generationContext.cpp diff --git a/src/vmime/generationContext.hpp b/src/vmime/generationContext.hpp new file mode 100644 index 00000000..949f06ac --- /dev/null +++ b/src/vmime/generationContext.hpp @@ -0,0 +1,106 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_GENERATIONCONTEXT_HPP_INCLUDED +#define VMIME_GENERATIONCONTEXT_HPP_INCLUDED + + +#include "vmime/context.hpp" + + +namespace vmime +{ + + +/** Holds configuration parameters used for generating messages. + */ + +class VMIME_EXPORT generationContext : public context +{ +public: + + generationContext(); + generationContext(const generationContext& ctx); + + /** Returns the current maximum line length used when generating messages. + * + * @return current maximum line length, in bytes + */ + size_t getMaxLineLength() const; + + /** Sets the maximum line length used when generating messages. + * You may use the constants lineLengthLimits::convenient, + * lineLengthLimits::max and lineLengthLimits::infinite. + * + * @param maxLineLength new maximum line length, in bytes + */ + void setMaxLineLength(const size_t maxLineLength); + + /** Returns the current prolog text used when generating MIME body parts. + * + * @return current MIME prolog text + */ + const string getPrologText() const; + + /** Sets the prolog text used when generating MIME body parts. This text + * appears before the part, and should be displayed by MUAs which do not + * support MIME. This should be 7-bit ASCII text only. + * + * @param prologText MIME prolog text + */ + void setPrologText(const string& prologText); + + /** Returns the current epilog text used when generating MIME body parts. + * + * @return current MIME epilog text + */ + const string getEpilogText() const; + + /** Sets the epilog text used when generating MIME body parts. This test + * appears after the part, and should be displayed by MUAs which do not + * support MIME. This should be 7-bit ASCII text only. + */ + void setEpilogText(const string& epilogText); + + /** Returns the default context used for generating messages. + * + * @return a reference to the default generation context + */ + static generationContext& getDefaultContext(); + + generationContext& operator=(const generationContext& ctx); + void copyFrom(const generationContext& ctx); + +protected: + + size_t m_maxLineLength; + + string m_prologText; + string m_epilogText; +}; + + +} // vmime + + +#endif // VMIME_GENERATIONCONTEXT_HPP_INCLUDED diff --git a/src/header.cpp b/src/vmime/header.cpp index 34b5fa6e..34b5fa6e 100644 --- a/src/header.cpp +++ b/src/vmime/header.cpp diff --git a/src/vmime/header.hpp b/src/vmime/header.hpp new file mode 100644 index 00000000..d2d20727 --- /dev/null +++ b/src/vmime/header.hpp @@ -0,0 +1,346 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_HEADER_HPP_INCLUDED +#define VMIME_HEADER_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/component.hpp" +#include "vmime/exception.hpp" + +#include "vmime/headerField.hpp" +#include "vmime/headerFieldFactory.hpp" + + +namespace vmime +{ + + +class bodyPart; + + +/** Header section of a MIME part. + */ + +class VMIME_EXPORT header : public component +{ + friend class bodyPart; + friend class body; + friend class message; + +public: + + header(); + ~header(); + +#define FIELD_ACCESS(methodName, fieldName) \ + shared_ptr <headerField> methodName() { return getField(fields::fieldName); } \ + shared_ptr <const headerField> methodName() const { return findField(fields::fieldName); } + + FIELD_ACCESS(From, FROM) + FIELD_ACCESS(Sender, SENDER) + FIELD_ACCESS(ReplyTo, REPLY_TO) + FIELD_ACCESS(DeliveredTo, DELIVERED_TO) + FIELD_ACCESS(InReplyTo, IN_REPLY_TO) + FIELD_ACCESS(ReturnPath, RETURN_PATH) + FIELD_ACCESS(References, REFERENCES) + + FIELD_ACCESS(To, TO) + FIELD_ACCESS(Cc, CC) + FIELD_ACCESS(Bcc, BCC) + FIELD_ACCESS(Date, DATE) + FIELD_ACCESS(Subject, SUBJECT) + FIELD_ACCESS(Organization, ORGANIZATION) + FIELD_ACCESS(UserAgent, USER_AGENT) + + FIELD_ACCESS(ContentType, CONTENT_TYPE) + FIELD_ACCESS(ContentDescription, CONTENT_DESCRIPTION) + FIELD_ACCESS(ContentTransferEncoding, CONTENT_TRANSFER_ENCODING) + FIELD_ACCESS(MimeVersion, MIME_VERSION) + FIELD_ACCESS(ContentDisposition, CONTENT_DISPOSITION) + FIELD_ACCESS(ContentId, CONTENT_ID) + FIELD_ACCESS(MessageId, MESSAGE_ID) + FIELD_ACCESS(ContentLocation, CONTENT_LOCATION) + + FIELD_ACCESS(OriginalMessageId, ORIGINAL_MESSAGE_ID) + FIELD_ACCESS(Disposition, DISPOSITION) + FIELD_ACCESS(DispositionNotificationTo, DISPOSITION_NOTIFICATION_TO) + +#undef FIELD_ACCESS + + /** Checks whether (at least) one field with this name exists. + * Field name is case-insensitive. + * + * @return true if at least one field with the specified name + * exists, or false otherwise + */ + bool hasField(const string& fieldName) const; + + /** Find the first field that matches the specified name. + * Field name is case-insensitive. + * If no field is found, NULL is returned. + * + * @param fieldName name of field to return (eg: "X-Mailer" or "From", + * common field names are available in the vmime::fields namespace) + * @return first field with the specified name, or NULL if no field + * with this name was found + */ + shared_ptr <headerField> findField(const string& fieldName) const; + + /** Find the first field that matches the specified name, + * casted to the specified field type. Field name is case-insensitive. + * If no field is found, or the field is not of the specified type, + * NULL is returned. + * + * @param fieldName name of field whose value is to be returned + * (eg: "X-Mailer" or "From", common field names are available in + * the vmime::fields namespace) + * @return first field with the specified name, or NULL if no field + * with this name was found + */ + template <typename T> + shared_ptr <T> findField(const string& fieldName) const + { + return dynamicCast <T>(findField(fieldName)); + } + + /** Find the value of the first field that matches the specified name, + * casted to the specified value type. Field name is case-insensitive. + * If no field is found, or the field value is not of the specified + * type, NULL is returned. + * + * @param fieldName name of field to return (eg: "X-Mailer" or "From", + * common field names are available in the vmime::fields namespace) + * @return value of the first field with the specified name, or NULL + * if no field with this name was found, or the value is not of the + * specified type + */ + template <typename T> + shared_ptr <T> findFieldValue(const string& fieldName) const + { + shared_ptr <headerField> field = findField(fieldName); + + if (field) + return dynamicCast <T>(field->getValue()); + else + return null; + } + + /** Find all fields that match the specified name. + * If no field is found, an empty vector is returned. + * + * @param fieldName name of field to return (eg: "X-Mailer" or "From", + * common field names are available in the vmime::fields namespace) + * @return list of fields with the specified name + */ + std::vector <shared_ptr <headerField> > findAllFields(const string& fieldName); + + /** Find the first field that matches the specified name. + * If no field is found, one will be created and inserted into + * the header. + * + * @param fieldName name of field to return (eg: "X-Mailer" or "From", + * common field names are available in the vmime::fields namespace) + * @return first field with the specified name or a new field + * if no field is found + */ + shared_ptr <headerField> getField(const string& fieldName); + + /** Find the first field that matches the specified name, + * casted to the specified type. + * If no field is found, one will be created and inserted into + * the header. + * + * @return first field with the specified name or a new field + * if no field is found + */ + template <typename T> + shared_ptr <T> getField(const string& fieldName) + { + return dynamicCast <T>(getField(fieldName)); + } + + /** Add a field at the end of the list. + * + * @param field field to append + */ + void appendField(shared_ptr <headerField> field); + + /** Insert a new field before the specified field. + * + * @param beforeField field before which the new field will be inserted + * @param field field to insert + * @throw exceptions::no_such_field if the field is not in the list + */ + void insertFieldBefore(shared_ptr <headerField> beforeField, shared_ptr <headerField> field); + + /** Insert a new field before the specified position. + * + * @param pos position at which to insert the new field (0 to insert at + * the beginning of the list) + * @param field field to insert + */ + void insertFieldBefore(const size_t pos, shared_ptr <headerField> field); + + /** Insert a new field after the specified field. + * + * @param afterField field after which the new field will be inserted + * @param field field to insert + * @throw exceptions::no_such_field if the field is not in the list + */ + void insertFieldAfter(shared_ptr <headerField> afterField, shared_ptr <headerField> field); + + /** Insert a new field after the specified position. + * + * @param pos position of the field before the new field + * @param field field to insert + */ + void insertFieldAfter(const size_t pos, shared_ptr <headerField> field); + + /** Remove the specified field from the list. + * + * @param field field to remove + * @throw exceptions::no_such_field if the field is not in the list + */ + void removeField(shared_ptr <headerField> field); + + /** Remove the field at the specified position. + * + * @param pos position of the field to remove + */ + void removeField(const size_t pos); + + /** Replaces a field with another field. + * + * @param field field to be replaced + * @param newField field to replace with + * @throw exceptions::no_such_field if the field is not in the list + */ + void replaceField(shared_ptr <headerField> field, shared_ptr <headerField> newField); + + /** Remove all fields from the list. + */ + void removeAllFields(); + + /** Remove all fields with the specified name. + */ + void removeAllFields(const string& fieldName); + + /** Return the number of fields in the list. + * + * @return number of fields + */ + size_t getFieldCount() const; + + /** Tests whether the list of fields is empty. + * + * @return true if there is no field, false otherwise + */ + bool isEmpty() const; + + /** Return the field at the specified position. + * + * @param pos position + * @return field at position 'pos' + */ + const shared_ptr <headerField> getFieldAt(const size_t pos); + + /** Return the field at the specified position. + * + * @param pos position + * @return field at position 'pos' + */ + const shared_ptr <const headerField> getFieldAt(const size_t pos) const; + + /** Return the field list. + * + * @return list of fields + */ + const std::vector <shared_ptr <const headerField> > getFieldList() const; + + /** Return the field list. + * + * @return list of fields + */ + const std::vector <shared_ptr <headerField> > getFieldList(); + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + header& operator=(const header& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + size_t getGeneratedSize(const generationContext& ctx); + +private: + + std::vector <shared_ptr <headerField> > m_fields; + + + class fieldHasName + { + public: + + fieldHasName(const string& name); + bool operator() (const shared_ptr <const headerField>& field); + + private: + + string m_name; + }; + + class fieldHasNotName + { + public: + + fieldHasNotName(const string& name); + bool operator() (const shared_ptr <const headerField>& field); + + private: + + string m_name; + }; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_HEADER_HPP_INCLUDED diff --git a/src/headerField.cpp b/src/vmime/headerField.cpp index f4c6187e..f4c6187e 100644 --- a/src/headerField.cpp +++ b/src/vmime/headerField.cpp diff --git a/src/vmime/headerField.hpp b/src/vmime/headerField.hpp new file mode 100644 index 00000000..555805db --- /dev/null +++ b/src/vmime/headerField.hpp @@ -0,0 +1,190 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_HEADERFIELD_HPP_INCLUDED +#define VMIME_HEADERFIELD_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/component.hpp" +#include "vmime/headerFieldValue.hpp" + + +namespace vmime +{ + + +/** Base class for header fields. + */ + +class VMIME_EXPORT headerField : public component +{ + friend class headerFieldFactory; + friend class header; + +protected: + + // Protected constructor to prevent the user from creating + // new objects without using 'headerFieldFactory' + headerField(); + headerField(const string& fieldName); + +public: + + ~headerField(); + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + headerField& operator=(const headerField& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Sets the name of this field. + * + * @param name field name (eg: "From" or "X-MyField"). + */ + void setName(const string& name); + + /** Return the name of this field. + * + * @return field name + */ + const string getName() const; + + /** Check whether this field is a custom (non-standard) field. + * Custom fields have a name beginning with "X-". + * + * @return true if the field is a custom field, false otherwise + */ + bool isCustom() const; + + /** Return the read-only value object attached to this field. + * + * @return read-only value object + */ + virtual shared_ptr <const headerFieldValue> getValue() const; + + /** Return the read-only value object attached to this field, + * casted to the specified type. + * + * @return value object + */ + template <typename T> + shared_ptr <const T> getValue() const + { + return dynamicCast <const T>(m_value); + } + + /** Return the value object attached to this field. + * + * @return value object + */ + virtual shared_ptr <headerFieldValue> getValue(); + + /** Return the value object attached to this field, + * casted to the specified type. + * + * @return value object + */ + template <typename T> + shared_ptr <T> getValue() + { + return dynamicCast <T>(m_value); + } + + /** Set the value of this field. + * + * @throw exceptions::bad_field_value_type if the value type is not + * valid for this header field + * @param value new value + */ + virtual void setValue(shared_ptr <headerFieldValue> value); + + /** Set the value of this field by cloning the specified value. + * + * @throw exceptions::bad_field_value_type if the value type is not + * valid for this header field + * @param value new value + */ + virtual void setValueConst(shared_ptr <const headerFieldValue> value); + + /** Set the value of this field (reference version). + * The value will be cloned. + * + * @throw exceptions::bad_field_value_type if the value type is not + * valid for this header field + * @param value new value + */ + virtual void setValue(const headerFieldValue& value); + + /** Set the value of this field given a character string. + * + * @param value value string to parse + */ + void setValue(const string& value); + + + /** Parse a header field from a buffer. + * + * @param ctx parsing context + * @param buffer input buffer + * @param position current position in the input buffer + * @param end end position in the input buffer + * @param newPosition will receive the new position in the input buffer + * @return parsed header field, or NULL if no more header field can be parsed + * in the input buffer + */ + static shared_ptr <headerField> parseNext + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + size_t getGeneratedSize(const generationContext& ctx); + +protected: + + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; + + + string m_name; + shared_ptr <headerFieldValue> m_value; +}; + + +} // vmime + + +#endif // VMIME_HEADERFIELD_HPP_INCLUDED diff --git a/src/headerFieldFactory.cpp b/src/vmime/headerFieldFactory.cpp index 5c60543e..5c60543e 100644 --- a/src/headerFieldFactory.cpp +++ b/src/vmime/headerFieldFactory.cpp diff --git a/src/vmime/headerFieldFactory.hpp b/src/vmime/headerFieldFactory.hpp new file mode 100644 index 00000000..960f27b7 --- /dev/null +++ b/src/vmime/headerFieldFactory.hpp @@ -0,0 +1,152 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_HEADERFIELDFACTORY_HPP_INCLUDED +#define VMIME_HEADERFIELDFACTORY_HPP_INCLUDED + + +#include "vmime/headerField.hpp" +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime +{ + + +/** Creates header field and header field value objects. + */ + +class VMIME_EXPORT headerFieldFactory +{ +protected: + + headerFieldFactory(); + ~headerFieldFactory(); + + typedef shared_ptr <headerField> (*AllocFunc)(void); + typedef std::map <string, AllocFunc> NameMap; + + NameMap m_nameMap; + + + struct ValueInfo + { + typedef shared_ptr <headerFieldValue> (*ValueAllocFunc)(void); + typedef bool (*ValueTypeCheckFunc)(const object&); + + ValueAllocFunc allocFunc; + ValueTypeCheckFunc checkTypeFunc; + }; + + typedef std::map <string, ValueInfo> ValueMap; + + ValueMap m_valueMap; + +public: + + static shared_ptr <headerFieldFactory> getInstance(); + +#ifndef VMIME_BUILDING_DOC + // TYPE must inherit from BASE_TYPE + template <class BASE_TYPE, class TYPE> + class registerer + { + public: + + static bool checkType(const object& obj) + { + const TYPE* typedObj = dynamic_cast <const TYPE*>(&obj); + return typedObj != NULL; + } + + static shared_ptr <BASE_TYPE> creator() + { + // Allocate a new object + return shared_ptr <BASE_TYPE>(new TYPE()); + } + }; +#endif // VMIME_BUILDING_DOC + + + /** Register a field type. + * + * @param T field class (must inherit from 'headerField') + * @param name field name (eg. "X-MyField") + */ + template <class T> + void registerField(const string& name) + { + m_nameMap.insert(NameMap::value_type + (utility::stringUtils::toLower(name), + ®isterer <headerField, T>::creator)); + } + + /** Register a field value type. + * + * @param T value class (must inherit from 'headerFieldValue') + * @param name field name + */ + template <class T> + void registerFieldValue(const string& name) + { + ValueInfo vi; + vi.allocFunc = ®isterer <headerFieldValue, T>::creator; + vi.checkTypeFunc = ®isterer <headerField, T>::checkType; + + m_valueMap.insert(ValueMap::value_type + (utility::stringUtils::toLower(name), vi)); + } + + /** Create a new field object for the specified field name. + * If the field name has not been registered, a default type + * is used. + * + * @param name field name + * @param body string that will be parsed to initialize + * the value of the field + * @return a new field object + */ + shared_ptr <headerField> create(const string& name, const string& body = NULL_STRING); + + /** Create a new field value for the specified field. + * + * @param fieldName name of the field for which to create value + * @return a new value object for the field + */ + shared_ptr <headerFieldValue> createValue(const string& fieldName); + + /** Returns whether the specified value type is valid for the specified field. + * + * @param field header field + * @param value value for this header field + * @return true if the value type is compatible with the header field, or + * false otherwise + */ + bool isValueTypeValid(const headerField& field, const headerFieldValue& value) const; +}; + + +} // vmime + + +#endif // VMIME_HEADERFIELDFACTORY_HPP_INCLUDED diff --git a/src/headerFieldValue.cpp b/src/vmime/headerFieldValue.cpp index a93e0061..a93e0061 100644 --- a/src/headerFieldValue.cpp +++ b/src/vmime/headerFieldValue.cpp diff --git a/src/vmime/headerFieldValue.hpp b/src/vmime/headerFieldValue.hpp new file mode 100644 index 00000000..a3681953 --- /dev/null +++ b/src/vmime/headerFieldValue.hpp @@ -0,0 +1,52 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_HEADERFIELDVALUE_HPP_INCLUDED +#define VMIME_HEADERFIELDVALUE_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/component.hpp" + + +namespace vmime +{ + + +/** Base class for all classes that can be used as a value + * for a header field. + */ + +class VMIME_EXPORT headerFieldValue : public component +{ +public: + + size_t getGeneratedSize(const generationContext& ctx); +}; + + +} // vmime + + +#endif // VMIME_HEADERFIELDVALUE_HPP_INCLUDED + diff --git a/src/htmlTextPart.cpp b/src/vmime/htmlTextPart.cpp index 44459336..44459336 100644 --- a/src/htmlTextPart.cpp +++ b/src/vmime/htmlTextPart.cpp diff --git a/src/vmime/htmlTextPart.hpp b/src/vmime/htmlTextPart.hpp new file mode 100644 index 00000000..4c1a8632 --- /dev/null +++ b/src/vmime/htmlTextPart.hpp @@ -0,0 +1,237 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_HTMLTEXTPART_HPP_INCLUDED +#define VMIME_HTMLTEXTPART_HPP_INCLUDED + + +#include "vmime/textPart.hpp" +#include "vmime/messageId.hpp" +#include "vmime/encoding.hpp" + +#include "vmime/contentHandler.hpp" + + +namespace vmime +{ + + +/** Text part of type 'text/html'. + */ + +class VMIME_EXPORT htmlTextPart : public textPart +{ +public: + + htmlTextPart(); + ~htmlTextPart(); + + const mediaType getType() const; + + const charset& getCharset() const; + void setCharset(const charset& ch); + + shared_ptr <const contentHandler> getPlainText() const; + void setPlainText(shared_ptr <contentHandler> plainText); + + const shared_ptr <const contentHandler> getText() const; + void setText(shared_ptr <contentHandler> text); + + /** Embedded object (eg: image for <IMG> tag). + */ + class embeddedObject : public object + { + public: + + /** The ways embedded objects can be referenced. */ + enum ReferenceType + { + REFERENCED_BY_ID, /**< Referenced by Content-Id. */ + REFERENCED_BY_LOCATION /**< Referenced by Content-Location. */ + }; + + /** Constructs an embedded object. + * + * @param data content of the object + * @param enc encoding of the data + * @param id object identifier + * @param type object content type + * @param refType reference type + * @return a reference to a new embedded object + */ + embeddedObject(shared_ptr <contentHandler> data, const encoding& enc, + const string& id, const mediaType& type, + const ReferenceType refType); + + /** Return data stored in this embedded object. + * + * @return stored data + */ + shared_ptr <const contentHandler> getData() const; + + /** Return the encoding used for data in this + * embedded object. + * + * @return data encoding + */ + const vmime::encoding getEncoding() const; + + /** Returns the identifier of this embedded object (either a + * unique ID or a location). + * + * @return object identifier + */ + const string getId() const; + + /** Return the identifier used to reference this embedded object + * in a text document (for example, you can use the result as + * the "src" attribute of an <img> tag). + * + * @return object reference identifier + */ + const string getReferenceId() const; + + /** Return the content type of data stored in + * this embedded object. + * + * @return data type + */ + const mediaType getType() const; + + /** Returns the way this object is referenced. + * + * @return reference type (see ReferenceType enum) + */ + ReferenceType getReferenceType() const; + + /** Returns whether this object matches the specified identifier. + * + * @param id identifier to test + * @return true if the specified identifier references this + * object, or false otherwise + */ + bool matchesId(const string& id) const; + + private: + + static const string cleanId(const string& id); + + shared_ptr <contentHandler> m_data; + encoding m_encoding; + string m_id; + mediaType m_type; + ReferenceType m_refType; + }; + + + /** Test the existence of an embedded object given its identifier. + * + * @param id object identifier + * @return true if an object with this identifier exists, + * false otherwise + */ + bool hasObject(const string& id) const; + + /** Return the embedded object with the specified identifier. + * + * @param id object identifier + * @return embedded object with the specified identifier, or NULL if + * no object has been found + */ + shared_ptr <const embeddedObject> findObject(const string& id) const; + + /** Return the number of embedded objects. + * + * @return number of embedded objects + */ + size_t getObjectCount() const; + + /** Return the embedded object at the specified position. + * + * @param pos position of the embedded object + * @return embedded object at position 'pos' + */ + shared_ptr <const embeddedObject> getObjectAt(const size_t pos) const; + + /** Embed an object and returns a string which identifies it. + * The returned identifier is suitable for use in the 'src' attribute + * of an <img> tag. + * + * \deprecated Use the addObject() methods which take a 'contentHandler' + * parameter type instead. + * + * @param data object data + * @param type data type + * @return an unique object identifier used to identify the new + * object among all other embedded objects + */ + shared_ptr <const embeddedObject> addObject(const string& data, const mediaType& type); + + /** Embed an object and returns a string which identifies it. + * The returned identifier is suitable for use in the 'src' attribute + * of an <img> tag. + * + * @param data object data + * @param type data type + * @return an unique object identifier used to identify the new + * object among all other embedded objects + */ + shared_ptr <const embeddedObject> addObject(shared_ptr <contentHandler> data, const mediaType& type); + + /** Embed an object and returns a string which identifies it. + * The returned identifier is suitable for use in the 'src' attribute + * of an <img> tag. + * + * @param data object data + * @param enc data encoding + * @param type data type + * @return an unique object identifier used to identify the new + * object among all other embedded objects + */ + shared_ptr <const embeddedObject> addObject(shared_ptr <contentHandler> data, const encoding& enc, const mediaType& type); + + + size_t getPartCount() const; + + void generateIn(shared_ptr <bodyPart> message, shared_ptr <bodyPart> parent) const; + void parse(shared_ptr <const bodyPart> message, shared_ptr <const bodyPart> parent, shared_ptr <const bodyPart> textPart); + +private: + + shared_ptr <contentHandler> m_plainText; + shared_ptr <contentHandler> m_text; + charset m_charset; + + std::vector <shared_ptr <embeddedObject> > m_objects; + + void findEmbeddedParts(const bodyPart& part, std::vector <shared_ptr <const bodyPart> >& cidParts, std::vector <shared_ptr <const bodyPart> >& locParts); + void addEmbeddedObject(const bodyPart& part, const string& id, const embeddedObject::ReferenceType refType); + + bool findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart); +}; + + +} // vmime + + +#endif // VMIME_HTMLTEXTPART_HPP_INCLUDED diff --git a/src/mailbox.cpp b/src/vmime/mailbox.cpp index 7c6d5e3b..7c6d5e3b 100644 --- a/src/mailbox.cpp +++ b/src/vmime/mailbox.cpp diff --git a/src/vmime/mailbox.hpp b/src/vmime/mailbox.hpp new file mode 100644 index 00000000..88abc0f5 --- /dev/null +++ b/src/vmime/mailbox.hpp @@ -0,0 +1,123 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MAILBOX_HPP_INCLUDED +#define VMIME_MAILBOX_HPP_INCLUDED + + +#include "vmime/emailAddress.hpp" +#include "vmime/address.hpp" +#include "vmime/text.hpp" + + +namespace vmime +{ + + +/** A mailbox: full name + email (basic type). + */ + +class VMIME_EXPORT mailbox : public address +{ + friend class mailboxGroup; + friend class mailboxField; + +public: + + mailbox(); + mailbox(const mailbox& mbox); + mailbox(const emailAddress& email); + mailbox(const text& name, const emailAddress& email); + + /** Return the full name of the mailbox (empty if not specified). + * + * @return full name of the mailbox + */ + const text& getName() const; + + /** Set the full name of the mailbox. + * + * @param name full name of the mailbox + */ + void setName(const text& name); + + /** Return the email of the mailbox. + * + * @return email of the mailbox + */ + const emailAddress& getEmail() const; + + /** Set the email of the mailbox. + * + * @param email email of the mailbox + */ + void setEmail(const emailAddress& email); + + // Comparison + bool operator==(const class mailbox& mailbox) const; + bool operator!=(const class mailbox& mailbox) const; + + // Assignment + void copyFrom(const component& other); + shared_ptr <component> clone() const; + mailbox& operator=(const mailbox& other); + + bool isEmpty() const; + + void clear(); + + const std::vector <shared_ptr <component> > getChildComponents(); + + + bool isGroup() const; + +protected: + + text m_name; + emailAddress m_email; + +public: + + using address::parse; + using address::generate; + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_MAILBOX_HPP_INCLUDED diff --git a/src/mailboxField.cpp b/src/vmime/mailboxField.cpp index 29fe9d33..29fe9d33 100644 --- a/src/mailboxField.cpp +++ b/src/vmime/mailboxField.cpp diff --git a/src/vmime/mailboxField.hpp b/src/vmime/mailboxField.hpp new file mode 100644 index 00000000..ca6863c0 --- /dev/null +++ b/src/vmime/mailboxField.hpp @@ -0,0 +1,68 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MAILBOXFIELD_HPP_INCLUDED +#define VMIME_MAILBOXFIELD_HPP_INCLUDED + + +#include "vmime/headerField.hpp" +#include "vmime/mailbox.hpp" + + +// Hide implementation details from user +#ifndef VMIME_BUILDING_DOC + + +namespace vmime +{ + + +/** Work-around for malformed header fields that are of type 'mailbox' + * and contains multiple addresses. + */ + +class VMIME_EXPORT mailboxField : public headerField +{ + friend class headerFieldFactory; + +protected: + + mailboxField(); + mailboxField(const mailboxField&); + +public: + + void parse(const parsingContext& ctx, const string& buffer, + const size_t position, const size_t end, + size_t * newPosition = NULL); +}; + + +#endif // VMIME_BUILDING_DOC + + +} // vmime + + +#endif // VMIME_MAILBOXFIELD_HPP_INCLUDED + diff --git a/src/mailboxGroup.cpp b/src/vmime/mailboxGroup.cpp index 5e8d6b1b..5e8d6b1b 100644 --- a/src/mailboxGroup.cpp +++ b/src/vmime/mailboxGroup.cpp diff --git a/src/vmime/mailboxGroup.hpp b/src/vmime/mailboxGroup.hpp new file mode 100644 index 00000000..b264cf60 --- /dev/null +++ b/src/vmime/mailboxGroup.hpp @@ -0,0 +1,194 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MAILBOXGROUP_HPP_INCLUDED +#define VMIME_MAILBOXGROUP_HPP_INCLUDED + + +#include "vmime/address.hpp" +#include "vmime/mailbox.hpp" +#include "vmime/text.hpp" + + +namespace vmime +{ + + +/** A group of mailboxes (basic type). + */ + +class VMIME_EXPORT mailboxGroup : public address +{ +public: + + mailboxGroup(); + mailboxGroup(const mailboxGroup& mboxGroup); + mailboxGroup(const text& name); + + ~mailboxGroup(); + + + void copyFrom(const component& other); + shared_ptr <component> clone() const; + mailboxGroup& operator=(const component& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Return the name of the group. + * + * @return group name + */ + const text& getName() const; + + /** Set the name of the group. + * + * @param name group name + */ + void setName(const text& name); + + /** Add a mailbox at the end of the list. + * + * @param mbox mailbox to append + */ + void appendMailbox(shared_ptr <mailbox> mbox); + + /** Insert a new mailbox before the specified mailbox. + * + * @param beforeMailbox mailbox before which the new mailbox will be inserted + * @param mbox mailbox to insert + * @throw std::out_of_range if the mailbox is not in the list + */ + void insertMailboxBefore(shared_ptr <mailbox> beforeMailbox, shared_ptr <mailbox> mbox); + + /** Insert a new mailbox before the specified position. + * + * @param pos position at which to insert the new mailbox (0 to insert at + * the beginning of the list) + * @param mbox mailbox to insert + * @throw std::out_of_range if the position is out of range + */ + void insertMailboxBefore(const size_t pos, shared_ptr <mailbox> mbox); + + /** Insert a new mailbox after the specified mailbox. + * + * @param afterMailbox mailbox after which the new mailbox will be inserted + * @param mbox mailbox to insert + * @throw std::out_of_range if the mailbox is not in the list + */ + void insertMailboxAfter(shared_ptr <mailbox> afterMailbox, shared_ptr <mailbox> mbox); + + /** Insert a new mailbox after the specified position. + * + * @param pos position of the mailbox before the new mailbox + * @param mbox mailbox to insert + * @throw std::out_of_range if the position is out of range + */ + void insertMailboxAfter(const size_t pos, shared_ptr <mailbox> mbox); + + /** Remove the specified mailbox from the list. + * + * @param mbox mailbox to remove + * @throw std::out_of_range if the mailbox is not in the list + */ + void removeMailbox(shared_ptr <mailbox> mbox); + + /** Remove the mailbox at the specified position. + * + * @param pos position of the mailbox to remove + * @throw std::out_of_range if the position is out of range + */ + void removeMailbox(const size_t pos); + + /** Remove all mailboxes from the list. + */ + void removeAllMailboxes(); + + /** Return the number of mailboxes in the list. + * + * @return number of mailboxes + */ + size_t getMailboxCount() const; + + /** Tests whether the list of mailboxes is empty. + * + * @return true if there is no mailbox, false otherwise + */ + bool isEmpty() const; + + /** Return the mailbox at the specified position. + * + * @param pos position + * @return mailbox at position 'pos' + * @throw std::out_of_range if the position is out of range + */ + shared_ptr <mailbox> getMailboxAt(const size_t pos); + + /** Return the mailbox at the specified position. + * + * @param pos position + * @return mailbox at position 'pos' + * @throw std::out_of_range if the position is out of range + */ + const shared_ptr <const mailbox> getMailboxAt(const size_t pos) const; + + /** Return the mailbox list. + * + * @return list of mailboxes + */ + const std::vector <shared_ptr <const mailbox> > getMailboxList() const; + + /** Return the mailbox list. + * + * @return list of mailboxes + */ + const std::vector <shared_ptr <mailbox> > getMailboxList(); + + bool isGroup() const; + +private: + + text m_name; + std::vector <shared_ptr <mailbox> > m_list; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_MAILBOXGROUP_HPP_INCLUDED diff --git a/src/mailboxList.cpp b/src/vmime/mailboxList.cpp index b356a1e7..b356a1e7 100644 --- a/src/mailboxList.cpp +++ b/src/vmime/mailboxList.cpp diff --git a/src/vmime/mailboxList.hpp b/src/vmime/mailboxList.hpp new file mode 100644 index 00000000..125c238e --- /dev/null +++ b/src/vmime/mailboxList.hpp @@ -0,0 +1,184 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MAILBOXLIST_HPP_INCLUDED +#define VMIME_MAILBOXLIST_HPP_INCLUDED + + +#include "vmime/addressList.hpp" +#include "vmime/mailbox.hpp" + + +namespace vmime +{ + + +/** A list of mailboxes (basic type). + * + * This class works exactly like 'addressList' except it prevents user + * from inserting mailbox groups where it is not allowed by the RFC. + */ + +class VMIME_EXPORT mailboxList : public headerFieldValue +{ +public: + + mailboxList(); + mailboxList(const mailboxList& mboxList); + + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + mailboxList& operator=(const mailboxList& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Add a mailbox at the end of the list. + * + * @param mbox mailbox to append + */ + void appendMailbox(shared_ptr <mailbox> mbox); + + /** Insert a new mailbox before the specified mailbox. + * + * @param beforeMailbox mailbox before which the new mailbox will be inserted + * @param mbox mailbox to insert + * @throw std::out_of_range if the mailbox is not in the list + */ + void insertMailboxBefore(shared_ptr <mailbox> beforeMailbox, shared_ptr <mailbox> mbox); + + /** Insert a new mailbox before the specified position. + * + * @param pos position at which to insert the new mailbox (0 to insert at + * the beginning of the list) + * @param mbox mailbox to insert + * @throw std::out_of_range if the position is out of range + */ + void insertMailboxBefore(const size_t pos, shared_ptr <mailbox> mbox); + + /** Insert a new mailbox after the specified mailbox. + * + * @param afterMailbox mailbox after which the new mailbox will be inserted + * @param mbox mailbox to insert + * @throw std::out_of_range if the mailbox is not in the list + */ + void insertMailboxAfter(shared_ptr <mailbox> afterMailbox, shared_ptr <mailbox> mbox); + + /** Insert a new mailbox after the specified position. + * + * @param pos position of the mailbox before the new mailbox + * @param mbox mailbox to insert + * @throw std::out_of_range if the position is out of range + */ + void insertMailboxAfter(const size_t pos, shared_ptr <mailbox> mbox); + + /** Remove the specified mailbox from the list. + * + * @param mbox mailbox to remove + * @throw std::out_of_range if the mailbox is not in the list + */ + void removeMailbox(shared_ptr <mailbox> mbox); + + /** Remove the mailbox at the specified position. + * + * @param pos position of the mailbox to remove + * @throw std::out_of_range if the position is out of range + */ + void removeMailbox(const size_t pos); + + /** Remove all mailboxes from the list. + */ + void removeAllMailboxes(); + + /** Return the number of mailboxes in the list. + * + * @return number of mailboxes + */ + size_t getMailboxCount() const; + + /** Tests whether the list of mailboxes is empty. + * + * @return true if there is no mailbox, false otherwise + */ + bool isEmpty() const; + + /** Return the mailbox at the specified position. + * + * @param pos position + * @return mailbox at position 'pos' + * @throw std::out_of_range if the position is out of range + */ + shared_ptr <mailbox> getMailboxAt(const size_t pos); + + /** Return the mailbox at the specified position. + * + * @param pos position + * @return mailbox at position 'pos' + * @throw std::out_of_range if the position is out of range + */ + const shared_ptr <const mailbox> getMailboxAt(const size_t pos) const; + + /** Return the mailbox list. + * + * @return list of mailboxes + */ + const std::vector <shared_ptr <const mailbox> > getMailboxList() const; + + /** Return the mailbox list. + * + * @return list of mailboxes + */ + const std::vector <shared_ptr <mailbox> > getMailboxList(); + + /** Return a list of addresses. + * + * @return list of addresses + */ + shared_ptr <addressList> toAddressList() const; + +private: + + addressList m_list; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_MAILBOXLIST_HPP_INCLUDED diff --git a/src/mdn/MDNHelper.cpp b/src/vmime/mdn/MDNHelper.cpp index 1205aef2..1205aef2 100644 --- a/src/mdn/MDNHelper.cpp +++ b/src/vmime/mdn/MDNHelper.cpp diff --git a/src/vmime/mdn/MDNHelper.hpp b/src/vmime/mdn/MDNHelper.hpp new file mode 100644 index 00000000..2584978f --- /dev/null +++ b/src/vmime/mdn/MDNHelper.hpp @@ -0,0 +1,139 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MDN_MDNHELPER_HPP_INCLUDED +#define VMIME_MDN_MDNHELPER_HPP_INCLUDED + + +#include "vmime/mdn/receivedMDNInfos.hpp" +#include "vmime/mdn/sendableMDNInfos.hpp" + +#include "vmime/mailboxList.hpp" + + +namespace vmime { +namespace mdn { + + +/** Helper for creating or extracting Message Disposition + * Notifications (MDN), as defined in RFC-3798. + */ + +class VMIME_EXPORT MDNHelper +{ +public: + + /** Attach a MDN request to the specified message. + * + * @param msg message in which to add a MDN request + * @param mailboxes list of mailboxes to which the MDN will be sent + */ + static void attachMDNRequest(shared_ptr <message> msg, const mailboxList& mailboxes); + + /** Attach a MDN request to the specified message. + * + * @param msg message in which to add a MDN request + * @param mbox mailbox to which the MDN will be sent + */ + static void attachMDNRequest(shared_ptr <message> msg, const mailbox& mbox); + + /** Return a list of possible MDNs that can be generated + * for the specified message. + * + * @param msg message for which to send a MDN + * @return list of possible MDNs + */ + static const std::vector <sendableMDNInfos> getPossibleMDNs(const shared_ptr <const message> msg); + + /** Test whether the specified message is a MDN. + * + * @param msg message + * @return true if the message is a MDN, false otherwise + */ + static bool isMDN(const shared_ptr <const message> msg); + + /** If the specified message is a MDN, return information + * about it. + * + * @param msg message + * @throw exceptions::invalid_argument if the message is not a MDN + * @return information about the MDN + */ + static receivedMDNInfos getReceivedMDN(const shared_ptr <const message> msg); + + /** Check whether we need user confirmation for sending a MDN even + * if he/she explicitely allowed automatic send of MDNs. This can + * happen in some situations, described in RFC-3798. + * + * @param msg message for which to send a MDN + * @return true if user confirmation should be asked, false otherwise + */ + static bool needConfirmation(const shared_ptr <const message> msg); + + /** Build a new MDN for the message. The resulting MDN can then be + * sent over SMTP transport service. + * + * @param mdnInfos information about the MDN to construct + * @param text human readable message. The purpose of this message is + * to provide an easily-understood description of the + * condition(s) that caused the report to be generated. + * @param ch charset of the text + * @param expeditor expeditor of the MDN + * @param dispo disposition information + * @param reportingUA name of reporting user-agent (optional) + * @param reportingUAProducts list of products in the reporting user-agent (optional) + * @param fields additional MDN fields, like "Error", "Warning" or "Failure" (optional) + * @return a new message object containing the MDN + */ + static shared_ptr <message> buildMDN(const sendableMDNInfos& mdnInfos, + const string& text, + const charset& ch, + const mailbox& expeditor, + const disposition& dispo, + const string& reportingUA = NULL_STRING, + const std::vector <string>& reportingUAProducts + = std::vector <string>(), + const std::map <string, string>& fields + = (std::map <string, string>())); + +private: + + static shared_ptr <bodyPart> createFirstMDNPart(const sendableMDNInfos& mdnInfos, + const string& text, const charset& ch); + + static shared_ptr <bodyPart> createSecondMDNPart(const sendableMDNInfos& mdnInfos, + const disposition& dispo, + const string& reportingUA, + const std::vector <string>& reportingUAProducts, + const std::map <string, string>& fields); + + + static shared_ptr <bodyPart> createThirdMDNPart(const sendableMDNInfos& mdnInfos); +}; + + +} // mdn +} // vmime + + +#endif // VMIME_MDN_MDNHELPER_HPP_INCLUDED diff --git a/src/mdn/MDNInfos.cpp b/src/vmime/mdn/MDNInfos.cpp index a70161b7..a70161b7 100644 --- a/src/mdn/MDNInfos.cpp +++ b/src/vmime/mdn/MDNInfos.cpp diff --git a/src/vmime/mdn/MDNInfos.hpp b/src/vmime/mdn/MDNInfos.hpp new file mode 100644 index 00000000..030aa23e --- /dev/null +++ b/src/vmime/mdn/MDNInfos.hpp @@ -0,0 +1,58 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MDN_MDNINFOS_HPP_INCLUDED +#define VMIME_MDN_MDNINFOS_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/message.hpp" + + +namespace vmime { +namespace mdn { + + +/** Holds information about Message Disposition Notifications (MDN). + */ + +class VMIME_EXPORT MDNInfos : public object +{ +public: + + virtual ~MDNInfos(); + + + /** Return the message related to this MDN. + * + * @return related message + */ + virtual const shared_ptr <const message> getMessage() const = 0; +}; + + +} // mdn +} // vmime + + +#endif // VMIME_MDN_MDNINFOS_HPP_INCLUDED diff --git a/src/mdn/receivedMDNInfos.cpp b/src/vmime/mdn/receivedMDNInfos.cpp index 53b2281e..53b2281e 100644 --- a/src/mdn/receivedMDNInfos.cpp +++ b/src/vmime/mdn/receivedMDNInfos.cpp diff --git a/src/vmime/mdn/receivedMDNInfos.hpp b/src/vmime/mdn/receivedMDNInfos.hpp new file mode 100644 index 00000000..c6953a24 --- /dev/null +++ b/src/vmime/mdn/receivedMDNInfos.hpp @@ -0,0 +1,94 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MDN_RECEIVEDMDNINFOS_HPP_INCLUDED +#define VMIME_MDN_RECEIVEDMDNINFOS_HPP_INCLUDED + + +#include "vmime/mdn/MDNInfos.hpp" + +#include "vmime/disposition.hpp" +#include "vmime/messageId.hpp" +#include "vmime/mailbox.hpp" + + +namespace vmime { +namespace mdn { + + +/** Holds information about a Message Disposition Notification (MDN) + * that has been received. + */ + +class VMIME_EXPORT receivedMDNInfos : public MDNInfos +{ +public: + + receivedMDNInfos(const shared_ptr <const message> msg); + receivedMDNInfos(const receivedMDNInfos& other); + + receivedMDNInfos& operator=(const receivedMDNInfos& other); + + + const shared_ptr <const message> getMessage() const; + + /** Return the identifier of the message for which this MDN + * has been generated. + * + * @return original message-id + */ + const messageId getOriginalMessageId() const; + + /** Return information about the disposition. + * + * @return disposition information + */ + const disposition getDisposition() const; + + /** Return the Message Integrity Check (MIC), that is the value + * of the "Received-content-MIC" field. + * + * @return MIC hash value, or an empty string if not specified + */ + const string getContentMIC() const; + +private: + + void copyFrom(const receivedMDNInfos& other); + + void extract(); + + + shared_ptr <const message> m_msg; + + disposition m_disp; + messageId m_omid; + string m_contentMIC; +}; + + +} // mdn +} // vmime + + +#endif // VMIME_MDN_RECEIVEDMDNINFOS_HPP_INCLUDED diff --git a/src/mdn/sendableMDNInfos.cpp b/src/vmime/mdn/sendableMDNInfos.cpp index c145c3b6..c145c3b6 100644 --- a/src/mdn/sendableMDNInfos.cpp +++ b/src/vmime/mdn/sendableMDNInfos.cpp diff --git a/src/vmime/mdn/sendableMDNInfos.hpp b/src/vmime/mdn/sendableMDNInfos.hpp new file mode 100644 index 00000000..e4f6d20d --- /dev/null +++ b/src/vmime/mdn/sendableMDNInfos.hpp @@ -0,0 +1,73 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MDN_SENDABLEMDNINFOS_HPP_INCLUDED +#define VMIME_MDN_SENDABLEMDNINFOS_HPP_INCLUDED + + +#include "vmime/mdn/MDNInfos.hpp" + +#include "vmime/mailbox.hpp" + + +namespace vmime { +namespace mdn { + + +/** Holds information about a Message Disposition Notifications (MDN) + * that is to be sent. + */ + +class VMIME_EXPORT sendableMDNInfos : public MDNInfos +{ +public: + + sendableMDNInfos(const shared_ptr <const message> msg, const mailbox& mbox); + sendableMDNInfos(const sendableMDNInfos& other); + + sendableMDNInfos& operator=(const sendableMDNInfos& other); + + const shared_ptr <const message> getMessage() const; + + /** Return the recipient of the MDN (the mailbox that will receive + * the notification message). + * + * @return recipient of the MDN + */ + const mailbox& getRecipient() const; + +private: + + void copyFrom(const sendableMDNInfos& other); + + + shared_ptr <const message> m_msg; + mailbox m_mailbox; +}; + + +} // mdn +} // vmime + + +#endif // VMIME_MDN_SENDABLEMDNINFOS_HPP_INCLUDED diff --git a/src/mediaType.cpp b/src/vmime/mediaType.cpp index 60486da7..60486da7 100644 --- a/src/mediaType.cpp +++ b/src/vmime/mediaType.cpp diff --git a/src/vmime/mediaType.hpp b/src/vmime/mediaType.hpp new file mode 100644 index 00000000..a7d6f4e4 --- /dev/null +++ b/src/vmime/mediaType.hpp @@ -0,0 +1,119 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MEDIATYPE_HPP_INCLUDED +#define VMIME_MEDIATYPE_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + + +namespace vmime +{ + + +/** Content media type (basic type). + */ + +class VMIME_EXPORT mediaType : public headerFieldValue +{ +public: + + mediaType(); + mediaType(const string& type); + mediaType(const string& type, const string& subType); + +public: + + bool operator==(const mediaType& type) const; + bool operator!=(const mediaType& type) const; + + mediaType& operator=(const string& type); + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + mediaType& operator=(const mediaType& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Return the media type. + * See the constants in vmime::mediaTypes. + * + * @return media type + */ + const string& getType() const; + + /** Set the media type. + * See the constants in vmime::mediaTypes. + * + * @param type media type + */ + void setType(const string& type); + + /** Return the media subtype. + * See the constants in vmime::mediaTypes. + * + * @return media subtype + */ + const string& getSubType() const; + + /** Set the media subtype. + * See the constants in vmime::mediaTypes. + * + * @param subType media subtype + */ + void setSubType(const string& subType); + + /** Set the media type and subtype from a string + * in the form "type/subtype" (eg: "image/jpeg"). + * + * @param type media type and subtype + */ + void setFromString(const string& type); + +protected: + + string m_type; + string m_subType; + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_MEDIATYPE_HPP_INCLUDED diff --git a/src/message.cpp b/src/vmime/message.cpp index 76735496..76735496 100644 --- a/src/message.cpp +++ b/src/vmime/message.cpp diff --git a/src/vmime/message.hpp b/src/vmime/message.hpp new file mode 100644 index 00000000..62ff77e1 --- /dev/null +++ b/src/vmime/message.hpp @@ -0,0 +1,62 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MESSAGE_HPP_INCLUDED +#define VMIME_MESSAGE_HPP_INCLUDED + + +#include "vmime/bodyPart.hpp" +#include "vmime/generationContext.hpp" + + +namespace vmime +{ + + +/** A MIME message. + */ + +class VMIME_EXPORT message : public bodyPart +{ +public: + + message(); + +public: + + using bodyPart::parse; + using bodyPart::generate; + + // Override default generate() functions so that we can change + // the default 'maxLineLength' value + const string generate + (const size_t maxLineLength = generationContext::getDefaultContext().getMaxLineLength(), + const size_t curLinePos = 0) const; +}; + + + +} // vmime + + +#endif // VMIME_MESSAGE_HPP_INCLUDED diff --git a/src/vmime/messageAttachment.hpp b/src/vmime/messageAttachment.hpp new file mode 100644 index 00000000..641fd3e1 --- /dev/null +++ b/src/vmime/messageAttachment.hpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MESSAGEATTACHMENT_HPP_INCLUDED +#define VMIME_MESSAGEATTACHMENT_HPP_INCLUDED + + +#include "vmime/attachment.hpp" +#include "vmime/message.hpp" + + +namespace vmime +{ + + +/** Attachment of type message/rfc822. + */ + +class VMIME_EXPORT messageAttachment : public attachment +{ +public: + + /** Return the message encapsulated in this attachment. + * + * @return encapsulated message + */ + virtual shared_ptr <message> getMessage() const = 0; +}; + + +} // vmime + + +#endif // VMIME_MESSAGEATTACHMENT_HPP_INCLUDED + diff --git a/src/messageBuilder.cpp b/src/vmime/messageBuilder.cpp index 64880483..64880483 100644 --- a/src/messageBuilder.cpp +++ b/src/vmime/messageBuilder.cpp diff --git a/src/vmime/messageBuilder.hpp b/src/vmime/messageBuilder.hpp new file mode 100644 index 00000000..af86e826 --- /dev/null +++ b/src/vmime/messageBuilder.hpp @@ -0,0 +1,223 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MESSAGEBUILDER_HPP_INCLUDED +#define VMIME_MESSAGEBUILDER_HPP_INCLUDED + + +#include "vmime/base.hpp" + +#include "vmime/mailbox.hpp" +#include "vmime/addressList.hpp" +#include "vmime/text.hpp" +#include "vmime/message.hpp" +#include "vmime/mediaType.hpp" +#include "vmime/attachment.hpp" +#include "vmime/textPart.hpp" +#include "vmime/bodyPart.hpp" + + +namespace vmime +{ + + +/** A helper for building MIME messages. + */ + +class VMIME_EXPORT messageBuilder +{ +public: + + messageBuilder(); + ~messageBuilder(); + +public: + + /** Return the expeditor of the message (From:). + * + * @return expeditor of the message + */ + const mailbox& getExpeditor() const; + + /** Set the expeditor of the message (From:). + * + * @param expeditor expeditor of the message + */ + void setExpeditor(const mailbox& expeditor); + + /** Return the recipients of the message (To:). + * + * return recipients of the message + */ + const addressList& getRecipients() const; + + /** Return the recipients of the message (To:). + * + * return recipients of the message + */ + addressList& getRecipients(); + + /** Set the recipients of the message (To:). + * + * @param recipients list of recipients + */ + void setRecipients(const addressList& recipients); + + /** Return the copy recipients of the message (Cc:). + * + * @return copy recipients of the message + */ + const addressList& getCopyRecipients() const; + + /** Return the copy recipients of the message (Cc:). + * + * @return copy recipients of the message + */ + addressList& getCopyRecipients(); + + /** Set the copy recipients of the message (Cc:). + * + * @param cc list of copy recipients + */ + void setCopyRecipients(const addressList& cc); + + /** Return the blind-copy recipients of the message (Bcc:). + * + * @return blind-copy recipients of the message + */ + const addressList& getBlindCopyRecipients() const; + + /** Return the blind-copy recipients of the message (Bcc:). + * + * @return blind-copy recipients of the message + */ + addressList& getBlindCopyRecipients(); + + /** Set the blind-copy recipients of the message (Bcc:). + * + * @param bcc list of blind-copy recipients + */ + void setBlindCopyRecipients(const addressList& bcc); + + /** Return the subject of the message. + * + * @return subject of the message + */ + const text& getSubject() const; + + /** Set the subject of the message. + * + * @param subject message subject + */ + void setSubject(const text& subject); + + /** Attach a new object to the message. + * \deprecated Use messageBuilder::appendAttachment() instead. + * + * @param attach new attachment + */ + void attach(shared_ptr <attachment> attach); + + /** Attach a new object to the message. + * + * @param attach new attachment + */ + void appendAttachment(shared_ptr <attachment> attach); + + /** Remove the attachment at the specified position. + * + * @param pos position of the attachment to remove + */ + void removeAttachment(const size_t pos); + + /** Return the attachment at the specified position. + * + * @param pos position of the attachment + * @return attachment at the specified position + */ + const shared_ptr <const attachment> getAttachmentAt(const size_t pos) const; + + /** Return the attachment at the specified position. + * + * @param pos position of the attachment + * @return attachment at the specified position + */ + shared_ptr <attachment> getAttachmentAt(const size_t pos); + + /** Return the number of attachments in the message. + * + * @return number of attachments + */ + size_t getAttachmentCount() const; + + /** Return the list of attachments. + * + * @return list of attachments + */ + const std::vector <shared_ptr <const attachment> > getAttachmentList() const; + + /** Return the list of attachments. + * + * @return list of attachments + */ + const std::vector <shared_ptr <attachment> > getAttachmentList(); + + /** Change the type of the text part and construct a new part. + * + * @param type media type of the text part + */ + void constructTextPart(const mediaType& type); + + /** Return the text part of the message. + * + * @return text part of the message + */ + shared_ptr <textPart> getTextPart(); + + /** Construct a new message based on the information specified + * in this object. + * + * @return a new message + */ + shared_ptr <message> construct() const; + +private: + + mailbox m_from; + + addressList m_to; + addressList m_cc; + addressList m_bcc; + + text m_subject; + + shared_ptr <textPart> m_textPart; + + std::vector <shared_ptr <attachment> > m_attach; +}; + + +} // vmime + + +#endif // VMIME_MESSAGEBUILDER_HPP_INCLUDED diff --git a/src/messageId.cpp b/src/vmime/messageId.cpp index edc4d1fb..edc4d1fb 100644 --- a/src/messageId.cpp +++ b/src/vmime/messageId.cpp diff --git a/src/vmime/messageId.hpp b/src/vmime/messageId.hpp new file mode 100644 index 00000000..83527468 --- /dev/null +++ b/src/vmime/messageId.hpp @@ -0,0 +1,143 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MESSAGEID_HPP_INCLUDED +#define VMIME_MESSAGEID_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + + +namespace vmime +{ + + +/** Message identifier (basic type). + */ + +class VMIME_EXPORT messageId : public headerFieldValue +{ + friend class messageIdSequence; + +public: + + messageId(); + messageId(const string& id); + messageId(const messageId& mid); + messageId(const string& left, const string& right); + +public: + + /** Return the left part of the message identifier. + * + * @return left part of message identifier + */ + const string& getLeft() const; + + /** Set the left part of the message identifier. + * + * @param left left part of message identifier + */ + void setLeft(const string& left); + + /** Return the right part of the message identifier. + * + * @return right part of message identifier + */ + const string& getRight() const; + + /** Set the right part of the message identifier. + * + * @param right right part of message identifier + */ + void setRight(const string& right); + + + messageId& operator=(const string& id); + + bool operator==(const messageId& mid) const; + bool operator!=(const messageId& mid) const; + + /** Generate a random message identifier. + * + * @return randomly created message identifier + */ + static messageId generateId(); + + /** Return the message identifier constructed by using + * the right part and the left part, separated by + * a '@' character. + * + * @return full message identifier + */ + const string getId() const; + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + messageId& operator=(const messageId& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + +private: + + string m_left; + string m_right; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; + + /** Parse a message-id from an input buffer. + * + * @param buffer input buffer + * @param position position in the input buffer + * @param end end position in the input buffer + * @param newPosition will receive the new position in the input buffer + * @return a new message-id object, or null if no more message-id can be parsed from the input buffer + */ + static shared_ptr <messageId> parseNext + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition); +}; + + +} // vmime + + +#endif // VMIME_MESSAGEID_HPP_INCLUDED diff --git a/src/messageIdSequence.cpp b/src/vmime/messageIdSequence.cpp index 23b12773..23b12773 100644 --- a/src/messageIdSequence.cpp +++ b/src/vmime/messageIdSequence.cpp diff --git a/src/vmime/messageIdSequence.hpp b/src/vmime/messageIdSequence.hpp new file mode 100644 index 00000000..07f0c422 --- /dev/null +++ b/src/vmime/messageIdSequence.hpp @@ -0,0 +1,172 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MESSAGEIDSEQUENCE_HPP_INCLUDED +#define VMIME_MESSAGEIDSEQUENCE_HPP_INCLUDED + + +#include "vmime/messageId.hpp" + + +namespace vmime +{ + + +/** A list of message identifiers (basic type). + */ + +class VMIME_EXPORT messageIdSequence : public headerFieldValue +{ +public: + + messageIdSequence(); + messageIdSequence(const messageIdSequence& midSeq); + + ~messageIdSequence(); + + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + messageIdSequence& operator=(const messageIdSequence& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + + /** Add a message-id at the end of the list. + * + * @param mid message-id to append + */ + void appendMessageId(shared_ptr <messageId> mid); + + /** Insert a new message-id before the specified message-id. + * + * @param beforeMid message-id before which the new message-id will be inserted + * @param mid message-id to insert + * @throw exceptions::no_such_messageid if the message-id is not in the list + */ + void insertMessageIdBefore(shared_ptr <messageId> beforeMid, shared_ptr <messageId> mid); + + /** Insert a new message-id before the specified position. + * + * @param pos position at which to insert the new message-id (0 to insert at + * the beginning of the list) + * @param mid message-id to insert + */ + void insertMessageIdBefore(const size_t pos, shared_ptr <messageId> mid); + + /** Insert a new message-id after the specified message-id. + * + * @param afterMid message-id after which the new message-id will be inserted + * @param mid message-id to insert + * @throw exceptions::no_such_message_id if the message-id is not in the list + */ + void insertMessageIdAfter(shared_ptr <messageId> afterMid, shared_ptr <messageId> mid); + + /** Insert a new message-id after the specified position. + * + * @param pos position of the message-id before the new message-id + * @param mid message-id to insert + */ + void insertMessageIdAfter(const size_t pos, shared_ptr <messageId> mid); + + /** Remove the specified message-id from the list. + * + * @param mid message-id to remove + * @throw exceptions::no_such_message_id if the message-id is not in the list + */ + void removeMessageId(shared_ptr <messageId> mid); + + /** Remove the message-id at the specified position. + * + * @param pos position of the message-id to remove + */ + void removeMessageId(const size_t pos); + + /** Remove all message-ids from the list. + */ + void removeAllMessageIds(); + + /** Return the number of message-ides in the list. + * + * @return number of message-ides + */ + size_t getMessageIdCount() const; + + /** Tests whether the list of message-ides is empty. + * + * @return true if there is no message-id, false otherwise + */ + bool isEmpty() const; + + /** Return the message-id at the specified position. + * + * @param pos position + * @return message-id at position 'pos' + */ + const shared_ptr <messageId> getMessageIdAt(const size_t pos); + + /** Return the message-id at the specified position. + * + * @param pos position + * @return message-id at position 'pos' + */ + const shared_ptr <const messageId> getMessageIdAt(const size_t pos) const; + + /** Return the message-id list. + * + * @return list of message-ids + */ + const std::vector <shared_ptr <const messageId> > getMessageIdList() const; + + /** Return the message-id list. + * + * @return list of message-ids + */ + const std::vector <shared_ptr <messageId> > getMessageIdList(); + +private: + + std::vector <shared_ptr <messageId> > m_list; + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_MESSAGEIDSEQUENCE_HPP_INCLUDED diff --git a/src/messageParser.cpp b/src/vmime/messageParser.cpp index 5fe219f3..5fe219f3 100644 --- a/src/messageParser.cpp +++ b/src/vmime/messageParser.cpp diff --git a/src/vmime/messageParser.hpp b/src/vmime/messageParser.hpp new file mode 100644 index 00000000..c3a48f11 --- /dev/null +++ b/src/vmime/messageParser.hpp @@ -0,0 +1,159 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MESSAGEPARSER_HPP_INCLUDED +#define VMIME_MESSAGEPARSER_HPP_INCLUDED + + +#include "vmime/base.hpp" + +#include "vmime/message.hpp" +#include "vmime/attachment.hpp" + +#include "vmime/mailbox.hpp" +#include "vmime/addressList.hpp" +#include "vmime/dateTime.hpp" + +#include "vmime/textPart.hpp" + + +namespace vmime +{ + + +/** A helper for parsing MIME messages. + */ + +class VMIME_EXPORT messageParser +{ +public: + + messageParser(const string& buffer); + messageParser(shared_ptr <const message> msg); + ~messageParser(); + +public: + + /** Return the expeditor of the message (From:). + * + * @return expeditor of the message + */ + const mailbox& getExpeditor() const; + + /** Return the recipients of the message (To:). + * + * return recipients of the message + */ + const addressList& getRecipients() const; + + /** Return the copy recipients of the message (Cc:). + * + * @return copy recipients of the message + */ + const addressList& getCopyRecipients() const; + + /** Return the blind-copy recipients of the message (Bcc:). + * + * @return blind-copy recipients of the message + */ + const addressList& getBlindCopyRecipients() const; + + /** Return the subject of the message. + * + * @return subject of the message + */ + const text& getSubject() const; + + /** Return the date of the message. + * + * @return date of the message + */ + const datetime& getDate() const; + + /** Return the number of attachments in the message. + * + * @return number of attachments + */ + size_t getAttachmentCount() const; + + /** Return the attachment at the specified position. + * + * @param pos position of the attachment + * @return attachment at position 'pos' + */ + const shared_ptr <const attachment> getAttachmentAt(const size_t pos) const; + + /** Return the attachments of the message. + * + * @return list of attachments in the message + */ + const std::vector <shared_ptr <const attachment> > getAttachmentList() const; + + /** Return the text parts of the message. + * + * @return list of text parts in the message + */ + const std::vector <shared_ptr <const textPart> > getTextPartList() const; + + /** Return the number of text parts in the message. + * + * @return number of text parts + */ + size_t getTextPartCount() const; + + /** Return the text part at the specified position. + * + * @param pos position of the text part + * @return text part at position 'pos' + */ + const shared_ptr <const textPart> getTextPartAt(const size_t pos) const; + +private: + + mailbox m_from; + + addressList m_to; + addressList m_cc; + addressList m_bcc; + + text m_subject; + + datetime m_date; + + std::vector <shared_ptr <const attachment> > m_attach; + + std::vector <shared_ptr <textPart> > m_textParts; + + void parse(shared_ptr <const message> msg); + + void findAttachments(shared_ptr <const message> msg); + + void findTextParts(shared_ptr <const bodyPart> msg, shared_ptr <const bodyPart> part); + bool findSubTextParts(shared_ptr <const bodyPart> msg, shared_ptr <const bodyPart> part); +}; + + +} // vmime + + +#endif // VMIME_MESSAGEPARSER_HPP_INCLUDED diff --git a/src/misc/importanceHelper.cpp b/src/vmime/misc/importanceHelper.cpp index b13f7466..b13f7466 100644 --- a/src/misc/importanceHelper.cpp +++ b/src/vmime/misc/importanceHelper.cpp diff --git a/src/vmime/misc/importanceHelper.hpp b/src/vmime/misc/importanceHelper.hpp new file mode 100644 index 00000000..ae8297fc --- /dev/null +++ b/src/vmime/misc/importanceHelper.hpp @@ -0,0 +1,105 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_MISC_IMPORTANCEHELPER_HPP_INCLUDED +#define VMIME_MISC_IMPORTANCEHELPER_HPP_INCLUDED + + +#include "vmime/message.hpp" + + +namespace vmime { +namespace misc { + + +/** Deals with setting and retrieving message importance (also + * known as priority). + * + * Basically, it wraps the use of the 'X-Priority' (non standard) + * and 'Importance' (RFC-1327, RFC-1911) fields. + */ + +class VMIME_EXPORT importanceHelper +{ +public: + + /** Different levels of importance. */ + enum Importance + { + IMPORTANCE_HIGHEST, + IMPORTANCE_HIGH, + IMPORTANCE_NORMAL, + IMPORTANCE_LOW, + IMPORTANCE_LOWEST + }; + + + /** Reset the importance of the message to the default importance. + * + * @param msg message on which to reset importance + */ + static void resetImportance(shared_ptr <message> msg); + + /** Reset the importance of a message to the default importance. + * + * @param hdr message header on which to reset importance + */ + static void resetImportanceHeader(shared_ptr <header> hdr); + + /** Return the importance of the specified message. + * + * @param msg message from which to retrieve importance + * @return importance of the message, or default importance is no + * information about importance is given in the message + */ + static Importance getImportance(shared_ptr <const message> msg); + + /** Return the importance of a message, given its header. + * + * @param hdr message header from which to retrieve importance + * @return importance of the message, or default importance is no + * information about importance is given in the message + */ + static Importance getImportanceHeader(shared_ptr <const header> hdr); + + /** Set the importance of the specified message. + * + * @param msg message on which to set importance + * @param i new message importance + */ + static void setImportance(shared_ptr <message> msg, const Importance i); + + /** Set the importance of a message, given its header. + * + * @param hdr message header on which to set importance + * @param i new message importance + */ + static void setImportanceHeader(shared_ptr <header> hdr, const Importance i); +}; + + +} // misc +} // vmime + + +#endif // VMIME_MISC_IMPORTANCEHELPER_HPP_INCLUDED diff --git a/src/net/builtinServices.inl b/src/vmime/net/builtinServices.inl index 9225ff30..fa2f3fe3 100644 --- a/src/net/builtinServices.inl +++ b/src/vmime/net/builtinServices.inl @@ -23,7 +23,7 @@ // Include registration helpers -#include "src/net/serviceRegistration.inl" +#include "vmime/net/serviceRegistration.inl" #ifndef VMIME_BUILDING_DOC diff --git a/src/vmime/net/connectionInfos.hpp b/src/vmime/net/connectionInfos.hpp new file mode 100644 index 00000000..6c86eeab --- /dev/null +++ b/src/vmime/net/connectionInfos.hpp @@ -0,0 +1,68 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_CONNECTIONINFOS_HPP_INCLUDED +#define VMIME_NET_CONNECTIONINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/object.hpp" + + +namespace vmime { +namespace net { + + +/** Information about the connection used by a service. + */ +class VMIME_EXPORT connectionInfos : public object +{ +public: + + /** Return the host to which the service is connected. + * + * @return server host name or address + */ + virtual const string getHost() const = 0; + + /** Return the port to which the service is connected. + * + * @return server port + */ + virtual port_t getPort() const = 0; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_CONNECTIONINFOS_HPP_INCLUDED + diff --git a/src/net/defaultConnectionInfos.cpp b/src/vmime/net/defaultConnectionInfos.cpp index 335e8f6f..335e8f6f 100644 --- a/src/net/defaultConnectionInfos.cpp +++ b/src/vmime/net/defaultConnectionInfos.cpp diff --git a/src/vmime/net/defaultConnectionInfos.hpp b/src/vmime/net/defaultConnectionInfos.hpp new file mode 100644 index 00000000..50673bbc --- /dev/null +++ b/src/vmime/net/defaultConnectionInfos.hpp @@ -0,0 +1,66 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_DEFAULTCONNECTIONINFOS_HPP_INCLUDED +#define VMIME_NET_DEFAULTCONNECTIONINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/connectionInfos.hpp" + + +namespace vmime { +namespace net { + + +/** Information about the connection used by a service. + */ +class VMIME_EXPORT defaultConnectionInfos : public connectionInfos +{ +public: + + defaultConnectionInfos(const string& host, const port_t port); + + const string getHost() const; + port_t getPort() const; + +private: + + string m_host; + port_t m_port; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_DEFAULTCONNECTIONINFOS_HPP_INCLUDED + diff --git a/src/net/events.cpp b/src/vmime/net/events.cpp index a19e1738..a19e1738 100644 --- a/src/net/events.cpp +++ b/src/vmime/net/events.cpp diff --git a/src/vmime/net/events.hpp b/src/vmime/net/events.hpp new file mode 100644 index 00000000..a3e952d4 --- /dev/null +++ b/src/vmime/net/events.hpp @@ -0,0 +1,273 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_EVENTS_HPP_INCLUDED +#define VMIME_NET_EVENTS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include <vector> + +#include "vmime/utility/path.hpp" + + +namespace vmime { +namespace net { + +class folder; + +namespace events { + + +/** Event occurring on folders or messages. + */ + +class VMIME_EXPORT event : public object +{ +public: + + event(); + virtual ~event(); + + virtual const char* getClass() const = 0; +}; + + +/** Event about the message count in a folder. + */ + +class VMIME_EXPORT messageCountEvent : public event +{ +public: + + static const char* EVENT_CLASS; + + + enum Types + { + TYPE_ADDED, /**< New messages have been added. */ + TYPE_REMOVED /**< Messages have been expunged (renumbering). */ + }; + + + messageCountEvent(shared_ptr <folder> folder, const Types type, const std::vector <int>& nums); + + /** Return the folder in which messages have been added/removed. + * + * @return folder in which message count changed + */ + shared_ptr <folder> getFolder() const; + + /** Return the event type. + * + * @return event type (see messageCountEvent::Types) + */ + Types getType() const; + + /** Return the numbers of the messages that have been added/removed. + * + * @return a list of message numbers + */ + const std::vector <int>& getNumbers() const; + + /** Dispatch the event to the specified listener. + * + * @param listener listener to notify + */ + void dispatch(class messageCountListener* listener); + + + const char* getClass() const; + +private: + + shared_ptr <folder> m_folder; + const Types m_type; + std::vector <int> m_nums; +}; + + +/** Listener for events about the message count in a folder. + */ + +class VMIME_EXPORT messageCountListener +{ +protected: + + virtual ~messageCountListener() { } + +public: + + virtual void messagesAdded(shared_ptr <messageCountEvent> event) = 0; + virtual void messagesRemoved(shared_ptr <messageCountEvent> event) = 0; +}; + + +/** Event occuring on a message. + */ + +class VMIME_EXPORT messageChangedEvent : public event +{ +public: + + static const char* EVENT_CLASS; + + + enum Types + { + TYPE_FLAGS // flags changed + }; + + + messageChangedEvent(shared_ptr <folder> folder, const Types type, const std::vector <int>& nums); + + /** Return the folder in which messages have changed. + * + * @return folder in which message count changed + */ + shared_ptr <folder> getFolder() const; + + /** Return the event type. + * + * @return event type (see messageChangedEvent::Types) + */ + Types getType() const; + + /** Return the numbers of the messages that have changed. + * + * @return a list of message numbers + */ + const std::vector <int>& getNumbers() const; + + /** Dispatch the event to the specified listener. + * + * @param listener listener to notify + */ + void dispatch(class messageChangedListener* listener); + + + const char* getClass() const; + +private: + + shared_ptr <folder> m_folder; + const Types m_type; + std::vector <int> m_nums; +}; + + +/** Listener for events occuring on a message. + */ + +class VMIME_EXPORT messageChangedListener +{ +protected: + + virtual ~messageChangedListener() { } + +public: + + virtual void messageChanged(shared_ptr <messageChangedEvent> event) = 0; +}; + + +/** Event occuring on a folder. + */ + +class VMIME_EXPORT folderEvent : public event +{ +public: + + static const char* EVENT_CLASS; + + + enum Types + { + TYPE_CREATED, /**< A folder was created. */ + TYPE_DELETED, /**< A folder was deleted. */ + TYPE_RENAMED /**< A folder was renamed. */ + }; + + + folderEvent(shared_ptr <folder> folder, const Types type, const utility::path& oldPath, const utility::path& newPath); + + /** Return the folder on which the event occured. + * + * @return folder on which the event occured + */ + shared_ptr <folder> getFolder() const; + + /** Return the event type. + * + * @return event type (see folderEvent::Types) + */ + Types getType() const; + + /** Dispatch the event to the specified listener. + * + * @param listener listener to notify + */ + void dispatch(class folderListener* listener); + + + const char* getClass() const; + +private: + + shared_ptr <folder> m_folder; + const Types m_type; + const utility::path m_oldPath; + const utility::path m_newPath; +}; + + +/** Listener for events occuring on a folder. + */ + +class VMIME_EXPORT folderListener +{ +protected: + + virtual ~folderListener() { } + +public: + + virtual void folderCreated(shared_ptr <folderEvent> event) = 0; + virtual void folderRenamed(shared_ptr <folderEvent> event) = 0; + virtual void folderDeleted(shared_ptr <folderEvent> event) = 0; +}; + + +} // events +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_EVENTS_HPP_INCLUDED diff --git a/src/net/fetchAttributes.cpp b/src/vmime/net/fetchAttributes.cpp index 85a41b8c..85a41b8c 100644 --- a/src/net/fetchAttributes.cpp +++ b/src/vmime/net/fetchAttributes.cpp diff --git a/src/vmime/net/fetchAttributes.hpp b/src/vmime/net/fetchAttributes.hpp new file mode 100644 index 00000000..d01e9f50 --- /dev/null +++ b/src/vmime/net/fetchAttributes.hpp @@ -0,0 +1,142 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_FETCHATTRIBUTES_HPP_INCLUDED +#define VMIME_NET_FETCHATTRIBUTES_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include <vector> + +#include "vmime/types.hpp" + + +namespace vmime { +namespace net { + + +/** Holds a set of attributes to fetch for a message. + */ +class VMIME_EXPORT fetchAttributes : public object +{ +public: + + /** Predefined attributes that can be fetched. + */ + enum PredefinedFetchAttributes + { + ENVELOPE = (1 << 0), /**< Sender, recipients, date, subject. */ + STRUCTURE = (1 << 1), /**< MIME structure (body parts). */ + CONTENT_INFO = (1 << 2), /**< Top-level content type. */ + FLAGS = (1 << 3), /**< Message flags. */ + SIZE = (1 << 4), /**< Message size (exact or estimated). */ + FULL_HEADER = (1 << 5), /**< Full RFC-[2]822 header. */ + UID = (1 << 6), /**< Unique identifier (protocol specific). */ + IMPORTANCE = (1 << 7), /**< Header fields suitable for use with misc::importanceHelper. */ + + CUSTOM = (1 << 16) /**< Reserved for future use. */ + }; + + /** Constructs an empty fetchAttributes object. + */ + fetchAttributes(); + + /** Constructs a new fetchAttributes object by specifying one or more + * predefined objects. + * + * @param attribs one or more OR-ed values of the PredefinedFetchAttributes enum + */ + fetchAttributes(const int attribs); + + /** Constructs a new fetchAttributes object by copying an existing object. + * + * @param attribs object to copy + */ + fetchAttributes(const fetchAttributes& attribs); + + /** Adds the specified predefined attribute to the set of attributes to fetch. + * + * @param attribs one or more OR-ed values of the PredefinedFetchAttributes enum + */ + void add(const int attribs); + + /** Adds the specified header field to the set of attributes to fetch. + * Fetching custom header fields is not supported by all protocols. + * At this time, only IMAP supports this. + * + * @param header name of header field (eg. "X-Mailer") + */ + void add(const string& header); + + /** Returns true if the set contains the specified attribute(s). + * + * @param attribs one or more OR-ed values of the PredefinedFetchAttributes enum + * @return true if the specified attributes are to be fetched + */ + bool has(const int attribs) const; + + /** Returns true if the set contains the specified header field. + * + * @param header name of header field (eg. "X-Mailer") + * @return true if the specified header fields are to be fetched + */ + bool has(const string& header) const; + + /** Returns true if the set contains the specified attribute(s). + * + * \deprecated Use the has() methods instead + * + * @param attribs one or more OR-ed values of the PredefinedFetchAttributes enum + * @return true if the specified attributes are to be fetched + */ + VMIME_DEPRECATED inline bool operator&(const int attribs) const + { + return has(attribs); + } + + /** Returns a list of header fields to fetch. + * + * @return list of header names (eg. "X-Mailer") + */ + const std::vector <string> getHeaderFields() const; + +private: + + int m_predefinedAttribs; + std::vector <string> m_headers; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#endif // VMIME_NET_FETCHATTRIBUTES_HPP_INCLUDED diff --git a/src/net/folder.cpp b/src/vmime/net/folder.cpp index 1d6f3140..1d6f3140 100644 --- a/src/net/folder.cpp +++ b/src/vmime/net/folder.cpp diff --git a/src/vmime/net/folder.hpp b/src/vmime/net/folder.hpp new file mode 100644 index 00000000..38ba4597 --- /dev/null +++ b/src/vmime/net/folder.hpp @@ -0,0 +1,399 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_FOLDER_HPP_INCLUDED +#define VMIME_NET_FOLDER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include <vector> + +#include "vmime/types.hpp" +#include "vmime/dateTime.hpp" + +#include "vmime/message.hpp" +#include "vmime/net/message.hpp" +#include "vmime/net/messageSet.hpp" +#include "vmime/net/events.hpp" +#include "vmime/net/folderStatus.hpp" +#include "vmime/net/fetchAttributes.hpp" + +#include "vmime/utility/path.hpp" +#include "vmime/utility/stream.hpp" +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace net { + + +class store; + + +/** Abstract representation of a folder in a message store. + */ + +class VMIME_EXPORT folder : public object +{ +protected: + + folder(const folder&) : object() { } + folder() { } + +public: + + virtual ~folder() { } + + /** Type used for fully qualified path name of a folder. + */ + typedef vmime::utility::path path; + + + /** Open mode. + */ + enum Modes + { + MODE_READ_ONLY, /**< Read-only mode (no modification to folder or messages is possible). */ + MODE_READ_WRITE /**< Full access mode (read and write). */ + }; + + /** Folder types. + */ + enum Types + { + TYPE_CONTAINS_FOLDERS = (1 << 0), /**< Folder can contain folders. */ + TYPE_CONTAINS_MESSAGES = (1 << 1), /**< Folder can contain messages. */ + + TYPE_UNDEFINED = 9999 /**< Used internally (this should not be returned + by the type() function). */ + }; + + /** Folder flags. + */ + enum Flags + { + FLAG_CHILDREN = (1 << 0), /**< Folder contains subfolders. */ + FLAG_NO_OPEN = (1 << 1), /**< Folder cannot be open. */ + + FLAG_UNDEFINED = 9999 /**< Used internally (this should not be returned + by the type() function). */ + }; + + /** Return the type of this folder. + * + * @return folder type (see folder::Types) + */ + virtual int getType() = 0; + + /** Return the flags of this folder. + * + * @return folder flags (see folder::Flags) + */ + virtual int getFlags() = 0; + + /** Return the mode in which the folder has been open. + * + * @return folder opening mode (see folder::Modes) + */ + virtual int getMode() const = 0; + + /** Return the name of this folder. + * + * @return folder name + */ + virtual const folder::path::component getName() const = 0; + + /** Return the fully qualified path name of this folder. + * + * @return absolute path of the folder + */ + virtual const folder::path getFullPath() const = 0; + + /** Open this folder. + * + * @param mode open mode (see folder::Modes) + * @param failIfModeIsNotAvailable if set to false and if the requested mode + * is not available, a more restricted mode will be selected automatically. + * If set to true and if the requested mode is not available, the opening + * will fail. + * @throw exceptions::net_exception if an error occurs + * @throw exceptions::folder_already_open if the folder is already open + * in the same session + */ + virtual void open(const int mode, bool failIfModeIsNotAvailable = false) = 0; + + /** Close this folder. + * + * @param expunge if set to true, deleted messages are expunged + * @throw exceptions::net_exception if an error occurs + */ + virtual void close(const bool expunge) = 0; + + /** Create this folder. + * + * @param type folder type (see folder::Types) + * @throw exceptions::net_exception if an error occurs + */ + virtual void create(const int type) = 0; + + /** Test whether this folder exists. + * + * @return true if the folder exists, false otherwise + */ + virtual bool exists() = 0; + + /** Delete this folder. + * The folder should be closed before attempting to delete it. + * + * @throw exceptions::net_exception if an error occurs + */ + virtual void destroy() = 0; + + /** Test whether this folder is open. + * + * @return true if the folder is open, false otherwise + */ + virtual bool isOpen() const = 0; + + /** Get a new reference to a message in this folder, given its number. + * + * @param num message sequence number + * @return a new object referencing the specified message + * @throw exceptions::net_exception if an error occurs + */ + virtual shared_ptr <message> getMessage(const int num) = 0; + + /** Get new references to messages in this folder, given either their + * sequence numbers or UIDs. + * + * To retrieve messages by their number, use: + * \code{.cpp} + * // Get messages from sequence number 5 to sequence number 8 (including) + * folder->getMessage(vmime::net::messageSet::byNumber(5, 8)); + * + * // Get all messages in the folder, starting from number 42 + * folder->getMessage(vmime::net::messageSet::byNumber(42, -1)); + * \endcode + * Or, to retrieve messages by their UID, use: + * \code{.cpp} + * // Get messages from UID 1000 to UID 1042 (including) + * folder->getMessage(vmime::net::messageSet::byUID(1000, 1042)); + * + * // Get message with UID 1042 + * folder->getMessage(vmime::net::messageSet::byUID(1042)); + * + * // Get all messages in the folder, starting from UID 1000 + * folder->getMessage(vmime::net::messageSet::byUID(1000, "*")); + * \endcode + * + * @param msgs index set of messages to retrieve + * @return new objects referencing the specified messages + * @throw exceptions::net_exception if an error occurs + */ + virtual std::vector <shared_ptr <message> > getMessages(const messageSet& msgs) = 0; + + /** Return the number of messages in this folder. + * + * @return number of messages in the folder + */ + virtual int getMessageCount() = 0; + + /** Get a new reference to a sub-folder in this folder. + * + * @param name sub-folder name + * @return a new object referencing the specified folder + * @throw exceptions::net_exception if an error occurs + */ + virtual shared_ptr <folder> getFolder(const folder::path::component& name) = 0; + + /** Get the list of all sub-folders in this folder. + * + * @param recursive if set to true, all the descendant are returned. + * If set to false, only the direct children are returned. + * @return list of sub-folders + * @throw exceptions::net_exception if an error occurs + */ + virtual std::vector <shared_ptr <folder> > getFolders(const bool recursive = false) = 0; + + /** Rename (move) this folder to another location. + * + * @param newPath new path of the folder + * @throw exceptions::net_exception if an error occurs + */ + virtual void rename(const folder::path& newPath) = 0; + + /** Remove one or more messages from this folder. + * + * @param msgs index set of messages to delete + * @throw exceptions::net_exception if an error occurs + */ + virtual void deleteMessages(const messageSet& msgs) = 0; + + /** Change the flags for one or more messages in this folder. + * + * @param msgs index set of messages on which to set the flags + * @param flags set of flags (see message::Flags) + * @param mode indicate how to treat old and new flags (see message::FlagsModes) + * @throw exceptions::net_exception if an error occurs + */ + virtual void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET) = 0; + + /** Add a message to this folder. + * + * @param msg message to add (data: header + body) + * @param flags flags for the new message + * @param date date/time for the new message (if NULL, the current time is used) + * @param progress progress listener, or NULL if not used + * @throw exceptions::net_exception if an error occurs + */ + virtual void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL) = 0; + + /** Add a message to this folder. + * + * @param is message to add (data: header + body) + * @param size size of the message to add (in bytes) + * @param flags flags for the new message + * @param date date/time for the new message (if NULL, the current time is used) + * @param progress progress listener, or NULL if not used + * @throw exceptions::net_exception if an error occurs + */ + virtual void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL) = 0; + + /** Copy messages from this folder to another folder. + * + * @param dest destination folder path + * @param msgs index set of messages to copy + * @throw exceptions::net_exception if an error occurs + */ + virtual void copyMessages(const folder::path& dest, const messageSet& msgs) = 0; + + /** Request folder status without opening it. + * + * \deprecated Use the new getStatus() method + * + * @param count will receive the number of messages in the folder + * @param unseen will receive the number of unseen messages in the folder + * @throw exceptions::net_exception if an error occurs + */ + virtual void status(int& count, int& unseen) = 0; + + /** Request folder status without opening it. + * + * @return current folder status + * @throw exceptions::net_exception if an error occurs + */ + virtual shared_ptr <folderStatus> getStatus() = 0; + + /** Expunge deleted messages. + * + * @throw exceptions::net_exception if an error occurs + */ + virtual void expunge() = 0; + + /** Return a new folder object referencing the parent folder of this folder. + * + * @return parent folder object + */ + virtual shared_ptr <folder> getParent() = 0; + + /** Return a reference to the store to which this folder belongs. + * + * @return the store object to which this folder is attached + */ + virtual shared_ptr <const store> getStore() const = 0; + + /** Return a reference to the store to which this folder belongs. + * + * @return the store object to which this folder is attached + */ + virtual shared_ptr <store> getStore() = 0; + + /** Fetch objects for the specified messages. + * + * @param msg list of message sequence numbers + * @param attribs set of attributes to fetch + * @param progress progress listener, or NULL if not used + * @throw exceptions::net_exception if an error occurs + */ + virtual void fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& attribs, utility::progressListener* progress = NULL) = 0; + + /** Fetch objects for the specified message. + * + * @param msg the message + * @param attribs set of attributes to fetch + * @throw exceptions::net_exception if an error occurs + */ + virtual void fetchMessage(shared_ptr <message> msg, const fetchAttributes& attribs) = 0; + + /** Return the list of fetchable objects supported by + * the underlying protocol (see folder::fetchAttributes). + * + * @return list of supported fetchable objects + */ + virtual int getFetchCapabilities() const = 0; + + /** Return the sequence numbers of messages whose UID equal or greater than + * the specified UID. + * + * @param uid the uid of the first message + * @throw exceptions::net_exception if an error occurs + */ + virtual std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid) = 0; + + // Event listeners + void addMessageChangedListener(events::messageChangedListener* l); + void removeMessageChangedListener(events::messageChangedListener* l); + + void addMessageCountListener(events::messageCountListener* l); + void removeMessageCountListener(events::messageCountListener* l); + + void addFolderListener(events::folderListener* l); + void removeFolderListener(events::folderListener* l); + +protected: + + void notifyMessageChanged(shared_ptr <events::messageChangedEvent> event); + void notifyMessageCount(shared_ptr <events::messageCountEvent> event); + void notifyFolder(shared_ptr <events::folderEvent> event); + void notifyEvent(shared_ptr <events::event> event); + +private: + + std::list <events::messageChangedListener*> m_messageChangedListeners; + std::list <events::messageCountListener*> m_messageCountListeners; + std::list <events::folderListener*> m_folderListeners; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_FOLDER_HPP_INCLUDED diff --git a/src/vmime/net/folderStatus.hpp b/src/vmime/net/folderStatus.hpp new file mode 100644 index 00000000..b94db052 --- /dev/null +++ b/src/vmime/net/folderStatus.hpp @@ -0,0 +1,74 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_FOLDERSTATUS_HPP_INCLUDED +#define VMIME_NET_FOLDERSTATUS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/base.hpp" + + +namespace vmime { +namespace net { + + +/** Holds the status of a mail store folder. + */ + +class VMIME_EXPORT folderStatus : public object +{ +public: + + /** Returns the total number of messages in the folder. + * + * @return number of messages + */ + virtual unsigned int getMessageCount() const = 0; + + /** Returns the number of unseen messages in the folder. + * + * @return number of unseen messages + */ + virtual unsigned int getUnseenCount() const = 0; + + /** Clones this object. + * + * @return a copy of this object + */ + virtual shared_ptr <folderStatus> clone() const = 0; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_FOLDERSTATUS_HPP_INCLUDED diff --git a/src/net/imap/IMAPConnection.cpp b/src/vmime/net/imap/IMAPConnection.cpp index 234c2b6a..234c2b6a 100644 --- a/src/net/imap/IMAPConnection.cpp +++ b/src/vmime/net/imap/IMAPConnection.cpp diff --git a/src/vmime/net/imap/IMAPConnection.hpp b/src/vmime/net/imap/IMAPConnection.hpp new file mode 100644 index 00000000..b38d0c27 --- /dev/null +++ b/src/vmime/net/imap/IMAPConnection.hpp @@ -0,0 +1,163 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPCONNECTION_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPCONNECTION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/socket.hpp" +#include "vmime/net/timeoutHandler.hpp" +#include "vmime/net/session.hpp" +#include "vmime/net/connectionInfos.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + +#include "vmime/security/authenticator.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPTag; +class IMAPStore; + + +class VMIME_EXPORT IMAPConnection : public object +{ +public: + + IMAPConnection(shared_ptr <IMAPStore> store, shared_ptr <security::authenticator> auth); + ~IMAPConnection(); + + + void connect(); + bool isConnected() const; + void disconnect(); + + + enum ProtocolStates + { + STATE_NONE, + STATE_NON_AUTHENTICATED, + STATE_AUTHENTICATED, + STATE_SELECTED, + STATE_LOGOUT + }; + + ProtocolStates state() const; + void setState(const ProtocolStates state); + + + char hierarchySeparator() const; + + + void send(bool tag, const string& what, bool end); + void sendRaw(const byte_t* buffer, const size_t count); + + IMAPParser::response* readResponse(IMAPParser::literalHandler* lh = NULL); + + + shared_ptr <const IMAPStore> getStore() const; + shared_ptr <IMAPStore> getStore(); + + shared_ptr <session> getSession(); + + void fetchCapabilities(); + void invalidateCapabilities(); + const std::vector <string> getCapabilities(); + bool hasCapability(const string& capa); + + shared_ptr <security::authenticator> getAuthenticator(); + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + + shared_ptr <const socket> getSocket() const; + + bool isMODSEQDisabled() const; + void disableMODSEQ(); + +private: + + void authenticate(); +#if VMIME_HAVE_SASL_SUPPORT + void authenticateSASL(); +#endif // VMIME_HAVE_SASL_SUPPORT + +#if VMIME_HAVE_TLS_SUPPORT + void startTLS(); +#endif // VMIME_HAVE_TLS_SUPPORT + + bool processCapabilityResponseData(const IMAPParser::response* resp); + void processCapabilityResponseData(const IMAPParser::capability_data* capaData); + + + weak_ptr <IMAPStore> m_store; + + shared_ptr <security::authenticator> m_auth; + + shared_ptr <socket> m_socket; + + shared_ptr <IMAPParser> m_parser; + + shared_ptr <IMAPTag> m_tag; + + char m_hierarchySeparator; + + ProtocolStates m_state; + + shared_ptr <timeoutHandler> m_timeoutHandler; + + bool m_secured; + shared_ptr <connectionInfos> m_cntInfos; + + bool m_firstTag; + + std::vector <string> m_capabilities; + bool m_capabilitiesFetched; + + bool m_noModSeq; + + + void internalDisconnect(); + + void initHierarchySeparator(); +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPCONNECTION_HPP_INCLUDED diff --git a/src/net/imap/IMAPFolder.cpp b/src/vmime/net/imap/IMAPFolder.cpp index fb98887c..fb98887c 100644 --- a/src/net/imap/IMAPFolder.cpp +++ b/src/vmime/net/imap/IMAPFolder.cpp diff --git a/src/vmime/net/imap/IMAPFolder.hpp b/src/vmime/net/imap/IMAPFolder.hpp new file mode 100644 index 00000000..cc7334ff --- /dev/null +++ b/src/vmime/net/imap/IMAPFolder.hpp @@ -0,0 +1,204 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPFOLDER_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPFOLDER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include <vector> +#include <map> + +#include "vmime/types.hpp" + +#include "vmime/net/folder.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPStore; +class IMAPMessage; +class IMAPConnection; +class IMAPFolderStatus; + + +/** IMAP folder implementation. + */ + +class VMIME_EXPORT IMAPFolder : public folder +{ +private: + + friend class IMAPStore; + friend class IMAPMessage; + + IMAPFolder(const IMAPFolder&); + +public: + + IMAPFolder(const folder::path& path, shared_ptr <IMAPStore> store, const int type = TYPE_UNDEFINED, const int flags = FLAG_UNDEFINED); + + ~IMAPFolder(); + + int getMode() const; + + int getType(); + + int getFlags(); + + const folder::path::component getName() const; + const folder::path getFullPath() const; + + void open(const int mode, bool failIfModeIsNotAvailable = false); + void close(const bool expunge); + void create(const int type); + + bool exists(); + + void destroy(); + + bool isOpen() const; + + shared_ptr <message> getMessage(const int num); + std::vector <shared_ptr <message> > getMessages(const messageSet& msgs); + + std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid); + + int getMessageCount(); + + shared_ptr <folder> getFolder(const folder::path::component& name); + std::vector <shared_ptr <folder> > getFolders(const bool recursive = false); + + void rename(const folder::path& newPath); + + void deleteMessages(const messageSet& msgs); + + void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); + + void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + + void copyMessages(const folder::path& dest, const messageSet& msgs); + + void status(int& count, int& unseen); + shared_ptr <folderStatus> getStatus(); + + void noop(); + + void expunge(); + + shared_ptr <folder> getParent(); + + shared_ptr <const store> getStore() const; + shared_ptr <store> getStore(); + + + void fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); + void fetchMessage(shared_ptr <message> msg, const fetchAttributes& options); + + int getFetchCapabilities() const; + + /** Returns the UID validity of the folder for the current session. + * If the server is capable of persisting UIDs accross sessions, + * this value should never change for a folder. If the UID validity + * differs across sessions, then the UIDs obtained during a previous + * session may not correspond to the UIDs of the same messages in + * this session. + * + * @return UID validity of the folder + */ + vmime_uint32 getUIDValidity() const; + + /** Returns the highest modification sequence of this folder, ie the + * modification sequence of the last message that changed in this + * folder. + * + * @return modification sequence, or zero if not supported by + * the underlying protocol + */ + vmime_uint64 getHighestModSequence() const; + +private: + + void registerMessage(IMAPMessage* msg); + void unregisterMessage(IMAPMessage* msg); + + void onStoreDisconnected(); + + void onClose(); + + int testExistAndGetType(); + + void setMessageFlagsImpl(const string& set, const int flags, const int mode); + + void copyMessagesImpl(const string& set, const folder::path& dest); + + + /** Process status updates ("unsolicited responses") contained in the + * specified response. Example: + * + * C: a006 NOOP + * S: * 930 EXISTS <-- this is a status update + * S: a006 OK Success + * + * @param resp parsed IMAP response + */ + void processStatusUpdate(const IMAPParser::response* resp); + + + weak_ptr <IMAPStore> m_store; + shared_ptr <IMAPConnection> m_connection; + + folder::path m_path; + folder::path::component m_name; + + int m_mode; + bool m_open; + + int m_type; + int m_flags; + + shared_ptr <IMAPFolderStatus> m_status; + + std::vector <IMAPMessage*> m_messages; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPFOLDER_HPP_INCLUDED diff --git a/src/net/imap/IMAPFolderStatus.cpp b/src/vmime/net/imap/IMAPFolderStatus.cpp index c78a40f3..c78a40f3 100644 --- a/src/net/imap/IMAPFolderStatus.cpp +++ b/src/vmime/net/imap/IMAPFolderStatus.cpp diff --git a/src/vmime/net/imap/IMAPFolderStatus.hpp b/src/vmime/net/imap/IMAPFolderStatus.hpp new file mode 100644 index 00000000..03ca5937 --- /dev/null +++ b/src/vmime/net/imap/IMAPFolderStatus.hpp @@ -0,0 +1,124 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPFOLDERSTATUS_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPFOLDERSTATUS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/folderStatus.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +/** Holds the status of an IMAP folder. + */ + +class VMIME_EXPORT IMAPFolderStatus : public folderStatus +{ +public: + + IMAPFolderStatus(); + IMAPFolderStatus(const IMAPFolderStatus& other); + + // Inherited from folderStatus + unsigned int getMessageCount() const; + unsigned int getUnseenCount() const; + + shared_ptr <folderStatus> clone() const; + + /** Returns the the number of messages with the Recent flag set. + * + * @return number of messages flagged Recent + */ + unsigned int getRecentCount() const; + + /** Returns the UID validity of the folder for the current session. + * If the server is capable of persisting UIDs accross sessions, + * this value should never change for a folder. + * + * @return UID validity of the folder + */ + vmime_uint32 getUIDValidity() const; + + /** Returns the UID value that will be assigned to a new message + * in the folder. If the server does not support the UIDPLUS + * extension, it will return 0. + * + * @return UID of the next message + */ + vmime_uint32 getUIDNext() const; + + /** Returns the highest modification sequence of all messages + * in the folder, or 0 if not available for this folder, or not + * supported by the server. The server must support the CONDSTORE + * extension for this to be available. + * + * @return highest modification sequence + */ + vmime_uint64 getHighestModSeq() const; + + + /** Reads the folder status from the specified IMAP response. + * + * @param resp parsed IMAP response + * @return true if the status changed, or false otherwise + */ + bool updateFromResponse(const IMAPParser::mailbox_data* resp); + + /** Reads the folder status from the specified IMAP response. + * + * @param resp parsed IMAP response + * @return true if the status changed, or false otherwise + */ + bool updateFromResponse(const IMAPParser::resp_text_code* resp); + +private: + + unsigned int m_count; + unsigned int m_unseen; + unsigned int m_recent; + vmime_uint32 m_uidValidity; + vmime_uint32 m_uidNext; + vmime_uint64 m_highestModSeq; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPFOLDERSTATUS_HPP_INCLUDED diff --git a/src/net/imap/IMAPMessage.cpp b/src/vmime/net/imap/IMAPMessage.cpp index c11aafc2..c11aafc2 100644 --- a/src/net/imap/IMAPMessage.cpp +++ b/src/vmime/net/imap/IMAPMessage.cpp diff --git a/src/vmime/net/imap/IMAPMessage.hpp b/src/vmime/net/imap/IMAPMessage.hpp new file mode 100644 index 00000000..92903d69 --- /dev/null +++ b/src/vmime/net/imap/IMAPMessage.hpp @@ -0,0 +1,191 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPMESSAGE_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPMESSAGE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/message.hpp" +#include "vmime/net/folder.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPFolder; + + +/** IMAP message implementation. + */ + +class VMIME_EXPORT IMAPMessage : public message +{ +private: + + friend class IMAPFolder; + friend class IMAPMessagePartContentHandler; + + IMAPMessage(const IMAPMessage&) : message() { } + +public: + + IMAPMessage(shared_ptr <IMAPFolder> folder, const int num); + IMAPMessage(shared_ptr <IMAPFolder> folder, const int num, const uid& uid); + + ~IMAPMessage(); + + int getNumber() const; + + const uid getUID() const; + + /** Returns the modification sequence for this message. + * + * Every time metadata for this message changes, the modification + * sequence is updated, and is greater than the previous one. The + * server must support the CONDSTORE extension for this to be + * available. + * + * @return modification sequence, or zero if not supported by + * the underlying protocol + */ + vmime_uint64 getModSequence() const; + + size_t getSize() const; + + bool isExpunged() const; + + shared_ptr <const messageStructure> getStructure() const; + shared_ptr <messageStructure> getStructure(); + + shared_ptr <const header> getHeader() const; + + int getFlags() const; + void setFlags(const int flags, const int mode = FLAG_MODE_SET); + + void extract + (utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, const size_t length = -1, + const bool peek = false) const; + + void extractPart + (shared_ptr <const messagePart> p, + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, const size_t length = -1, + const bool peek = false) const; + + void fetchPartHeader(shared_ptr <messagePart> p); + + shared_ptr <vmime::message> getParsedMessage(); + +private: + + /** Renumbers the message. + * + * @param number new sequence number + */ + void renumber(const int number); + + /** Marks the message as expunged. + */ + void setExpunged(); + + /** Processes the parsed response to fill in the attributes + * and metadata of this message. + * + * @param options one or more fetch options (see folder::fetchAttributes) + * @param msgData pointer to message_data component of the parsed response + * @return a combination of flags that specify what changed exactly on + * this message (see events::messageChangedEvent::Types) + */ + int processFetchResponse(const fetchAttributes& options, const IMAPParser::message_data* msgData); + + /** Recursively fetch part header for all parts in the structure. + * + * @param str structure for which to fetch parts headers + */ + void fetchPartHeaderForStructure(shared_ptr <messageStructure> str); + + /** Recursively contruct parsed message from structure. + * Called by getParsedMessage(). + * + * @param parentPart root body part (the message) + * @param str structure for which to construct part + * @param level current nesting level (0 is root) + */ + void constructParsedMessage(shared_ptr <bodyPart> parentPart, shared_ptr <messageStructure> str, int level = 0); + + + enum ExtractFlags + { + EXTRACT_HEADER = 0x1, + EXTRACT_BODY = 0x2, + EXTRACT_PEEK = 0x10 + }; + + void extractImpl + (shared_ptr <const messagePart> p, + utility::outputStream& os, + utility::progressListener* progress, + const size_t start, const size_t length, + const int extractFlags) const; + + + shared_ptr <header> getOrCreateHeader(); + + + void onFolderClosed(); + + weak_ptr <IMAPFolder> m_folder; + + int m_num; + size_t m_size; + int m_flags; + bool m_expunged; + uid m_uid; + vmime_uint64 m_modseq; + + shared_ptr <header> m_header; + shared_ptr <messageStructure> m_structure; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPMESSAGE_HPP_INCLUDED diff --git a/src/net/imap/IMAPMessagePart.cpp b/src/vmime/net/imap/IMAPMessagePart.cpp index eed885dc..eed885dc 100644 --- a/src/net/imap/IMAPMessagePart.cpp +++ b/src/vmime/net/imap/IMAPMessagePart.cpp diff --git a/src/vmime/net/imap/IMAPMessagePart.hpp b/src/vmime/net/imap/IMAPMessagePart.hpp new file mode 100644 index 00000000..af8581d7 --- /dev/null +++ b/src/vmime/net/imap/IMAPMessagePart.hpp @@ -0,0 +1,92 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPMESSAGEPART_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPMESSAGEPART_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/message.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPMessageStructure; + + +class VMIME_EXPORT IMAPMessagePart : public messagePart +{ +public: + + IMAPMessagePart(shared_ptr <IMAPMessagePart> parent, const int number, const IMAPParser::body_type_mpart* mpart); + IMAPMessagePart(shared_ptr <IMAPMessagePart> parent, const int number, const IMAPParser::body_type_1part* part); + + shared_ptr <const messageStructure> getStructure() const; + shared_ptr <messageStructure> getStructure(); + + shared_ptr <const IMAPMessagePart> getParent() const; + + const mediaType& getType() const; + size_t getSize() const; + int getNumber() const; + + shared_ptr <const header> getHeader() const; + + + static shared_ptr <IMAPMessagePart> create + (shared_ptr <IMAPMessagePart> parent, const int number, const IMAPParser::body* body); + + + header& getOrCreateHeader(); + +private: + + shared_ptr <IMAPMessageStructure> m_structure; + weak_ptr <IMAPMessagePart> m_parent; + shared_ptr <header> m_header; + + int m_number; + size_t m_size; + mediaType m_mediaType; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPMESSAGEPART_HPP_INCLUDED + diff --git a/src/net/imap/IMAPMessagePartContentHandler.cpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp index 1f53f082..1f53f082 100644 --- a/src/net/imap/IMAPMessagePartContentHandler.cpp +++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.cpp diff --git a/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp b/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp new file mode 100644 index 00000000..cb52b2e3 --- /dev/null +++ b/src/vmime/net/imap/IMAPMessagePartContentHandler.hpp @@ -0,0 +1,87 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/contentHandler.hpp" +#include "vmime/net/imap/IMAPMessage.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class VMIME_EXPORT IMAPMessagePartContentHandler : public contentHandler +{ +public: + + IMAPMessagePartContentHandler(shared_ptr <IMAPMessage> msg, shared_ptr <messagePart> part, const vmime::encoding& encoding); + + shared_ptr <contentHandler> clone() const; + + void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + + void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; + + size_t getLength() const; + + bool isEncoded() const; + + const vmime::encoding& getEncoding() const; + + bool isEmpty() const; + + bool isBuffered() const; + + void setContentTypeHint(const mediaType& type); + const mediaType getContentTypeHint() const; + +private: + + weak_ptr <IMAPMessage> m_message; + weak_ptr <messagePart> m_part; + + vmime::encoding m_encoding; + vmime::mediaType m_contentType; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED + diff --git a/src/net/imap/IMAPMessageStructure.cpp b/src/vmime/net/imap/IMAPMessageStructure.cpp index 8dc333e9..8dc333e9 100644 --- a/src/net/imap/IMAPMessageStructure.cpp +++ b/src/vmime/net/imap/IMAPMessageStructure.cpp diff --git a/src/vmime/net/imap/IMAPMessageStructure.hpp b/src/vmime/net/imap/IMAPMessageStructure.hpp new file mode 100644 index 00000000..44b6d6f0 --- /dev/null +++ b/src/vmime/net/imap/IMAPMessageStructure.hpp @@ -0,0 +1,75 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPMESSAGESTRUCTURE_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPMESSAGESTRUCTURE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/message.hpp" + +#include "vmime/net/imap/IMAPParser.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPMessagePart; + + +class VMIME_EXPORT IMAPMessageStructure : public messageStructure +{ +public: + + IMAPMessageStructure(); + IMAPMessageStructure(const IMAPParser::body* body); + IMAPMessageStructure(shared_ptr <IMAPMessagePart> parent, const std::vector <IMAPParser::body*>& list); + + shared_ptr <const messagePart> getPartAt(const size_t x) const; + shared_ptr <messagePart> getPartAt(const size_t x); + size_t getPartCount() const; + + static shared_ptr <IMAPMessageStructure> emptyStructure(); + +private: + + std::vector <shared_ptr <IMAPMessagePart> > m_parts; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPMESSAGESTRUCTURE_HPP_INCLUDED + diff --git a/src/vmime/net/imap/IMAPParser.hpp b/src/vmime/net/imap/IMAPParser.hpp new file mode 100644 index 00000000..8c7fcb60 --- /dev/null +++ b/src/vmime/net/imap/IMAPParser.hpp @@ -0,0 +1,5617 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPPARSER_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPPARSER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/base.hpp" +#include "vmime/dateTime.hpp" +#include "vmime/charset.hpp" +#include "vmime/exception.hpp" + +#include "vmime/utility/stringUtils.hpp" +#include "vmime/utility/progressListener.hpp" + +#include "vmime/utility/encoder/b64Encoder.hpp" +#include "vmime/utility/encoder/qpEncoder.hpp" + +#include "vmime/utility/inputStreamStringAdapter.hpp" +#include "vmime/utility/outputStreamStringAdapter.hpp" + +#include "vmime/platform.hpp" + +#include "vmime/net/timeoutHandler.hpp" +#include "vmime/net/socket.hpp" + +#include "vmime/net/imap/IMAPTag.hpp" + +#include <vector> +#include <stdexcept> +#include <memory> + + +//#define DEBUG_RESPONSE 1 + + +#if DEBUG_RESPONSE +# include <iostream> +#endif + + +namespace vmime { +namespace net { +namespace imap { + + +#if DEBUG_RESPONSE + static int IMAPParserDebugResponse_level = 0; + static std::vector <string> IMAPParserDebugResponse_stack; + + class IMAPParserDebugResponse + { + public: + + IMAPParserDebugResponse(const string& name, string& line, const size_t currentPos) + : m_name(name), m_line(line), m_pos(currentPos) + { + ++IMAPParserDebugResponse_level; + IMAPParserDebugResponse_stack.push_back(name); + + for (int i = 0 ; i < IMAPParserDebugResponse_level ; ++i) + std::cout << " "; + + std::cout << "ENTER(" << m_name << "), pos=" << m_pos; + std::cout << std::endl; + + for (std::vector <string>::iterator it = IMAPParserDebugResponse_stack.begin() ; + it != IMAPParserDebugResponse_stack.end() ; ++it) + { + std::cout << "> " << *it << " "; + } + + std::cout << std::endl; + std::cout << string(m_line.begin() + (m_pos < 30 ? 0U : m_pos - 30), + m_line.begin() + std::min(m_line.length(), m_pos + 30)) << std::endl; + + for (size_t i = (m_pos < 30 ? m_pos : (m_pos - (m_pos - 30))) ; i != 0 ; --i) + std::cout << " "; + + std::cout << "^" << std::endl; + } + + ~IMAPParserDebugResponse() + { + for (int i = 0 ; i < IMAPParserDebugResponse_level ; ++i) + std::cout << " "; + + std::cout << "LEAVE(" << m_name << "), result="; + std::cout << (std::uncaught_exception() ? "FALSE" : "TRUE") << ", pos=" << m_pos; + std::cout << std::endl; + + --IMAPParserDebugResponse_level; + IMAPParserDebugResponse_stack.pop_back(); + } + + private: + + const string& m_name; + string& m_line; + size_t m_pos; + }; + + + #define DEBUG_ENTER_COMPONENT(x) \ + IMAPParserDebugResponse dbg(x, line, *currentPos) + + #define DEBUG_FOUND(x, y) \ + std::cout << "FOUND: " << x << ": " << y << std::endl; +#else + #define DEBUG_ENTER_COMPONENT(x) + #define DEBUG_FOUND(x, y) +#endif + + +class VMIME_EXPORT IMAPParser : public object +{ +public: + + IMAPParser(weak_ptr <IMAPTag> tag, weak_ptr <socket> sok, weak_ptr <timeoutHandler> _timeoutHandler) + : m_tag(tag), m_socket(sok), m_progress(NULL), m_strict(false), + m_literalHandler(NULL), m_timeoutHandler(_timeoutHandler) + { + } + + + shared_ptr <const IMAPTag> getTag() const + { + return m_tag.lock(); + } + + void setSocket(shared_ptr <socket> sok) + { + m_socket = sok; + } + + /** Set whether we operate in strict mode (this may not work + * with some servers which are not fully standard-compliant). + * + * @param strict true to operate in strict mode, or false + * to operate in default, relaxed mode + */ + void setStrict(const bool strict) + { + m_strict = strict; + } + + /** Return true if the parser operates in strict mode, or + * false otherwise. + * + * @return true if we are in strict mode, false otherwise + */ + bool isStrict() const + { + return m_strict; + } + + + + // + // literalHandler : literal content handler + // + + class component; + + class literalHandler + { + public: + + virtual ~literalHandler() { } + + + // Abstract target class + class target + { + protected: + + target(utility::progressListener* progress) : m_progress(progress) {} + target(const target&) {} + + public: + + virtual ~target() { } + + + utility::progressListener* progressListener() { return (m_progress); } + + virtual void putData(const string& chunk) = 0; + + private: + + utility::progressListener* m_progress; + }; + + + // Target: put in a string + class targetString : public target + { + public: + + targetString(utility::progressListener* progress, vmime::string& str) + : target(progress), m_string(str) { } + + const vmime::string& string() const { return (m_string); } + vmime::string& string() { return (m_string); } + + + void putData(const vmime::string& chunk) + { + m_string += chunk; + } + + private: + + vmime::string& m_string; + }; + + + // Target: redirect to an output stream + class targetStream : public target + { + public: + + targetStream(utility::progressListener* progress, utility::outputStream& stream) + : target(progress), m_stream(stream) { } + + const utility::outputStream& stream() const { return (m_stream); } + utility::outputStream& stream() { return (m_stream); } + + + void putData(const string& chunk) + { + m_stream.write(chunk.data(), chunk.length()); + } + + private: + + utility::outputStream& m_stream; + }; + + + // Called when the parser needs to know what to do with a literal + // . comp: the component in which we are at this moment + // . data: data specific to the component (may not be used) + // + // Returns : + // . == NULL to put the literal into the response + // . != NULL to redirect the literal to the specified target + + virtual target* targetFor(const component& comp, const int data) = 0; + }; + + + // + // Base class for a terminal or a non-terminal + // + + class component + { + public: + + component() { } + virtual ~component() { } + + virtual void go(IMAPParser& parser, string& line, size_t* currentPos) = 0; + + + const string makeResponseLine(const string& comp, const string& line, + const size_t pos) + { +#if DEBUG_RESPONSE + if (pos > line.length()) + std::cout << "WARNING: component::makeResponseLine(): pos > line.length()" << std::endl; +#endif + + string result(line.substr(0, pos)); + result += "[^]"; // indicates current parser position + result += line.substr(pos, line.length()); + if (!comp.empty()) result += " [" + comp + "]"; + + return (result); + } + }; + + +#define COMPONENT_ALIAS(parent, name) \ + class name : public parent \ + { \ + void go(IMAPParser& parser, string& line, size_t* currentPos) \ + { \ + DEBUG_ENTER_COMPONENT(#name); \ + parent::go(parser, line, currentPos); \ + } \ + } + + + // + // Parse one character + // + + template <char C> + class one_char : public component + { + public: + + void go(IMAPParser& /* parser */, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT(string("one_char <") + C + ">: current='" + ((*currentPos < line.length() ? line[*currentPos] : '?')) + "'"); + + const size_t pos = *currentPos; + + if (pos < line.length() && line[pos] == C) + *currentPos = pos + 1; + else + throw exceptions::invalid_response("", makeResponseLine("", line, pos)); + } + }; + + + // + // SPACE ::= <ASCII SP, space, 0x20> + // + + class SPACE : public component + { + public: + + void go(IMAPParser& /* parser */, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("SPACE"); + + size_t pos = *currentPos; + + while (pos < line.length() && (line[pos] == ' ' || line[pos] == '\t')) + ++pos; + + if (pos > *currentPos) + *currentPos = pos; + else + throw exceptions::invalid_response("", makeResponseLine("SPACE", line, pos)); + } + }; + + + // + // CR ::= <ASCII CR, carriage return, 0x0D> + // LF ::= <ASCII LF, line feed, 0x0A> + // CRLF ::= CR LF + // + + class CRLF : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("CRLF"); + + size_t pos = *currentPos; + + parser.check <SPACE>(line, &pos, true); + + if (pos + 1 < line.length() && + line[pos] == 0x0d && line[pos + 1] == 0x0a) + { + *currentPos = pos + 2; + } + else + { + throw exceptions::invalid_response("", makeResponseLine("CRLF", line, pos)); + } + } + }; + + + // + // SPACE ::= <ASCII SP, space, 0x20> + // CTL ::= <any ASCII control character and DEL, 0x00 - 0x1f, 0x7f> + // CHAR ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f> + // ATOM_CHAR ::= <any CHAR except atom_specials> + // atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards / quoted_specials + // list_wildcards ::= "%" / "*" + // quoted_specials ::= <"> / "\" + // + // tag ::= 1*<any ATOM_CHAR except "+"> (named "xtag") + // + + class xtag : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("tag"); + + size_t pos = *currentPos; + + bool end = false; + + string tagString; + tagString.reserve(10); + + while (!end && pos < line.length()) + { + const unsigned char c = line[pos]; + + switch (c) + { + case '+': + case '(': + case ')': + case '{': + case 0x20: // SPACE + case '%': // list_wildcards + case '*': // list_wildcards + case '"': // quoted_specials + case '\\': // quoted_specials + + end = true; + break; + + default: + + if (c <= 0x1f || c >= 0x7f) + end = true; + else + { + tagString += c; + ++pos; + } + + break; + } + } + + if (tagString == string(*parser.getTag())) + { + *currentPos = pos; + } + else + { + // Invalid tag + throw exceptions::invalid_response("", makeResponseLine("tag", line, pos)); + } + } + }; + + + // + // digit ::= "0" / digit_nz + // digit_nz ::= "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" + // + // number ::= 1*digit + // ;; Unsigned 32-bit integer + // ;; (0 <= n < 4,294,967,296) + // + + class number : public component + { + public: + + number(const bool nonZero = false) + : m_nonZero(nonZero), m_value(0) + { + } + + void go(IMAPParser& /* parser */, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("number"); + + size_t pos = *currentPos; + + bool valid = true; + unsigned int val = 0; + + while (valid && pos < line.length()) + { + const char c = line[pos]; + + if (c >= '0' && c <= '9') + { + val = (val * 10) + (c - '0'); + ++pos; + } + else + { + valid = false; + } + } + + // Check for non-null length (and for non-zero number) + if (!(m_nonZero && val == 0) && pos != *currentPos) + { + m_value = val; + *currentPos = pos; + } + else + { + throw exceptions::invalid_response("", makeResponseLine("number", line, pos)); + } + } + + private: + + const bool m_nonZero; + unsigned long m_value; + + public: + + unsigned long value() const { return (m_value); } + }; + + + // nz_number ::= digit_nz *digit + // ;; Non-zero unsigned 32-bit integer + // ;; (0 < n < 4,294,967,296) + // + + class nz_number : public number + { + public: + + nz_number() : number(true) + { + } + }; + + + // + // text ::= 1*TEXT_CHAR + // + // CHAR ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f> + // TEXT_CHAR ::= <any CHAR except CR and LF> + // + + class text : public component + { + public: + + text(bool allow8bits = false, const char except = 0) + : m_allow8bits(allow8bits), m_except(except) + { + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("text"); + + size_t pos = *currentPos; + size_t len = 0; + + if (m_allow8bits || !parser.isStrict()) + { + const unsigned char except = m_except; + + for (bool end = false ; !end && pos < line.length() ; ) + { + const unsigned char c = line[pos]; + + if (c == 0x00 || c == 0x0d || c == 0x0a || c == except) + { + end = true; + } + else + { + ++pos; + ++len; + } + } + } + else + { + const unsigned char except = m_except; + + for (bool end = false ; !end && pos < line.length() ; ) + { + const unsigned char c = line[pos]; + + if (c < 0x01 || c > 0x7f || c == 0x0d || c == 0x0a || c == except) + { + end = true; + } + else + { + ++pos; + ++len; + } + } + } + + if (len != 0) + { + m_value.resize(len); + std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin()); + + *currentPos = pos; + } + else + { + throw exceptions::invalid_response("", makeResponseLine("text", line, pos)); + } + } + + private: + + string m_value; + const bool m_allow8bits; + const char m_except; + + public: + + const string& value() const { return (m_value); } + }; + + + class text8 : public text + { + public: + + text8() : text(true) + { + } + }; + + + template <char C> + class text_except : public text + { + public: + + text_except() : text(false, C) + { + } + }; + + + template <char C> + class text8_except : public text + { + public: + + text8_except() : text(true, C) + { + } + }; + + + // + // QUOTED_CHAR ::= <any TEXT_CHAR except quoted_specials> / "\" quoted_specials + // quoted_specials ::= <"> / "\" + // TEXT_CHAR ::= <any CHAR except CR and LF> + // CHAR ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f> + // + + class QUOTED_CHAR : public component + { + public: + + void go(IMAPParser& /* parser */, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("quoted_char"); + + size_t pos = *currentPos; + + const unsigned char c = static_cast <unsigned char>(pos < line.length() ? line[pos] : 0); + + if (c >= 0x01 && c <= 0x7f && // 0x01 - 0x7f + c != '"' && c != '\\' && // quoted_specials + c != '\r' && c != '\n') // CR and LF + { + m_value = c; + *currentPos = pos + 1; + } + else if (c == '\\' && pos + 1 < line.length() && + (line[pos + 1] == '"' || line[pos + 1] == '\\')) + { + m_value = line[pos + 1]; + *currentPos = pos + 2; + } + else + { + throw exceptions::invalid_response("", makeResponseLine("QUOTED_CHAR", line, pos)); + } + } + + private: + + char m_value; + + public: + + char value() const { return (m_value); } + }; + + + // + // quoted ::= <"> *QUOTED_CHAR <"> + // QUOTED_CHAR ::= <any TEXT_CHAR except quoted_specials> / "\" quoted_specials + // quoted_specials ::= <"> / "\" + // TEXT_CHAR ::= <any CHAR except CR and LF> + // CHAR ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f> + // + + class quoted_text : public component + { + public: + + void go(IMAPParser& /* parser */, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("quoted_text"); + + size_t pos = *currentPos; + size_t len = 0; + bool valid = false; + + m_value.reserve(line.length() - pos); + + for (bool end = false, quoted = false ; !end && pos < line.length() ; ) + { + const unsigned char c = line[pos]; + + if (quoted) + { + if (c == '"' || c == '\\') + m_value += c; + else + { + m_value += '\\'; + m_value += c; + } + + quoted = false; + + ++pos; + ++len; + } + else + { + if (c == '\\') + { + quoted = true; + + ++pos; + ++len; + } + else if (c == '"') + { + valid = true; + end = true; + } + else if (c >= 0x01 && c <= 0x7f && // CHAR + c != 0x0a && c != 0x0d) // CR and LF + { + m_value += c; + + ++pos; + ++len; + } + else + { + valid = false; + end = true; + } + } + } + + if (valid) + { + *currentPos = pos; + } + else + { + throw exceptions::invalid_response("", makeResponseLine("quoted_text", line, pos)); + } + } + + private: + + string m_value; + + public: + + const string& value() const { return (m_value); } + }; + + + // + // nil ::= "NIL" + // + + class NIL : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("NIL"); + + size_t pos = *currentPos; + + parser.checkWithArg <special_atom>(line, &pos, "nil"); + + *currentPos = pos; + } + }; + + + // + // string ::= quoted / literal ----> named 'xstring' + // + // nil ::= "NIL" + // quoted ::= <"> *QUOTED_CHAR <"> + // QUOTED_CHAR ::= <any TEXT_CHAR except quoted_specials> / "\" quoted_specials + // quoted_specials ::= <"> / "\" + // TEXT_CHAR ::= <any CHAR except CR and LF> + // CHAR ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f> + // literal ::= "{" number "}" CRLF *CHAR8 + // ;; Number represents the number of CHAR8 octets + // CHAR8 ::= <any 8-bit octet except NUL, 0x01 - 0xff> + // + + class xstring : public component + { + public: + + xstring(const bool canBeNIL = false, component* comp = NULL, const int data = 0) + : m_canBeNIL(canBeNIL), m_component(comp), m_data(data) + { + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("string"); + + size_t pos = *currentPos; + + if (m_canBeNIL && + parser.checkWithArg <special_atom>(line, &pos, "nil", true)) + { + // NIL + } + else + { + pos = *currentPos; + + // quoted ::= <"> *QUOTED_CHAR <"> + if (parser.check <one_char <'"'> >(line, &pos, true)) + { + std::auto_ptr <quoted_text> text(parser.get <quoted_text>(line, &pos)); + parser.check <one_char <'"'> >(line, &pos); + + if (parser.m_literalHandler != NULL) + { + literalHandler::target* target = + parser.m_literalHandler->targetFor(*m_component, m_data); + + if (target != NULL) + { + m_value = "[literal-handler]"; + + const size_t length = text->value().length(); + utility::progressListener* progress = target->progressListener(); + + if (progress) + { + progress->start(length); + } + + target->putData(text->value()); + + if (progress) + { + progress->progress(length, length); + progress->stop(length); + } + + delete (target); + } + else + { + m_value = text->value(); + } + } + else + { + m_value = text->value(); + } + + DEBUG_FOUND("string[quoted]", "<length=" << m_value.length() << ", value='" << m_value << "'>"); + } + // literal ::= "{" number "}" CRLF *CHAR8 + else + { + parser.check <one_char <'{'> >(line, &pos); + + number* num = parser.get <number>(line, &pos); + + const size_t length = num->value(); + delete (num); + + parser.check <one_char <'}'> >(line, &pos); + + parser.check <CRLF>(line, &pos); + + + if (parser.m_literalHandler != NULL) + { + literalHandler::target* target = + parser.m_literalHandler->targetFor(*m_component, m_data); + + if (target != NULL) + { + m_value = "[literal-handler]"; + + parser.m_progress = target->progressListener(); + parser.readLiteral(*target, length); + parser.m_progress = NULL; + + delete (target); + } + else + { + literalHandler::targetString target(NULL, m_value); + parser.readLiteral(target, length); + } + } + else + { + literalHandler::targetString target(NULL, m_value); + parser.readLiteral(target, length); + } + + line += parser.readLine(); + + DEBUG_FOUND("string[literal]", "<length=" << length << ", value='" << m_value << "'>"); + } + } + + *currentPos = pos; + } + + private: + + bool m_canBeNIL; + string m_value; + + component* m_component; + const int m_data; + + public: + + const string& value() const { return (m_value); } + void setValue(const string& val) { m_value = val; } + }; + + + // + // nstring ::= string / nil + // + + class nstring : public xstring + { + public: + + nstring(component* comp = NULL, const int data = 0) + : xstring(true, comp, data) + { + } + }; + + + // + // astring ::= atom / string + // + + class astring : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("astring"); + + size_t pos = *currentPos; + + xstring* str = NULL; + + if ((str = parser.get <xstring>(line, &pos, true))) + { + m_value = str->value(); + delete (str); + } + else + { + atom* at = parser.get <atom>(line, &pos); + m_value = at->value(); + delete (at); + } + + *currentPos = pos; + } + + private: + + string m_value; + + public: + + const string& value() const { return (m_value); } + }; + + + // + // atom ::= 1*ATOM_CHAR + // + // ATOM_CHAR ::= <any CHAR except atom_specials> + // atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards / quoted_specials + // CHAR ::= <any 7-bit US-ASCII character except NUL, 0x01 - 0x7f> + // CTL ::= <any ASCII control character and DEL, 0x00 - 0x1f, 0x7f> + // list_wildcards ::= "%" / "*" + // quoted_specials ::= <"> / "\" + // SPACE ::= <ASCII SP, space, 0x20> + // + + class atom : public component + { + public: + + void go(IMAPParser& /* parser */, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("atom"); + + size_t pos = *currentPos; + size_t len = 0; + + for (bool end = false ; !end && pos < line.length() ; ) + { + const unsigned char c = line[pos]; + + switch (c) + { + case '(': + case ')': + case '{': + case 0x20: // SPACE + case '%': // list_wildcards + case '*': // list_wildcards + case '"': // quoted_specials + case '\\': // quoted_specials + + case '[': + case ']': // for "special_atom" + + end = true; + break; + + default: + + if (c <= 0x1f || c >= 0x7f) + end = true; + else + { + ++pos; + ++len; + } + } + } + + if (len != 0) + { + m_value.resize(len); + std::copy(line.begin() + *currentPos, line.begin() + pos, m_value.begin()); + + *currentPos = pos; + } + else + { + throw exceptions::invalid_response("", makeResponseLine("atom", line, pos)); + } + } + + private: + + string m_value; + + public: + + const string& value() const { return (m_value); } + }; + + + // + // special atom (eg. "CAPABILITY", "FLAGS", "STATUS"...) + // + // " Except as noted otherwise, all alphabetic characters are case- + // insensitive. The use of upper or lower case characters to define + // token strings is for editorial clarity only. Implementations MUST + // accept these strings in a case-insensitive fashion. " + // + + class special_atom : public atom + { + public: + + special_atom(const char* str) + : m_string(str) // 'string' must be in lower-case + { + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT(string("special_atom(") + m_string + ")"); + + size_t pos = *currentPos; + + atom::go(parser, line, &pos); + + const char* cmp = value().c_str(); + const char* with = m_string; + + bool ok = true; + + while (ok && *cmp && *with) + { + ok = (std::tolower(*cmp, std::locale()) == *with); + + ++cmp; + ++with; + } + + if (!ok || *cmp || *with) + { + throw exceptions::invalid_response("", makeResponseLine(string("special_atom <") + m_string + ">", line, pos)); + } + else + { + *currentPos = pos; + } + } + + private: + + const char* m_string; + }; + + + // + // text_mime2 ::= "=?" <charset> "?" <encoding> "?" <encoded-text> "?=" + // ;; Syntax defined in [MIME-HDRS] + // + + class text_mime2 : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("text_mime2"); + + size_t pos = *currentPos; + + atom* theCharset = NULL, *theEncoding = NULL; + text* theText = NULL; + + try + { + parser.check <one_char <'='> >(line, &pos); + parser.check <one_char <'?'> >(line, &pos); + + theCharset = parser.get <atom>(line, &pos); + + parser.check <one_char <'?'> >(line, &pos); + + theEncoding = parser.get <atom>(line, &pos); + + parser.check <one_char <'?'> >(line, &pos); + + theText = parser.get <text8_except <'?'> >(line, &pos); + + parser.check <one_char <'?'> >(line, &pos); + parser.check <one_char <'='> >(line, &pos); + } + catch (std::exception&) + { + delete (theCharset); + delete (theEncoding); + delete (theText); + + throw; + } + + m_charset = theCharset->value(); + delete (theCharset); + + // Decode text + utility::encoder::encoder* theEncoder = NULL; + + if (theEncoding->value()[0] == 'q' || theEncoding->value()[0] == 'Q') + { + // Quoted-printable + theEncoder = new utility::encoder::qpEncoder(); + theEncoder->getProperties()["rfc2047"] = true; + } + else if (theEncoding->value()[0] == 'b' || theEncoding->value()[0] == 'B') + { + // Base64 + theEncoder = new utility::encoder::b64Encoder(); + } + + if (theEncoder) + { + utility::inputStreamStringAdapter in(theText->value()); + utility::outputStreamStringAdapter out(m_value); + + theEncoder->decode(in, out); + delete (theEncoder); + } + // No decoder available + else + { + m_value = theText->value(); + } + + delete (theEncoding); + delete (theText); + + *currentPos = pos; + } + + private: + + vmime::charset m_charset; + string m_value; + + public: + + const vmime::charset& charset() const { return (m_charset); } + const string& value() const { return (m_value); } + }; + + + // seq-number = nz-number / "*" + // ; message sequence number (COPY, FETCH, STORE + // ; commands) or unique identifier (UID COPY, + // ; UID FETCH, UID STORE commands). + + class seq_number : public component + { + public: + + seq_number() + : m_number(NULL), m_star(false) + { + } + + ~seq_number() + { + delete m_number; + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("seq_number"); + + size_t pos = *currentPos; + + if (parser.check <one_char <'*'> >(line, &pos, true)) + { + m_star = true; + m_number = NULL; + } + else + { + m_star = false; + m_number = parser.get <IMAPParser::number>(line, &pos); + } + + *currentPos = pos; + } + + private: + + IMAPParser::number* m_number; + bool m_star; + + public: + + const IMAPParser::number* number() const { return m_number; } + bool star() const { return m_star; } + }; + + + // seq-range = seq-number ":" seq-number + // ; two seq-number values and all values between + // ; these two regardless of order. + // ; Example: 2:4 and 4:2 are equivalent and indicate + // ; values 2, 3, and 4. + + class seq_range : public component + { + public: + + seq_range() + : m_first(NULL), m_last(NULL) + { + } + + ~seq_range() + { + delete m_first; + delete m_last; + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("seq_range"); + + size_t pos = *currentPos; + + m_first = parser.get <seq_number>(line, &pos); + + parser.check <one_char <'*'> >(line, &pos); + + m_last = parser.get <seq_number>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::seq_number* m_first; + IMAPParser::seq_number* m_last; + + public: + + const IMAPParser::seq_number* first() const { return m_first; } + const IMAPParser::seq_number* last() const { return m_last; } + }; + + + // sequence-set = (seq-number / seq-range) *("," sequence-set) + // ; set of seq-number values, regardless of order. + // ; Servers MAY coalesce overlaps and/or execute the + // ; sequence in any order. + // ; Example: a message sequence number set of + // ; 2,4:7,9,12:* for a mailbox with 15 messages is + // ; equivalent to 2,4,5,6,7,9,12,13,14,15 + + class sequence_set : public component + { + public: + + sequence_set() + : m_number(NULL), m_range(NULL), m_nextSet(NULL) + { + } + + ~sequence_set() + { + delete m_number; + delete m_range; + delete m_nextSet; + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("sequence_set"); + + size_t pos = *currentPos; + + if ((m_range = parser.get <IMAPParser::seq_range>(line, &pos, true)) == NULL) + m_number = parser.get <IMAPParser::seq_number>(line, &pos); + + if (parser.check <one_char <','> >(line, &pos, true)) + m_nextSet = parser.get <sequence_set>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::seq_number* m_number; + IMAPParser::seq_range* m_range; + IMAPParser::sequence_set* m_nextSet; + + public: + + const IMAPParser::seq_number* seq_number() const { return m_number; } + const IMAPParser::seq_range* seq_range() const { return m_range; } + const IMAPParser::sequence_set* next_sequence_set() const { return m_nextSet; } + }; + + + // mod-sequence-value = 1*DIGIT + // ;; Positive unsigned 64-bit integer + // ;; (mod-sequence) + // ;; (1 <= n < 18,446,744,073,709,551,615) + + class mod_sequence_value : public component + { + public: + + mod_sequence_value() + : m_value(0) + { + } + + void go(IMAPParser& /* parser */, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("mod_sequence_value"); + + size_t pos = *currentPos; + + bool valid = true; + vmime_uint64 val = 0; + + while (valid && pos < line.length()) + { + const char c = line[pos]; + + if (c >= '0' && c <= '9') + { + val = (val * 10) + (c - '0'); + ++pos; + } + else + { + valid = false; + } + } + + m_value = val; + + *currentPos = pos; + } + + private: + + vmime_uint64 m_value; + + public: + + vmime_uint64 value() const { return m_value; } + }; + + + // + // flag ::= "\Answered" / "\Flagged" / "\Deleted" / + // "\Seen" / "\Draft" / flag_keyword / flag_extension + // + // flag_extension ::= "\" atom + // ;; Future expansion. Client implementations + // ;; MUST accept flag_extension flags. Server + // ;; implementations MUST NOT generate + // ;; flag_extension flags except as defined by + // ;; future standard or standards-track + // ;; revisions of this specification. + // + // flag_keyword ::= atom + // + + class flag : public component + { + public: + + flag() + : m_type(UNKNOWN), m_flag_keyword(NULL) + { + } + + ~flag() + { + delete (m_flag_keyword); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("flag_keyword"); + + size_t pos = *currentPos; + + if (parser.check <one_char <'\\'> >(line, &pos, true)) + { + if (parser.check <one_char <'*'> >(line, &pos, true)) + { + m_type = STAR; + } + else + { + atom* at = parser.get <atom>(line, &pos); + const string name = utility::stringUtils::toLower(at->value()); + delete (at); + + if (name == "answered") + m_type = ANSWERED; + else if (name == "flagged") + m_type = FLAGGED; + else if (name == "deleted") + m_type = DELETED; + else if (name == "seen") + m_type = SEEN; + else if (name == "draft") + m_type = DRAFT; + else + { + m_type = UNKNOWN; + m_name = name; + } + } + } + else + { + m_type = KEYWORD_OR_EXTENSION; + m_flag_keyword = parser.get <atom>(line, &pos); + } + + *currentPos = pos; + } + + + enum Type + { + UNKNOWN, + ANSWERED, + FLAGGED, + DELETED, + SEEN, + DRAFT, + KEYWORD_OR_EXTENSION, + STAR // * = custom flags allowed + }; + + private: + + Type m_type; + string m_name; + + IMAPParser::atom* m_flag_keyword; + + public: + + Type type() const { return (m_type); } + const string& name() const { return (m_name); } + + const IMAPParser::atom* flag_keyword() const { return (m_flag_keyword); } + }; + + + // + // flag_list ::= "(" #flag ")" + // + + class flag_list : public component + { + public: + + ~flag_list() + { + for (std::vector <flag*>::iterator it = m_flags.begin() ; + it != m_flags.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("flag_list"); + + size_t pos = *currentPos; + + parser.check <one_char <'('> >(line, &pos); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + m_flags.push_back(parser.get <flag>(line, &pos)); + parser.check <SPACE>(line, &pos, true); + } + + *currentPos = pos; + } + + private: + + std::vector <flag*> m_flags; + + public: + + const std::vector <flag*>& flags() const { return (m_flags); } + }; + + + // + // mailbox ::= "INBOX" / astring + // ;; INBOX is case-insensitive. All case variants of + // ;; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX + // ;; not as an astring. Refer to section 5.1 for + // ;; further semantic details of mailbox names. + // + + class mailbox : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("mailbox"); + + size_t pos = *currentPos; + + if (parser.checkWithArg <special_atom>(line, &pos, "inbox", true)) + { + m_type = INBOX; + m_name = "INBOX"; + } + else + { + m_type = OTHER; + + astring* astr = parser.get <astring>(line, &pos); + m_name = astr->value(); + delete (astr); + } + + *currentPos = pos; + } + + + enum Type + { + INBOX, + OTHER + }; + + private: + + Type m_type; + string m_name; + + public: + + Type type() const { return (m_type); } + const string& name() const { return (m_name); } + }; + + + // + // mailbox_flag := "\Marked" / "\Noinferiors" / + // "\Noselect" / "\Unmarked" / flag_extension + // + + class mailbox_flag : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("mailbox_flag"); + + size_t pos = *currentPos; + + if (parser.check <one_char <'\\'> >(line, &pos, true)) + { + atom* at = parser.get <atom>(line, &pos); + const string name = utility::stringUtils::toLower(at->value()); + delete (at); + + if (name == "marked") + m_type = MARKED; + else if (name == "noinferiors") + m_type = NOINFERIORS; + else if (name == "noselect") + m_type = NOSELECT; + else if (name == "unmarked") + m_type = UNMARKED; + else + { + m_type = UNKNOWN; + m_name = "\\" + name; + } + } + else + { + atom* at = parser.get <atom>(line, &pos); + const string name = utility::stringUtils::toLower(at->value()); + delete (at); + + m_type = UNKNOWN; + m_name = name; + } + + *currentPos = pos; + } + + + enum Type + { + UNKNOWN, + MARKED, + NOINFERIORS, + NOSELECT, + UNMARKED + }; + + private: + + Type m_type; + string m_name; + + public: + + Type type() const { return (m_type); } + const string& name() const { return (m_name); } + }; + + + // + // mailbox_flag_list ::= "(" #(mailbox_flag) ")" + // + + class mailbox_flag_list : public component + { + public: + + ~mailbox_flag_list() + { + for (std::vector <mailbox_flag*>::iterator it = m_flags.begin() ; + it != m_flags.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("mailbox_flag_list"); + + size_t pos = *currentPos; + + parser.check <one_char <'('> >(line, &pos); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + m_flags.push_back(parser.get <mailbox_flag>(line, &pos)); + parser.check <SPACE>(line, &pos, true); + } + + *currentPos = pos; + } + + private: + + std::vector <mailbox_flag*> m_flags; + + public: + + const std::vector <mailbox_flag*>& flags() const { return (m_flags); } + }; + + + // + // mailbox_list ::= mailbox_flag_list SPACE + // (<"> QUOTED_CHAR <"> / nil) SPACE mailbox + // + + class mailbox_list : public component + { + public: + + mailbox_list() + : m_mailbox_flag_list(NULL), + m_mailbox(NULL), m_quoted_char('\0') + { + } + + ~mailbox_list() + { + delete (m_mailbox_flag_list); + delete (m_mailbox); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("mailbox_list"); + + size_t pos = *currentPos; + + m_mailbox_flag_list = parser.get <IMAPParser::mailbox_flag_list>(line, &pos); + + parser.check <SPACE>(line, &pos); + + if (!parser.check <NIL>(line, &pos, true)) + { + parser.check <one_char <'"'> >(line, &pos); + + QUOTED_CHAR* qc = parser.get <QUOTED_CHAR>(line, &pos); + m_quoted_char = qc->value(); + delete (qc); + + parser.check <one_char <'"'> >(line, &pos); + } + + parser.check <SPACE>(line, &pos); + + m_mailbox = parser.get <IMAPParser::mailbox>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::mailbox_flag_list* m_mailbox_flag_list; + IMAPParser::mailbox* m_mailbox; + char m_quoted_char; + + public: + + const IMAPParser::mailbox_flag_list* mailbox_flag_list() const { return (m_mailbox_flag_list); } + const IMAPParser::mailbox* mailbox() const { return (m_mailbox); } + char quoted_char() const { return (m_quoted_char); } + }; + + + // + // auth_type ::= atom + // ;; Defined by [IMAP-AUTH] + // + + class auth_type : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("auth_type"); + + atom* at = parser.get <atom>(line, currentPos); + m_name = utility::stringUtils::toLower(at->value()); + delete (at); + + if (m_name == "kerberos_v4") + m_type = KERBEROS_V4; + else if (m_name == "gssapi") + m_type = GSSAPI; + else if (m_name == "skey") + m_type = SKEY; + else + m_type = UNKNOWN; + } + + + enum Type + { + UNKNOWN, + + // RFC 1731 - IMAP4 Authentication Mechanisms + KERBEROS_V4, + GSSAPI, + SKEY + }; + + private: + + Type m_type; + string m_name; + + public: + + Type type() const { return (m_type); } + const string name() const { return (m_name); } + }; + + + // + // status-att-val = ("MESSAGES" SP number) / + // ("RECENT" SP number) / + // ("UIDNEXT" SP nz-number) / + // ("UIDVALIDITY" SP nz-number) / + // ("UNSEEN" SP number) + // + // IMAP Extension for Conditional STORE (RFC-4551): + // + // status-att-val =/ "HIGHESTMODSEQ" SP mod-sequence-valzer + // ;; extends non-terminal defined in [IMAPABNF]. + // ;; Value 0 denotes that the mailbox doesn't + // ;; support persistent mod-sequences + // + + class status_att_val : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("status_att"); + + size_t pos = *currentPos; + + // "HIGHESTMODSEQ" SP mod-sequence-valzer + if (parser.checkWithArg <special_atom>(line, &pos, "highestmodseq", true)) + { + m_type = HIGHESTMODSEQ; + + parser.check <SPACE>(line, &pos); + m_value = parser.get <IMAPParser::mod_sequence_value>(line, &pos); + } + else + { + if (parser.checkWithArg <special_atom>(line, &pos, "messages", true)) + { + m_type = MESSAGES; + } + else if (parser.checkWithArg <special_atom>(line, &pos, "recent", true)) + { + m_type = RECENT; + } + else if (parser.checkWithArg <special_atom>(line, &pos, "uidnext", true)) + { + m_type = UIDNEXT; + } + else if (parser.checkWithArg <special_atom>(line, &pos, "uidvalidity", true)) + { + m_type = UIDVALIDITY; + } + else + { + parser.checkWithArg <special_atom>(line, &pos, "unseen"); + m_type = UNSEEN; + } + + parser.check <SPACE>(line, &pos); + m_value = parser.get <IMAPParser::number>(line, &pos); + } + + *currentPos = pos; + } + + + enum Type + { + // Extensions + HIGHESTMODSEQ, + + // Standard IMAP + MESSAGES, + RECENT, + UIDNEXT, + UIDVALIDITY, + UNSEEN + }; + + private: + + Type m_type; + IMAPParser::component* m_value; + + public: + + Type type() const { return (m_type); } + + const IMAPParser::number* value_as_number() const + { + return dynamic_cast <IMAPParser::number *>(m_value); + } + + const IMAPParser::mod_sequence_value* value_as_mod_sequence_value() const + { + return dynamic_cast <IMAPParser::mod_sequence_value *>(m_value); + } + }; + + + // status-att-list = status-att-val *(SP status-att-val) + + class status_att_list : public component + { + public: + + ~status_att_list() + { + for (std::vector <status_att_val*>::iterator it = m_values.begin() ; + it != m_values.end() ; ++it) + { + delete *it; + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("status_att_list"); + + size_t pos = *currentPos; + + m_values.push_back(parser.get <IMAPParser::status_att_val>(line, &pos)); + + while (parser.check <SPACE>(line, &pos, true)) + m_values.push_back(parser.get <IMAPParser::status_att_val>(line, &pos)); + + *currentPos = pos; + } + + private: + + std::vector <status_att_val*> m_values; + + public: + + const std::vector <status_att_val*>& values() const { return m_values; } + }; + + + // + // capability ::= "AUTH=" auth_type / atom + // ;; New capabilities MUST begin with "X" or be + // ;; registered with IANA as standard or standards-track + // + + class capability : public component + { + public: + + capability() + : m_auth_type(NULL), m_atom(NULL) + { + } + + ~capability() + { + delete (m_auth_type); + delete (m_atom); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("capability"); + + size_t pos = *currentPos; + + class atom* at = parser.get <IMAPParser::atom>(line, &pos); + + string value = at->value(); + const char* str = value.c_str(); + + if ((str[0] == 'a' || str[0] == 'A') && + (str[1] == 'u' || str[1] == 'U') && + (str[2] == 't' || str[2] == 'T') && + (str[3] == 'h' || str[3] == 'H') && + (str[4] == '=')) + { + size_t pos = 5; + m_auth_type = parser.get <IMAPParser::auth_type>(value, &pos); + delete (at); + } + else + { + m_atom = at; + } + + *currentPos = pos; + } + + private: + + IMAPParser::auth_type* m_auth_type; + IMAPParser::atom* m_atom; + + public: + + const IMAPParser::auth_type* auth_type() const { return (m_auth_type); } + const IMAPParser::atom* atom() const { return (m_atom); } + }; + + + // + // capability_data ::= "CAPABILITY" SPACE [1#capability SPACE] "IMAP4rev1" + // [SPACE 1#capability] + // ;; IMAP4rev1 servers which offer RFC 1730 + // ;; compatibility MUST list "IMAP4" as the first + // ;; capability. + // + + class capability_data : public component + { + public: + + ~capability_data() + { + for (std::vector <capability*>::iterator it = m_capabilities.begin() ; + it != m_capabilities.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("capability_data"); + + size_t pos = *currentPos; + + parser.checkWithArg <special_atom>(line, &pos, "capability"); + + while (parser.check <SPACE>(line, &pos, true)) + { + capability* cap; + + if (parser.isStrict() || m_capabilities.empty()) + cap = parser.get <capability>(line, &pos); + else + cap = parser.get <capability>(line, &pos, /* noThrow */ true); // allow SPACE at end of line (Apple iCloud IMAP server) + + if (cap == NULL) break; + + m_capabilities.push_back(cap); + } + + *currentPos = pos; + } + + private: + + std::vector <capability*> m_capabilities; + + public: + + const std::vector <capability*>& capabilities() const { return (m_capabilities); } + }; + + + // + // date_day_fixed ::= (SPACE digit) / 2digit + // ;; Fixed-format version of date_day + // + // date_month ::= "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / + // "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" + // + // date_year ::= 4digit + // + // time ::= 2digit ":" 2digit ":" 2digit + // ;; Hours minutes seconds + // + // zone ::= ("+" / "-") 4digit + // ;; Signed four-digit value of hhmm representing + // ;; hours and minutes west of Greenwich (that is, + // ;; (the amount that the given time differs from + // ;; Universal Time). Subtracting the timezone + // ;; from the given time will give the UT form. + // ;; The Universal Time zone is "+0000". + // + // date_time ::= <"> date_day_fixed "-" date_month "-" date_year + // SPACE time SPACE zone <"> + // + + class date_time : public component + { + public: + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("date_time"); + + size_t pos = *currentPos; + + // <"> date_day_fixed "-" date_month "-" date_year + parser.check <one_char <'"'> >(line, &pos); + parser.check <SPACE>(line, &pos, true); + + std::auto_ptr <number> nd(parser.get <number>(line, &pos)); + + parser.check <one_char <'-'> >(line, &pos); + + std::auto_ptr <atom> amo(parser.get <atom>(line, &pos)); + + parser.check <one_char <'-'> >(line, &pos); + + std::auto_ptr <number> ny(parser.get <number>(line, &pos)); + + parser.check <SPACE>(line, &pos, true); + + // 2digit ":" 2digit ":" 2digit + std::auto_ptr <number> nh(parser.get <number>(line, &pos)); + + parser.check <one_char <':'> >(line, &pos); + + std::auto_ptr <number> nmi(parser.get <number>(line, &pos)); + + parser.check <one_char <':'> >(line, &pos); + + std::auto_ptr <number> ns(parser.get <number>(line, &pos)); + + parser.check <SPACE>(line, &pos, true); + + // ("+" / "-") 4digit + int sign = 1; + + if (!(parser.check <one_char <'+'> >(line, &pos, true))) + parser.check <one_char <'-'> >(line, &pos); + + std::auto_ptr <number> nz(parser.get <number>(line, &pos)); + + parser.check <one_char <'"'> >(line, &pos); + + + m_datetime.setHour(static_cast <int>(std::min(std::max(nh->value(), 0ul), 23ul))); + m_datetime.setMinute(static_cast <int>(std::min(std::max(nmi->value(), 0ul), 59ul))); + m_datetime.setSecond(static_cast <int>(std::min(std::max(ns->value(), 0ul), 59ul))); + + const int zone = static_cast <int>(nz->value()); + const int zh = zone / 100; // hour offset + const int zm = zone % 100; // minute offset + + m_datetime.setZone(((zh * 60) + zm) * sign); + + m_datetime.setDay(static_cast <int>(std::min(std::max(nd->value(), 1ul), 31ul))); + m_datetime.setYear(static_cast <int>(ny->value())); + + const string month(utility::stringUtils::toLower(amo->value())); + int mon = vmime::datetime::JANUARY; + + if (month.length() >= 3) + { + switch (month[0]) + { + case 'j': + { + switch (month[1]) + { + case 'a': mon = vmime::datetime::JANUARY; break; + case 'u': + { + switch (month[2]) + { + case 'n': mon = vmime::datetime::JUNE; break; + default: mon = vmime::datetime::JULY; break; + } + + break; + } + + } + + break; + } + case 'f': mon = vmime::datetime::FEBRUARY; break; + case 'm': + { + switch (month[2]) + { + case 'r': mon = vmime::datetime::MARCH; break; + default: mon = vmime::datetime::MAY; break; + } + + break; + } + case 'a': + { + switch (month[1]) + { + case 'p': mon = vmime::datetime::APRIL; break; + default: mon = vmime::datetime::AUGUST; break; + } + + break; + } + case 's': mon = vmime::datetime::SEPTEMBER; break; + case 'o': mon = vmime::datetime::OCTOBER; break; + case 'n': mon = vmime::datetime::NOVEMBER; break; + case 'd': mon = vmime::datetime::DECEMBER; break; + } + } + + m_datetime.setMonth(mon); + + *currentPos = pos; + } + + private: + + vmime::datetime m_datetime; + }; + + + // + // header_fld_name ::= astring + // + + typedef astring header_fld_name; + + + // + // header_list ::= "(" 1#header_fld_name ")" + // + + class header_list : public component + { + public: + + ~header_list() + { + for (std::vector <header_fld_name*>::iterator it = m_fld_names.begin() ; + it != m_fld_names.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("header_list"); + + size_t pos = *currentPos; + + parser.check <one_char <'('> >(line, &pos); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + m_fld_names.push_back(parser.get <header_fld_name>(line, &pos)); + parser.check <SPACE>(line, &pos, true); + } + + *currentPos = pos; + } + + private: + + std::vector <header_fld_name*> m_fld_names; + + public: + + const std::vector <header_fld_name*>& fld_names() const { return (m_fld_names); } + }; + + + // + // body_extension ::= nstring / number / "(" 1#body_extension ")" + // ;; Future expansion. Client implementations + // ;; MUST accept body_extension fields. Server + // ;; implementations MUST NOT generate + // ;; body_extension fields except as defined by + // ;; future standard or standards-track + // ;; revisions of this specification. + // + + class body_extension : public component + { + public: + + body_extension() + : m_nstring(NULL), m_number(NULL) + { + } + + ~body_extension() + { + delete (m_nstring); + delete (m_number); + + for (std::vector <body_extension*>::iterator it = m_body_extensions.begin() ; + it != m_body_extensions.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + size_t pos = *currentPos; + + if (parser.check <one_char <'('> >(line, &pos, true)) + { + m_body_extensions.push_back + (parser.get <body_extension>(line, &pos)); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + m_body_extensions.push_back(parser.get <body_extension>(line, &pos)); + parser.check <SPACE>(line, &pos, true); + } + } + else + { + if (!(m_nstring = parser.get <IMAPParser::nstring>(line, &pos, true))) + m_number = parser.get <IMAPParser::number>(line, &pos); + } + + *currentPos = pos; + } + + private: + + IMAPParser::nstring* m_nstring; + IMAPParser::number* m_number; + + std::vector <body_extension*> m_body_extensions; + + public: + + IMAPParser::nstring* nstring() const { return (m_nstring); } + IMAPParser::number* number() const { return (m_number); } + + const std::vector <body_extension*>& body_extensions() const { return (m_body_extensions); } + }; + + + // + // section_text ::= "HEADER" / "HEADER.FIELDS" [".NOT"] + // SPACE header_list / "TEXT" / "MIME" + // + + class section_text : public component + { + public: + + section_text() + : m_header_list(NULL) + { + } + + ~section_text() + { + delete (m_header_list); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("section_text"); + + size_t pos = *currentPos; + + // "HEADER.FIELDS" [".NOT"] SPACE header_list + const bool b1 = parser.checkWithArg <special_atom>(line, &pos, "header.fields.not", true); + const bool b2 = (b1 ? false : parser.checkWithArg <special_atom>(line, &pos, "header.fields", true)); + + if (b1 || b2) + { + m_type = b1 ? HEADER_FIELDS_NOT : HEADER_FIELDS; + + parser.check <SPACE>(line, &pos); + m_header_list = parser.get <IMAPParser::header_list>(line, &pos); + } + // "HEADER" + else if (parser.checkWithArg <special_atom>(line, &pos, "header", true)) + { + m_type = HEADER; + } + // "MIME" + else if (parser.checkWithArg <special_atom>(line, &pos, "mime", true)) + { + m_type = MIME; + } + // "TEXT" + else + { + m_type = TEXT; + + parser.checkWithArg <special_atom>(line, &pos, "text"); + } + + *currentPos = pos; + } + + + enum Type + { + HEADER, + HEADER_FIELDS, + HEADER_FIELDS_NOT, + MIME, + TEXT + }; + + private: + + Type m_type; + IMAPParser::header_list* m_header_list; + + public: + + Type type() const { return (m_type); } + const IMAPParser::header_list* header_list() const { return (m_header_list); } + }; + + + // + // section ::= "[" [section_text / (nz_number *["." nz_number] + // ["." (section_text / "MIME")])] "]" + // + + class section : public component + { + public: + + section() + : m_section_text1(NULL), m_section_text2(NULL) + { + } + + ~section() + { + delete (m_section_text1); + delete (m_section_text2); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("section"); + + size_t pos = *currentPos; + + parser.check <one_char <'['> >(line, &pos); + + if (!parser.check <one_char <']'> >(line, &pos, true)) + { + if (!(m_section_text1 = parser.get <section_text>(line, &pos, true))) + { + nz_number* num = parser.get <nz_number>(line, &pos); + m_nz_numbers.push_back(static_cast <unsigned int>(num->value())); + delete (num); + + while (parser.check <one_char <'.'> >(line, &pos, true)) + { + if ((num = parser.get <nz_number>(line, &pos, true))) + { + m_nz_numbers.push_back(static_cast <unsigned int>(num->value())); + delete (num); + } + else + { + m_section_text2 = parser.get <section_text>(line, &pos); + break; + } + } + } + + parser.check <one_char <']'> >(line, &pos); + } + + *currentPos = pos; + } + + private: + + section_text* m_section_text1; + section_text* m_section_text2; + std::vector <unsigned int> m_nz_numbers; + + public: + + const section_text* section_text1() const { return (m_section_text1); } + const section_text* section_text2() const { return (m_section_text2); } + const std::vector <unsigned int>& nz_numbers() const { return (m_nz_numbers); } + }; + + + // + // addr_adl ::= nstring + // ;; Holds route from [RFC-822] route-addr if + // ;; non-NIL + // + // addr_host ::= nstring + // ;; NIL indicates [RFC-822] group syntax. + // ;; Otherwise, holds [RFC-822] domain name + // + // addr_mailbox ::= nstring + // ;; NIL indicates end of [RFC-822] group; if + // ;; non-NIL and addr_host is NIL, holds + // ;; [RFC-822] group name. + // ;; Otherwise, holds [RFC-822] local-part + // + // addr_name ::= nstring + // ;; Holds phrase from [RFC-822] mailbox if + // ;; non-NIL + // + // address ::= "(" addr_name SPACE addr_adl SPACE addr_mailbox + // SPACE addr_host ")" + // + + class address : public component + { + public: + + address() + : m_addr_name(NULL), m_addr_adl(NULL), + m_addr_mailbox(NULL), m_addr_host(NULL) + { + } + + ~address() + { + delete (m_addr_name); + delete (m_addr_adl); + delete (m_addr_mailbox); + delete (m_addr_host); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("address"); + + size_t pos = *currentPos; + + parser.check <one_char <'('> >(line, &pos); + m_addr_name = parser.get <nstring>(line, &pos); + parser.check <SPACE>(line, &pos); + m_addr_adl = parser.get <nstring>(line, &pos); + parser.check <SPACE>(line, &pos); + m_addr_mailbox = parser.get <nstring>(line, &pos); + parser.check <SPACE>(line, &pos); + m_addr_host = parser.get <nstring>(line, &pos); + parser.check <one_char <')'> >(line, &pos); + + *currentPos = pos; + } + + private: + + nstring* m_addr_name; + nstring* m_addr_adl; + nstring* m_addr_mailbox; + nstring* m_addr_host; + + public: + + nstring* addr_name() const { return (m_addr_name); } + nstring* addr_adl() const { return (m_addr_adl); } + nstring* addr_mailbox() const { return (m_addr_mailbox); } + nstring* addr_host() const { return (m_addr_host); } + }; + + + // + // address_list ::= "(" 1*address ")" / nil + // + + class address_list : public component + { + public: + + ~address_list() + { + for (std::vector <address*>::iterator it = m_addresses.begin() ; + it != m_addresses.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("address_list"); + + size_t pos = *currentPos; + + if (!parser.check <NIL>(line, &pos, true)) + { + parser.check <one_char <'('> >(line, &pos); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + m_addresses.push_back(parser.get <address>(line, &pos)); + parser.check <SPACE>(line, &pos, true); + } + } + + *currentPos = pos; + } + + private: + + std::vector <address*> m_addresses; + + public: + + const std::vector <address*>& addresses() const { return (m_addresses); } + }; + + + // + // env_bcc ::= "(" 1*address ")" / nil + // + + COMPONENT_ALIAS(address_list, env_bcc); + + + // + // env_cc ::= "(" 1*address ")" / nil + // + + COMPONENT_ALIAS(address_list, env_cc); + + + // + // env_date ::= nstring + // + + COMPONENT_ALIAS(nstring, env_date); + + + // + // env_from ::= "(" 1*address ")" / nil + // + + COMPONENT_ALIAS(address_list, env_from); + + + // + // env_in_reply_to ::= nstring + // + + COMPONENT_ALIAS(nstring, env_in_reply_to); + + + // + // env_message_id ::= nstring + // + + COMPONENT_ALIAS(nstring, env_message_id); + + + // + // env_reply_to ::= "(" 1*address ")" / nil + // + + COMPONENT_ALIAS(address_list, env_reply_to); + + + // + // env_sender ::= "(" 1*address ")" / nil + // + + COMPONENT_ALIAS(address_list, env_sender); + + + // + // env_subject ::= nstring + // + + COMPONENT_ALIAS(nstring, env_subject); + + + // + // env_to ::= "(" 1*address ")" / nil + // + + COMPONENT_ALIAS(address_list, env_to); + + + // + // envelope ::= "(" env_date SPACE env_subject SPACE env_from + // SPACE env_sender SPACE env_reply_to SPACE env_to + // SPACE env_cc SPACE env_bcc SPACE env_in_reply_to + // SPACE env_message_id ")" + // + + class envelope : public component + { + public: + + envelope() + : m_env_date(NULL), m_env_subject(NULL), + m_env_from(NULL), m_env_sender(NULL), m_env_reply_to(NULL), + m_env_to(NULL), m_env_cc(NULL), m_env_bcc(NULL), + m_env_in_reply_to(NULL), m_env_message_id(NULL) + { + } + + ~envelope() + { + delete (m_env_date); + delete (m_env_subject); + delete (m_env_from); + delete (m_env_sender); + delete (m_env_reply_to); + delete (m_env_to); + delete (m_env_cc); + delete (m_env_bcc); + delete (m_env_in_reply_to); + delete (m_env_message_id); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("envelope"); + + size_t pos = *currentPos; + + parser.check <one_char <'('> >(line, &pos); + + m_env_date = parser.get <IMAPParser::env_date>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_subject = parser.get <IMAPParser::env_subject>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_from = parser.get <IMAPParser::env_from>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_sender = parser.get <IMAPParser::env_sender>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_reply_to = parser.get <IMAPParser::env_reply_to>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_to = parser.get <IMAPParser::env_to>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_cc = parser.get <IMAPParser::env_cc>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_bcc = parser.get <IMAPParser::env_bcc>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_in_reply_to = parser.get <IMAPParser::env_in_reply_to>(line, &pos); + parser.check <SPACE>(line, &pos); + + m_env_message_id = parser.get <IMAPParser::env_message_id>(line, &pos); + + parser.check <one_char <')'> >(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::env_date* m_env_date; + IMAPParser::env_subject* m_env_subject; + IMAPParser::env_from* m_env_from; + IMAPParser::env_sender* m_env_sender; + IMAPParser::env_reply_to* m_env_reply_to; + IMAPParser::env_to* m_env_to; + IMAPParser::env_cc* m_env_cc; + IMAPParser::env_bcc* m_env_bcc; + IMAPParser::env_in_reply_to* m_env_in_reply_to; + IMAPParser::env_message_id* m_env_message_id; + + public: + + const IMAPParser::env_date* env_date() const { return (m_env_date); } + const IMAPParser::env_subject* env_subject() const { return (m_env_subject); } + const IMAPParser::env_from* env_from() const { return (m_env_from); } + const IMAPParser::env_sender* env_sender() const { return (m_env_sender); } + const IMAPParser::env_reply_to* env_reply_to() const { return (m_env_reply_to); } + const IMAPParser::env_to* env_to() const { return (m_env_to); } + const IMAPParser::env_cc* env_cc() const { return (m_env_cc); } + const IMAPParser::env_bcc* env_bcc() const { return (m_env_bcc); } + const IMAPParser::env_in_reply_to* env_in_reply_to() const { return (m_env_in_reply_to); } + const IMAPParser::env_message_id* env_message_id() const { return (m_env_message_id); } + }; + + + // + // body_fld_desc ::= nstring + // + + typedef nstring body_fld_desc; + + + // + // body_fld_id ::= nstring + // + + typedef nstring body_fld_id; + + + // + // body_fld_md5 ::= nstring + // + + typedef nstring body_fld_md5; + + + // + // body_fld_octets ::= number + // + + typedef number body_fld_octets; + + + // + // body_fld_lines ::= number + // + + typedef number body_fld_lines; + + + // + // body_fld_enc ::= (<"> ("7BIT" / "8BIT" / "BINARY" / "BASE64"/ + // "QUOTED-PRINTABLE") <">) / string + // + + typedef xstring body_fld_enc; + + + // + // body_fld_param_item ::= string SPACE string + // + + class body_fld_param_item : public component + { + public: + + body_fld_param_item() + : m_string1(NULL), m_string2(NULL) + { + } + + ~body_fld_param_item() + { + delete (m_string1); + delete (m_string2); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_fld_param_item"); + + size_t pos = *currentPos; + + if (!parser.isStrict()) + { + // Some servers send an <atom> instead of a <string> here: + // eg. ... (CHARSET "X-UNKNOWN") ... + if (!(m_string1 = parser.get <xstring>(line, &pos, true))) + { + std::auto_ptr <atom> at(parser.get <atom>(line, &pos)); + + m_string1 = new xstring(); + m_string1->setValue(at->value()); + } + } + else + { + m_string1 = parser.get <xstring>(line, &pos); + } + + parser.check <SPACE>(line, &pos); + m_string2 = parser.get <xstring>(line, &pos); + + DEBUG_FOUND("body_fld_param_item", "<" << m_string1->value() << ", " << m_string2->value() << ">"); + + *currentPos = pos; + } + + private: + + xstring* m_string1; + xstring* m_string2; + + public: + + const xstring* string1() const { return (m_string1); } + const xstring* string2() const { return (m_string2); } + }; + + + // + // body_fld_param ::= "(" 1#(body_fld_param_item) ")" / nil + // + + class body_fld_param : public component + { + public: + + ~body_fld_param() + { + for (std::vector <body_fld_param_item*>::iterator it = m_items.begin() ; + it != m_items.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_fld_param"); + + size_t pos = *currentPos; + + if (parser.check <one_char <'('> >(line, &pos, true)) + { + m_items.push_back(parser.get <body_fld_param_item>(line, &pos)); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + parser.check <SPACE>(line, &pos); + m_items.push_back(parser.get <body_fld_param_item>(line, &pos)); + } + } + else + { + parser.check <NIL>(line, &pos); + } + + *currentPos = pos; + } + + private: + + std::vector <body_fld_param_item*> m_items; + + public: + + const std::vector <body_fld_param_item*>& items() const { return (m_items); } + }; + + + // + // body_fld_dsp ::= "(" string SPACE body_fld_param ")" / nil + // + + class body_fld_dsp : public component + { + public: + + body_fld_dsp() + : m_string(NULL), m_body_fld_param(NULL) + { + } + + ~body_fld_dsp() + { + delete (m_string); + delete (m_body_fld_param); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_fld_dsp"); + + size_t pos = *currentPos; + + if (parser.check <one_char <'('> >(line, &pos, true)) + { + m_string = parser.get <xstring>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fld_param = parser.get <class body_fld_param>(line, &pos); + parser.check <one_char <')'> >(line, &pos); + } + else + { + parser.check <NIL>(line, &pos); + } + + *currentPos = pos; + } + + private: + + class xstring* m_string; + class body_fld_param* m_body_fld_param; + + public: + + const class xstring* str() const { return (m_string); } + const class body_fld_param* body_fld_param() const { return (m_body_fld_param); } + }; + + + // + // body_fld_lang ::= nstring / "(" 1#string ")" + // + + class body_fld_lang : public component + { + public: + + ~body_fld_lang() + { + for (std::vector <xstring*>::iterator it = m_strings.begin() ; + it != m_strings.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_fld_lang"); + + size_t pos = *currentPos; + + if (parser.check <one_char <'('> >(line, &pos, true)) + { + m_strings.push_back(parser.get <class xstring>(line, &pos)); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + parser.check <SPACE>(line, &pos); + m_strings.push_back(parser.get <class xstring>(line, &pos)); + } + } + else + { + m_strings.push_back(parser.get <class nstring>(line, &pos)); + } + + *currentPos = pos; + } + + private: + + std::vector <xstring*> m_strings; + + public: + + const std::vector <xstring*>& strings() const { return (m_strings); } + }; + + + // + // body_fields ::= body_fld_param SPACE body_fld_id SPACE + // body_fld_desc SPACE body_fld_enc SPACE + // body_fld_octets + // + + class body_fields : public component + { + public: + + body_fields() + : m_body_fld_param(NULL), m_body_fld_id(NULL), + m_body_fld_desc(NULL), m_body_fld_enc(NULL), m_body_fld_octets(NULL) + { + } + + ~body_fields() + { + delete (m_body_fld_param); + delete (m_body_fld_id); + delete (m_body_fld_desc); + delete (m_body_fld_enc); + delete (m_body_fld_octets); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_fields"); + + size_t pos = *currentPos; + + m_body_fld_param = parser.get <IMAPParser::body_fld_param>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fld_id = parser.get <IMAPParser::body_fld_id>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fld_desc = parser.get <IMAPParser::body_fld_desc>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fld_enc = parser.get <IMAPParser::body_fld_enc>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fld_octets = parser.get <IMAPParser::body_fld_octets>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::body_fld_param* m_body_fld_param; + IMAPParser::body_fld_id* m_body_fld_id; + IMAPParser::body_fld_desc* m_body_fld_desc; + IMAPParser::body_fld_enc* m_body_fld_enc; + IMAPParser::body_fld_octets* m_body_fld_octets; + + public: + + const IMAPParser::body_fld_param* body_fld_param() const { return (m_body_fld_param); } + const IMAPParser::body_fld_id* body_fld_id() const { return (m_body_fld_id); } + const IMAPParser::body_fld_desc* body_fld_desc() const { return (m_body_fld_desc); } + const IMAPParser::body_fld_enc* body_fld_enc() const { return (m_body_fld_enc); } + const IMAPParser::body_fld_octets* body_fld_octets() const { return (m_body_fld_octets); } + }; + + + // + // media_subtype ::= string + // ;; Defined in [MIME-IMT] + // + + typedef xstring media_subtype; + + + // + // media_text ::= <"> "TEXT" <"> SPACE media_subtype + // ;; Defined in [MIME-IMT] + // + + class media_text : public component + { + public: + + media_text() + : m_media_subtype(NULL) + { + } + + ~media_text() + { + delete (m_media_subtype); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("media_text"); + + size_t pos = *currentPos; + + parser.check <one_char <'"'> >(line, &pos); + parser.checkWithArg <special_atom>(line, &pos, "text"); + parser.check <one_char <'"'> >(line, &pos); + parser.check <SPACE>(line, &pos); + + m_media_subtype = parser.get <IMAPParser::media_subtype>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::media_subtype* m_media_subtype; + + public: + + const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } + }; + + + // + // media_message ::= <"> "MESSAGE" <"> SPACE <"> "RFC822" <"> + // ;; Defined in [MIME-IMT] + // + + class media_message : public component + { + public: + + media_message() + : m_media_subtype(NULL) + { + } + + ~media_message() + { + delete m_media_subtype; + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("media_message"); + + size_t pos = *currentPos; + + parser.check <one_char <'"'> >(line, &pos); + parser.checkWithArg <special_atom>(line, &pos, "message"); + parser.check <one_char <'"'> >(line, &pos); + parser.check <SPACE>(line, &pos); + + //parser.check <one_char <'"'> >(line, &pos); + //parser.checkWithArg <special_atom>(line, &pos, "rfc822"); + //parser.check <one_char <'"'> >(line, &pos); + + m_media_subtype = parser.get <IMAPParser::media_subtype>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::media_subtype* m_media_subtype; + + public: + + const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } + }; + + + // + // media_basic ::= (<"> ("APPLICATION" / "AUDIO" / "IMAGE" / + // "MESSAGE" / "VIDEO") <">) / string) + // SPACE media_subtype + // ;; Defined in [MIME-IMT] + + class media_basic : public component + { + public: + + media_basic() + : m_media_type(NULL), m_media_subtype(NULL) + { + } + + ~media_basic() + { + delete (m_media_type); + delete (m_media_subtype); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("media_basic"); + + size_t pos = *currentPos; + + m_media_type = parser.get <xstring>(line, &pos); + + parser.check <SPACE>(line, &pos); + + m_media_subtype = parser.get <IMAPParser::media_subtype>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::xstring* m_media_type; + IMAPParser::media_subtype* m_media_subtype; + + public: + + const IMAPParser::xstring* media_type() const { return (m_media_type); } + const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } + }; + + + // + // body_ext_1part ::= body_fld_md5 [SPACE body_fld_dsp + // [SPACE body_fld_lang + // [SPACE 1#body_extension]]] + // ;; MUST NOT be returned on non-extensible + // ;; "BODY" fetch + // + + class body_ext_1part : public component + { + public: + + body_ext_1part() + : m_body_fld_md5(NULL), m_body_fld_dsp(NULL), m_body_fld_lang(NULL) + { + } + + ~body_ext_1part() + { + delete (m_body_fld_md5); + delete (m_body_fld_dsp); + delete (m_body_fld_lang); + + for (std::vector <body_extension*>::iterator it = m_body_extensions.begin() ; + it != m_body_extensions.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_ext_1part"); + + size_t pos = *currentPos; + + m_body_fld_md5 = parser.get <IMAPParser::body_fld_md5>(line, &pos); + + // [SPACE body_fld_dsp + if (parser.check <SPACE>(line, &pos, true)) + { + m_body_fld_dsp = parser.get <IMAPParser::body_fld_dsp>(line, &pos); + + // [SPACE body_fld_lang + if (parser.check <SPACE>(line, &pos, true)) + { + m_body_fld_lang = parser.get <IMAPParser::body_fld_lang>(line, &pos); + + // [SPACE 1#body_extension] + if (parser.check <SPACE>(line, &pos, true)) + { + m_body_extensions.push_back + (parser.get <body_extension>(line, &pos)); + + parser.check <SPACE>(line, &pos, true); + + body_extension* ext = NULL; + + while ((ext = parser.get <body_extension>(line, &pos, true)) != NULL) + { + m_body_extensions.push_back(ext); + parser.check <SPACE>(line, &pos, true); + } + } + } + } + + *currentPos = pos; + } + + private: + + IMAPParser::body_fld_md5* m_body_fld_md5; + IMAPParser::body_fld_dsp* m_body_fld_dsp; + IMAPParser::body_fld_lang* m_body_fld_lang; + + std::vector <body_extension*> m_body_extensions; + + public: + + const IMAPParser::body_fld_md5* body_fld_md5() const { return (m_body_fld_md5); } + const IMAPParser::body_fld_dsp* body_fld_dsp() const { return (m_body_fld_dsp); } + const IMAPParser::body_fld_lang* body_fld_lang() const { return (m_body_fld_lang); } + + const std::vector <body_extension*> body_extensions() const { return (m_body_extensions); } + }; + + + // + // body_ext_mpart ::= body_fld_param + // [SPACE body_fld_dsp SPACE body_fld_lang + // [SPACE 1#body_extension]] + // ;; MUST NOT be returned on non-extensible + // ;; "BODY" fetch + + class body_ext_mpart : public component + { + public: + + body_ext_mpart() + : m_body_fld_param(NULL), m_body_fld_dsp(NULL), m_body_fld_lang(NULL) + { + } + + ~body_ext_mpart() + { + delete (m_body_fld_param); + delete (m_body_fld_dsp); + delete (m_body_fld_lang); + + for (std::vector <body_extension*>::iterator it = m_body_extensions.begin() ; + it != m_body_extensions.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_ext_mpart"); + + size_t pos = *currentPos; + + m_body_fld_param = parser.get <IMAPParser::body_fld_param>(line, &pos); + + // [SPACE body_fld_dsp SPACE body_fld_lang [SPACE 1#body_extension]] + if (parser.check <SPACE>(line, &pos, true)) + { + m_body_fld_dsp = parser.get <IMAPParser::body_fld_dsp>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fld_lang = parser.get <IMAPParser::body_fld_lang>(line, &pos); + + // [SPACE 1#body_extension] + if (parser.check <SPACE>(line, &pos, true)) + { + m_body_extensions.push_back + (parser.get <body_extension>(line, &pos)); + + parser.check <SPACE>(line, &pos, true); + + body_extension* ext = NULL; + + while ((ext = parser.get <body_extension>(line, &pos, true)) != NULL) + { + m_body_extensions.push_back(ext); + parser.check <SPACE>(line, &pos, true); + } + } + } + + *currentPos = pos; + } + + private: + + IMAPParser::body_fld_param* m_body_fld_param; + IMAPParser::body_fld_dsp* m_body_fld_dsp; + IMAPParser::body_fld_lang* m_body_fld_lang; + + std::vector <body_extension*> m_body_extensions; + + public: + + const IMAPParser::body_fld_param* body_fld_param() const { return (m_body_fld_param); } + const IMAPParser::body_fld_dsp* body_fld_dsp() const { return (m_body_fld_dsp); } + const IMAPParser::body_fld_lang* body_fld_lang() const { return (m_body_fld_lang); } + + const std::vector <body_extension*> body_extensions() const { return (m_body_extensions); } + }; + + + // + // body_type_basic ::= media_basic SPACE body_fields + // ;; MESSAGE subtype MUST NOT be "RFC822" + // + + class body_type_basic : public component + { + public: + + body_type_basic() + : m_media_basic(NULL), m_body_fields(NULL) + { + } + + ~body_type_basic() + { + delete (m_media_basic); + delete (m_body_fields); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_type_basic"); + + size_t pos = *currentPos; + + m_media_basic = parser.get <IMAPParser::media_basic>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fields = parser.get <IMAPParser::body_fields>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::media_basic* m_media_basic; + IMAPParser::body_fields* m_body_fields; + + public: + + const IMAPParser::media_basic* media_basic() const { return (m_media_basic); } + const IMAPParser::body_fields* body_fields() const { return (m_body_fields); } + }; + + + // + // body_type_msg ::= media_message SPACE body_fields SPACE envelope + // SPACE body SPACE body_fld_lines + // + + class xbody; + typedef xbody body; + + class body_type_msg : public component + { + public: + + body_type_msg() + : m_media_message(NULL), m_body_fields(NULL), + m_envelope(NULL), m_body(NULL), m_body_fld_lines(NULL) + { + } + + ~body_type_msg() + { + delete (m_media_message); + delete (m_body_fields); + delete (m_envelope); + delete (m_body); + delete (m_body_fld_lines); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_type_msg"); + + size_t pos = *currentPos; + + m_media_message = parser.get <IMAPParser::media_message>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fields = parser.get <IMAPParser::body_fields>(line, &pos); + parser.check <SPACE>(line, &pos); + + // BUGFIX: made SPACE optional. This is not standard, but some servers + // seem to return responses like that... + m_envelope = parser.get <IMAPParser::envelope>(line, &pos); + parser.check <SPACE>(line, &pos, true); + m_body = parser.get <IMAPParser::xbody>(line, &pos); + parser.check <SPACE>(line, &pos, true); + m_body_fld_lines = parser.get <IMAPParser::body_fld_lines>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::media_message* m_media_message; + IMAPParser::body_fields* m_body_fields; + IMAPParser::envelope* m_envelope; + IMAPParser::xbody* m_body; + IMAPParser::body_fld_lines* m_body_fld_lines; + + public: + + const IMAPParser::media_message* media_message() const { return (m_media_message); } + const IMAPParser::body_fields* body_fields() const { return (m_body_fields); } + const IMAPParser::envelope* envelope() const { return (m_envelope); } + const IMAPParser::xbody* body() const { return (m_body); } + const IMAPParser::body_fld_lines* body_fld_lines() const { return (m_body_fld_lines); } + }; + + + // + // body_type_text ::= media_text SPACE body_fields SPACE body_fld_lines + // + + class body_type_text : public component + { + public: + + body_type_text() + : m_media_text(NULL), + m_body_fields(NULL), m_body_fld_lines(NULL) + { + } + + ~body_type_text() + { + delete (m_media_text); + delete (m_body_fields); + delete (m_body_fld_lines); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_type_text"); + + size_t pos = *currentPos; + + m_media_text = parser.get <IMAPParser::media_text>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fields = parser.get <IMAPParser::body_fields>(line, &pos); + parser.check <SPACE>(line, &pos); + m_body_fld_lines = parser.get <IMAPParser::body_fld_lines>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::media_text* m_media_text; + IMAPParser::body_fields* m_body_fields; + IMAPParser::body_fld_lines* m_body_fld_lines; + + public: + + const IMAPParser::media_text* media_text() const { return (m_media_text); } + const IMAPParser::body_fields* body_fields() const { return (m_body_fields); } + const IMAPParser::body_fld_lines* body_fld_lines() const { return (m_body_fld_lines); } + }; + + + // + // body_type_1part ::= (body_type_basic / body_type_msg / body_type_text) + // [SPACE body_ext_1part] + // + + class body_type_1part : public component + { + public: + + body_type_1part() + : m_body_type_basic(NULL), m_body_type_msg(NULL), + m_body_type_text(NULL), m_body_ext_1part(NULL) + { + } + + ~body_type_1part() + { + delete (m_body_type_basic); + delete (m_body_type_msg); + delete (m_body_type_text); + + delete (m_body_ext_1part); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_type_1part"); + + size_t pos = *currentPos; + + if (!(m_body_type_text = parser.get <IMAPParser::body_type_text>(line, &pos, true))) + if (!(m_body_type_msg = parser.get <IMAPParser::body_type_msg>(line, &pos, true))) + m_body_type_basic = parser.get <IMAPParser::body_type_basic>(line, &pos); + + if (parser.check <SPACE>(line, &pos, true)) + { + m_body_ext_1part = parser.get <IMAPParser::body_ext_1part>(line, &pos, true); + + if (!m_body_ext_1part) + --pos; + } + + *currentPos = pos; + } + + private: + + IMAPParser::body_type_basic* m_body_type_basic; + IMAPParser::body_type_msg* m_body_type_msg; + IMAPParser::body_type_text* m_body_type_text; + + IMAPParser::body_ext_1part* m_body_ext_1part; + + public: + + const IMAPParser::body_type_basic* body_type_basic() const { return (m_body_type_basic); } + const IMAPParser::body_type_msg* body_type_msg() const { return (m_body_type_msg); } + const IMAPParser::body_type_text* body_type_text() const { return (m_body_type_text); } + + const IMAPParser::body_ext_1part* body_ext_1part() const { return (m_body_ext_1part); } + }; + + + // + // body_type_mpart ::= 1*body SPACE media_subtype + // [SPACE body_ext_mpart] + // + + class body_type_mpart : public component + { + public: + + body_type_mpart() + : m_media_subtype(NULL), m_body_ext_mpart(NULL) + { + } + + ~body_type_mpart() + { + delete (m_media_subtype); + delete (m_body_ext_mpart); + + for (std::vector <xbody*>::iterator it = m_list.begin() ; + it != m_list.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body_type_mpart"); + + size_t pos = *currentPos; + + m_list.push_back(parser.get <xbody>(line, &pos)); + + for (xbody* b ; (b = parser.get <xbody>(line, &pos, true)) ; ) + m_list.push_back(b); + + parser.check <SPACE>(line, &pos); + + m_media_subtype = parser.get <IMAPParser::media_subtype>(line, &pos); + + if (parser.check <SPACE>(line, &pos, true)) + m_body_ext_mpart = parser.get <IMAPParser::body_ext_mpart>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::media_subtype* m_media_subtype; + IMAPParser::body_ext_mpart* m_body_ext_mpart; + + std::vector <xbody*> m_list; + + public: + + const std::vector <IMAPParser::xbody*>& list() const { return (m_list); } + + const IMAPParser::media_subtype* media_subtype() const { return (m_media_subtype); } + const IMAPParser::body_ext_mpart* body_ext_mpart() const { return (m_body_ext_mpart); } + }; + + + // + // xbody ::= "(" body_type_1part / body_type_mpart ")" + // + + class xbody : public component + { + public: + + xbody() + : m_body_type_1part(NULL), m_body_type_mpart(NULL) + { + } + + ~xbody() + { + delete (m_body_type_1part); + delete (m_body_type_mpart); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("body"); + + size_t pos = *currentPos; + + parser.check <one_char <'('> >(line, &pos); + + if (!(m_body_type_mpart = parser.get <IMAPParser::body_type_mpart>(line, &pos, true))) + m_body_type_1part = parser.get <IMAPParser::body_type_1part>(line, &pos); + + parser.check <one_char <')'> >(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::body_type_1part* m_body_type_1part; + IMAPParser::body_type_mpart* m_body_type_mpart; + + public: + + const IMAPParser::body_type_1part* body_type_1part() const { return (m_body_type_1part); } + const IMAPParser::body_type_mpart* body_type_mpart() const { return (m_body_type_mpart); } + }; + + + // + // uniqueid ::= nz_number + // ;; Strictly ascending + // + // msg_att_item ::= "ENVELOPE" SPACE envelope / + // "FLAGS" SPACE "(" #(flag / "\Recent") ")" / + // "INTERNALDATE" SPACE date_time / + // "RFC822" [".HEADER" / ".TEXT"] SPACE nstring / + // "RFC822.SIZE" SPACE number / + // "BODY" ["STRUCTURE"] SPACE body / + // "BODY" section ["<" number ">"] SPACE nstring / + // "UID" SPACE uniqueid + // + // IMAP Extension for Conditional STORE (RFC-4551): + // + // msg_att_item /= "MODSEQ" SP "(" mod_sequence_value ")" + + class msg_att_item : public component + { + public: + + msg_att_item() + : m_date_time(NULL), m_number(NULL), m_envelope(NULL), + m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL), + m_section(NULL), m_mod_sequence_value(NULL) + + { + } + + ~msg_att_item() + { + delete (m_date_time); + delete (m_number); + delete (m_envelope); + delete (m_uniqueid); + delete (m_nstring); + delete (m_body); + delete (m_flag_list); + delete (m_section); + delete m_mod_sequence_value; + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("msg_att_item"); + + size_t pos = *currentPos; + + // "ENVELOPE" SPACE envelope + if (parser.checkWithArg <special_atom>(line, &pos, "envelope", true)) + { + m_type = ENVELOPE; + + parser.check <SPACE>(line, &pos); + m_envelope = parser.get <IMAPParser::envelope>(line, &pos); + } + // "FLAGS" SPACE "(" #(flag / "\Recent") ")" + else if (parser.checkWithArg <special_atom>(line, &pos, "flags", true)) + { + m_type = FLAGS; + + parser.check <SPACE>(line, &pos); + + m_flag_list = parser.get <IMAPParser::flag_list>(line, &pos); + } + // "INTERNALDATE" SPACE date_time + else if (parser.checkWithArg <special_atom>(line, &pos, "internaldate", true)) + { + m_type = INTERNALDATE; + + parser.check <SPACE>(line, &pos); + m_date_time = parser.get <IMAPParser::date_time>(line, &pos); + } + // "RFC822" ".HEADER" SPACE nstring + else if (parser.checkWithArg <special_atom>(line, &pos, "rfc822.header", true)) + { + m_type = RFC822_HEADER; + + parser.check <SPACE>(line, &pos); + + m_nstring = parser.get <IMAPParser::nstring>(line, &pos); + } + // "RFC822" ".TEXT" SPACE nstring + else if (parser.checkWithArg <special_atom>(line, &pos, "rfc822.text", true)) + { + m_type = RFC822_TEXT; + + parser.check <SPACE>(line, &pos); + + m_nstring = parser.getWithArgs <IMAPParser::nstring> + (line, &pos, this, RFC822_TEXT); + } + // "RFC822.SIZE" SPACE number + else if (parser.checkWithArg <special_atom>(line, &pos, "rfc822.size", true)) + { + m_type = RFC822_SIZE; + + parser.check <SPACE>(line, &pos); + m_number = parser.get <IMAPParser::number>(line, &pos); + } + // "RFC822" SPACE nstring + else if (parser.checkWithArg <special_atom>(line, &pos, "rfc822", true)) + { + m_type = RFC822; + + parser.check <SPACE>(line, &pos); + + m_nstring = parser.get <IMAPParser::nstring>(line, &pos); + } + // "BODY" "STRUCTURE" SPACE body + else if (parser.checkWithArg <special_atom>(line, &pos, "bodystructure", true)) + { + m_type = BODY_STRUCTURE; + + parser.check <SPACE>(line, &pos); + + m_body = parser.get <IMAPParser::body>(line, &pos); + } + // "BODY" section ["<" number ">"] SPACE nstring + // "BODY" SPACE body + else if (parser.checkWithArg <special_atom>(line, &pos, "body", true)) + { + m_section = parser.get <IMAPParser::section>(line, &pos, true); + + // "BODY" section ["<" number ">"] SPACE nstring + if (m_section != NULL) + { + m_type = BODY_SECTION; + + if (parser.check <one_char <'<'> >(line, &pos, true)) + { + m_number = parser.get <IMAPParser::number>(line, &pos); + parser.check <one_char <'>'> >(line, &pos); + } + + parser.check <SPACE>(line, &pos); + + m_nstring = parser.getWithArgs <IMAPParser::nstring> + (line, &pos, this, BODY_SECTION); + } + // "BODY" SPACE body + else + { + m_type = BODY; + + parser.check <SPACE>(line, &pos); + + m_body = parser.get <IMAPParser::body>(line, &pos); + } + } + // "MODSEQ" SP "(" mod_sequence_value ")" + else if (parser.checkWithArg <special_atom>(line, &pos, "modseq", true)) + { + m_type = MODSEQ; + + parser.check <SPACE>(line, &pos); + parser.check <one_char <'('> >(line, &pos); + + m_mod_sequence_value = parser.get <IMAPParser::mod_sequence_value>(line, &pos); + + parser.check <one_char <')'> >(line, &pos); + } + // "UID" SPACE uniqueid + else + { + m_type = UID; + + parser.checkWithArg <special_atom>(line, &pos, "uid"); + parser.check <SPACE>(line, &pos); + + m_uniqueid = parser.get <nz_number>(line, &pos); + } + + *currentPos = pos; + } + + + enum Type + { + ENVELOPE, + FLAGS, + INTERNALDATE, + RFC822, + RFC822_SIZE, + RFC822_HEADER, + RFC822_TEXT, + BODY, + BODY_SECTION, + BODY_STRUCTURE, + UID, + MODSEQ + }; + + private: + + Type m_type; + + IMAPParser::date_time* m_date_time; + IMAPParser::number* m_number; + IMAPParser::envelope* m_envelope; + IMAPParser::nz_number* m_uniqueid; + IMAPParser::nstring* m_nstring; + IMAPParser::xbody* m_body; + IMAPParser::flag_list* m_flag_list; + IMAPParser::section* m_section; + IMAPParser::mod_sequence_value* m_mod_sequence_value; + + public: + + Type type() const { return (m_type); } + + const IMAPParser::date_time* date_time() const { return (m_date_time); } + const IMAPParser::number* number() const { return (m_number); } + const IMAPParser::envelope* envelope() const { return (m_envelope); } + const IMAPParser::nz_number* unique_id() const { return (m_uniqueid); } + const IMAPParser::nstring* nstring() const { return (m_nstring); } + const IMAPParser::xbody* body() const { return (m_body); } + const IMAPParser::flag_list* flag_list() const { return (m_flag_list); } + const IMAPParser::section* section() const { return (m_section); } + const IMAPParser::mod_sequence_value* mod_sequence_value() { return m_mod_sequence_value; } + }; + + + // + // msg_att ::= "(" 1#(msg_att_item) ")" + // + + class msg_att : public component + { + public: + + ~msg_att() + { + for (std::vector <msg_att_item*>::iterator it = m_items.begin() ; + it != m_items.end() ; ++it) + { + delete (*it); + } + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("msg_att"); + + size_t pos = *currentPos; + + parser.check <one_char <'('> >(line, &pos); + + m_items.push_back(parser.get <msg_att_item>(line, &pos)); + + while (!parser.check <one_char <')'> >(line, &pos, true)) + { + parser.check <SPACE>(line, &pos); + m_items.push_back(parser.get <msg_att_item>(line, &pos)); + } + + *currentPos = pos; + } + + private: + + std::vector <msg_att_item*> m_items; + + public: + + const std::vector <msg_att_item*>& items() const { return (m_items); } + }; + + + // + // message_data ::= nz_number SPACE ("EXPUNGE" / + // ("FETCH" SPACE msg_att)) + // + + class message_data : public component + { + public: + + message_data() + : m_number(0), m_msg_att(NULL) + { + } + + ~message_data() + { + delete (m_msg_att); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("message_data"); + + size_t pos = *currentPos; + + nz_number* num = parser.get <nz_number>(line, &pos); + m_number = static_cast <unsigned int>(num->value()); + delete (num); + + parser.check <SPACE>(line, &pos); + + if (parser.checkWithArg <special_atom>(line, &pos, "expunge", true)) + { + m_type = EXPUNGE; + } + else + { + parser.checkWithArg <special_atom>(line, &pos, "fetch"); + + parser.check <SPACE>(line, &pos); + + m_type = FETCH; + m_msg_att = parser.get <IMAPParser::msg_att>(line, &pos); + } + + *currentPos = pos; + } + + + enum Type + { + EXPUNGE, + FETCH + }; + + private: + + Type m_type; + unsigned int m_number; + IMAPParser::msg_att* m_msg_att; + + public: + + Type type() const { return (m_type); } + unsigned int number() const { return (m_number); } + const IMAPParser::msg_att* msg_att() const { return (m_msg_att); } + }; + + + // + // resp_text_code ::= "ALERT" / "PARSE" / + // capability-data / + // "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" / + // "READ-ONLY" / "READ-WRITE" / "TRYCREATE" / + // "UIDVALIDITY" SPACE nz_number / + // "UNSEEN" SPACE nz_number / + // atom [SPACE 1*<any TEXT_CHAR except "]">] + // + // IMAP Extension for Conditional STORE (RFC-4551): + // + // resp-text-code =/ "HIGHESTMODSEQ" SP mod-sequence-value / + // "NOMODSEQ" / + // "MODIFIED" SP set + + class resp_text_code : public component + { + public: + + resp_text_code() + : m_nz_number(NULL), m_atom(NULL), m_flag_list(NULL), + m_text(NULL), m_capability_data(NULL) + { + } + + ~resp_text_code() + { + delete (m_nz_number); + delete (m_atom); + delete (m_flag_list); + delete (m_text); + delete m_capability_data; + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("resp_text_code"); + + size_t pos = *currentPos; + + // "ALERT" + if (parser.checkWithArg <special_atom>(line, &pos, "alert", true)) + { + m_type = ALERT; + } + // "PARSE" + else if (parser.checkWithArg <special_atom>(line, &pos, "parse", true)) + { + m_type = PARSE; + } + // capability_data + else if ((m_capability_data = parser.get <IMAPParser::capability_data>(line, &pos, true))) + { + m_type = CAPABILITY; + } + // "PERMANENTFLAGS" SPACE flag_list + else if (parser.checkWithArg <special_atom>(line, &pos, "permanentflags", true)) + { + m_type = PERMANENTFLAGS; + + parser.check <SPACE>(line, &pos); + + m_flag_list = parser.get <IMAPParser::flag_list>(line, &pos); + } + // "READ-ONLY" + else if (parser.checkWithArg <special_atom>(line, &pos, "read-only", true)) + { + m_type = READ_ONLY; + } + // "READ-WRITE" + else if (parser.checkWithArg <special_atom>(line, &pos, "read-write", true)) + { + m_type = READ_WRITE; + } + // "TRYCREATE" + else if (parser.checkWithArg <special_atom>(line, &pos, "trycreate", true)) + { + m_type = TRYCREATE; + } + // "UIDVALIDITY" SPACE nz_number + else if (parser.checkWithArg <special_atom>(line, &pos, "uidvalidity", true)) + { + m_type = UIDVALIDITY; + + parser.check <SPACE>(line, &pos); + m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos); + } + // "UIDNEXT" SPACE nz_number + else if (parser.checkWithArg <special_atom>(line, &pos, "uidnext", true)) + { + m_type = UIDNEXT; + + parser.check <SPACE>(line, &pos); + m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos); + } + // "UNSEEN" SPACE nz_number + else if (parser.checkWithArg <special_atom>(line, &pos, "unseen", true)) + { + m_type = UNSEEN; + + parser.check <SPACE>(line, &pos); + m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos); + } + // "HIGHESTMODSEQ" SP mod-sequence-value + else if (parser.checkWithArg <special_atom>(line, &pos, "highestmodseq", true)) + { + m_type = HIGHESTMODSEQ; + + parser.check <SPACE>(line, &pos); + m_mod_sequence_value = parser.get <IMAPParser::mod_sequence_value>(line, &pos); + } + // "NOMODSEQ" + else if (parser.checkWithArg <special_atom>(line, &pos, "nomodseq", true)) + { + m_type = NOMODSEQ; + } + // "MODIFIED" SP sequence-set + else if (parser.checkWithArg <special_atom>(line, &pos, "modified", true)) + { + m_type = MODIFIED; + + parser.check <SPACE>(line, &pos); + + m_sequence_set = parser.get <IMAPParser::sequence_set>(line, &pos); + } + // atom [SPACE 1*<any TEXT_CHAR except "]">] + else + { + m_type = OTHER; + + m_atom = parser.get <IMAPParser::atom>(line, &pos); + + if (parser.check <SPACE>(line, &pos, true)) + m_text = parser.get <text_except <']'> >(line, &pos); + } + + *currentPos = pos; + } + + + enum Type + { + // Extensions + HIGHESTMODSEQ, + NOMODSEQ, + MODIFIED, + + // Standard IMAP + ALERT, + PARSE, + CAPABILITY, + PERMANENTFLAGS, + READ_ONLY, + READ_WRITE, + TRYCREATE, + UIDVALIDITY, + UIDNEXT, + UNSEEN, + OTHER + }; + + private: + + Type m_type; + + IMAPParser::nz_number* m_nz_number; + IMAPParser::atom* m_atom; + IMAPParser::flag_list* m_flag_list; + IMAPParser::text* m_text; + IMAPParser::mod_sequence_value* m_mod_sequence_value; + IMAPParser::sequence_set* m_sequence_set; + IMAPParser::capability_data* m_capability_data; + + public: + + Type type() const { return (m_type); } + + const IMAPParser::nz_number* nz_number() const { return (m_nz_number); } + const IMAPParser::atom* atom() const { return (m_atom); } + const IMAPParser::flag_list* flag_list() const { return (m_flag_list); } + const IMAPParser::text* text() const { return (m_text); } + const IMAPParser::mod_sequence_value* mod_sequence_value() const { return m_mod_sequence_value; } + const IMAPParser::sequence_set* sequence_set() const { return m_sequence_set; } + const IMAPParser::capability_data* capability_data() const { return m_capability_data; } + }; + + + // + // resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text) + // ;; text SHOULD NOT begin with "[" or "=" + + class resp_text : public component + { + public: + + resp_text() + : m_resp_text_code(NULL) + { + } + + ~resp_text() + { + delete (m_resp_text_code); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("resp_text"); + + size_t pos = *currentPos; + + if (parser.check <one_char <'['> >(line, &pos, true)) + { + m_resp_text_code = parser.get <IMAPParser::resp_text_code>(line, &pos); + + parser.check <one_char <']'> >(line, &pos); + parser.check <SPACE>(line, &pos, true); + } + + text_mime2* text1 = parser.get <text_mime2>(line, &pos, true); + + if (text1 != NULL) + { + m_text = text1->value(); + delete (text1); + } + else + { + IMAPParser::text* text2 = + parser.get <IMAPParser::text>(line, &pos, true); + + if (text2 != NULL) + { + m_text = text2->value(); + delete (text2); + } + else + { + // Empty response text + } + } + + *currentPos = pos; + } + + private: + + IMAPParser::resp_text_code* m_resp_text_code; + string m_text; + + public: + + const IMAPParser::resp_text_code* resp_text_code() const { return (m_resp_text_code); } + const string& text() const { return (m_text); } + }; + + + // + // continue_req ::= "+" SPACE (resp_text / base64) + // + + class continue_req : public component + { + public: + + continue_req() + : m_resp_text(NULL) + { + } + + ~continue_req() + { + delete (m_resp_text); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("continue_req"); + + size_t pos = *currentPos; + + parser.check <one_char <'+'> >(line, &pos); + + if (!parser.isStrict()) + { + // Some servers do not send SPACE when response text is empty + if (parser.check <SPACE>(line, &pos, true)) + m_resp_text = parser.get <IMAPParser::resp_text>(line, &pos); + else + m_resp_text = new IMAPParser::resp_text(); // empty + } + else + { + parser.check <SPACE>(line, &pos); + + m_resp_text = parser.get <IMAPParser::resp_text>(line, &pos); + } + + parser.check <CRLF>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::resp_text* m_resp_text; + + public: + + const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } + }; + + + // + // resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text + // ;; Status condition + // + + class resp_cond_state : public component + { + public: + + resp_cond_state() + : m_resp_text(NULL), m_status(BAD) + { + } + + ~resp_cond_state() + { + delete (m_resp_text); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("resp_cond_state"); + + size_t pos = *currentPos; + + if (parser.checkWithArg <special_atom>(line, &pos, "ok", true)) + { + m_status = OK; + } + else if (parser.checkWithArg <special_atom>(line, &pos, "no", true)) + { + m_status = NO; + } + else + { + parser.checkWithArg <special_atom>(line, &pos, "bad"); + m_status = BAD; + } + + parser.check <SPACE>(line, &pos); + + m_resp_text = parser.get <IMAPParser::resp_text>(line, &pos); + + *currentPos = pos; + } + + + enum Status + { + OK, + NO, + BAD + }; + + private: + + IMAPParser::resp_text* m_resp_text; + Status m_status; + + public: + + const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } + Status status() const { return (m_status); } + }; + + + // + // resp_cond_bye ::= "BYE" SPACE resp_text + // + + class resp_cond_bye : public component + { + public: + + resp_cond_bye() + : m_resp_text(NULL) + { + } + + ~resp_cond_bye() + { + delete (m_resp_text); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("resp_cond_bye"); + + size_t pos = *currentPos; + + parser.checkWithArg <special_atom>(line, &pos, "bye"); + + parser.check <SPACE>(line, &pos); + + m_resp_text = parser.get <IMAPParser::resp_text>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::resp_text* m_resp_text; + + public: + + const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } + }; + + + // + // resp_cond_auth ::= ("OK" / "PREAUTH") SPACE resp_text + // ;; Authentication condition + // + + class resp_cond_auth : public component + { + public: + + resp_cond_auth() + : m_resp_text(NULL) + { + } + + ~resp_cond_auth() + { + delete (m_resp_text); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("resp_cond_auth"); + + size_t pos = *currentPos; + + if (parser.checkWithArg <special_atom>(line, &pos, "ok", true)) + { + m_cond = OK; + } + else + { + parser.checkWithArg <special_atom>(line, &pos, "preauth"); + + m_cond = PREAUTH; + } + + parser.check <SPACE>(line, &pos); + + m_resp_text = parser.get <IMAPParser::resp_text>(line, &pos); + + *currentPos = pos; + } + + + enum Condition + { + OK, + PREAUTH + }; + + private: + + Condition m_cond; + IMAPParser::resp_text* m_resp_text; + + public: + + Condition condition() const { return (m_cond); } + const IMAPParser::resp_text* resp_text() const { return (m_resp_text); } + }; + + + // + // mailbox_data ::= "FLAGS" SPACE mailbox_flag_list / + // "LIST" SPACE mailbox_list / + // "LSUB" SPACE mailbox_list / + // "MAILBOX" SPACE text / + // "SEARCH" [SPACE 1#nz_number] / + // "STATUS" SPACE mailbox SPACE + // "(" [status-att-list] ")" / + // number SPACE "EXISTS" / + // number SPACE "RECENT" + // + + class mailbox_data : public component + { + public: + + mailbox_data() + : m_number(NULL), m_mailbox_flag_list(NULL), m_mailbox_list(NULL), + m_mailbox(NULL), m_text(NULL), m_status_att_list(NULL) + { + } + + ~mailbox_data() + { + delete (m_number); + delete (m_mailbox_flag_list); + delete (m_mailbox_list); + delete (m_mailbox); + delete (m_text); + + for (std::vector <nz_number*>::iterator it = m_search_nz_number_list.begin() ; + it != m_search_nz_number_list.end() ; ++it) + { + delete (*it); + } + + delete m_status_att_list; + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("mailbox_data"); + + size_t pos = *currentPos; + + m_number = parser.get <IMAPParser::number>(line, &pos, true); + + if (m_number) + { + parser.check <SPACE>(line, &pos); + + if (parser.checkWithArg <special_atom>(line, &pos, "exists", true)) + { + m_type = EXISTS; + } + else + { + parser.checkWithArg <special_atom>(line, &pos, "recent"); + + m_type = RECENT; + } + } + else + { + // "FLAGS" SPACE mailbox_flag_list + if (parser.checkWithArg <special_atom>(line, &pos, "flags", true)) + { + parser.check <SPACE>(line, &pos); + + m_mailbox_flag_list = parser.get <IMAPParser::mailbox_flag_list>(line, &pos); + + m_type = FLAGS; + } + // "LIST" SPACE mailbox_list + else if (parser.checkWithArg <special_atom>(line, &pos, "list", true)) + { + parser.check <SPACE>(line, &pos); + + m_mailbox_list = parser.get <IMAPParser::mailbox_list>(line, &pos); + + m_type = LIST; + } + // "LSUB" SPACE mailbox_list + else if (parser.checkWithArg <special_atom>(line, &pos, "lsub", true)) + { + parser.check <SPACE>(line, &pos); + + m_mailbox_list = parser.get <IMAPParser::mailbox_list>(line, &pos); + + m_type = LSUB; + } + // "MAILBOX" SPACE text + else if (parser.checkWithArg <special_atom>(line, &pos, "mailbox", true)) + { + parser.check <SPACE>(line, &pos); + + m_text = parser.get <IMAPParser::text>(line, &pos); + + m_type = MAILBOX; + } + // "SEARCH" [SPACE 1#nz_number] + else if (parser.checkWithArg <special_atom>(line, &pos, "search", true)) + { + if (parser.check <SPACE>(line, &pos, true)) + { + m_search_nz_number_list.push_back + (parser.get <nz_number>(line, &pos)); + + while (parser.check <SPACE>(line, &pos, true)) + { + m_search_nz_number_list.push_back + (parser.get <nz_number>(line, &pos)); + } + } + + m_type = SEARCH; + } + // "STATUS" SPACE mailbox SPACE + // "(" [status_att_list] ")" + else + { + parser.checkWithArg <special_atom>(line, &pos, "status"); + parser.check <SPACE>(line, &pos); + + m_mailbox = parser.get <IMAPParser::mailbox>(line, &pos); + + parser.check <SPACE>(line, &pos); + + parser.check <one_char <'('> >(line, &pos); + + m_status_att_list = parser.get <IMAPParser::status_att_list>(line, &pos, true); + + parser.check <one_char <')'> >(line, &pos); + + m_type = STATUS; + } + } + + *currentPos = pos; + } + + + enum Type + { + FLAGS, + LIST, + LSUB, + MAILBOX, + SEARCH, + STATUS, + EXISTS, + RECENT + }; + + private: + + Type m_type; + + IMAPParser::number* m_number; + IMAPParser::mailbox_flag_list* m_mailbox_flag_list; + IMAPParser::mailbox_list* m_mailbox_list; + IMAPParser::mailbox* m_mailbox; + IMAPParser::text* m_text; + std::vector <nz_number*> m_search_nz_number_list; + IMAPParser::status_att_list* m_status_att_list; + + public: + + Type type() const { return (m_type); } + + const IMAPParser::number* number() const { return (m_number); } + const IMAPParser::mailbox_flag_list* mailbox_flag_list() const { return (m_mailbox_flag_list); } + const IMAPParser::mailbox_list* mailbox_list() const { return (m_mailbox_list); } + const IMAPParser::mailbox* mailbox() const { return (m_mailbox); } + const IMAPParser::text* text() const { return (m_text); } + const std::vector <nz_number*>& search_nz_number_list() const { return (m_search_nz_number_list); } + const IMAPParser::status_att_list* status_att_list() const { return m_status_att_list; } + }; + + + // + // response_data ::= "*" SPACE (resp_cond_state / resp_cond_bye / + // mailbox_data / message_data / capability_data) CRLF + // + + class response_data : public component + { + public: + + response_data() + : m_resp_cond_state(NULL), m_resp_cond_bye(NULL), + m_mailbox_data(NULL), m_message_data(NULL), m_capability_data(NULL) + { + } + + ~response_data() + { + delete (m_resp_cond_state); + delete (m_resp_cond_bye); + delete (m_mailbox_data); + delete (m_message_data); + delete (m_capability_data); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("response_data"); + + size_t pos = *currentPos; + + parser.check <one_char <'*'> >(line, &pos); + parser.check <SPACE>(line, &pos); + + if (!(m_resp_cond_state = parser.get <IMAPParser::resp_cond_state>(line, &pos, true))) + if (!(m_resp_cond_bye = parser.get <IMAPParser::resp_cond_bye>(line, &pos, true))) + if (!(m_mailbox_data = parser.get <IMAPParser::mailbox_data>(line, &pos, true))) + if (!(m_message_data = parser.get <IMAPParser::message_data>(line, &pos, true))) + m_capability_data = parser.get <IMAPParser::capability_data>(line, &pos); + + if (!parser.isStrict()) + { + // Allow SPACEs at end of line + while (parser.check <SPACE>(line, &pos, /* noThrow */ true)) + ; + } + + parser.check <CRLF>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::resp_cond_state* m_resp_cond_state; + IMAPParser::resp_cond_bye* m_resp_cond_bye; + IMAPParser::mailbox_data* m_mailbox_data; + IMAPParser::message_data* m_message_data; + IMAPParser::capability_data* m_capability_data; + + public: + + const IMAPParser::resp_cond_state* resp_cond_state() const { return (m_resp_cond_state); } + const IMAPParser::resp_cond_bye* resp_cond_bye() const { return (m_resp_cond_bye); } + const IMAPParser::mailbox_data* mailbox_data() const { return (m_mailbox_data); } + const IMAPParser::message_data* message_data() const { return (m_message_data); } + const IMAPParser::capability_data* capability_data() const { return (m_capability_data); } + }; + + + class continue_req_or_response_data : public component + { + public: + + continue_req_or_response_data() + : m_continue_req(NULL), m_response_data(NULL) + { + } + + ~continue_req_or_response_data() + { + delete (m_continue_req); + delete (m_response_data); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("continue_req_or_response_data"); + + size_t pos = *currentPos; + + if (!(m_continue_req = parser.get <IMAPParser::continue_req>(line, &pos, true))) + m_response_data = parser.get <IMAPParser::response_data>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::continue_req* m_continue_req; + IMAPParser::response_data* m_response_data; + + public: + + const IMAPParser::continue_req* continue_req() const { return (m_continue_req); } + const IMAPParser::response_data* response_data() const { return (m_response_data); } + }; + + + // + // response_fatal ::= "*" SPACE resp_cond_bye CRLF + // ;; Server closes connection immediately + // + + class response_fatal : public component + { + public: + + response_fatal() + : m_resp_cond_bye(NULL) + { + } + + ~response_fatal() + { + delete (m_resp_cond_bye); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("response_fatal"); + + size_t pos = *currentPos; + + parser.check <one_char <'*'> >(line, &pos); + parser.check <SPACE>(line, &pos); + + m_resp_cond_bye = parser.get <IMAPParser::resp_cond_bye>(line, &pos); + + if (!parser.isStrict()) + { + // Allow SPACEs at end of line + while (parser.check <SPACE>(line, &pos, /* noThrow */ true)) + ; + } + + parser.check <CRLF>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::resp_cond_bye* m_resp_cond_bye; + + public: + + const IMAPParser::resp_cond_bye* resp_cond_bye() const { return (m_resp_cond_bye); } + }; + + + // + // response_tagged ::= tag SPACE resp_cond_state CRLF + // + + class response_tagged : public component + { + public: + + response_tagged() + : m_resp_cond_state(NULL) + { + } + + ~response_tagged() + { + delete (m_resp_cond_state); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("response_tagged"); + + size_t pos = *currentPos; + + parser.check <IMAPParser::xtag>(line, &pos); + parser.check <SPACE>(line, &pos); + m_resp_cond_state = parser.get <IMAPParser::resp_cond_state>(line, &pos); + + if (!parser.isStrict()) + { + // Allow SPACEs at end of line + while (parser.check <SPACE>(line, &pos, /* noThrow */ true)) + ; + } + + parser.check <CRLF>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::resp_cond_state* m_resp_cond_state; + + public: + + const IMAPParser::resp_cond_state* resp_cond_state() const { return (m_resp_cond_state); } + }; + + + // + // response_done ::= response_tagged / response_fatal + // + + class response_done : public component + { + public: + + response_done() + : m_response_tagged(NULL), m_response_fatal(NULL) + { + } + + ~response_done() + { + delete (m_response_tagged); + delete (m_response_fatal); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("response_done"); + + size_t pos = *currentPos; + + if (!(m_response_tagged = parser.get <IMAPParser::response_tagged>(line, &pos, true))) + m_response_fatal = parser.get <IMAPParser::response_fatal>(line, &pos); + + *currentPos = pos; + } + + private: + + IMAPParser::response_tagged* m_response_tagged; + IMAPParser::response_fatal* m_response_fatal; + + public: + + const IMAPParser::response_tagged* response_tagged() const { return (m_response_tagged); } + const IMAPParser::response_fatal* response_fatal() const { return (m_response_fatal); } + }; + + + // + // response ::= *(continue_req / response_data) response_done + // + + class response : public component + { + public: + + response() + : m_response_done(NULL) + { + } + + ~response() + { + for (std::vector <IMAPParser::continue_req_or_response_data*>::iterator + it = m_continue_req_or_response_data.begin() ; + it != m_continue_req_or_response_data.end() ; ++it) + { + delete (*it); + } + + delete (m_response_done); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("response"); + + size_t pos = *currentPos; + string curLine = line; + bool partial = false; // partial response + + IMAPParser::continue_req_or_response_data* resp = NULL; + + while ((resp = parser.get <IMAPParser::continue_req_or_response_data>(curLine, &pos, true)) != NULL) + { + m_continue_req_or_response_data.push_back(resp); + + // Partial response (continue_req) + if (resp->continue_req()) + { + partial = true; + break; + } + + // We have read a CRLF, read another line + curLine = parser.readLine(); + pos = 0; + } + + if (!partial) + m_response_done = parser.get <IMAPParser::response_done>(curLine, &pos); + + *currentPos = pos; + } + + + bool isBad() const + { + if (!response_done()) // incomplete (partial) response + return (true); + + if (response_done()->response_fatal()) + return (true); + + if (response_done()->response_tagged()->resp_cond_state()-> + status() == IMAPParser::resp_cond_state::BAD) + { + return (true); + } + + return (false); + } + + void setErrorLog(const string& errorLog) + { + m_errorLog = errorLog; + } + + const string& getErrorLog() const + { + return m_errorLog; + } + + private: + + std::vector <IMAPParser::continue_req_or_response_data*> m_continue_req_or_response_data; + IMAPParser::response_done* m_response_done; + + string m_errorLog; + + public: + + const std::vector <IMAPParser::continue_req_or_response_data*>& continue_req_or_response_data() const { return (m_continue_req_or_response_data); } + const IMAPParser::response_done* response_done() const { return (m_response_done); } + }; + + + // + // greeting ::= "*" SPACE (resp_cond_auth / resp_cond_bye) CRLF + // + + class greeting : public component + { + public: + + greeting() + : m_resp_cond_auth(NULL), m_resp_cond_bye(NULL) + { + } + + ~greeting() + { + delete (m_resp_cond_auth); + delete (m_resp_cond_bye); + } + + void go(IMAPParser& parser, string& line, size_t* currentPos) + { + DEBUG_ENTER_COMPONENT("greeting"); + + size_t pos = *currentPos; + + parser.check <one_char <'*'> >(line, &pos); + parser.check <SPACE>(line, &pos); + + if (!(m_resp_cond_auth = parser.get <IMAPParser::resp_cond_auth>(line, &pos, true))) + m_resp_cond_bye = parser.get <IMAPParser::resp_cond_bye>(line, &pos); + + parser.check <CRLF>(line, &pos); + + *currentPos = pos; + } + + void setErrorLog(const string& errorLog) + { + m_errorLog = errorLog; + } + + const string& getErrorLog() const + { + return m_errorLog; + } + + private: + + IMAPParser::resp_cond_auth* m_resp_cond_auth; + IMAPParser::resp_cond_bye* m_resp_cond_bye; + + string m_errorLog; + + public: + + const IMAPParser::resp_cond_auth* resp_cond_auth() const { return (m_resp_cond_auth); } + const IMAPParser::resp_cond_bye* resp_cond_bye() const { return (m_resp_cond_bye); } + }; + + + + // + // The main functions used to parse a response + // + + response* readResponse(literalHandler* lh = NULL) + { + size_t pos = 0; + string line = readLine(); + + m_literalHandler = lh; + response* resp = get <response>(line, &pos); + m_literalHandler = NULL; + + resp->setErrorLog(lastLine()); + + return (resp); + } + + + greeting* readGreeting() + { + size_t pos = 0; + string line = readLine(); + + greeting* greet = get <greeting>(line, &pos); + + greet->setErrorLog(lastLine()); + + return greet; + } + + + // + // Get a token and advance + // + + template <class TYPE> + TYPE* get(string& line, size_t* currentPos, + const bool noThrow = false) + { + component* resp = new TYPE; + return internalGet <TYPE>(resp, line, currentPos, noThrow); + } + + + template <class TYPE, class ARG1_TYPE, class ARG2_TYPE> + TYPE* getWithArgs(string& line, size_t* currentPos, + ARG1_TYPE arg1, ARG2_TYPE arg2, const bool noThrow = false) + { + component* resp = new TYPE(arg1, arg2); + return internalGet <TYPE>(resp, line, currentPos, noThrow); + } + + +private: + + template <class TYPE> + TYPE* internalGet(component* resp, string& line, size_t* currentPos, + const bool noThrow = false) + { + const size_t oldPos = *currentPos; + + try + { + resp->go(*this, line, currentPos); + } + catch (exceptions::operation_timed_out&) + { + // Always rethrow + throw; + } + catch (exception&) + { + *currentPos = oldPos; + + delete (resp); + if (!noThrow) throw; + return (NULL); + } + + return static_cast <TYPE*>(resp); + } + + const string lastLine() const + { + // Remove blanks and new lines at the end of the line. + string line(m_lastLine); + + string::const_iterator it = line.end(); + int count = 0; + + while (it != line.begin()) + { + const unsigned char c = *(it - 1); + + if (!(c == ' ' || c == '\t' || c == '\n' || c == '\r')) + break; + + ++count; + --it; + } + + line.resize(line.length() - count); + + return (line); + } + +public: + + // + // Check a token and advance + // + + template <class TYPE> + bool check(string& line, size_t* currentPos, + const bool noThrow = false) + { + const size_t oldPos = *currentPos; + + try + { + TYPE term; + term.go(*this, line, currentPos); + } + catch (exceptions::operation_timed_out&) + { + // Always rethrow + throw; + } + catch (exception&) + { + *currentPos = oldPos; + + if (!noThrow) throw; + return false; + } + + return true; + } + + template <class TYPE, class ARG_TYPE> + bool checkWithArg(string& line, size_t* currentPos, + const ARG_TYPE arg, const bool noThrow = false) + { + const size_t oldPos = *currentPos; + + try + { + TYPE term(arg); + term.go(*this, line, currentPos); + } + catch (exceptions::operation_timed_out&) + { + // Always rethrow + throw; + } + catch (exception&) + { + *currentPos = oldPos; + + if (!noThrow) throw; + return false; + } + + return true; + } + + +private: + + weak_ptr <IMAPTag> m_tag; + weak_ptr <socket> m_socket; + + utility::progressListener* m_progress; + + bool m_strict; + + literalHandler* m_literalHandler; + + weak_ptr <timeoutHandler> m_timeoutHandler; + + + string m_buffer; + + string m_lastLine; + +public: + + // + // Read one line + // + + const string readLine() + { + size_t pos; + + while ((pos = m_buffer.find('\n')) == string::npos) + { + read(); + } + + string line; + line.resize(pos + 1); + std::copy(m_buffer.begin(), m_buffer.begin() + pos + 1, line.begin()); + + m_buffer.erase(m_buffer.begin(), m_buffer.begin() + pos + 1); + + m_lastLine = line; + +#if DEBUG_RESPONSE + std::cout << std::endl << "Read line:" << std::endl << line << std::endl; +#endif + + return (line); + } + + + // + // Read available data from socket stream + // + + void read() + { + string receiveBuffer; + + shared_ptr <timeoutHandler> toh = m_timeoutHandler.lock(); + shared_ptr <socket> sok = m_socket.lock(); + + if (toh) + toh->resetTimeOut(); + + while (receiveBuffer.empty()) + { + // Check whether the time-out delay is elapsed + if (toh && toh->isTimeOut()) + { + if (!toh->handleTimeOut()) + throw exceptions::operation_timed_out(); + } + + // We have received data: reset the time-out counter + sok->receive(receiveBuffer); + + if (receiveBuffer.empty()) // buffer is empty + { + platform::getHandler()->wait(); + continue; + } + + // We have received data ... + if (toh) + toh->resetTimeOut(); + } + + m_buffer += receiveBuffer; + } + + + void readLiteral(literalHandler::target& buffer, size_t count) + { + size_t len = 0; + string receiveBuffer; + + shared_ptr <timeoutHandler> toh = m_timeoutHandler.lock(); + shared_ptr <socket> sok = m_socket.lock(); + + if (m_progress) + m_progress->start(count); + + if (toh) + toh->resetTimeOut(); + + if (!m_buffer.empty()) + { + if (m_buffer.length() > count) + { + buffer.putData(string(m_buffer.begin(), m_buffer.begin() + count)); + m_buffer.erase(m_buffer.begin(), m_buffer.begin() + count); + len = count; + } + else + { + len += m_buffer.length(); + buffer.putData(m_buffer); + m_buffer.clear(); + } + } + + while (len < count) + { + // Check whether the time-out delay is elapsed + if (toh && toh->isTimeOut()) + { + if (!toh->handleTimeOut()) + throw exceptions::operation_timed_out(); + + toh->resetTimeOut(); + } + + // Receive data from the socket + sok->receive(receiveBuffer); + + if (receiveBuffer.empty()) // buffer is empty + { + platform::getHandler()->wait(); + continue; + } + + // We have received data: reset the time-out counter + if (toh) + toh->resetTimeOut(); + + if (len + receiveBuffer.length() > count) + { + const size_t remaining = count - len; + + // Get the needed amount of data + buffer.putData(string(receiveBuffer.begin(), receiveBuffer.begin() + remaining)); + + // Put the remaining data into the internal response buffer + receiveBuffer.erase(receiveBuffer.begin(), receiveBuffer.begin() + remaining); + m_buffer += receiveBuffer; + + len = count; + } + else + { + buffer.putData(receiveBuffer); + len += receiveBuffer.length(); + } + + // Notify progress + if (m_progress) + m_progress->progress(len, count); + } + + if (m_progress) + m_progress->stop(count); + } +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPPARSER_HPP_INCLUDED diff --git a/src/net/imap/IMAPSStore.cpp b/src/vmime/net/imap/IMAPSStore.cpp index c9e64f5b..c9e64f5b 100644 --- a/src/net/imap/IMAPSStore.cpp +++ b/src/vmime/net/imap/IMAPSStore.cpp diff --git a/src/vmime/net/imap/IMAPSStore.hpp b/src/vmime/net/imap/IMAPSStore.hpp new file mode 100644 index 00000000..9d27bdd0 --- /dev/null +++ b/src/vmime/net/imap/IMAPSStore.hpp @@ -0,0 +1,71 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPSSTORE_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPSSTORE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/imap/IMAPStore.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +/** IMAPS store service. + */ + +class VMIME_EXPORT IMAPSStore : public IMAPStore +{ +public: + + IMAPSStore(shared_ptr <session> sess, shared_ptr <security::authenticator> auth); + ~IMAPSStore(); + + const string getProtocolName() const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + +private: + + static IMAPServiceInfos sm_infos; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPSSTORE_HPP_INCLUDED + diff --git a/src/net/imap/IMAPServiceInfos.cpp b/src/vmime/net/imap/IMAPServiceInfos.cpp index 46dbc2e1..46dbc2e1 100644 --- a/src/net/imap/IMAPServiceInfos.cpp +++ b/src/vmime/net/imap/IMAPServiceInfos.cpp diff --git a/src/vmime/net/imap/IMAPServiceInfos.hpp b/src/vmime/net/imap/IMAPServiceInfos.hpp new file mode 100644 index 00000000..376f4476 --- /dev/null +++ b/src/vmime/net/imap/IMAPServiceInfos.hpp @@ -0,0 +1,91 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPSERVICEINFOS_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPSERVICEINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/serviceInfos.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +/** Information about IMAP service. + */ + +class VMIME_EXPORT IMAPServiceInfos : public serviceInfos +{ +public: + + IMAPServiceInfos(const bool imaps); + + struct props + { + // IMAP-specific options +#if VMIME_HAVE_SASL_SUPPORT + serviceInfos::property PROPERTY_OPTIONS_SASL; + serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK; +#endif // VMIME_HAVE_SASL_SUPPORT + + // Common properties + serviceInfos::property PROPERTY_AUTH_USERNAME; + serviceInfos::property PROPERTY_AUTH_PASSWORD; + +#if VMIME_HAVE_TLS_SUPPORT + serviceInfos::property PROPERTY_CONNECTION_TLS; + serviceInfos::property PROPERTY_CONNECTION_TLS_REQUIRED; +#endif // VMIME_HAVE_TLS_SUPPORT + + serviceInfos::property PROPERTY_SERVER_ADDRESS; + serviceInfos::property PROPERTY_SERVER_PORT; + }; + + const props& getProperties() const; + + const string getPropertyPrefix() const; + const std::vector <serviceInfos::property> getAvailableProperties() const; + +private: + + const bool m_imaps; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPSERVICEINFOS_HPP_INCLUDED + diff --git a/src/net/imap/IMAPStore.cpp b/src/vmime/net/imap/IMAPStore.cpp index a1a8c9ca..a1a8c9ca 100644 --- a/src/net/imap/IMAPStore.cpp +++ b/src/vmime/net/imap/IMAPStore.cpp diff --git a/src/vmime/net/imap/IMAPStore.hpp b/src/vmime/net/imap/IMAPStore.hpp new file mode 100644 index 00000000..f854fadf --- /dev/null +++ b/src/vmime/net/imap/IMAPStore.hpp @@ -0,0 +1,120 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPSTORE_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPSTORE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/net/store.hpp" +#include "vmime/net/socket.hpp" +#include "vmime/net/folder.hpp" + +#include "vmime/net/imap/IMAPServiceInfos.hpp" +#include "vmime/net/imap/IMAPConnection.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class IMAPParser; +class IMAPTag; +class IMAPFolder; + + +/** IMAP store service. + */ + +class VMIME_EXPORT IMAPStore : public store +{ + friend class IMAPFolder; + friend class IMAPMessage; + friend class IMAPConnection; + +public: + + IMAPStore(shared_ptr <session> sess, shared_ptr <security::authenticator> auth, const bool secured = false); + ~IMAPStore(); + + const string getProtocolName() const; + + shared_ptr <folder> getDefaultFolder(); + shared_ptr <folder> getRootFolder(); + shared_ptr <folder> getFolder(const folder::path& path); + + bool isValidFolderName(const folder::path::component& name) const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + + void connect(); + bool isConnected() const; + void disconnect(); + + void noop(); + + int getCapabilities() const; + + bool isIMAPS() const; + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + shared_ptr <IMAPConnection> getConnection(); + +protected: + + // Connection + shared_ptr <IMAPConnection> m_connection; + + + + shared_ptr <IMAPConnection> connection(); + + + void registerFolder(IMAPFolder* folder); + void unregisterFolder(IMAPFolder* folder); + + std::list <IMAPFolder*> m_folders; + + const bool m_isIMAPS; // Use IMAPS + + + static IMAPServiceInfos sm_infos; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPSTORE_HPP_INCLUDED diff --git a/src/net/imap/IMAPTag.cpp b/src/vmime/net/imap/IMAPTag.cpp index 14d12788..14d12788 100644 --- a/src/net/imap/IMAPTag.cpp +++ b/src/vmime/net/imap/IMAPTag.cpp diff --git a/src/vmime/net/imap/IMAPTag.hpp b/src/vmime/net/imap/IMAPTag.hpp new file mode 100644 index 00000000..430a3b10 --- /dev/null +++ b/src/vmime/net/imap/IMAPTag.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPTAG_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPTAG_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace net { +namespace imap { + + +class VMIME_EXPORT IMAPTag : public object +{ +private: + + IMAPTag(const int number); + IMAPTag(const IMAPTag& tag); + +public: + + IMAPTag(); + + IMAPTag& operator++(); // ++IMAPTag + const IMAPTag operator++(int); // IMAPTag++ + + int maximumNumber() const; + int number() const; + + operator string() const; + +private: + + void generate(); + + static const int sm_maxNumber; + + int m_number; + string m_tag; +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPTAG_HPP_INCLUDED diff --git a/src/net/imap/IMAPUtils.cpp b/src/vmime/net/imap/IMAPUtils.cpp index ff81ce71..ff81ce71 100644 --- a/src/net/imap/IMAPUtils.cpp +++ b/src/vmime/net/imap/IMAPUtils.cpp diff --git a/src/vmime/net/imap/IMAPUtils.hpp b/src/vmime/net/imap/IMAPUtils.hpp new file mode 100644 index 00000000..988b6a2c --- /dev/null +++ b/src/vmime/net/imap/IMAPUtils.hpp @@ -0,0 +1,129 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAPUTILS_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAPUTILS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + + +#include "vmime/types.hpp" +#include "vmime/dateTime.hpp" + +#include "vmime/net/folder.hpp" +#include "vmime/net/message.hpp" +#include "vmime/net/imap/IMAPParser.hpp" +#include "vmime/net/imap/IMAPConnection.hpp" + +#include "vmime/mailboxList.hpp" + +#include <vector> + + +namespace vmime { +namespace net { +namespace imap { + + +class VMIME_EXPORT IMAPUtils +{ +public: + + static const string pathToString(const char hierarchySeparator, const folder::path& path); + static const folder::path stringToPath(const char hierarchySeparator, const string& str); + + static const string toModifiedUTF7(const char hierarchySeparator, const folder::path::component& text); + static const folder::path::component fromModifiedUTF7(const string& text); + + /** Quote string if it contains IMAP-special characters. + * + * @param text string to quote + * @return quoted string + */ + static const string quoteString(const string& text); + + static int folderTypeFromFlags(const IMAPParser::mailbox_flag_list* list); + static int folderFlagsFromFlags(const IMAPParser::mailbox_flag_list* list); + + static int messageFlagsFromFlags(const IMAPParser::flag_list* list); + + static const string messageFlagList(const int flags); + + /** Format a date/time to IMAP date/time format. + * + * @param date date/time to format + * @return IMAP-formatted date/time + */ + static const string dateTime(const vmime::datetime& date); + + /** Construct a fetch request for the specified messages, designated + * either by their sequence numbers or their UIDs. + * + * @param cnt connection + * @param msgs message set + * @param options fetch options + * @return fetch request + */ + static const string buildFetchRequest + (shared_ptr <IMAPConnection> cnt, const messageSet& msgs, const fetchAttributes& options); + + /** Convert a parser-style address list to a mailbox list. + * + * @param src input address list + * @param dest output mailbox list + */ + static void convertAddressList(const IMAPParser::address_list& src, mailboxList& dest); + + /** Returns an IMAP-formatted sequence set given a message set. + * + * @param msgs message set + * @return IMAP sequence set (eg. "1:5,7,15:*") + */ + static const string messageSetToSequenceSet(const messageSet& msgs); + + /** Returns a list of message sequence numbers given a message set. + * + * @param msgs message set + * @return list of message numbers + */ + static const std::vector <int> messageSetToNumberList(const messageSet& msgs); + +private: + + static const string buildFetchRequestImpl + (shared_ptr <IMAPConnection> cnt, const string& mode, const string& set, const int options); +}; + + +} // imap +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP + +#endif // VMIME_NET_IMAP_IMAPUTILS_HPP_INCLUDED diff --git a/src/vmime/net/imap/imap.hpp b/src/vmime/net/imap/imap.hpp new file mode 100644 index 00000000..5e10619a --- /dev/null +++ b/src/vmime/net/imap/imap.hpp @@ -0,0 +1,35 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_IMAP_IMAP_HPP_INCLUDED +#define VMIME_NET_IMAP_IMAP_HPP_INCLUDED + + +#include "vmime/net/imap/IMAPFolder.hpp" +#include "vmime/net/imap/IMAPFolderStatus.hpp" +#include "vmime/net/imap/IMAPMessage.hpp" +#include "vmime/net/imap/IMAPStore.hpp" +#include "vmime/net/imap/IMAPSStore.hpp" + + +#endif // VMIME_NET_IMAP_IMAP_HPP_INCLUDED diff --git a/src/net/maildir/format/courierMaildirFormat.cpp b/src/vmime/net/maildir/format/courierMaildirFormat.cpp index 6d460d5e..6d460d5e 100644 --- a/src/net/maildir/format/courierMaildirFormat.cpp +++ b/src/vmime/net/maildir/format/courierMaildirFormat.cpp diff --git a/src/vmime/net/maildir/format/courierMaildirFormat.hpp b/src/vmime/net/maildir/format/courierMaildirFormat.hpp new file mode 100644 index 00000000..b8443426 --- /dev/null +++ b/src/vmime/net/maildir/format/courierMaildirFormat.hpp @@ -0,0 +1,121 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_FORMAT_COURIERMAILDIRFORMAT_HPP_INCLUDED +#define VMIME_NET_MAILDIR_FORMAT_COURIERMAILDIRFORMAT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/maildir/maildirFormat.hpp" + + +namespace vmime { +namespace net { +namespace maildir { +namespace format { + + +/** Reads Courier/QMail Maildir format. + */ + +class VMIME_EXPORT courierMaildirFormat : public maildirFormat +{ +public: + + courierMaildirFormat(shared_ptr <context> ctx); + + + /* Folder types: + * + * - ROOT_DIRECTORY: ~/Mail/.MyFolder + * - NEW_DIRECTORY: ~/Mail/.MyFolder/new + * - CUR_DIRECTORY: ~/Mail/.MyFolder/cur + * - TMP_DIRECTORY: ~/Mail/.MyFolder/tmp + * - CONTAINER_DIRECTORY: not used + */ + + const string getName() const; + + void createFolder(const folder::path& path); + void destroyFolder(const folder::path& path); + void renameFolder(const folder::path& oldPath, const folder::path& newPath); + + bool folderExists(const folder::path& path) const; + bool folderHasSubfolders(const folder::path& path) const; + + const utility::file::path folderPathToFileSystemPath + (const folder::path& path, const DirectoryType type) const; + + const std::vector <folder::path> listFolders + (const folder::path& root, const bool recursive) const; + +protected: + + bool supports() const; + + + static const string toModifiedUTF7(const folder::path::component& text); + static const folder::path::component fromModifiedUTF7(const string& text); + + void renameFolderImpl(const folder::path& oldPath, const folder::path& newPath); + + /** Test whether the specified file system directory corresponds to + * a maildir subfolder. The name of the directory should start + * with a '.' to be listed as a subfolder. + * + * @param file reference to a file system directory + * @return true if the specified directory is a maildir subfolder, + * false otherwise + */ + static bool isSubfolderDirectory(const utility::file& file); + + /** List directories corresponding to folders which are (direct or + * indirect) children of specified folder. + * + * @param root root folder + * @param dirs list in which found directories will be added + * @param onlyTestForExistence if true, the function returns as soon + * as the first directory is found + * @return true if at least one directory has been found, + * false otherwise + */ + bool listDirectories(const folder::path& root, + std::vector <string>& dirs, const bool onlyTestForExistence) const; +}; + + +} // format +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_FORMAT_COURIERMAILDIRFORMAT_HPP_INCLUDED + diff --git a/src/net/maildir/format/kmailMaildirFormat.cpp b/src/vmime/net/maildir/format/kmailMaildirFormat.cpp index 975752a5..975752a5 100644 --- a/src/net/maildir/format/kmailMaildirFormat.cpp +++ b/src/vmime/net/maildir/format/kmailMaildirFormat.cpp diff --git a/src/vmime/net/maildir/format/kmailMaildirFormat.hpp b/src/vmime/net/maildir/format/kmailMaildirFormat.hpp new file mode 100644 index 00000000..98ca212e --- /dev/null +++ b/src/vmime/net/maildir/format/kmailMaildirFormat.hpp @@ -0,0 +1,109 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_FORMAT_KMAILMAILDIRFORMAT_HPP_INCLUDED +#define VMIME_NET_MAILDIR_FORMAT_KMAILMAILDIRFORMAT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/maildir/maildirFormat.hpp" + + +namespace vmime { +namespace net { +namespace maildir { +namespace format { + + +/** Reads KMail Maildir format. + */ + +class VMIME_EXPORT kmailMaildirFormat : public maildirFormat +{ +public: + + kmailMaildirFormat(shared_ptr <context> ctx); + + + /* Folder types: + * + * - ROOT_DIRECTORY: ~/Mail/MyFolder + * - NEW_DIRECTORY: ~/Mail/MyFolder/new + * - CUR_DIRECTORY: ~/Mail/MyFolder/cur + * - TMP_DIRECTORY: ~/Mail/MyFolder/tmp + * - CONTAINER_DIRECTORY: ~/Mail/.MyFolder.directory + */ + + const string getName() const; + + void createFolder(const folder::path& path); + void destroyFolder(const folder::path& path); + void renameFolder(const folder::path& oldPath, const folder::path& newPath); + + bool folderExists(const folder::path& path) const; + bool folderHasSubfolders(const folder::path& path) const; + + const utility::file::path folderPathToFileSystemPath + (const folder::path& path, const DirectoryType type) const; + + const std::vector <folder::path> listFolders + (const folder::path& root, const bool recursive) const; + +protected: + + bool supports() const; + + + /** Recursive implementation of listFolders(). + */ + void listFoldersImpl(std::vector <folder::path>& list, + const folder::path& root, const bool recursive) const; + + /** Test whether the specified file system directory corresponds to + * a maildir subfolder. The name of the directory should not start + * with '.' to be listed as a subfolder. + * + * @param file reference to a file system directory + * @return true if the specified directory is a maildir subfolder, + * false otherwise + */ + static bool isSubfolderDirectory(const utility::file& file); +}; + + +} // format +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#endif // VMIME_NET_MAILDIR_FORMAT_KMAILMAILDIRFORMAT_HPP_INCLUDED + diff --git a/src/vmime/net/maildir/maildir.hpp b/src/vmime/net/maildir/maildir.hpp new file mode 100644 index 00000000..42bbbea4 --- /dev/null +++ b/src/vmime/net/maildir/maildir.hpp @@ -0,0 +1,34 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIR_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIR_HPP_INCLUDED + + +#include "vmime/net/maildir/maildirFolder.hpp" +#include "vmime/net/maildir/maildirFolderStatus.hpp" +#include "vmime/net/maildir/maildirMessage.hpp" +#include "vmime/net/maildir/maildirStore.hpp" + + +#endif // VMIME_NET_MAILDIR_MAILDIR_HPP_INCLUDED diff --git a/src/net/maildir/maildirFolder.cpp b/src/vmime/net/maildir/maildirFolder.cpp index 660178ff..660178ff 100644 --- a/src/net/maildir/maildirFolder.cpp +++ b/src/vmime/net/maildir/maildirFolder.cpp diff --git a/src/vmime/net/maildir/maildirFolder.hpp b/src/vmime/net/maildir/maildirFolder.hpp new file mode 100644 index 00000000..5cff53fc --- /dev/null +++ b/src/vmime/net/maildir/maildirFolder.hpp @@ -0,0 +1,190 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include <vector> +#include <map> + +#include "vmime/types.hpp" + +#include "vmime/net/folder.hpp" + +#include "vmime/utility/file.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +class maildirStore; +class maildirMessage; + + +/** maildir folder implementation. + */ + +class VMIME_EXPORT maildirFolder : public folder +{ +private: + + friend class maildirStore; + friend class maildirMessage; + + maildirFolder(const maildirFolder&) : folder() { } + +public: + + maildirFolder(const folder::path& path, shared_ptr <maildirStore> store); + + ~maildirFolder(); + + + int getMode() const; + + int getType(); + + int getFlags(); + + const folder::path::component getName() const; + const folder::path getFullPath() const; + + void open(const int mode, bool failIfModeIsNotAvailable = false); + void close(const bool expunge); + void create(const int type); + + bool exists(); + + void destroy(); + + bool isOpen() const; + + shared_ptr <message> getMessage(const int num); + std::vector <shared_ptr <message> > getMessages(const messageSet& msgs); + + int getMessageCount(); + + shared_ptr <folder> getFolder(const folder::path::component& name); + std::vector <shared_ptr <folder> > getFolders(const bool recursive = false); + + void rename(const folder::path& newPath); + + void deleteMessages(const messageSet& msgs); + + void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); + + void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + + void copyMessages(const folder::path& dest, const messageSet& msgs); + + void status(int& count, int& unseen); + shared_ptr <folderStatus> getStatus(); + + void expunge(); + + shared_ptr <folder> getParent(); + + shared_ptr <const store> getStore() const; + shared_ptr <store> getStore(); + + + void fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); + void fetchMessage(shared_ptr <message> msg, const fetchAttributes& options); + + int getFetchCapabilities() const; + + std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid); + +private: + + void scanFolder(); + + void listFolders(std::vector <shared_ptr <folder> >& list, const bool recursive); + + void registerMessage(maildirMessage* msg); + void unregisterMessage(maildirMessage* msg); + + const utility::file::path getMessageFSPath(const int number) const; + + void onStoreDisconnected(); + + void onClose(); + + void deleteMessagesImpl(const std::vector <int>& nums); + void setMessageFlagsImpl(const std::vector <int>& nums, const int flags, const int mode); + + void copyMessagesImpl(const folder::path& dest, const std::vector <int>& nums); + void copyMessageImpl(const utility::file::path& tmpDirPath, const utility::file::path& curDirPath, const utility::file::path::component& filename, utility::inputStream& is, const size_t size, utility::progressListener* progress); + + void notifyMessagesCopied(const folder::path& dest); + + + weak_ptr <maildirStore> m_store; + + folder::path m_path; + folder::path::component m_name; + + int m_mode; + bool m_open; + + int m_unreadMessageCount; + int m_messageCount; + + // Store information about scanned messages + struct messageInfos + { + enum Type + { + TYPE_CUR, + TYPE_DELETED + }; + + utility::file::path::component path; // filename + Type type; // current location + }; + + std::vector <messageInfos> m_messageInfos; + + // Instanciated message objects + std::vector <maildirMessage*> m_messages; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRFOLDER_HPP_INCLUDED diff --git a/src/net/maildir/maildirFolderStatus.cpp b/src/vmime/net/maildir/maildirFolderStatus.cpp index 9ee84dba..9ee84dba 100644 --- a/src/net/maildir/maildirFolderStatus.cpp +++ b/src/vmime/net/maildir/maildirFolderStatus.cpp diff --git a/src/vmime/net/maildir/maildirFolderStatus.hpp b/src/vmime/net/maildir/maildirFolderStatus.hpp new file mode 100644 index 00000000..155fb20f --- /dev/null +++ b/src/vmime/net/maildir/maildirFolderStatus.hpp @@ -0,0 +1,76 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRFOLDERSTATUS_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRFOLDERSTATUS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/folderStatus.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +/** Holds the status of a Maildir folder. + */ + +class VMIME_EXPORT maildirFolderStatus : public folderStatus +{ +public: + + maildirFolderStatus(); + maildirFolderStatus(const maildirFolderStatus& other); + + // Inherited from folderStatus + unsigned int getMessageCount() const; + unsigned int getUnseenCount() const; + + shared_ptr <folderStatus> clone() const; + + + void setMessageCount(const unsigned int count); + void setUnseenCount(const unsigned int unseen); + +private: + + unsigned int m_count; + unsigned int m_unseen; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRFOLDERSTATUS_HPP_INCLUDED diff --git a/src/net/maildir/maildirFormat.cpp b/src/vmime/net/maildir/maildirFormat.cpp index f7a3c8fe..f7a3c8fe 100644 --- a/src/net/maildir/maildirFormat.cpp +++ b/src/vmime/net/maildir/maildirFormat.cpp diff --git a/src/vmime/net/maildir/maildirFormat.hpp b/src/vmime/net/maildir/maildirFormat.hpp new file mode 100644 index 00000000..c0daf288 --- /dev/null +++ b/src/vmime/net/maildir/maildirFormat.hpp @@ -0,0 +1,195 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_FORMAT_MAILDIRFORMAT_HPP_INCLUDED +#define VMIME_NET_MAILDIR_FORMAT_MAILDIRFORMAT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/folder.hpp" + +#include "vmime/utility/file.hpp" +#include "vmime/utility/path.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +class maildirStore; + + +/** Interface for an object capable of reading a specific Maildir format. */ + +class VMIME_EXPORT maildirFormat : public object +{ +public: + + class context : public object + { + public: + + context(shared_ptr <maildirStore> store); + + shared_ptr <maildirStore> getStore() const; + + private: + + weak_ptr <maildirStore> m_store; + }; + + + /** Physical directory types. */ + enum DirectoryType + { + ROOT_DIRECTORY, /**< Root directory. */ + NEW_DIRECTORY, /**< Directory containing unread messages. */ + CUR_DIRECTORY, /**< Directory containing messages that have been seen. */ + TMP_DIRECTORY, /**< Temporary directory used for reliable delivery. */ + CONTAINER_DIRECTORY /**< Container for subfolders. */ + }; + + /** Return the name of this Maildir format. + * + * @return format name + */ + virtual const string getName() const = 0; + + /** Create the specified folder. + * + * @param path virtual path of the folder + * @throw exceptions::filesystem_exception, invalid_folder_name + */ + virtual void createFolder(const folder::path& path) = 0; + + /** Destroy the specified folder. + * + * @param path virtual path of the folder + * @throw exceptions::filesystem_exception + */ + virtual void destroyFolder(const folder::path& path) = 0; + + /** Rename the specified folder. + * + * @param oldPath old virtual path of the folder + * @param newPath new virtual path of the folder + * @throw exceptions::filesystem_exception + */ + virtual void renameFolder(const folder::path& oldPath, const folder::path& newPath) = 0; + + /** Test whether the specified folder exists. + * + * @param path virtual path of the folder + * @return true if the folder exists, false otherwise + */ + virtual bool folderExists(const folder::path& path) const = 0; + + /** Test whether the specified folder has subfolders. + * + * @param path virtual path of the folder + * @return true if the folder has at least one subfolder, + * false otherwise + */ + virtual bool folderHasSubfolders(const folder::path& path) const = 0; + + /** Returns the directory which represents the specified + * folder on the file system. + * + * @param path virtual path of the folder + * @param type type of directory to return + * @return corresponding directory on the file system + */ + virtual const utility::file::path folderPathToFileSystemPath + (const folder::path& path, const DirectoryType type) const = 0; + + /** List subfolders in the specified folder. + * + * @param root root folder in which to start the search + * @param recursive if set to true, all the descendant are + * returned; if set to false, only direct children are returned. + * @return list of subfolders + */ + virtual const std::vector <folder::path> listFolders + (const folder::path& root, const bool recursive) const = 0; + + + /** Try to detect the format of the specified Maildir store. + * If the format cannot be detected, a compatible implementation + * will be returned. + * + * @param store of which to detect format + * @return a Maildir format implementation for the specified store + */ + static shared_ptr <maildirFormat> detect(shared_ptr <maildirStore> store); + +protected: + + static const utility::file::path::component TMP_DIR; /**< Ensure reliable delivery (not to be listed). */ + static const utility::file::path::component CUR_DIR; /**< No longer new messages. */ + static const utility::file::path::component NEW_DIR; /**< Unread messages. */ + + + maildirFormat(shared_ptr <context> ctx); + + + /** Returns the current context. + * + * @return current context + */ + shared_ptr <context> getContext(); + + /** Returns the current context (const version). + * + * @return current context + */ + shared_ptr <const context> getContext() const; + + /** Quick checks whether this implementation can read the Maildir + * format in the specified directory. + * + * @return true if the implementation supports the specified + * Maildir, or false otherwise + */ + virtual bool supports() const = 0; + +private: + + shared_ptr <context> m_context; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_FORMAT_MAILDIRFORMAT_HPP_INCLUDED + diff --git a/src/net/maildir/maildirMessage.cpp b/src/vmime/net/maildir/maildirMessage.cpp index a14f067e..a14f067e 100644 --- a/src/net/maildir/maildirMessage.cpp +++ b/src/vmime/net/maildir/maildirMessage.cpp diff --git a/src/vmime/net/maildir/maildirMessage.hpp b/src/vmime/net/maildir/maildirMessage.hpp new file mode 100644 index 00000000..7480d49c --- /dev/null +++ b/src/vmime/net/maildir/maildirMessage.hpp @@ -0,0 +1,116 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/message.hpp" +#include "vmime/net/folder.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +class maildirFolder; + + +/** maildir message implementation. + */ + +class VMIME_EXPORT maildirMessage : public message +{ + friend class maildirFolder; + + maildirMessage(const maildirMessage&) : message() { } + +public: + + maildirMessage(shared_ptr <maildirFolder> folder, const int num); + + ~maildirMessage(); + + + int getNumber() const; + + const uid getUID() const; + + size_t getSize() const; + + bool isExpunged() const; + + shared_ptr <const messageStructure> getStructure() const; + shared_ptr <messageStructure> getStructure(); + + shared_ptr <const header> getHeader() const; + + int getFlags() const; + void setFlags(const int flags, const int mode = FLAG_MODE_SET); + + void extract(utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; + void extractPart(shared_ptr <const messagePart> p, utility::outputStream& os, utility::progressListener* progress = NULL, const size_t start = 0, const size_t length = -1, const bool peek = false) const; + + void fetchPartHeader(shared_ptr <messagePart> p); + + shared_ptr <vmime::message> getParsedMessage(); + +private: + + void fetch(shared_ptr <maildirFolder> folder, const fetchAttributes& options); + + void onFolderClosed(); + + shared_ptr <header> getOrCreateHeader(); + + void extractImpl(utility::outputStream& os, utility::progressListener* progress, const size_t start, const size_t length, const size_t partialStart, const size_t partialLength, const bool peek) const; + + + weak_ptr <maildirFolder> m_folder; + + int m_num; + size_t m_size; + int m_flags; + bool m_expunged; + uid m_uid; + + shared_ptr <header> m_header; + shared_ptr <messageStructure> m_structure; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRMESSAGE_HPP_INCLUDED diff --git a/src/net/maildir/maildirMessagePart.cpp b/src/vmime/net/maildir/maildirMessagePart.cpp index 6ae085c9..6ae085c9 100644 --- a/src/net/maildir/maildirMessagePart.cpp +++ b/src/vmime/net/maildir/maildirMessagePart.cpp diff --git a/src/vmime/net/maildir/maildirMessagePart.hpp b/src/vmime/net/maildir/maildirMessagePart.hpp new file mode 100644 index 00000000..3a4be0f3 --- /dev/null +++ b/src/vmime/net/maildir/maildirMessagePart.hpp @@ -0,0 +1,99 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRMESSAGEPART_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRMESSAGEPART_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/message.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +class maildirMessageStructure; + + +class maildirMessagePart : public messagePart +{ +public: + + maildirMessagePart(shared_ptr <maildirMessagePart> parent, const int number, const bodyPart& part); + ~maildirMessagePart(); + + + shared_ptr <const messageStructure> getStructure() const; + shared_ptr <messageStructure> getStructure(); + + weak_ptr <const maildirMessagePart> getParent() const { return (m_parent); } + + const mediaType& getType() const; + size_t getSize() const; + int getNumber() const; + + shared_ptr <const header> getHeader() const; + + header& getOrCreateHeader(); + + size_t getHeaderParsedOffset() const; + size_t getHeaderParsedLength() const; + + size_t getBodyParsedOffset() const; + size_t getBodyParsedLength() const; + + void initStructure(const bodyPart& part); + +private: + + shared_ptr <maildirMessageStructure> m_structure; + weak_ptr <maildirMessagePart> m_parent; + shared_ptr <header> m_header; + + int m_number; + size_t m_size; + mediaType m_mediaType; + + size_t m_headerParsedOffset; + size_t m_headerParsedLength; + + size_t m_bodyParsedOffset; + size_t m_bodyParsedLength; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRMESSAGEPART_HPP_INCLUDED diff --git a/src/net/maildir/maildirMessageStructure.cpp b/src/vmime/net/maildir/maildirMessageStructure.cpp index f3b7cf59..f3b7cf59 100644 --- a/src/net/maildir/maildirMessageStructure.cpp +++ b/src/vmime/net/maildir/maildirMessageStructure.cpp diff --git a/src/vmime/net/maildir/maildirMessageStructure.hpp b/src/vmime/net/maildir/maildirMessageStructure.hpp new file mode 100644 index 00000000..a43fc15c --- /dev/null +++ b/src/vmime/net/maildir/maildirMessageStructure.hpp @@ -0,0 +1,76 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRMESSAGESTRUCTURE_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRMESSAGESTRUCTURE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/message.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +class maildirMessagePart; + + +class maildirMessageStructure : public messageStructure +{ +public: + + maildirMessageStructure(); + maildirMessageStructure(shared_ptr <maildirMessagePart> parent, const bodyPart& part); + maildirMessageStructure(shared_ptr <maildirMessagePart> parent, const std::vector <shared_ptr <const vmime::bodyPart> >& list); + + + shared_ptr <const messagePart> getPartAt(const size_t x) const; + shared_ptr <messagePart> getPartAt(const size_t x); + + size_t getPartCount() const; + + static shared_ptr <maildirMessageStructure> emptyStructure(); + +private: + + static shared_ptr <maildirMessageStructure> m_emptyStructure; + + std::vector <shared_ptr <maildirMessagePart> > m_parts; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRMESSAGESTRUCTURE_HPP_INCLUDED diff --git a/src/net/maildir/maildirServiceInfos.cpp b/src/vmime/net/maildir/maildirServiceInfos.cpp index 974a0c21..974a0c21 100644 --- a/src/net/maildir/maildirServiceInfos.cpp +++ b/src/vmime/net/maildir/maildirServiceInfos.cpp diff --git a/src/vmime/net/maildir/maildirServiceInfos.hpp b/src/vmime/net/maildir/maildirServiceInfos.hpp new file mode 100644 index 00000000..70ddc6dc --- /dev/null +++ b/src/vmime/net/maildir/maildirServiceInfos.hpp @@ -0,0 +1,71 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRSERVICEINFOS_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRSERVICEINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/serviceInfos.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +/** Information about maildir service. + */ + +class VMIME_EXPORT maildirServiceInfos : public serviceInfos +{ +public: + + maildirServiceInfos(); + + struct props + { + serviceInfos::property PROPERTY_SERVER_ROOTPATH; + }; + + const props& getProperties() const; + + const string getPropertyPrefix() const; + const std::vector <serviceInfos::property> getAvailableProperties() const; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRSERVICEINFOS_HPP_INCLUDED + diff --git a/src/net/maildir/maildirStore.cpp b/src/vmime/net/maildir/maildirStore.cpp index 87e733e2..87e733e2 100644 --- a/src/net/maildir/maildirStore.cpp +++ b/src/vmime/net/maildir/maildirStore.cpp diff --git a/src/vmime/net/maildir/maildirStore.hpp b/src/vmime/net/maildir/maildirStore.hpp new file mode 100644 index 00000000..efadfdfe --- /dev/null +++ b/src/vmime/net/maildir/maildirStore.hpp @@ -0,0 +1,120 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRSTORE_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRSTORE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/net/store.hpp" +#include "vmime/net/socket.hpp" +#include "vmime/net/folder.hpp" + +#include "vmime/net/maildir/maildirFormat.hpp" +#include "vmime/net/maildir/maildirServiceInfos.hpp" + +#include "vmime/utility/file.hpp" + +#include <ostream> + + +namespace vmime { +namespace net { +namespace maildir { + + +class maildirFolder; + + +/** maildir store service. + */ + +class VMIME_EXPORT maildirStore : public store +{ + friend class maildirFolder; + +public: + + maildirStore(shared_ptr <session> sess, shared_ptr <security::authenticator> auth); + ~maildirStore(); + + const string getProtocolName() const; + + shared_ptr <folder> getDefaultFolder(); + shared_ptr <folder> getRootFolder(); + shared_ptr <folder> getFolder(const folder::path& path); + + bool isValidFolderName(const folder::path::component& name) const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + + void connect(); + bool isConnected() const; + void disconnect(); + + void noop(); + + const utility::path& getFileSystemPath() const; + + int getCapabilities() const; + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + + shared_ptr <maildirFormat> getFormat(); + shared_ptr <const maildirFormat> getFormat() const; + +private: + + void registerFolder(maildirFolder* folder); + void unregisterFolder(maildirFolder* folder); + + + std::list <maildirFolder*> m_folders; + + shared_ptr <maildirFormat> m_format; + + bool m_connected; + + utility::path m_fsPath; + + + // Service infos + static maildirServiceInfos sm_infos; +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRSTORE_HPP_INCLUDED diff --git a/src/net/maildir/maildirUtils.cpp b/src/vmime/net/maildir/maildirUtils.cpp index 77aac715..77aac715 100644 --- a/src/net/maildir/maildirUtils.cpp +++ b/src/vmime/net/maildir/maildirUtils.cpp diff --git a/src/vmime/net/maildir/maildirUtils.hpp b/src/vmime/net/maildir/maildirUtils.hpp new file mode 100644 index 00000000..82deefbb --- /dev/null +++ b/src/vmime/net/maildir/maildirUtils.hpp @@ -0,0 +1,151 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MAILDIR_MAILDIRUTILS_HPP_INCLUDED +#define VMIME_NET_MAILDIR_MAILDIRUTILS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + + +#include "vmime/utility/file.hpp" +#include "vmime/utility/path.hpp" + +#include "vmime/net/messageSet.hpp" + + +namespace vmime { +namespace net { +namespace maildir { + + +class maildirStore; + + +/** Miscellaneous helpers functions for maildir messaging system. + */ + +class VMIME_EXPORT maildirUtils +{ +public: + + /** Comparator for message filenames, based only on the + * unique identifier part of the filename. + */ + class messageIdComparator + { + public: + + messageIdComparator(const utility::file::path::component& comp); + + bool operator()(const utility::file::path::component& other) const; + + private: + + const utility::file::path::component m_comp; + }; + + /** Test whether the specified file-system object is a message. + * + * @param file reference to a file-system object + * @return true if the specified object is a message file, + * false otherwise + */ + static bool isMessageFile(const utility::file& file); + + /** Extract the unique identifier part of the message filename. + * Eg: for the filename "1071577232.28549.m03s:2,RS", it will + * return "1071577232.28549.m03s". + * + * @param filename filename part + * @return part of the filename that corresponds to the unique + * identifier of the message + */ + static const utility::file::path::component extractId(const utility::file::path::component& filename); + + /** Extract message flags from the specified message filename. + * Eg: for the filename "1071577232.28549.m03s:2,RS", it will + * return (message::FLAG_SEEN | message::FLAG_REPLIED). + * + * @param comp filename part + * @return message flags extracted from the specified filename + */ + static int extractFlags(const utility::file::path::component& comp); + + /** Return a string representing the specified message flags. + * Eg: for (message::FLAG_SEEN | message::FLAG_REPLIED), it will + * return "RS". + * + * @param flags set of flags + * @return message flags in a string representation + */ + static const utility::file::path::component buildFlags(const int flags); + + /** Build a filename with the specified id and flags. + * + * @param id id part of the filename + * @param flags flags part of the filename + * @return message filename + */ + static const utility::file::path::component buildFilename(const utility::file::path::component& id, const utility::file::path::component& flags); + + /** Build a filename with the specified id and flags. + * + * @param id id part of the filename + * @param flags set of flags + * @return message filename + */ + static const utility::file::path::component buildFilename(const utility::file::path::component& id, const int flags); + + /** Generate a new unique message identifier. + * + * @return unique message id + */ + static const utility::file::path::component generateId(); + + /** Recursively delete a directory on the file system. + * + * @param dir directory to delete + */ + static void recursiveFSDelete(shared_ptr <utility::file> dir); + + /** Returns a list of message numbers given a message set. + * + * @param msgs message set + * @return list of message numbers + */ + static const std::vector <int> messageSetToNumberList(const messageSet& msgs); +}; + + +} // maildir +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_MAILDIR + +#endif // VMIME_NET_MAILDIR_MAILDIRUTILS_HPP_INCLUDED diff --git a/src/net/message.cpp b/src/vmime/net/message.cpp index 6765e73c..6765e73c 100644 --- a/src/net/message.cpp +++ b/src/vmime/net/message.cpp diff --git a/src/vmime/net/message.hpp b/src/vmime/net/message.hpp new file mode 100644 index 00000000..5bb62c53 --- /dev/null +++ b/src/vmime/net/message.hpp @@ -0,0 +1,355 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MESSAGE_HPP_INCLUDED +#define VMIME_NET_MESSAGE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/header.hpp" +#include "vmime/mediaType.hpp" + +#include "vmime/utility/progressListener.hpp" +#include "vmime/utility/stream.hpp" + +#include "vmime/message.hpp" + + +namespace vmime { +namespace net { + + +class messageStructure; + + +/** A MIME part in a message. + */ + +class VMIME_EXPORT messagePart : public object +{ +protected: + + messagePart() { } + messagePart(const messagePart&) : object() { } + + virtual ~messagePart() { } + +public: + + /** Return the structure of this part. + * + * @return structure of the part + */ + virtual shared_ptr <const messageStructure> getStructure() const = 0; + + /** Return the structure of this part. + * + * @return structure of the part + */ + virtual shared_ptr <messageStructure> getStructure() = 0; + + /** Return the header section for this part (you must fetch header + * before using this function: see message::fetchPartHeader). + * + * @return header section + */ + virtual shared_ptr <const header> getHeader() const = 0; + + /** Return the media-type of the content in this part. + * + * @return content media type + */ + virtual const mediaType& getType() const = 0; + + /** Return the size of this part. + * + * @return size of the part (in bytes) + */ + virtual size_t getSize() const = 0; + + /** Return the part sequence number (index). + * The first part is at index zero. + * + * @return part number + */ + virtual int getNumber() const = 0; + + /** Return the sub-part at the specified position (zero is the + * first part). + * + * @param pos index of the sub-part + * @return sub-part at position 'pos' + */ + shared_ptr <const messagePart> getPartAt(const size_t pos) const; + + /** Return the sub-part at the specified position (zero is the + * first part). + * + * @param pos index of the sub-part + * @return sub-part at position 'pos' + */ + shared_ptr <messagePart> getPartAt(const size_t pos); + + /** Return the number of sub-parts in this part. + * + * @return number of sub-parts + */ + size_t getPartCount() const; +}; + + +/** Structure of a MIME part/message. + */ + +class VMIME_EXPORT messageStructure : public object +{ +protected: + + messageStructure() { } + messageStructure(const messageStructure&) : object() { } + +public: + + virtual ~messageStructure() { } + + /** Return the part at the specified position (first + * part is at position 0). + * + * @param pos position + * @return part at position 'pos' + */ + virtual shared_ptr <const messagePart> getPartAt(const size_t pos) const = 0; + + /** Return the part at the specified position (first + * part is at position 0). + * + * @param pos position + * @return part at position 'pos' + */ + virtual shared_ptr <messagePart> getPartAt(const size_t pos) = 0; + + /** Return the number of parts in this part. + * + * @return number of parts + */ + virtual size_t getPartCount() const = 0; +}; + + +/** Abstract representation of a message in a store/transport service. + */ + +class VMIME_EXPORT message : public object +{ +protected: + + message() { } + message(const message&) : object() { } + +public: + + virtual ~message() { } + + /** The type for an unique message identifier. + */ + class VMIME_EXPORT uid + { + public: + + uid(); + uid(const string& uid); + uid(const unsigned long uid); + uid(const char* uid); + uid(const uid& other); + + uid& operator=(const uid& other); + uid& operator=(const string& uid); + uid& operator=(const unsigned long uid); + + operator string() const; + + bool empty() const; + + bool operator==(const uid& other) const; + + private: + + string m_str; + }; + + /** Return the MIME structure of the message (must fetch before). + * + * @return MIME structure of the message + */ + virtual shared_ptr <const messageStructure> getStructure() const = 0; + + /** Return the MIME structure of the message (must fetch before). + * + * @return MIME structure of the message + */ + virtual shared_ptr <messageStructure> getStructure() = 0; + + /** Return a reference to the header fields of the message (must fetch before). + * + * @return header section of the message + */ + virtual shared_ptr <const header> getHeader() const = 0; + + /** Return the sequence number of this message. This number is + * used to reference the message in the folder. + * + * @return sequence number of the message + */ + virtual int getNumber() const = 0; + + /** Return the unique identifier (UID) of this message in its + * folder (must fetch before). + * + * @return UID of the message + */ + virtual const uid getUID() const = 0; + + /** Return the size of the message (must fetch before). + * + * @return size of the message (in bytes) + */ + virtual size_t getSize() const = 0; + + /** Check whether this message has been expunged (ie: definitively + * deleted) and does not exist in the folder anymore. + * + * @return true if the message is expunged, false otherwise + */ + virtual bool isExpunged() const = 0; + + /** Possible flags for a message. + */ + enum Flags + { + FLAG_SEEN = (1 << 0), /**< Message has been seen. */ + FLAG_RECENT = (1 << 1), /**< Message has been recently received. */ + FLAG_DELETED = (1 << 2), /**< Message is marked for deletion. */ + FLAG_REPLIED = (1 << 3), /**< User replied to this message. */ + FLAG_MARKED = (1 << 4), /**< Used-defined flag. */ + FLAG_PASSED = (1 << 5), /**< Message has been resent/forwarded/bounced. */ + FLAG_DRAFT = (1 << 6), /**< Message is marked as a 'draft'. */ + + FLAG_UNDEFINED = 9999 /**< Used internally (this should not be returned + by the flags() function). */ + }; + + /** Methods for setting the flags. + */ + enum FlagsModes + { + FLAG_MODE_SET, /**< Set (replace) the flags. */ + FLAG_MODE_ADD, /**< Add the flags. */ + FLAG_MODE_REMOVE /**< Remove the flags. */ + }; + + /** Return the flags of this message. + * + * @return flags of the message + */ + virtual int getFlags() const = 0; + + /** Set the flags of this message. + * + * @param flags set of flags (see Flags) + * @param mode indicate how to treat old and new flags (see FlagsModes) + */ + virtual void setFlags(const int flags, const int mode = FLAG_MODE_SET) = 0; + + /** Extract the whole message data (header + contents). + * + * \warning Partial fetch might not be supported by the underlying protocol. + * + * @param os output stream in which to write message data + * @param progress progress listener, or NULL if not used + * @param start index of the first byte to retrieve (used for partial fetch) + * @param length number of bytes to retrieve (used for partial fetch) + * @param peek if true, try not to mark the message as read. This may not + * be supported by the protocol (IMAP supports this), but it will NOT throw + * an exception if not supported. + */ + virtual void extract + (utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false) const = 0; + + /** Extract the specified MIME part of the message (header + contents). + * + * \warning Partial fetch might not be supported by the underlying protocol. + * + * @param p part to extract + * @param os output stream in which to write part data + * @param progress progress listener, or NULL if not used + * @param start index of the first byte to retrieve (used for partial fetch) + * @param length number of bytes to retrieve (used for partial fetch) + * @param peek if true, try not to mark the message as read. This may not + * be supported by the protocol (IMAP supports this), but it will NOT throw + * an exception if not supported. + */ + virtual void extractPart + (shared_ptr <const messagePart> p, + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, + const size_t length = -1, + const bool peek = false) const = 0; + + /** Fetch the MIME header for the specified part. + * + * @param p the part for which to fetch the header + */ + virtual void fetchPartHeader(shared_ptr <messagePart> p) = 0; + + /** Get the RFC-822 message for this abstract message. + * Warning: This may require getting some data (ie: structure and headers) from + * the server, which is done automatically. Actual message contents (ie: body) + * will not be fetched if possible (IMAP allows it, whereas POP3 will require + * to fetch the whole message). + * + * @return a RFC-822-parsed message + */ + virtual shared_ptr <vmime::message> getParsedMessage() = 0; +}; + + +VMIME_EXPORT std::ostream& operator<<(std::ostream& os, const message::uid& uid); + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_MESSAGE_HPP_INCLUDED diff --git a/src/net/messageSet.cpp b/src/vmime/net/messageSet.cpp index 2939042e..2939042e 100644 --- a/src/net/messageSet.cpp +++ b/src/vmime/net/messageSet.cpp diff --git a/src/vmime/net/messageSet.hpp b/src/vmime/net/messageSet.hpp new file mode 100644 index 00000000..6c7d7f44 --- /dev/null +++ b/src/vmime/net/messageSet.hpp @@ -0,0 +1,335 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_MESSAGESET_HPP_INCLUDED +#define VMIME_NET_MESSAGESET_HPP_INCLUDED + + +#include "vmime/net/message.hpp" + + +namespace vmime { +namespace net { + + +// Forward references +class numberMessageRange; +class UIDMessageRange; + + +/** Enumerator used to retrieve the message number/UID ranges contained + * in a messageSet object. + */ + +class VMIME_EXPORT messageSetEnumerator +{ +public: + + virtual void enumerateNumberMessageRange(const numberMessageRange& range) = 0; + virtual void enumerateUIDMessageRange(const UIDMessageRange& range) = 0; +}; + + +/** A range of (continuous) messages, designated either by their + * sequence number, or by their UID. + */ + +class VMIME_EXPORT messageRange : public object +{ +public: + + virtual ~messageRange(); + + /** Enumerates this range with the specified enumerator. + * + * @param en enumerator that will receive the method calls while + * enumerating this range + */ + virtual void enumerate(messageSetEnumerator& en) const = 0; + + /** Clones this message range. + */ + virtual messageRange* clone() const = 0; + +protected: + + messageRange(); + messageRange(const messageRange&); +}; + + +/** A range of (continuous) messages designated by their sequence number. + */ + +class VMIME_EXPORT numberMessageRange : public messageRange +{ +public: + + /** Constructs a message range containing a single message. + * + * @param number message number (numbering starts at 1, not 0) + */ + numberMessageRange(const int number); + + /** Constructs a message range for multiple messages. + * + * @param first number of the first message in the range (numbering + * starts at 1, not 0) + * @param last number of the last message in the range, or use the + * special value -1 to designate the last message in the folder + */ + numberMessageRange(const int first, const int last); + + /** Constructs a message range by copying from another range. + * + * @param other range to copy + */ + numberMessageRange(const numberMessageRange& other); + + /** Returns the number of the first message in the range. + * + * @return number of the first message + */ + int getFirst() const; + + /** Returns the number of the last message in the range, or -1 + * to designate the last message in the folder + * + * @return number of the last message + */ + int getLast() const; + + void enumerate(messageSetEnumerator& en) const; + + messageRange* clone() const; + +private: + + int m_first, m_last; +}; + + +/** A range of (continuous) messages represented by their UID. + */ + +class VMIME_EXPORT UIDMessageRange : public messageRange +{ +public: + + /** Constructs a message range containing a single message. + * + * @param uid message UID + */ + UIDMessageRange(const message::uid& uid); + + /** Constructs a message range for multiple messages. + * + * @param first UID of the first message in the range + * @param last UID of the last message in the range, or use the + * special value '*' to designate the last message in the folder + */ + UIDMessageRange(const message::uid& first, const message::uid& last); + + /** Constructs a message range by copying from another range. + * + * @param other range to copy + */ + UIDMessageRange(const UIDMessageRange& other); + + /** Returns the UID of the first message in the range. + * + * @return UID of the first message + */ + const message::uid getFirst() const; + + /** Returns the UID of the last message in the range, or '*' + * to designate the last message in the folder + * + * @return UID of the last message + */ + const message::uid getLast() const; + + void enumerate(messageSetEnumerator& en) const; + + messageRange* clone() const; + +private: + + message::uid m_first, m_last; +}; + + +/** Represents a set of messages, designated either by their sequence + * number, or by their UID (but not both). + * + * Following is example code to designate messages by their number: + * \code{.cpp} + * // Designate a single message with sequence number 42 + * vmime::net::messageSet::byNumber(42) + * + * // Designate messages from sequence number 5 to sequence number 8 (including) + * vmime::net::messageSet::byNumber(5, 8) + * + * // Designate all messages in the folder, starting from number 42 + * vmime::net::messageSet::byNumber(42, -1) + * \endcode + * Or, to designate messages by their UID, use: + * \code{.cpp} + * // Designate a single message with UID 1042 + * vmime::net::messageSet::byUID(1042) + * + * // Designate messages from UID 1000 to UID 1042 (including) + * vmime::net::messageSet::byUID(1000, 1042) + * + * // Designate all messages in the folder, starting from UID 1000 + * vmime::net::messageSet::byUID(1000, "*") + * \endcode + */ + +class VMIME_EXPORT messageSet : public object +{ +public: + + ~messageSet(); + + messageSet(const messageSet& other); + + /** Constructs a new message set and initializes it with a single + * message represented by its sequence number. + * + * @param number message number (numbering starts at 1, not 0) + * @return new message set + */ + static messageSet byNumber(const int number); + + /** Constructs a new message set and initializes it with a range + * of messages represented by their sequence number. + * + * @param first number of the first message in the range (numbering + * starts at 1, not 0) + * @param last number of the last message in the range, or use the + * special value -1 to designate the last message in the folder + * @return new message set + */ + static messageSet byNumber(const int first, const int last); + + /** Constructs a new message set and initializes it with a possibly + * unsorted list of messages represented by their sequence number. + * Please note that numbering starts at 1, not 0. + * + * The function tries to group consecutive message numbers into + * ranges to reduce the size of the resulting set. + * + * For example, given the list "1,2,3,4,5,7,8,13,15,16,17" it will + * result in the following ranges: "1:5,7:8,13,15:17". + * + * @param numbers a vector containing numbers of the messages + * @return new message set + */ + static messageSet byNumber(const std::vector <int>& numbers); + + /** Constructs a new message set and initializes it with a single + * message represented by its UID. + * + * @param uid message UID + * @return new message set + */ + static messageSet byUID(const message::uid& uid); + + /** Constructs a new message set and initializes it with a range + * of messages represented by their sequence number. + * + * @param first UID of the first message in the range + * @param last UID of the last message in the range, or use the + * special value '*' to designate the last message in the folder + * @return new message set + */ + static messageSet byUID(const message::uid& first, const message::uid& last); + + /** Constructs a new message set and initializes it with a possibly + * unsorted list of messages represented by their UID. + * + * For UIDs that actually are numbers (this is the case for IMAP), the + * function tries to group consecutive UIDs into ranges to reduce the + * size of the resulting set. + * + * For example, given the list "1,2,3,4,5,7,8,13,15,16,17" it will + * result in the following ranges: "1:5,7:8,13,15:17". + * + * @param uids a vector containing UIDs of the messages + * @return new message set + */ + static messageSet byUID(const std::vector <message::uid>& uids); + + /** Adds the specified range to this set. The type of message range + * (either number or UID) must match the type of the ranges already + * contained in this set (ie. it's not possible to have a message + * set which contains both number ranges and UID ranges). + * + * @param range range to add + * @throw std::invalid_argument exception if the range type does + * not match the type of the ranges in this set + */ + void addRange(const messageRange& range); + + /** Enumerates this set with the specified enumerator. + * + * @param en enumerator that will receive the method calls while + * enumerating the ranges in this set + */ + void enumerate(messageSetEnumerator& en) const; + + /** Returns whether this set is empty (contains no range). + * + * @return true if this set is empty, or false otherwise + */ + bool isEmpty() const; + + /** Returns whether this set references messages by their sequence + * number. + * + * @return true if this set references messages by their sequence + * number, or false otherwise + */ + bool isNumberSet() const; + + /** Returns whether this set references messages by their UID. + * + * @return true if this set references messages by their UID, + * or false otherwise + */ + bool isUIDSet() const; + +private: + + messageSet(); + + std::vector <messageRange*> m_ranges; +}; + + +} // net +} // vmime + + +#endif // VMIME_NET_MESSAGESET_HPP_INCLUDED diff --git a/src/net/pop3/POP3Command.cpp b/src/vmime/net/pop3/POP3Command.cpp index 6fe301ce..6fe301ce 100644 --- a/src/net/pop3/POP3Command.cpp +++ b/src/vmime/net/pop3/POP3Command.cpp diff --git a/src/vmime/net/pop3/POP3Command.hpp b/src/vmime/net/pop3/POP3Command.hpp new file mode 100644 index 00000000..cc3c4fd5 --- /dev/null +++ b/src/vmime/net/pop3/POP3Command.hpp @@ -0,0 +1,113 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3COMMAND_HPP_INCLUDED +#define VMIME_NET_POP3_POP3COMMAND_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/object.hpp" +#include "vmime/base.hpp" + + +namespace vmime { + + +class mailbox; + + +namespace net { +namespace pop3 { + + +class POP3Connection; + + +/** A POP3 command that will be sent to the server. + */ +class VMIME_EXPORT POP3Command : public object +{ +public: + + static shared_ptr <POP3Command> CAPA(); + static shared_ptr <POP3Command> NOOP(); + static shared_ptr <POP3Command> AUTH(const string& mechName); + static shared_ptr <POP3Command> STLS(); + static shared_ptr <POP3Command> APOP(const string& username, const string& digest); + static shared_ptr <POP3Command> USER(const string& username); + static shared_ptr <POP3Command> PASS(const string& password); + static shared_ptr <POP3Command> STAT(); + static shared_ptr <POP3Command> LIST(); + static shared_ptr <POP3Command> LIST(const unsigned long msg); + static shared_ptr <POP3Command> UIDL(); + static shared_ptr <POP3Command> UIDL(const unsigned long msg); + static shared_ptr <POP3Command> DELE(const unsigned long msg); + static shared_ptr <POP3Command> RETR(const unsigned long msg); + static shared_ptr <POP3Command> TOP(const unsigned long msg, const unsigned long lines); + static shared_ptr <POP3Command> RSET(); + static shared_ptr <POP3Command> QUIT(); + + /** Creates a new POP3 command with the specified text. + * + * @param text command text + * @return a new POP3Command object + */ + static shared_ptr <POP3Command> createCommand(const string& text); + + /** Sends this command over the specified connection. + * + * @param conn connection onto which the command will be sent + */ + virtual void send(shared_ptr <POP3Connection> conn); + + /** Returns the full text of the command, including command name + * and parameters (if any). + * + * @return command text (eg. "LIST 42") + */ + virtual const string getText() const; + +protected: + + POP3Command(const string& text); + POP3Command(const POP3Command&); + +private: + + string m_text; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3COMMAND_HPP_INCLUDED diff --git a/src/net/pop3/POP3Connection.cpp b/src/vmime/net/pop3/POP3Connection.cpp index 5fa923f4..5fa923f4 100644 --- a/src/net/pop3/POP3Connection.cpp +++ b/src/vmime/net/pop3/POP3Connection.cpp diff --git a/src/vmime/net/pop3/POP3Connection.hpp b/src/vmime/net/pop3/POP3Connection.hpp new file mode 100644 index 00000000..3622f745 --- /dev/null +++ b/src/vmime/net/pop3/POP3Connection.hpp @@ -0,0 +1,125 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3CONNECTION_HPP_INCLUDED +#define VMIME_NET_POP3_POP3CONNECTION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/messageId.hpp" + +#include "vmime/net/socket.hpp" +#include "vmime/net/timeoutHandler.hpp" +#include "vmime/net/session.hpp" +#include "vmime/net/connectionInfos.hpp" + +#include "vmime/net/pop3/POP3Command.hpp" +#include "vmime/net/pop3/POP3Response.hpp" + +#include "vmime/security/authenticator.hpp" + + +namespace vmime { +namespace net { + + +class socket; +class timeoutHandler; + + +namespace pop3 { + + +class POP3Store; + + +/** Manage connection to a POP3 server. + */ +class VMIME_EXPORT POP3Connection : public object +{ +public: + + POP3Connection(shared_ptr <POP3Store> store, shared_ptr <security::authenticator> auth); + virtual ~POP3Connection(); + + + virtual void connect(); + virtual bool isConnected() const; + virtual void disconnect(); + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + + virtual shared_ptr <POP3Store> getStore(); + virtual shared_ptr <socket> getSocket(); + virtual shared_ptr <timeoutHandler> getTimeoutHandler(); + virtual shared_ptr <security::authenticator> getAuthenticator(); + virtual shared_ptr <session> getSession(); + +private: + + void authenticate(const messageId& randomMID); +#if VMIME_HAVE_SASL_SUPPORT + void authenticateSASL(); +#endif // VMIME_HAVE_SASL_SUPPORT + +#if VMIME_HAVE_TLS_SUPPORT + void startTLS(); +#endif // VMIME_HAVE_TLS_SUPPORT + + void fetchCapabilities(); + void invalidateCapabilities(); + const std::vector <string> getCapabilities(); + + void internalDisconnect(); + + + weak_ptr <POP3Store> m_store; + + shared_ptr <security::authenticator> m_auth; + shared_ptr <socket> m_socket; + shared_ptr <timeoutHandler> m_timeoutHandler; + + bool m_authenticated; + bool m_secured; + + shared_ptr <connectionInfos> m_cntInfos; + + std::vector <string> m_capabilities; + bool m_capabilitiesFetched; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3CONNECTION_HPP_INCLUDED diff --git a/src/net/pop3/POP3Folder.cpp b/src/vmime/net/pop3/POP3Folder.cpp index 096de8af..096de8af 100644 --- a/src/net/pop3/POP3Folder.cpp +++ b/src/vmime/net/pop3/POP3Folder.cpp diff --git a/src/vmime/net/pop3/POP3Folder.hpp b/src/vmime/net/pop3/POP3Folder.hpp new file mode 100644 index 00000000..27ea6e5f --- /dev/null +++ b/src/vmime/net/pop3/POP3Folder.hpp @@ -0,0 +1,157 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3FOLDER_HPP_INCLUDED +#define VMIME_NET_POP3_POP3FOLDER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include <vector> +#include <map> + +#include "vmime/types.hpp" + +#include "vmime/net/folder.hpp" + + +namespace vmime { +namespace net { +namespace pop3 { + + +class POP3Store; +class POP3Message; + + +/** POP3 folder implementation. + */ + +class VMIME_EXPORT POP3Folder : public folder +{ +private: + + friend class POP3Store; + friend class POP3Message; + + POP3Folder(const POP3Folder&); + +public: + + POP3Folder(const folder::path& path, shared_ptr <POP3Store> store); + + ~POP3Folder(); + + int getMode() const; + + int getType(); + + int getFlags(); + + const folder::path::component getName() const; + const folder::path getFullPath() const; + + void open(const int mode, bool failIfModeIsNotAvailable = false); + void close(const bool expunge); + void create(const int type); + + bool exists(); + + void destroy(); + + bool isOpen() const; + + shared_ptr <message> getMessage(const int num); + std::vector <shared_ptr <message> > getMessages(const messageSet& msgs); + + int getMessageCount(); + + shared_ptr <folder> getFolder(const folder::path::component& name); + std::vector <shared_ptr <folder> > getFolders(const bool recursive = false); + + void rename(const folder::path& newPath); + + void deleteMessages(const messageSet& msgs); + + void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET); + + void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL); + + void copyMessages(const folder::path& dest, const messageSet& msgs); + + void status(int& count, int& unseen); + shared_ptr <folderStatus> getStatus(); + + void expunge(); + + shared_ptr <folder> getParent(); + + shared_ptr <const store> getStore() const; + shared_ptr <store> getStore(); + + + void fetchMessages(std::vector <shared_ptr <message> >& msg, const fetchAttributes& options, utility::progressListener* progress = NULL); + void fetchMessage(shared_ptr <message> msg, const fetchAttributes& options); + + int getFetchCapabilities() const; + + std::vector <int> getMessageNumbersStartingOnUID(const message::uid& uid); + +private: + + void registerMessage(POP3Message* msg); + void unregisterMessage(POP3Message* msg); + + void onStoreDisconnected(); + + void onClose(); + + + weak_ptr <POP3Store> m_store; + + folder::path m_path; + folder::path::component m_name; + + int m_mode; + bool m_open; + + int m_messageCount; + + typedef std::map <POP3Message*, int> MessageMap; + MessageMap m_messages; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3FOLDER_HPP_INCLUDED diff --git a/src/net/pop3/POP3FolderStatus.cpp b/src/vmime/net/pop3/POP3FolderStatus.cpp index 944379ac..944379ac 100644 --- a/src/net/pop3/POP3FolderStatus.cpp +++ b/src/vmime/net/pop3/POP3FolderStatus.cpp diff --git a/src/vmime/net/pop3/POP3FolderStatus.hpp b/src/vmime/net/pop3/POP3FolderStatus.hpp new file mode 100644 index 00000000..70ba48b6 --- /dev/null +++ b/src/vmime/net/pop3/POP3FolderStatus.hpp @@ -0,0 +1,76 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3FOLDERSTATUS_HPP_INCLUDED +#define VMIME_NET_POP3_POP3FOLDERSTATUS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/net/folderStatus.hpp" + + +namespace vmime { +namespace net { +namespace pop3 { + + +/** Holds the status of a POP3 folder. + */ + +class VMIME_EXPORT POP3FolderStatus : public folderStatus +{ +public: + + POP3FolderStatus(); + POP3FolderStatus(const POP3FolderStatus& other); + + // Inherited from folderStatus + unsigned int getMessageCount() const; + unsigned int getUnseenCount() const; + + shared_ptr <folderStatus> clone() const; + + + void setMessageCount(const unsigned int count); + void setUnseenCount(const unsigned int unseen); + +private: + + unsigned int m_count; + unsigned int m_unseen; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3FOLDERSTATUS_HPP_INCLUDED diff --git a/src/net/pop3/POP3Message.cpp b/src/vmime/net/pop3/POP3Message.cpp index 08523611..08523611 100644 --- a/src/net/pop3/POP3Message.cpp +++ b/src/vmime/net/pop3/POP3Message.cpp diff --git a/src/vmime/net/pop3/POP3Message.hpp b/src/vmime/net/pop3/POP3Message.hpp new file mode 100644 index 00000000..87e71ba7 --- /dev/null +++ b/src/vmime/net/pop3/POP3Message.hpp @@ -0,0 +1,121 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3MESSAGE_HPP_INCLUDED +#define VMIME_NET_POP3_POP3MESSAGE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/net/message.hpp" +#include "vmime/net/folder.hpp" + + +namespace vmime { +namespace net { +namespace pop3 { + + +class POP3Folder; + + +/** POP3 message implementation. + */ + +class VMIME_EXPORT POP3Message : public message +{ +private: + + friend class POP3Folder; + + POP3Message(const POP3Message&); + +public: + + POP3Message(shared_ptr <POP3Folder> folder, const int num); + + ~POP3Message(); + + + int getNumber() const; + + const uid getUID() const; + + size_t getSize() const; + + bool isExpunged() const; + + shared_ptr <const messageStructure> getStructure() const; + shared_ptr <messageStructure> getStructure(); + + shared_ptr <const header> getHeader() const; + + int getFlags() const; + void setFlags(const int flags, const int mode = FLAG_MODE_SET); + + void extract + (utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, const size_t length = -1, + const bool peek = false) const; + + void extractPart + (shared_ptr <const messagePart> p, + utility::outputStream& os, + utility::progressListener* progress = NULL, + const size_t start = 0, const size_t length = -1, + const bool peek = false) const; + + void fetchPartHeader(shared_ptr <messagePart> p); + + shared_ptr <vmime::message> getParsedMessage(); + +private: + + void fetch(shared_ptr <POP3Folder> folder, const fetchAttributes& options); + + void onFolderClosed(); + + weak_ptr <POP3Folder> m_folder; + int m_num; + uid m_uid; + size_t m_size; + + bool m_deleted; + + shared_ptr <header> m_header; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3MESSAGE_HPP_INCLUDED diff --git a/src/net/pop3/POP3Response.cpp b/src/vmime/net/pop3/POP3Response.cpp index 1dc5ee76..1dc5ee76 100644 --- a/src/net/pop3/POP3Response.cpp +++ b/src/vmime/net/pop3/POP3Response.cpp diff --git a/src/vmime/net/pop3/POP3Response.hpp b/src/vmime/net/pop3/POP3Response.hpp new file mode 100644 index 00000000..20477b5e --- /dev/null +++ b/src/vmime/net/pop3/POP3Response.hpp @@ -0,0 +1,182 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_POP3RESPONSE_HPP_INCLUDED +#define VMIME_NET_SMTP_POP3RESPONSE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/object.hpp" +#include "vmime/base.hpp" + +#include "vmime/utility/outputStream.hpp" +#include "vmime/utility/progressListener.hpp" + +#include "vmime/net/socket.hpp" + + +namespace vmime { +namespace net { + + +class timeoutHandler; + + +namespace pop3 { + + +class POP3Connection; + + +/** A POP3 response, as sent by the server. + */ +class VMIME_EXPORT POP3Response : public object +{ +public: + + /** Possible response codes. */ + enum ResponseCode + { + CODE_OK = 0, + CODE_READY, + CODE_ERR + }; + + + /** Receive and parse a POP3 response from the + * specified connection. + * + * @param conn connection from which to read + * @return POP3 response + * @throws exceptions::operation_timed_out if no data + * has been received within the granted time + */ + static shared_ptr <POP3Response> readResponse(shared_ptr <POP3Connection> conn); + + /** Receive and parse a multiline POP3 response from + * the specified connection. + * + * @param conn connection from which to read + * @return POP3 response + * @throws exceptions::operation_timed_out if no data + * has been received within the granted time + */ + static shared_ptr <POP3Response> readMultilineResponse(shared_ptr <POP3Connection> conn); + + /** Receive and parse a large POP3 response (eg. message data) + * from the specified connection. + * + * @param conn connection from which to read + * @param os output stream to which response data will be written + * @param progress progress listener (can be NULL) + * @param predictedSize estimated size of response data (in bytes) + * @return POP3 response + * @throws exceptions::operation_timed_out if no data + * has been received within the granted time + */ + static shared_ptr <POP3Response> readLargeResponse + (shared_ptr <POP3Connection> conn, utility::outputStream& os, + utility::progressListener* progress, const size_t predictedSize); + + + /** Returns whether the response is successful ("OK"). + * + * @return true if the response if successful, false otherwise + */ + bool isSuccess() const; + + /** Return the POP3 response code. + * + * @return response code + */ + ResponseCode getCode() const; + + /** Return the POP3 response text (first line). + * + * @return response text + */ + const string getText() const; + + /** Return the first POP3 response line. + * + * @return first response line + */ + const string getFirstLine() const; + + /** Return the response line at the specified position. + * + * @param pos line index + * @return line at the specified index + */ + const string getLineAt(const size_t pos) const; + + /** Return the number of lines in the response. + * + * @return number of lines in the response + */ + size_t getLineCount() const; + +private: + + POP3Response(shared_ptr <socket> sok, shared_ptr <timeoutHandler> toh); + + void readResponseImpl(string& buffer, const bool multiLine); + void readResponseImpl + (string& firstLine, utility::outputStream& os, + utility::progressListener* progress, const size_t predictedSize); + + + static bool stripFirstLine(const string& buffer, string& result, string* firstLine); + + static ResponseCode getResponseCode(const string& buffer); + + static void stripResponseCode(const string& buffer, string& result); + + static bool checkTerminator(string& buffer, const bool multiLine); + static bool checkOneTerminator(string& buffer, const string& term); + + + shared_ptr <socket> m_socket; + shared_ptr <timeoutHandler> m_timeoutHandler; + + string m_firstLine; + ResponseCode m_code; + string m_text; + + std::vector <string> m_lines; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_SMTP_POP3RESPONSE_HPP_INCLUDED diff --git a/src/net/pop3/POP3SStore.cpp b/src/vmime/net/pop3/POP3SStore.cpp index f1c3da74..f1c3da74 100644 --- a/src/net/pop3/POP3SStore.cpp +++ b/src/vmime/net/pop3/POP3SStore.cpp diff --git a/src/vmime/net/pop3/POP3SStore.hpp b/src/vmime/net/pop3/POP3SStore.hpp new file mode 100644 index 00000000..e60b4ef8 --- /dev/null +++ b/src/vmime/net/pop3/POP3SStore.hpp @@ -0,0 +1,71 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED +#define VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/net/pop3/POP3Store.hpp" + + +namespace vmime { +namespace net { +namespace pop3 { + + +/** POP3S store service. + */ + +class VMIME_EXPORT POP3SStore : public POP3Store +{ +public: + + POP3SStore(shared_ptr <session> sess, shared_ptr <security::authenticator> auth); + ~POP3SStore(); + + const string getProtocolName() const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + +private: + + static POP3ServiceInfos sm_infos; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3SSTORE_HPP_INCLUDED + diff --git a/src/net/pop3/POP3ServiceInfos.cpp b/src/vmime/net/pop3/POP3ServiceInfos.cpp index 4760d4f2..4760d4f2 100644 --- a/src/net/pop3/POP3ServiceInfos.cpp +++ b/src/vmime/net/pop3/POP3ServiceInfos.cpp diff --git a/src/vmime/net/pop3/POP3ServiceInfos.hpp b/src/vmime/net/pop3/POP3ServiceInfos.hpp new file mode 100644 index 00000000..710d8be3 --- /dev/null +++ b/src/vmime/net/pop3/POP3ServiceInfos.hpp @@ -0,0 +1,93 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED +#define VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/net/serviceInfos.hpp" + + +namespace vmime { +namespace net { +namespace pop3 { + + +/** Information about POP3 service. + */ + +class VMIME_EXPORT POP3ServiceInfos : public serviceInfos +{ +public: + + POP3ServiceInfos(const bool pop3s); + + struct props + { + // POP3-specific options + serviceInfos::property PROPERTY_OPTIONS_APOP; + serviceInfos::property PROPERTY_OPTIONS_APOP_FALLBACK; +#if VMIME_HAVE_SASL_SUPPORT + serviceInfos::property PROPERTY_OPTIONS_SASL; + serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK; +#endif // VMIME_HAVE_SASL_SUPPORT + + // Common properties + serviceInfos::property PROPERTY_AUTH_USERNAME; + serviceInfos::property PROPERTY_AUTH_PASSWORD; + +#if VMIME_HAVE_TLS_SUPPORT + serviceInfos::property PROPERTY_CONNECTION_TLS; + serviceInfos::property PROPERTY_CONNECTION_TLS_REQUIRED; +#endif // VMIME_HAVE_TLS_SUPPORT + + serviceInfos::property PROPERTY_SERVER_ADDRESS; + serviceInfos::property PROPERTY_SERVER_PORT; + }; + + const props& getProperties() const; + + const string getPropertyPrefix() const; + const std::vector <serviceInfos::property> getAvailableProperties() const; + +private: + + const bool m_pop3s; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3SERVICEINFOS_HPP_INCLUDED + diff --git a/src/net/pop3/POP3Store.cpp b/src/vmime/net/pop3/POP3Store.cpp index e6e95b1b..e6e95b1b 100644 --- a/src/net/pop3/POP3Store.cpp +++ b/src/vmime/net/pop3/POP3Store.cpp diff --git a/src/vmime/net/pop3/POP3Store.hpp b/src/vmime/net/pop3/POP3Store.hpp new file mode 100644 index 00000000..b35659a0 --- /dev/null +++ b/src/vmime/net/pop3/POP3Store.hpp @@ -0,0 +1,116 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3STORE_HPP_INCLUDED +#define VMIME_NET_POP3_POP3STORE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include "vmime/net/store.hpp" + +#include "vmime/net/pop3/POP3ServiceInfos.hpp" +#include "vmime/net/pop3/POP3Connection.hpp" + +#include "vmime/utility/stream.hpp" + + +namespace vmime { +namespace net { +namespace pop3 { + + +class POP3Folder; +class POP3Command; +class POP3Response; + + +/** POP3 store service. + */ + +class VMIME_EXPORT POP3Store : public store +{ + friend class POP3Folder; + friend class POP3Message; + +public: + + POP3Store(shared_ptr <session> sess, shared_ptr <security::authenticator> auth, const bool secured = false); + ~POP3Store(); + + const string getProtocolName() const; + + shared_ptr <folder> getDefaultFolder(); + shared_ptr <folder> getRootFolder(); + shared_ptr <folder> getFolder(const folder::path& path); + + bool isValidFolderName(const folder::path::component& name) const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + + void connect(); + bool isConnected() const; + void disconnect(); + + void noop(); + + int getCapabilities() const; + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + shared_ptr <POP3Connection> getConnection(); + + bool isPOP3S() const; + +private: + + shared_ptr <POP3Connection> m_connection; + + + void registerFolder(POP3Folder* folder); + void unregisterFolder(POP3Folder* folder); + + std::list <POP3Folder*> m_folders; + + + const bool m_isPOP3S; + + + // Service infos + static POP3ServiceInfos sm_infos; +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3STORE_HPP_INCLUDED diff --git a/src/net/pop3/POP3Utils.cpp b/src/vmime/net/pop3/POP3Utils.cpp index 7ba65fff..7ba65fff 100644 --- a/src/net/pop3/POP3Utils.cpp +++ b/src/vmime/net/pop3/POP3Utils.cpp diff --git a/src/vmime/net/pop3/POP3Utils.hpp b/src/vmime/net/pop3/POP3Utils.hpp new file mode 100644 index 00000000..c7459efe --- /dev/null +++ b/src/vmime/net/pop3/POP3Utils.hpp @@ -0,0 +1,86 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3UTILS_HPP_INCLUDED +#define VMIME_NET_POP3_POP3UTILS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + + +#include <map> + +#include "vmime/types.hpp" + +#include "vmime/net/messageSet.hpp" + + +namespace vmime { +namespace net { +namespace pop3 { + + +class POP3Response; + + +class VMIME_EXPORT POP3Utils +{ +public: + + /** Parse a response of type ([integer] [string] \n)*. + * This is used in LIST or UIDL commands: + * + * C: UIDL + * S: +OK + * S: 1 whqtswO00WBw418f9t5JxYwZ + * S: 2 QhdPYR:00WBw1Ph7x7 + * S: . + * + * @param response raw response string as returned by the server + * @param result points to an associative array which maps a message + * number to its corresponding data (either UID or size) + */ + static void parseMultiListOrUidlResponse + (shared_ptr <POP3Response> response, std::map <int, string>& result); + + /** Returns a list of message numbers given a message set. + * + * @param msgs message set + * @return list of message numbers + */ + static const std::vector <int> messageSetToNumberList(const messageSet& msgs); +}; + + +} // pop3 +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_POP3 + +#endif // VMIME_NET_POP3_POP3UTILS_HPP_INCLUDED + diff --git a/src/vmime/net/pop3/pop3.hpp b/src/vmime/net/pop3/pop3.hpp new file mode 100644 index 00000000..366b1e4a --- /dev/null +++ b/src/vmime/net/pop3/pop3.hpp @@ -0,0 +1,35 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_POP3_POP3_HPP_INCLUDED +#define VMIME_NET_POP3_POP3_HPP_INCLUDED + + +#include "vmime/net/pop3/POP3Folder.hpp" +#include "vmime/net/pop3/POP3FolderStatus.hpp" +#include "vmime/net/pop3/POP3Message.hpp" +#include "vmime/net/pop3/POP3Store.hpp" +#include "vmime/net/pop3/POP3SStore.hpp" + + +#endif // VMIME_NET_POP3_POP3_HPP_INCLUDED diff --git a/src/vmime/net/securedConnectionInfos.hpp b/src/vmime/net/securedConnectionInfos.hpp new file mode 100644 index 00000000..8ed8b138 --- /dev/null +++ b/src/vmime/net/securedConnectionInfos.hpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SECUREDCONNECTIONINFOS_HPP_INCLUDED +#define VMIME_NET_SECUREDCONNECTIONINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/connectionInfos.hpp" + + +namespace vmime { +namespace net { + + +/** Information about the secured connection used by a service. + */ +class VMIME_EXPORT securedConnectionInfos : public connectionInfos +{ +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_SECUREDCONNECTIONINFOS_HPP_INCLUDED + diff --git a/src/vmime/net/sendmail/sendmail.hpp b/src/vmime/net/sendmail/sendmail.hpp new file mode 100644 index 00000000..b3692526 --- /dev/null +++ b/src/vmime/net/sendmail/sendmail.hpp @@ -0,0 +1,31 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SENDMAIL_SENDMAIL_HPP_INCLUDED +#define VMIME_NET_SENDMAIL_SENDMAIL_HPP_INCLUDED + + +#include "vmime/net/sendmail/sendmailTransport.hpp" + + +#endif // VMIME_NET_SENDMAIL_SENDMAIL_HPP_INCLUDED diff --git a/src/net/sendmail/sendmailServiceInfos.cpp b/src/vmime/net/sendmail/sendmailServiceInfos.cpp index 21cac00c..21cac00c 100644 --- a/src/net/sendmail/sendmailServiceInfos.cpp +++ b/src/vmime/net/sendmail/sendmailServiceInfos.cpp diff --git a/src/vmime/net/sendmail/sendmailServiceInfos.hpp b/src/vmime/net/sendmail/sendmailServiceInfos.hpp new file mode 100644 index 00000000..de94e392 --- /dev/null +++ b/src/vmime/net/sendmail/sendmailServiceInfos.hpp @@ -0,0 +1,71 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SENDMAIL_SENDMAILSERVICEINFOS_HPP_INCLUDED +#define VMIME_NET_SENDMAIL_SENDMAILSERVICEINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SENDMAIL + + +#include "vmime/net/serviceInfos.hpp" + + +namespace vmime { +namespace net { +namespace sendmail { + + +/** Information about sendmail service. + */ + +class VMIME_EXPORT sendmailServiceInfos : public serviceInfos +{ +public: + + sendmailServiceInfos(); + + struct props + { + serviceInfos::property PROPERTY_BINPATH; + }; + + const props& getProperties() const; + + const string getPropertyPrefix() const; + const std::vector <serviceInfos::property> getAvailableProperties() const; +}; + + +} // sendmail +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SENDMAIL + +#endif // VMIME_NET_SENDMAIL_SENDMAILSERVICEINFOS_HPP_INCLUDED + diff --git a/src/net/sendmail/sendmailTransport.cpp b/src/vmime/net/sendmail/sendmailTransport.cpp index 8ef18e3b..8ef18e3b 100644 --- a/src/net/sendmail/sendmailTransport.cpp +++ b/src/vmime/net/sendmail/sendmailTransport.cpp diff --git a/src/vmime/net/sendmail/sendmailTransport.hpp b/src/vmime/net/sendmail/sendmailTransport.hpp new file mode 100644 index 00000000..d1c6aec0 --- /dev/null +++ b/src/vmime/net/sendmail/sendmailTransport.hpp @@ -0,0 +1,103 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED +#define VMIME_NET_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SENDMAIL + + +#include "vmime/net/transport.hpp" +#include "vmime/net/socket.hpp" +#include "vmime/net/timeoutHandler.hpp" + +#include "vmime/net/sendmail/sendmailServiceInfos.hpp" + + +namespace vmime { +namespace net { +namespace sendmail { + + +/** Sendmail local transport service. + */ + +class VMIME_EXPORT sendmailTransport : public transport +{ +public: + + sendmailTransport(shared_ptr <session> sess, shared_ptr <security::authenticator> auth); + ~sendmailTransport(); + + const string getProtocolName() const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + + void connect(); + bool isConnected() const; + void disconnect(); + + void noop(); + + void send + (const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox()); + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + +private: + + void internalDisconnect(); + + void internalSend(const std::vector <string> args, utility::inputStream& is, + const size_t size, utility::progressListener* progress); + + + string m_sendmailPath; + + bool m_connected; + + + // Service infos + static sendmailServiceInfos sm_infos; +}; + + +} // sendmail +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SENDMAIL + +#endif // VMIME_NET_SENDMAIL_SENDMAILTRANSPORT_HPP_INCLUDED diff --git a/src/net/service.cpp b/src/vmime/net/service.cpp index c52ba592..c52ba592 100644 --- a/src/net/service.cpp +++ b/src/vmime/net/service.cpp diff --git a/src/vmime/net/service.hpp b/src/vmime/net/service.hpp new file mode 100644 index 00000000..6969ac20 --- /dev/null +++ b/src/vmime/net/service.hpp @@ -0,0 +1,233 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SERVICE_HPP_INCLUDED +#define VMIME_NET_SERVICE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/types.hpp" + +#include "vmime/net/session.hpp" + +#include "vmime/net/serviceInfos.hpp" +#include "vmime/net/connectionInfos.hpp" + +#include "vmime/net/socket.hpp" +#include "vmime/net/timeoutHandler.hpp" + +#if VMIME_HAVE_TLS_SUPPORT + #include "vmime/security/cert/certificateVerifier.hpp" +#endif // VMIME_HAVE_TLS_SUPPORT + +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace net { + + +/** Base class for messaging services. + */ + +class VMIME_EXPORT service : public object +{ +protected: + + service(shared_ptr <session> sess, const serviceInfos& infos, shared_ptr <security::authenticator> auth); + +public: + + virtual ~service(); + + /** Possible service types. */ + enum Type + { + TYPE_STORE = 0, /**< The service is a message store. */ + TYPE_TRANSPORT /**< The service sends messages. */ + }; + + /** Return the type of service. + * + * @return type of service + */ + virtual Type getType() const = 0; + + /** Return the protocol name of this service. + * + * @return protocol name + */ + virtual const string getProtocolName() const = 0; + + /** Return the session object associated with this service instance. + * + * @return session object + */ + shared_ptr <const session> getSession() const; + + /** Return the session object associated with this service instance. + * + * @return session object + */ + shared_ptr <session> getSession(); + + /** Return information about this service. + * + * @return information about the service + */ + virtual const serviceInfos& getInfos() const = 0; + + /** Connect to service. + */ + virtual void connect() = 0; + + /** Disconnect from service. + */ + virtual void disconnect() = 0; + + /** Test whether this service is connected. + * + * @return true if the service is connected, false otherwise + */ + virtual bool isConnected() const = 0; + + /** Do nothing but ensure the server do not disconnect (for + * example, this can reset the auto-logout timer on the + * server, if one exists). + */ + virtual void noop() = 0; + + /** Return the authenticator object used with this service instance. + * + * @return authenticator object + */ + shared_ptr <const security::authenticator> getAuthenticator() const; + + /** Return the authenticator object used with this service instance. + * + * @return authenticator object + */ + shared_ptr <security::authenticator> getAuthenticator(); + + /** Set the authenticator object used with this service instance. + * + * @param auth authenticator object + */ + void setAuthenticator(shared_ptr <security::authenticator> auth); + +#if VMIME_HAVE_TLS_SUPPORT + + /** Set the object responsible for verifying certificates when + * using secured connections (TLS/SSL). + */ + void setCertificateVerifier(shared_ptr <security::cert::certificateVerifier> cv); + + /** Get the object responsible for verifying certificates when + * using secured connections (TLS/SSL). + */ + shared_ptr <security::cert::certificateVerifier> getCertificateVerifier(); + +#endif // VMIME_HAVE_TLS_SUPPORT + + /** Set the factory used to create socket objects for this + * service. + * + * @param sf socket factory + */ + void setSocketFactory(shared_ptr <socketFactory> sf); + + /** Return the factory used to create socket objects for this + * service. + * + * @return socket factory + */ + shared_ptr <socketFactory> getSocketFactory(); + + /** Set the factory used to create timeoutHandler objects for + * this service. By default, no timeout handler is used. Not all + * services support timeout handling. + * + * @param thf timeoutHandler factory + */ + void setTimeoutHandlerFactory(shared_ptr <timeoutHandlerFactory> thf); + + /** Return the factory used to create timeoutHandler objects for + * this service. + * + * @return timeoutHandler factory + */ + shared_ptr <timeoutHandlerFactory> getTimeoutHandlerFactory(); + + /** Set a property for this service (service prefix is added automatically). + * + * WARNING: this sets the property on the session object, so all service + * instances created with the session object will inherit the property. + * + * @param name property name + * @param value property value + */ + template <typename TYPE> + void setProperty(const string& name, const TYPE& value) + { + m_session->getProperties()[getInfos().getPropertyPrefix() + name] = value; + } + + /** Check whether the connection is secured. + * + * @return true if the connection is secured, false otherwise + */ + virtual bool isSecuredConnection() const = 0; + + /** Get information about the connection. + * + * @return information about the connection + */ + virtual shared_ptr <connectionInfos> getConnectionInfos() const = 0; + +private: + + shared_ptr <session> m_session; + shared_ptr <security::authenticator> m_auth; + +#if VMIME_HAVE_TLS_SUPPORT + shared_ptr <security::cert::certificateVerifier> m_certVerifier; +#endif // VMIME_HAVE_TLS_SUPPORT + + shared_ptr <socketFactory> m_socketFactory; + + shared_ptr <timeoutHandlerFactory> m_toHandlerFactory; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_SERVICE_HPP_INCLUDED diff --git a/src/net/serviceFactory.cpp b/src/vmime/net/serviceFactory.cpp index 98aee646..bbc9944a 100644 --- a/src/net/serviceFactory.cpp +++ b/src/vmime/net/serviceFactory.cpp @@ -32,7 +32,7 @@ #include "vmime/exception.hpp" -#include "src/net/builtinServices.inl" +#include "vmime/net/builtinServices.inl" namespace vmime { diff --git a/src/vmime/net/serviceFactory.hpp b/src/vmime/net/serviceFactory.hpp new file mode 100644 index 00000000..9295b345 --- /dev/null +++ b/src/vmime/net/serviceFactory.hpp @@ -0,0 +1,165 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SERVICEFACTORY_HPP_INCLUDED +#define VMIME_NET_SERVICEFACTORY_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include <map> + +#include "vmime/types.hpp" +#include "vmime/base.hpp" + +#include "vmime/utility/stringUtils.hpp" +#include "vmime/utility/url.hpp" + +#include "vmime/net/service.hpp" +#include "vmime/net/serviceInfos.hpp" +#include "vmime/net/timeoutHandler.hpp" + +#include "vmime/security/authenticator.hpp" + +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace net { + + +class session; + + +/** A factory to create 'service' objects for a specified protocol. + */ + +class VMIME_EXPORT serviceFactory +{ +private: + + serviceFactory(); + ~serviceFactory(); + +public: + + static shared_ptr <serviceFactory> getInstance(); + + /** Information about a registered service. */ + class registeredService : public object + { + friend class serviceFactory; + + protected: + + virtual ~registeredService() { } + + public: + + virtual shared_ptr <service> create + (shared_ptr <session> sess, + shared_ptr <security::authenticator> auth) const = 0; + + virtual int getType() const = 0; + virtual const string& getName() const = 0; + virtual const serviceInfos& getInfos() const = 0; + }; + + + /** Register a new service by its protocol name. + * + * @param reg service registration infos + */ + void registerService(shared_ptr <registeredService> reg); + + /** Create a new service instance from a protocol name. + * + * @param sess session + * @param protocol protocol name (eg. "pop3") + * @param auth authenticator used to provide credentials (can be NULL if not used) + * @return a new service instance for the specified protocol, or NULL if no service + * is registered for this protocol + */ + shared_ptr <service> create + (shared_ptr <session> sess, + const string& protocol, + shared_ptr <security::authenticator> auth = null); + + /** Create a new service instance from a URL. + * + * @param sess session + * @param u full URL with at least protocol and server (you can also specify + * port, username and password) + * @param auth authenticator used to provide credentials (can be NULL if not used) + * @return a new service instance for the specified protocol or NULL if no service + * is registered for this protocol + */ + shared_ptr <service> create + (shared_ptr <session> sess, + const utility::url& u, + shared_ptr <security::authenticator> auth = null); + + /** Return information about a registered protocol. + * + * @param protocol protocol name + * @return information about this protocol, or NULL if no service is registered + * for this protocol + */ + shared_ptr <const registeredService> getServiceByProtocol(const string& protocol) const; + + /** Return the number of registered services. + * + * @return number of registered services + */ + size_t getServiceCount() const; + + /** Return the registered service at the specified position. + * + * @param pos position of the registered service to return + * @return registered service at the specified position + */ + shared_ptr <const registeredService> getServiceAt(const size_t pos) const; + + /** Return a list of all registered services. + * + * @return list of registered services + */ + const std::vector <shared_ptr <const registeredService> > getServiceList() const; + +private: + + std::vector <shared_ptr <registeredService> > m_services; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_SERVICEFACTORY_HPP_INCLUDED diff --git a/src/net/serviceInfos.cpp b/src/vmime/net/serviceInfos.cpp index 8de0529e..8de0529e 100644 --- a/src/net/serviceInfos.cpp +++ b/src/vmime/net/serviceInfos.cpp diff --git a/src/vmime/net/serviceInfos.hpp b/src/vmime/net/serviceInfos.hpp new file mode 100644 index 00000000..6e3209ca --- /dev/null +++ b/src/vmime/net/serviceInfos.hpp @@ -0,0 +1,246 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SERVICEINFOS_HPP_INCLUDED +#define VMIME_NET_SERVICEINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include <vector> + +#include "vmime/types.hpp" + +#include "vmime/net/session.hpp" + + +namespace vmime { +namespace net { + + +/** Stores information about a messaging service. + */ + +class VMIME_EXPORT serviceInfos +{ + friend class serviceFactory; + +protected: + + serviceInfos(); + serviceInfos(const serviceInfos&); + +private: + + serviceInfos& operator=(const serviceInfos&); + +public: + + virtual ~serviceInfos(); + + + /** A service property. + */ + class property + { + public: + + /** The common property 'server.address' which is + * the host name or the IP address of the server. */ + static const property SERVER_ADDRESS; + + /** The common property 'server.port' which is + * the port used to connect to the server. */ + static const property SERVER_PORT; + + /** The common property 'server.rootpath' which is + * the full path of the folder on the server (for + * maildir, this is the local filesystem directory). */ + static const property SERVER_ROOTPATH; + + /** The common property 'auth.username' which is the + * username used to authenticate with the server. */ + static const property AUTH_USERNAME; + + /** The common property 'auth.password' which is the + * password used to authenticate with the server. */ + static const property AUTH_PASSWORD; + +#if VMIME_HAVE_TLS_SUPPORT + + /** The common property 'connection.tls': this is used to + * start a secured connection if it is supported by the + * server (STARTTLS extension). + */ + static const property CONNECTION_TLS; + + /** The common property 'connection.tls.required' should be + * set to 'true' to make the connection process fail if the + * server can't start a secured connection (no effect if + * 'connection.tls' is not set to 'true'). + */ + static const property CONNECTION_TLS_REQUIRED; + +#endif // VMIME_HAVE_TLS_SUPPORT + + + /** Value types. + */ + enum Types + { + TYPE_INTEGER, /*< Integer number. */ + TYPE_STRING, /*< Character string. */ + TYPE_BOOLEAN, /*< Boolean (true or false). */ + + TYPE_DEFAULT = TYPE_STRING + }; + + /** Property flags. + */ + enum Flags + { + FLAG_NONE = 0, /*< No flags. */ + FLAG_REQUIRED = (1 << 0), /*< The property must be valued. */ + FLAG_HIDDEN = (1 << 1), /*< The property should not be shown + to the user but can be modified. */ + + FLAG_DEFAULT = FLAG_NONE /*< Default flags. */ + }; + + + /** Construct a new property. + * + * @param name property name + * @param type value type + * @param defaultValue default value + * @param flags property attributes + */ + property(const string& name, const Types type, const string& defaultValue = "", const int flags = FLAG_DEFAULT); + + /** Construct a new property from an existing property. + * + * @param p source property + * @param addFlags flags to add + * @param removeFlags flags to remove + */ + property(const property& p, const int addFlags = FLAG_NONE, const int removeFlags = FLAG_NONE); + + /** Construct a new property from an existing property. + * + * @param p source property + * @param newDefaultValue new default value + * @param addFlags flags to add + * @param removeFlags flags to remove + */ + property(const property& p, const string& newDefaultValue, const int addFlags = FLAG_NONE, const int removeFlags = FLAG_NONE); + + property& operator=(const property& p); + + /** Return the name of the property. + * + * @return property name + */ + const string& getName() const; + + /** Return the default value of the property or + * an empty string if there is no default value. + * + * @return default value for the property + */ + const string& getDefaultValue() const; + + /** Return the value type of the property. + * + * @return property value type + */ + Types getType() const; + + /** Return the attributes of the property (see + * serviceInfos::property::Types constants). + * + * @return property attributes + */ + int getFlags() const; + + private: + + string m_name; + string m_defaultValue; + Types m_type; + int m_flags; + }; + + + /** Return the property prefix used by this service. + * Use this to set/get properties in the session object. + * + * @return property prefix + */ + virtual const string getPropertyPrefix() const = 0; + + /** Return a list of available properties for this service. + * + * @return list of properties + */ + virtual const std::vector <property> getAvailableProperties() const = 0; + + /** Helper function to retrieve the value of a property. + * + * @param s session object + * @param p property to retrieve + * @throw exceptions::no_such_property if the property does not exist + * and has the flag property::FLAG_REQUIRED + * @return value of the property + */ + template <typename TYPE> + const TYPE getPropertyValue(shared_ptr <session> s, const property& p) const + { + if (p.getFlags() & property::FLAG_REQUIRED) + return s->getProperties()[getPropertyPrefix() + p.getName()].template getValue <TYPE>(); + + return s->getProperties().template getProperty <TYPE>(getPropertyPrefix() + p.getName(), + propertySet::valueFromString <TYPE>(p.getDefaultValue())); + } + + /** Helper function to test if the specified property is set in + * the session object. + * + * @param s session object + * @param p property to test + * @return true if the property is set, false otherwise + */ + bool hasProperty(shared_ptr <session> s, const property& p) const; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_SERVICEINFOS_HPP_INCLUDED diff --git a/src/net/serviceRegistration.inl b/src/vmime/net/serviceRegistration.inl index 2366fe01..2366fe01 100644 --- a/src/net/serviceRegistration.inl +++ b/src/vmime/net/serviceRegistration.inl diff --git a/src/net/session.cpp b/src/vmime/net/session.cpp index 36b9f2c3..36b9f2c3 100644 --- a/src/net/session.cpp +++ b/src/vmime/net/session.cpp diff --git a/src/vmime/net/session.hpp b/src/vmime/net/session.hpp new file mode 100644 index 00000000..a7e0ea1a --- /dev/null +++ b/src/vmime/net/session.hpp @@ -0,0 +1,178 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SESSION_HPP_INCLUDED +#define VMIME_NET_SESSION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/security/authenticator.hpp" + +#include "vmime/net/tls/TLSProperties.hpp" + +#include "vmime/utility/url.hpp" + +#include "vmime/propertySet.hpp" + + +namespace vmime { +namespace net { + + +class store; +class transport; + + +/** An object that contains all the information needed + * for connection to a service. + */ + +class VMIME_EXPORT session : public object +{ +public: + + session(); + session(const session& sess); + session(const propertySet& props); + + virtual ~session(); + + /** Return a transport service instance for the protocol specified + * in the session properties. + * + * The property "transport.protocol" specify the protocol to use. + * + * @param auth authenticator object to use for the new transport service. If + * NULL, a default one is used. The default authenticator simply return user + * credentials by reading the session properties "auth.username" and "auth.password". + * @return a new transport service, or NULL if no service is registered for this + * protocol or is not a transport protocol + */ + shared_ptr <transport> getTransport + (shared_ptr <security::authenticator> auth = null); + + /** Return a transport service instance for the specified protocol. + * + * @param protocol transport protocol to use (eg. "smtp") + * @param auth authenticator object to use for the new transport service. If + * NULL, a default one is used. The default authenticator simply return user + * credentials by reading the session properties "auth.username" and "auth.password". + * @return a new transport service, or NULL if no service is registered for this + * protocol or is not a transport protocol + */ + shared_ptr <transport> getTransport + (const string& protocol, + shared_ptr <security::authenticator> auth = null); + + /** Return a transport service instance for the specified URL. + * + * @param url full URL with at least the protocol to use (eg: "smtp://myserver.com/") + * @param auth authenticator object to use for the new transport service. If + * NULL, a default one is used. The default authenticator simply return user + * credentials by reading the session properties "auth.username" and "auth.password". + * @return a new transport service, or NULL if no service is registered for this + * protocol or is not a transport protocol + */ + shared_ptr <transport> getTransport + (const utility::url& url, + shared_ptr <security::authenticator> auth = null); + + /** Return a transport service instance for the protocol specified + * in the session properties. + * + * The property "store.protocol" specify the protocol to use. + * + * @param auth authenticator object to use for the new store service. If + * NULL, a default one is used. The default authenticator simply return user + * credentials by reading the session properties "auth.username" and "auth.password". + * @return a new store service, or NULL if no service is registered for this + * protocol or is not a store protocol + */ + shared_ptr <store> getStore(shared_ptr <security::authenticator> auth = null); + + /** Return a store service instance for the specified protocol. + * + * @param protocol store protocol to use (eg. "imap") + * @param auth authenticator object to use for the new store service. If + * NULL, a default one is used. The default authenticator simply return user + * credentials by reading the session properties "auth.username" and "auth.password". + * @return a new store service, or NULL if no service is registered for this + * protocol or is not a store protocol + */ + shared_ptr <store> getStore + (const string& protocol, + shared_ptr <security::authenticator> auth = null); + + /** Return a store service instance for the specified URL. + * + * @param url full URL with at least the protocol to use (eg: "imap://username:[email protected]/") + * @param auth authenticator object to use for the new store service. If + * NULL, a default one is used. The default authenticator simply return user + * credentials by reading the session properties "auth.username" and "auth.password". + * @return a new store service, or NULL if no service is registered for this + * protocol or is not a store protocol + */ + shared_ptr <store> getStore + (const utility::url& url, + shared_ptr <security::authenticator> auth = null); + + /** Properties for the session and for the services. + */ + const propertySet& getProperties() const; + + /** Properties for the session and for the services. + */ + propertySet& getProperties(); + + /** Set properties for SSL/TLS secured connections in this session. + * + * @param tlsProps SSL/TLS properties + */ + void setTLSProperties(shared_ptr <tls::TLSProperties> tlsProps); + + /** Get properties for SSL/TLS secured connections in this session. + * + * @return SSL/TLS properties + */ + shared_ptr <tls::TLSProperties> getTLSProperties() const; + +private: + + propertySet m_props; + + shared_ptr <tls::TLSProperties> m_tlsProps; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_SESSION_HPP_INCLUDED diff --git a/src/net/smtp/SMTPChunkingOutputStreamAdapter.cpp b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp index 69f63bc9..69f63bc9 100644 --- a/src/net/smtp/SMTPChunkingOutputStreamAdapter.cpp +++ b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.cpp diff --git a/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp new file mode 100644 index 00000000..cfb3f50f --- /dev/null +++ b/src/vmime/net/smtp/SMTPChunkingOutputStreamAdapter.hpp @@ -0,0 +1,85 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPCHUNKINGOUTPUTSTREAMADAPTER_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPCHUNKINGOUTPUTSTREAMADAPTER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/utility/outputStream.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +class SMTPConnection; + + +/** An output stream adapter used with ESMTP CHUNKING extension. + */ +class VMIME_EXPORT SMTPChunkingOutputStreamAdapter : public utility::outputStream +{ +public: + + SMTPChunkingOutputStreamAdapter(shared_ptr <SMTPConnection> conn); + + void flush(); + + size_t getBlockSize(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + SMTPChunkingOutputStreamAdapter(const SMTPChunkingOutputStreamAdapter&); + + + void sendChunk(const byte_t* const data, const size_t count, const bool last); + + + shared_ptr <SMTPConnection> m_connection; + + byte_t m_buffer[262144]; // 256 KB + size_t m_bufferSize; + + unsigned int m_chunkCount; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPCHUNKINGOUTPUTSTREAMADAPTER_HPP_INCLUDED diff --git a/src/net/smtp/SMTPCommand.cpp b/src/vmime/net/smtp/SMTPCommand.cpp index 949ab0c1..949ab0c1 100644 --- a/src/net/smtp/SMTPCommand.cpp +++ b/src/vmime/net/smtp/SMTPCommand.cpp diff --git a/src/vmime/net/smtp/SMTPCommand.hpp b/src/vmime/net/smtp/SMTPCommand.hpp new file mode 100644 index 00000000..dbb0888b --- /dev/null +++ b/src/vmime/net/smtp/SMTPCommand.hpp @@ -0,0 +1,111 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPCOMMAND_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPCOMMAND_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/object.hpp" +#include "vmime/base.hpp" + + +namespace vmime { + + +class mailbox; + + +namespace net { + + +class socket; +class timeoutHandler; + + +namespace smtp { + + +/** A SMTP command, as sent to server. + */ +class VMIME_EXPORT SMTPCommand : public object +{ +public: + + static shared_ptr <SMTPCommand> HELO(const string& hostname); + static shared_ptr <SMTPCommand> EHLO(const string& hostname); + static shared_ptr <SMTPCommand> AUTH(const string& mechName); + static shared_ptr <SMTPCommand> STARTTLS(); + static shared_ptr <SMTPCommand> MAIL(const mailbox& mbox, const bool utf8); + static shared_ptr <SMTPCommand> MAIL(const mailbox& mbox, const bool utf8, const size_t size); + static shared_ptr <SMTPCommand> RCPT(const mailbox& mbox, const bool utf8); + static shared_ptr <SMTPCommand> RSET(); + static shared_ptr <SMTPCommand> DATA(); + static shared_ptr <SMTPCommand> BDAT(const size_t chunkSize, const bool last); + static shared_ptr <SMTPCommand> NOOP(); + static shared_ptr <SMTPCommand> QUIT(); + + /** Creates a new SMTP command with the specified text. + * + * @param text command text + * @return a new SMTPCommand object + */ + static shared_ptr <SMTPCommand> createCommand(const string& text); + + /** Sends this command to the specified socket. + * + * @param sok socket to which the command will be written + */ + virtual void writeToSocket(shared_ptr <socket> sok); + + /** Returns the full text of the command, including command name + * and parameters (if any). + * + * @return command text (eg. "RCPT TO:<[email protected]>") + */ + virtual const string getText() const; + +protected: + + SMTPCommand(const string& text); + SMTPCommand(const SMTPCommand&); + +private: + + string m_text; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPCOMMAND_HPP_INCLUDED diff --git a/src/net/smtp/SMTPCommandSet.cpp b/src/vmime/net/smtp/SMTPCommandSet.cpp index 3e03427c..3e03427c 100644 --- a/src/net/smtp/SMTPCommandSet.cpp +++ b/src/vmime/net/smtp/SMTPCommandSet.cpp diff --git a/src/vmime/net/smtp/SMTPCommandSet.hpp b/src/vmime/net/smtp/SMTPCommandSet.hpp new file mode 100644 index 00000000..8e744c2b --- /dev/null +++ b/src/vmime/net/smtp/SMTPCommandSet.hpp @@ -0,0 +1,105 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPCOMMANDSET_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPCOMMANDSET_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include <list> + +#include "vmime/net/smtp/SMTPCommand.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +/** A set of SMTP commands, which may be sent all at once + * to the server if pipelining is supported. + */ +class VMIME_EXPORT SMTPCommandSet : public SMTPCommand +{ +public: + + /** Creates a new set of SMTP commands. + * + * @param pipeline set to true if the server supports pipelining + * @return a new SMTPCommandSet object + */ + static shared_ptr <SMTPCommandSet> create(const bool pipeline); + + /** Adds a new command to this set. + * If one or more comments have already been sent to the server, + * an exception will be thrown. + * + * @param cmd command to add + */ + void addCommand(shared_ptr <SMTPCommand> cmd); + + /** Tests whether all commands have been sent. + * + * @return true if all commands have been sent, + * or false otherwise + */ + bool isFinished() const; + + /** Returns the last command which has been sent. + * + * @return a pointer to a SMTPCommand, of NULL if no command + * has been sent yet + */ + shared_ptr <SMTPCommand> getLastCommandSent() const; + + + void writeToSocket(shared_ptr <socket> sok); + + const string getText() const; + +private: + + SMTPCommandSet(const bool pipeline); + SMTPCommandSet(const SMTPCommandSet&); + + + bool m_pipeline; + bool m_started; + std::list <shared_ptr <SMTPCommand> > m_commands; + shared_ptr <SMTPCommand> m_lastCommandSent; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPCOMMANDSET_HPP_INCLUDED diff --git a/src/net/smtp/SMTPConnection.cpp b/src/vmime/net/smtp/SMTPConnection.cpp index 26be25db..26be25db 100644 --- a/src/net/smtp/SMTPConnection.cpp +++ b/src/vmime/net/smtp/SMTPConnection.cpp diff --git a/src/vmime/net/smtp/SMTPConnection.hpp b/src/vmime/net/smtp/SMTPConnection.hpp new file mode 100644 index 00000000..cc59ef34 --- /dev/null +++ b/src/vmime/net/smtp/SMTPConnection.hpp @@ -0,0 +1,129 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPCONNECTION_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPCONNECTION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/messageId.hpp" + +#include "vmime/net/socket.hpp" +#include "vmime/net/timeoutHandler.hpp" +#include "vmime/net/session.hpp" +#include "vmime/net/connectionInfos.hpp" + +#include "vmime/net/smtp/SMTPCommand.hpp" +#include "vmime/net/smtp/SMTPResponse.hpp" + +#include "vmime/security/authenticator.hpp" + + +namespace vmime { +namespace net { + + +class socket; +class timeoutHandler; + + +namespace smtp { + + +class SMTPTransport; + + +/** Manage connection to a SMTP server. + */ +class VMIME_EXPORT SMTPConnection : public object +{ +public: + + SMTPConnection(shared_ptr <SMTPTransport> transport, shared_ptr <security::authenticator> auth); + virtual ~SMTPConnection(); + + + virtual void connect(); + virtual bool isConnected() const; + virtual void disconnect(); + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + + virtual shared_ptr <SMTPTransport> getTransport(); + virtual shared_ptr <socket> getSocket(); + virtual shared_ptr <timeoutHandler> getTimeoutHandler(); + virtual shared_ptr <security::authenticator> getAuthenticator(); + virtual shared_ptr <session> getSession(); + + void sendRequest(shared_ptr <SMTPCommand> cmd); + shared_ptr <SMTPResponse> readResponse(); + + bool hasExtension(const std::string& extName, std::vector <string>* params = NULL) const; + +private: + + void internalDisconnect(); + + void helo(); + void authenticate(); +#if VMIME_HAVE_SASL_SUPPORT + void authenticateSASL(); +#endif // VMIME_HAVE_SASL_SUPPORT + +#if VMIME_HAVE_TLS_SUPPORT + void startTLS(); +#endif // VMIME_HAVE_TLS_SUPPORT + + + weak_ptr <SMTPTransport> m_transport; + + shared_ptr <security::authenticator> m_auth; + shared_ptr <socket> m_socket; + shared_ptr <timeoutHandler> m_timeoutHandler; + + SMTPResponse::state m_responseState; + + bool m_authenticated; + bool m_secured; + + shared_ptr <connectionInfos> m_cntInfos; + + bool m_extendedSMTP; + std::map <string, std::vector <string> > m_extensions; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPCONNECTION_HPP_INCLUDED diff --git a/src/net/smtp/SMTPExceptions.cpp b/src/vmime/net/smtp/SMTPExceptions.cpp index 0c3112c0..0c3112c0 100644 --- a/src/net/smtp/SMTPExceptions.cpp +++ b/src/vmime/net/smtp/SMTPExceptions.cpp diff --git a/src/vmime/net/smtp/SMTPExceptions.hpp b/src/vmime/net/smtp/SMTPExceptions.hpp new file mode 100644 index 00000000..75842042 --- /dev/null +++ b/src/vmime/net/smtp/SMTPExceptions.hpp @@ -0,0 +1,127 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPEXCEPTIONS_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPEXCEPTIONS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/exception.hpp" +#include "vmime/base.hpp" + +#include "vmime/net/smtp/SMTPResponse.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +/** SMTP Command error: a SMTP command failed. + */ + +class VMIME_EXPORT SMTPCommandError : public exceptions::command_error +{ +public: + + SMTPCommandError(const string& command, const string& response, + const string& desc, const int statusCode, + const SMTPResponse::enhancedStatusCode& extendedStatusCode, + const exception& other = NO_EXCEPTION); + + SMTPCommandError(const string& command, const string& response, + const int statusCode, const SMTPResponse::enhancedStatusCode& extendedStatusCode, + const exception& other = NO_EXCEPTION); + + ~SMTPCommandError() throw(); + + /** Returns the SMTP status code for this error. + * + * @return status code (protocol-dependent) + */ + int statusCode() const; + + /** Returns the extended status code (following RFC-3463) for this + * error, if available. + * + * @return status code + */ + const SMTPResponse::enhancedStatusCode extendedStatusCode() const; + + + exception* clone() const; + const char* name() const throw(); + +private: + + int m_status; + SMTPResponse::enhancedStatusCode m_exStatus; +}; + + +/** SMTP error: message size exceeds maximum server limits. + * This is a permanent error. + */ + +class VMIME_EXPORT SMTPMessageSizeExceedsMaxLimitsException : public exceptions::net_exception +{ +public: + + SMTPMessageSizeExceedsMaxLimitsException(const exception& other = NO_EXCEPTION); + ~SMTPMessageSizeExceedsMaxLimitsException() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +/** SMTP error: message size exceeds current server limits. + * This is a temporary error (you may retry later). + */ + +class VMIME_EXPORT SMTPMessageSizeExceedsCurLimitsException : public exceptions::net_exception +{ +public: + + SMTPMessageSizeExceedsCurLimitsException(const exception& other = NO_EXCEPTION); + ~SMTPMessageSizeExceedsCurLimitsException() throw(); + + exception* clone() const; + const char* name() const throw(); +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPEXCEPTIONS_HPP_INCLUDED + diff --git a/src/net/smtp/SMTPResponse.cpp b/src/vmime/net/smtp/SMTPResponse.cpp index f7980351..f7980351 100644 --- a/src/net/smtp/SMTPResponse.cpp +++ b/src/vmime/net/smtp/SMTPResponse.cpp diff --git a/src/vmime/net/smtp/SMTPResponse.hpp b/src/vmime/net/smtp/SMTPResponse.hpp new file mode 100644 index 00000000..000448ac --- /dev/null +++ b/src/vmime/net/smtp/SMTPResponse.hpp @@ -0,0 +1,186 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPRESPONSE_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPRESPONSE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/object.hpp" +#include "vmime/base.hpp" + + +namespace vmime { +namespace net { + + +class socket; +class timeoutHandler; + + +namespace smtp { + + +/** A SMTP response, as sent by the server. + */ +class VMIME_EXPORT SMTPResponse : public object +{ +public: + + /** Current state of response parser. */ + struct state + { + string responseBuffer; + }; + + /** Enhanced status code (as per RFC-3463). */ + struct enhancedStatusCode + { + enhancedStatusCode(); + enhancedStatusCode(const enhancedStatusCode& enhCode); + + unsigned short klass; /**< Success/failure. */ + unsigned short subject; /**< Source of anomaly. */ + unsigned short detail; /**< Precise error condition. */ + }; + + /** An element of a SMTP response. */ + class responseLine + { + public: + + responseLine(const int code, const string& text, const enhancedStatusCode& enhCode); + + void setCode(const int code); + int getCode() const; + + void setEnhancedCode(const enhancedStatusCode& enhCode); + const enhancedStatusCode getEnhancedCode() const; + + void setText(const string& text); + const string getText() const; + + private: + + int m_code; + string m_text; + enhancedStatusCode m_enhCode; + }; + + /** Receive and parse a new SMTP response from the + * specified socket. + * + * @param sok socket from which to read + * @param toh time-out handler + * @param st previous state of response parser for the specified socket + * @return SMTP response + * @throws exceptions::operation_timed_out if no data + * has been received within the granted time + */ + static shared_ptr <SMTPResponse> readResponse(shared_ptr <socket> sok, shared_ptr <timeoutHandler> toh, const state& st); + + /** Return the SMTP response code. + * + * @return response code + */ + int getCode() const; + + /** Return the SMTP enhanced status code, if available. + * + * @return enhanced status code + */ + const enhancedStatusCode getEnhancedCode() const; + + /** Return the SMTP response text. + * The text of each line is concatenated. + * + * @return response text + */ + const string getText() const; + + /** Return the response line at the specified position. + * + * @param pos line index + * @return line at the specified index + */ + const responseLine getLineAt(const size_t pos) const; + + /** Return the number of lines in the response. + * + * @return number of lines in the response + */ + size_t getLineCount() const; + + /** Return the last line in the response. + * + * @return last response line + */ + const responseLine getLastLine() const; + + /** Returns the current state of the response parser. + * + * @return current parser state + */ + const state getCurrentState() const; + +private: + + SMTPResponse(shared_ptr <socket> sok, shared_ptr <timeoutHandler> toh, const state& st); + SMTPResponse(const SMTPResponse&); + + void readResponse(); + + const string readResponseLine(); + const responseLine getNextResponse(); + + static int extractResponseCode(const string& response); + static const enhancedStatusCode extractEnhancedCode(const string& responseText); + + + std::vector <responseLine> m_lines; + + shared_ptr <socket> m_socket; + shared_ptr <timeoutHandler> m_timeoutHandler; + + string m_responseBuffer; + bool m_responseContinues; +}; + + +VMIME_EXPORT std::ostream& operator<<(std::ostream& os, const SMTPResponse::enhancedStatusCode& code); + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPRESPONSE_HPP_INCLUDED + diff --git a/src/net/smtp/SMTPSTransport.cpp b/src/vmime/net/smtp/SMTPSTransport.cpp index ab64d49d..ab64d49d 100644 --- a/src/net/smtp/SMTPSTransport.cpp +++ b/src/vmime/net/smtp/SMTPSTransport.cpp diff --git a/src/vmime/net/smtp/SMTPSTransport.hpp b/src/vmime/net/smtp/SMTPSTransport.hpp new file mode 100644 index 00000000..7782f711 --- /dev/null +++ b/src/vmime/net/smtp/SMTPSTransport.hpp @@ -0,0 +1,71 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPSSTORE_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPSSTORE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/net/smtp/SMTPTransport.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +/** SMTPS transport service. + */ + +class VMIME_EXPORT SMTPSTransport : public SMTPTransport +{ +public: + + SMTPSTransport(shared_ptr <session> sess, shared_ptr <security::authenticator> auth); + ~SMTPSTransport(); + + const string getProtocolName() const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + +private: + + static SMTPServiceInfos sm_infos; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPSSTORE_HPP_INCLUDED + diff --git a/src/net/smtp/SMTPServiceInfos.cpp b/src/vmime/net/smtp/SMTPServiceInfos.cpp index 532bb8b8..532bb8b8 100644 --- a/src/net/smtp/SMTPServiceInfos.cpp +++ b/src/vmime/net/smtp/SMTPServiceInfos.cpp diff --git a/src/vmime/net/smtp/SMTPServiceInfos.hpp b/src/vmime/net/smtp/SMTPServiceInfos.hpp new file mode 100644 index 00000000..f783194d --- /dev/null +++ b/src/vmime/net/smtp/SMTPServiceInfos.hpp @@ -0,0 +1,95 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPSERVICEINFOS_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPSERVICEINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/net/serviceInfos.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +/** Information about SMTP service. + */ + +class VMIME_EXPORT SMTPServiceInfos : public serviceInfos +{ +public: + + SMTPServiceInfos(const bool smtps); + + struct props + { + // SMTP-specific options + serviceInfos::property PROPERTY_OPTIONS_NEEDAUTH; +#if VMIME_HAVE_SASL_SUPPORT + serviceInfos::property PROPERTY_OPTIONS_SASL; + serviceInfos::property PROPERTY_OPTIONS_SASL_FALLBACK; +#endif // VMIME_HAVE_SASL_SUPPORT + + serviceInfos::property PROPERTY_OPTIONS_PIPELINING; + serviceInfos::property PROPERTY_OPTIONS_CHUNKING; + + // Common properties + serviceInfos::property PROPERTY_AUTH_USERNAME; + serviceInfos::property PROPERTY_AUTH_PASSWORD; + +#if VMIME_HAVE_TLS_SUPPORT + serviceInfos::property PROPERTY_CONNECTION_TLS; + serviceInfos::property PROPERTY_CONNECTION_TLS_REQUIRED; +#endif // VMIME_HAVE_TLS_SUPPORT + + serviceInfos::property PROPERTY_SERVER_ADDRESS; + serviceInfos::property PROPERTY_SERVER_PORT; + }; + + const props& getProperties() const; + + const string getPropertyPrefix() const; + const std::vector <serviceInfos::property> getAvailableProperties() const; + +private: + + const bool m_smtps; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPSERVICEINFOS_HPP_INCLUDED + diff --git a/src/net/smtp/SMTPTransport.cpp b/src/vmime/net/smtp/SMTPTransport.cpp index 0020d010..0020d010 100644 --- a/src/net/smtp/SMTPTransport.cpp +++ b/src/vmime/net/smtp/SMTPTransport.cpp diff --git a/src/vmime/net/smtp/SMTPTransport.hpp b/src/vmime/net/smtp/SMTPTransport.hpp new file mode 100644 index 00000000..a0f02418 --- /dev/null +++ b/src/vmime/net/smtp/SMTPTransport.hpp @@ -0,0 +1,131 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTPTRANSPORT_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTPTRANSPORT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + + +#include "vmime/net/transport.hpp" +#include "vmime/net/socket.hpp" +#include "vmime/net/timeoutHandler.hpp" + +#include "vmime/net/smtp/SMTPServiceInfos.hpp" +#include "vmime/net/smtp/SMTPConnection.hpp" + + +namespace vmime { +namespace net { +namespace smtp { + + +class SMTPCommand; + + +/** SMTP transport service. + */ + +class VMIME_EXPORT SMTPTransport : public transport +{ +public: + + SMTPTransport(shared_ptr <session> sess, shared_ptr <security::authenticator> auth, const bool secured = false); + ~SMTPTransport(); + + const string getProtocolName() const; + + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; + + void connect(); + bool isConnected() const; + void disconnect(); + + void noop(); + + void send + (const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox()); + + void send + (shared_ptr <vmime::message> msg, + const mailbox& expeditor, + const mailboxList& recipients, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox()); + + bool isSecuredConnection() const; + shared_ptr <connectionInfos> getConnectionInfos() const; + shared_ptr <SMTPConnection> getConnection(); + + bool isSMTPS() const; + +private: + + /** Send the MAIL and RCPT commands to the server, checking the + * response, and using pipelining if supported by the server. + * Optionally, the DATA command can also be sent. + * + * @param expeditor expeditor mailbox + * @param recipients list of recipient mailboxes + * @param sender envelope sender (if empty, expeditor will be used) + * @param sendDATACommand if true, the DATA command will be sent + * @param size message size, in bytes (or 0, if not known) + */ + void sendEnvelope + (const mailbox& expeditor, + const mailboxList& recipients, + const mailbox& sender, + bool sendDATACommand, + const size_t size); + + + shared_ptr <SMTPConnection> m_connection; + + + const bool m_isSMTPS; + + bool m_needReset; + + // Service infos + static SMTPServiceInfos sm_infos; +}; + + +} // smtp +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_SMTP + +#endif // VMIME_NET_SMTP_SMTPTRANSPORT_HPP_INCLUDED diff --git a/src/vmime/net/smtp/smtp.hpp b/src/vmime/net/smtp/smtp.hpp new file mode 100644 index 00000000..2a9ee312 --- /dev/null +++ b/src/vmime/net/smtp/smtp.hpp @@ -0,0 +1,33 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SMTP_SMTP_HPP_INCLUDED +#define VMIME_NET_SMTP_SMTP_HPP_INCLUDED + + +#include "vmime/net/smtp/SMTPTransport.hpp" +#include "vmime/net/smtp/SMTPSTransport.hpp" +#include "vmime/net/smtp/SMTPExceptions.hpp" + + +#endif // VMIME_NET_SMTP_SMTP_HPP_INCLUDED diff --git a/src/vmime/net/socket.hpp b/src/vmime/net/socket.hpp new file mode 100644 index 00000000..537c34bb --- /dev/null +++ b/src/vmime/net/socket.hpp @@ -0,0 +1,184 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_SOCKET_HPP_INCLUDED +#define VMIME_NET_SOCKET_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/base.hpp" + +#include "vmime/net/timeoutHandler.hpp" + + +namespace vmime { +namespace net { + + +/** Interface for connecting to servers. + */ + +class VMIME_EXPORT socket : public object +{ +public: + + enum Status + { + STATUS_WOULDBLOCK = 0x1 /**< The receive operation would block. */ + }; + + + virtual ~socket() { } + + + /** Connect to the specified address and port. + * + * @param address server address (this can be a full qualified domain name + * or an IP address, doesn't matter) + * @param port server port + */ + virtual void connect(const string& address, const port_t port) = 0; + + /** Disconnect from the server. + */ + virtual void disconnect() = 0; + + /** Test whether this socket is connected. + * + * @return true if the socket is connected, false otherwise + */ + virtual bool isConnected() const = 0; + + /** Receive text data from the socket. + * + * @param buffer buffer in which to write received data + */ + virtual void receive(string& buffer) = 0; + + /** Receive raw data from the socket. + * + * @param buffer buffer in which to write received data + * @param count maximum number of bytes to receive (size of buffer) + * @return number of bytes received/written into output buffer + */ + virtual size_t receiveRaw(byte_t* buffer, const size_t count) = 0; + + /** Send text data to the socket. + * + * @param buffer data to send + */ + virtual void send(const string& buffer) = 0; + + /** Send text data to the socket. + * + * @param str null-terminated string + */ + virtual void send(const char* str) = 0; + + /** Send raw data to the socket. + * + * @param buffer data to send + * @param count number of bytes to send (size of buffer) + */ + virtual void sendRaw(const byte_t* buffer, const size_t count) = 0; + + /** Send raw data to the socket. + * Function may returns before all data is sent. + * + * @param buffer data to send + * @param count number of bytes to send (size of buffer) + * @return number of bytes sent + */ + virtual size_t sendRawNonBlocking(const byte_t* buffer, const size_t count) = 0; + + /** Return the preferred maximum block size when reading + * from or writing to this stream. + * + * @return block size, in bytes + */ + virtual size_t getBlockSize() const = 0; + + /** Return the current status of this socket. + * + * @return status flags for this socket + */ + virtual unsigned int getStatus() const = 0; + + /** Return the hostname of peer this socket is connected to. + * + * @return name of the peer, or numeric address if it cannot be found + */ + virtual const string getPeerName() const = 0; + + /** Return the address of peer this socket is connected to. + * + * @return numeric address of the peer + */ + virtual const string getPeerAddress() const = 0; + +protected: + + socket() { } + +private: + + socket(const socket&) : object() { } +}; + + +/** A class to create 'socket' objects. + */ + +class socketFactory : public object +{ +public: + + virtual ~socketFactory() { } + + /** Creates a socket without timeout handler. + * + * @return a new socket + */ + virtual shared_ptr <socket> create() = 0; + + /** Creates a socket with the specified timeout handler. + * + * @param th timeout handler + * @return a new socket + */ + virtual shared_ptr <socket> create(shared_ptr <timeoutHandler> th) = 0; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_SOCKET_HPP_INCLUDED diff --git a/src/vmime/net/store.hpp b/src/vmime/net/store.hpp new file mode 100644 index 00000000..37dcadbc --- /dev/null +++ b/src/vmime/net/store.hpp @@ -0,0 +1,114 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_STORE_HPP_INCLUDED +#define VMIME_NET_STORE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/service.hpp" +#include "vmime/net/folder.hpp" + + +namespace vmime { +namespace net { + + +/** A store service. + * Encapsulate protocols that provide access to user's mail drop. + */ + +class VMIME_EXPORT store : public service +{ +protected: + + store(shared_ptr <session> sess, const serviceInfos& infos, shared_ptr <security::authenticator> auth) + : service(sess, infos, auth) { } + +public: + + /** Return the default folder. This is protocol dependent + * and usually is the INBOX folder. + * + * @return default folder + */ + virtual shared_ptr <folder> getDefaultFolder() = 0; + + /** Return the root folder. This is protocol dependent + * and usually is the user's mail drop root folder. + * + * @return root folder + */ + virtual shared_ptr <folder> getRootFolder() = 0; + + /** Return the folder specified by the path. + * + * @param path absolute folder path + * @return folder at the specified path + */ + virtual shared_ptr <folder> getFolder(const folder::path& path) = 0; + + /** Test whether the specified folder name is a syntactically + * a valid name. + * + * @return true if the specified folder name is valid, false otherwise + */ + virtual bool isValidFolderName(const folder::path::component& name) const = 0; + + /** Store capabilities. */ + enum Capabilities + { + CAPABILITY_CREATE_FOLDER = (1 << 0), /**< Can create folders. */ + CAPABILITY_RENAME_FOLDER = (1 << 1), /**< Can rename folders. */ + CAPABILITY_ADD_MESSAGE = (1 << 2), /**< Can append message to folders. */ + CAPABILITY_COPY_MESSAGE = (1 << 3), /**< Can copy messages from a folder to another one. */ + CAPABILITY_DELETE_MESSAGE = (1 << 4), /**< Can delete messages. */ + CAPABILITY_PARTIAL_FETCH = (1 << 5), /**< Is partial fetch supported? */ + CAPABILITY_MESSAGE_FLAGS = (1 << 6), /**< Can set flags on messages. */ + CAPABILITY_EXTRACT_PART = (1 << 7) /**< Can extract a specific part of the message. */ + }; + + /** Return the features supported by this service. This is + * a combination of store::CAPABILITY_xxx flags. + * + * @return features supported by this service + */ + virtual int getCapabilities() const = 0; + + + Type getType() const { return (TYPE_STORE); } +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_STORE_HPP_INCLUDED diff --git a/src/vmime/net/timeoutHandler.hpp b/src/vmime/net/timeoutHandler.hpp new file mode 100644 index 00000000..24129701 --- /dev/null +++ b/src/vmime/net/timeoutHandler.hpp @@ -0,0 +1,89 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TIMEOUTHANDLER_HPP_INCLUDED +#define VMIME_NET_TIMEOUTHANDLER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace net { + + +/** A class to manage time-out in messaging services. + */ + +class VMIME_EXPORT timeoutHandler : public object +{ +public: + + virtual ~timeoutHandler() { } + + /** Called to test if the time limit has been reached. + * + * @return true if the time-out delay is elapsed + */ + virtual bool isTimeOut() = 0; + + /** Called to reset the time-out counter. + */ + virtual void resetTimeOut() = 0; + + /** Called when the time limit has been reached (when + * isTimeOut() returned true). + * + * @return true to continue (and reset the time-out) + * or false to cancel the current operation + */ + virtual bool handleTimeOut() = 0; +}; + + +/** A class to create 'timeoutHandler' objects. + */ + +class timeoutHandlerFactory : public object +{ +public: + + virtual ~timeoutHandlerFactory() { } + + virtual shared_ptr <timeoutHandler> create() = 0; +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_TIMEOUTHANDLER_HPP_INCLUDED diff --git a/src/net/tls/TLSProperties.cpp b/src/vmime/net/tls/TLSProperties.cpp index 1986db79..1986db79 100644 --- a/src/net/tls/TLSProperties.cpp +++ b/src/vmime/net/tls/TLSProperties.cpp diff --git a/src/vmime/net/tls/TLSProperties.hpp b/src/vmime/net/tls/TLSProperties.hpp new file mode 100644 index 00000000..0dbc8f05 --- /dev/null +++ b/src/vmime/net/tls/TLSProperties.hpp @@ -0,0 +1,105 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSPROPERTIES_HPP_INCLUDED +#define VMIME_NET_TLS_TLSPROPERTIES_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +/** Holds options for a TLS session. + */ +class VMIME_EXPORT TLSProperties : public object +{ +public: + + TLSProperties(); + TLSProperties(const TLSProperties&); + + + /** Predefined generic cipher suites (work with all TLS libraries). */ + enum GenericCipherSuite + { + CIPHERSUITE_HIGH, /**< High encryption cipher suites (> 128 bits). */ + CIPHERSUITE_MEDIUM, /**< Medium encryption cipher suites (>= 128 bits). */ + CIPHERSUITE_LOW, /**< Low encryption cipher suites (>= 64 bits). */ + + CIPHERSUITE_DEFAULT /**< Default cipher suite. */ + }; + + /** Sets the cipher suite preferences for a SSL/TLS session, using + * predefined, generic suites. This works with all underlying TLS + * libraries (OpenSSL and GNU TLS). + * + * @param cipherSuite predefined cipher suite + */ + void setCipherSuite(const GenericCipherSuite cipherSuite); + + /** Sets the cipher suite preferences for a SSL/TLS session, using + * a character string. The format and meaning of the string depend + * on the underlying TLS library. + * + * For GNU TLS, read this: + * http://gnutls.org/manual/html_node/Priority-Strings.html + * + * For OpenSSL, read this: + * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS + * + * @param cipherSuite cipher suite as a string + */ + void setCipherSuite(const string& cipherSuite); + + /** Returns the cipher suite preferences for a SSL/TLS session, as + * a character string. The format and meaning of the string depend + * on the underlying TLS library (see setCipherSuite() method). + * + * @return cipher suite string + */ + const string getCipherSuite() const; + +private: + + shared_ptr <object> m_data; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + +#endif // VMIME_NET_TLS_TLSPROPERTIES_HPP_INCLUDED diff --git a/src/net/tls/TLSSecuredConnectionInfos.cpp b/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp index 4856e9af..4856e9af 100644 --- a/src/net/tls/TLSSecuredConnectionInfos.cpp +++ b/src/vmime/net/tls/TLSSecuredConnectionInfos.cpp diff --git a/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp b/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp new file mode 100644 index 00000000..e552d6f9 --- /dev/null +++ b/src/vmime/net/tls/TLSSecuredConnectionInfos.hpp @@ -0,0 +1,84 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLSSECUREDCONNECTIONINFOS_HPP_INCLUDED +#define VMIME_NET_TLSSECUREDCONNECTIONINFOS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#include "vmime/net/securedConnectionInfos.hpp" + +#include "vmime/security/cert/certificateChain.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSSession; +class TLSSocket; + + +/** Information about a TLS-secured connection used by a service. + */ +class VMIME_EXPORT TLSSecuredConnectionInfos : public securedConnectionInfos +{ +public: + + TLSSecuredConnectionInfos(const string& host, const port_t port, + shared_ptr <TLSSession> tlsSession, shared_ptr <TLSSocket> tlsSocket); + + const string getHost() const; + port_t getPort() const; + + /** Return the peer's certificate (chain) as sent by the peer. + * + * @return server certificate chain + */ + shared_ptr <const security::cert::certificateChain> getPeerCertificates() const; + +private: + + string m_host; + port_t m_port; + + shared_ptr <TLSSession> m_tlsSession; + shared_ptr <TLSSocket> m_tlsSocket; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + +#endif // VMIME_NET_TLSSECUREDCONNECTIONINFOS_HPP_INCLUDED + diff --git a/src/net/tls/TLSSession.cpp b/src/vmime/net/tls/TLSSession.cpp index a46f07ca..a46f07ca 100644 --- a/src/net/tls/TLSSession.cpp +++ b/src/vmime/net/tls/TLSSession.cpp diff --git a/src/vmime/net/tls/TLSSession.hpp b/src/vmime/net/tls/TLSSession.hpp new file mode 100644 index 00000000..9e061f89 --- /dev/null +++ b/src/vmime/net/tls/TLSSession.hpp @@ -0,0 +1,93 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSSESSION_HPP_INCLUDED +#define VMIME_NET_TLS_TLSSESSION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/net/tls/TLSSocket.hpp" +#include "vmime/net/tls/TLSProperties.hpp" + +#include "vmime/security/cert/certificateVerifier.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +/** Describe a TLS connection between a client and a server. + */ +class VMIME_EXPORT TLSSession : public object +{ +public: + + /** Create and initialize a new TLS session. + * + * @param cv object responsible for verifying certificates + * sent by the server + * @param props TLS properties for this session + * @return a new TLS session + */ + static shared_ptr <TLSSession> create(shared_ptr <security::cert::certificateVerifier> cv, shared_ptr <TLSProperties> props); + + /** Create a new socket that adds a TLS security layer around + * an existing socket. You should create only one socket + * per session. + * + * @param sok socket to wrap + * @return TLS socket wrapper + */ + virtual shared_ptr <TLSSocket> getSocket(shared_ptr <socket> sok) = 0; + + /** Get the object responsible for verifying certificates when + * using secured connections (TLS/SSL). + */ + virtual shared_ptr <security::cert::certificateVerifier> getCertificateVerifier() = 0; + +protected: + + TLSSession(); + +private: + + TLSSession(const TLSSession&); +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + +#endif // VMIME_NET_TLS_TLSSESSION_HPP_INCLUDED diff --git a/src/net/tls/TLSSocket.cpp b/src/vmime/net/tls/TLSSocket.cpp index 0419a571..0419a571 100644 --- a/src/net/tls/TLSSocket.cpp +++ b/src/vmime/net/tls/TLSSocket.cpp diff --git a/src/vmime/net/tls/TLSSocket.hpp b/src/vmime/net/tls/TLSSocket.hpp new file mode 100644 index 00000000..e2668ad4 --- /dev/null +++ b/src/vmime/net/tls/TLSSocket.hpp @@ -0,0 +1,88 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSSOCKET_HPP_INCLUDED +#define VMIME_NET_TLS_TLSSOCKET_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#include "vmime/exception.hpp" + +#include "vmime/net/socket.hpp" +#include "vmime/net/timeoutHandler.hpp" + +#include "vmime/security/cert/certificateChain.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSSession; + + +/** Add a TLS security layer to an existing socket. + */ +class VMIME_EXPORT TLSSocket : public socket +{ +public: + + /** Create a new socket object that adds a security layer + * around an existing socket. + * + * @param session TLS session + * @param sok socket to wrap + */ + static shared_ptr <TLSSocket> wrap(shared_ptr <TLSSession> session, shared_ptr <socket> sok); + + /** Starts a TLS handshake on this connection. + * + * @throw exceptions::tls_exception if a fatal error occurs + * during the negociation process, exceptions::operation_timed_out + * if a time-out occurs + */ + virtual void handshake(shared_ptr <timeoutHandler> toHandler = null) = 0; + + /** Return the peer's certificate (chain) as sent by the peer. + * + * @return server certificate chain, or NULL if the handshake + * has not been performed yet + */ + virtual shared_ptr <security::cert::certificateChain> getPeerCertificates() const = 0; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + +#endif // VMIME_NET_TLS_TLSSOCKET_HPP_INCLUDED diff --git a/src/net/tls/gnutls/TLSProperties_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.cpp index 36ab7d7a..36ab7d7a 100644 --- a/src/net/tls/gnutls/TLSProperties_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.cpp diff --git a/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp new file mode 100644 index 00000000..2038778a --- /dev/null +++ b/src/vmime/net/tls/gnutls/TLSProperties_GnuTLS.hpp @@ -0,0 +1,68 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSPROPERTIES_GNUTLS_HPP_INCLUDED +#define VMIME_NET_TLS_TLSPROPERTIES_GNUTLS_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + + +#include "vmime/types.hpp" + +#include "vmime/net/tls/TLSProperties.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSProperties_GnuTLS : public object +{ +public: + + TLSProperties_GnuTLS& operator=(const TLSProperties_GnuTLS& other); + + + string cipherSuite; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + +#endif // VMIME_BUILDING_DOC + +#endif // VMIME_NET_TLS_TLSPROPERTIES_GNUTLS_HPP_INCLUDED + diff --git a/src/net/tls/gnutls/TLSSession_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp index 1c520ed1..1c520ed1 100644 --- a/src/net/tls/gnutls/TLSSession_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.cpp diff --git a/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp new file mode 100644 index 00000000..7f762b58 --- /dev/null +++ b/src/vmime/net/tls/gnutls/TLSSession_GnuTLS.hpp @@ -0,0 +1,91 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSSESSION_GNUTLS_HPP_INCLUDED +#define VMIME_NET_TLS_TLSSESSION_GNUTLS_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + + +#include "vmime/types.hpp" + +#include "vmime/net/tls/TLSSession.hpp" +#include "vmime/net/tls/TLSSocket.hpp" +#include "vmime/net/tls/TLSProperties.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSSession_GnuTLS : public TLSSession +{ + friend class TLSSocket_GnuTLS; + +public: + + TLSSession_GnuTLS(shared_ptr <security::cert::certificateVerifier> cv, shared_ptr <TLSProperties> props); + ~TLSSession_GnuTLS(); + + + shared_ptr <TLSSocket> getSocket(shared_ptr <socket> sok); + + shared_ptr <security::cert::certificateVerifier> getCertificateVerifier(); + +private: + + TLSSession_GnuTLS(const TLSSession_GnuTLS&); + + static void throwTLSException(const string& fname, const int code); + + +#ifdef LIBGNUTLS_VERSION + gnutls_session* m_gnutlsSession; +#else + void* m_gnutlsSession; +#endif // LIBGNUTLS_VERSION + + shared_ptr <security::cert::certificateVerifier> m_certVerifier; + shared_ptr <TLSProperties> m_props; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + +#endif // VMIME_BUILDING_DOC + +#endif // VMIME_NET_TLS_TLSSESSION_GNUTLS_HPP_INCLUDED + diff --git a/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp index 5a90565b..5a90565b 100644 --- a/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.cpp diff --git a/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp new file mode 100644 index 00000000..885fac13 --- /dev/null +++ b/src/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp @@ -0,0 +1,120 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSSOCKET_GNUTLS_HPP_INCLUDED +#define VMIME_NET_TLS_TLSSOCKET_GNUTLS_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + + +#include "vmime/net/tls/TLSSocket.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSSession; +class TLSSession_GnuTLS; + + +class TLSSocket_GnuTLS : public TLSSocket +{ +public: + + TLSSocket_GnuTLS(shared_ptr <TLSSession_GnuTLS> session, shared_ptr <socket> sok); + ~TLSSocket_GnuTLS(); + + + void handshake(shared_ptr <timeoutHandler> toHandler = null); + + shared_ptr <security::cert::certificateChain> getPeerCertificates() const; + + // Implementation of 'socket' + void connect(const string& address, const port_t port); + void disconnect(); + bool isConnected() const; + + void receive(string& buffer); + size_t receiveRaw(byte_t* buffer, const size_t count); + + void send(const string& buffer); + void send(const char* str); + void sendRaw(const byte_t* buffer, const size_t count); + size_t sendRawNonBlocking(const byte_t* buffer, const size_t count); + + size_t getBlockSize() const; + + unsigned int getStatus() const; + + const string getPeerName() const; + const string getPeerAddress() const; + +private: + + void internalThrow(); + +#ifdef LIBGNUTLS_VERSION + static ssize_t gnutlsPushFunc(gnutls_transport_ptr trspt, const void* data, size_t len); + static ssize_t gnutlsPullFunc(gnutls_transport_ptr trspt, void* data, size_t len); +#else + static int gnutlsPushFunc(void* trspt, const void* data, size_t len); + static int gnutlsPullFunc(void* trspt, void* data, size_t len); +#endif // LIBGNUTLS_VERSION + + + shared_ptr <TLSSession_GnuTLS> m_session; + shared_ptr <socket> m_wrapped; + + bool m_connected; + + byte_t m_buffer[65536]; + + bool m_handshaking; + shared_ptr <timeoutHandler> m_toHandler; + + exception* m_ex; + + unsigned int m_status; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + +#endif // VMIME_BUILDING_DOC + +#endif // VMIME_NET_TLS_TLSSOCKET_GNUTLS_HPP_INCLUDED + diff --git a/src/net/tls/openssl/OpenSSLInitializer.cpp b/src/vmime/net/tls/openssl/OpenSSLInitializer.cpp index 1bbb9ee5..1bbb9ee5 100644 --- a/src/net/tls/openssl/OpenSSLInitializer.cpp +++ b/src/vmime/net/tls/openssl/OpenSSLInitializer.cpp diff --git a/src/vmime/net/tls/openssl/OpenSSLInitializer.hpp b/src/vmime/net/tls/openssl/OpenSSLInitializer.hpp new file mode 100644 index 00000000..d7595aa8 --- /dev/null +++ b/src/vmime/net/tls/openssl/OpenSSLInitializer.hpp @@ -0,0 +1,111 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_OPENSSL_OPENSSLINITIALIZER_HPP_INCLUDED +#define VMIME_NET_TLS_OPENSSL_OPENSSLINITIALIZER_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC + + +#include "vmime/config.hpp" + +#include <vector> + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + + +#include "vmime/utility/sync/criticalSection.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +/** Class responsible for setting up OpenSSL + */ +class OpenSSLInitializer +{ +public: + + /** Automatically initialize OpenSSL + */ + class autoInitializer + { + public: + + autoInitializer(); + ~autoInitializer(); + }; + +protected: + + class oneTimeInitializer + { + public: + + oneTimeInitializer(); + ~oneTimeInitializer(); + }; + + + /** Initializes the OpenSSL lib + */ + static void initialize(); + + /** Shutdown the OpenSSL lib + */ + static void uninitialize(); + + + static shared_ptr <vmime::utility::sync::criticalSection> getMutex(); + + enum + { + SEEDSIZE = 256 + }; + + + // OpenSSL multithreading support + static void lock(int mode, int n, const char* file, int line); + static unsigned long id(); + +private: + + static shared_ptr <vmime::utility::sync::criticalSection >* sm_mutexes; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + +#endif // VMIME_BUILDING_DOC + +#endif // VMIME_NET_TLS_OPENSSL_OPENSSLINITIALIZER_HPP_INCLUDED + diff --git a/src/net/tls/openssl/TLSProperties_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.cpp index 932477df..932477df 100644 --- a/src/net/tls/openssl/TLSProperties_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.cpp diff --git a/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp new file mode 100644 index 00000000..5d2f075a --- /dev/null +++ b/src/vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp @@ -0,0 +1,68 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSPROPERTIES_OPENSSL_HPP_INCLUDED +#define VMIME_NET_TLS_TLSPROPERTIES_OPENSSL_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + + +#include "vmime/types.hpp" + +#include "vmime/net/tls/TLSProperties.hpp" + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSProperties_OpenSSL : public object +{ +public: + + TLSProperties_OpenSSL& operator=(const TLSProperties_OpenSSL& other); + + + string cipherSuite; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + +#endif // VMIME_BUILDING_DOC + +#endif // VMIME_NET_TLS_TLSPROPERTIES_OPENSSL_HPP_INCLUDED + diff --git a/src/net/tls/openssl/TLSSession_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp index cf600a63..cf600a63 100644 --- a/src/net/tls/openssl/TLSSession_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.cpp diff --git a/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp new file mode 100644 index 00000000..5a2b60a8 --- /dev/null +++ b/src/vmime/net/tls/openssl/TLSSession_OpenSSL.hpp @@ -0,0 +1,108 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSSESSION_OPENSSL_HPP_INCLUDED +#define VMIME_NET_TLS_TLSSESSION_OPENSSL_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + + +#include "vmime/types.hpp" + +#include "vmime/net/tls/TLSSession.hpp" +#include "vmime/net/tls/TLSSocket.hpp" +#include "vmime/net/tls/TLSProperties.hpp" + + +#include <openssl/ssl.h> + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSSession_OpenSSL : public TLSSession +{ + friend class TLSSocket_OpenSSL; + +public: + + TLSSession_OpenSSL(const shared_ptr <security::cert::certificateVerifier> cv, shared_ptr <TLSProperties> props); + ~TLSSession_OpenSSL(); + + + shared_ptr <TLSSocket> getSocket(shared_ptr <socket> sok); + + shared_ptr <security::cert::certificateVerifier> getCertificateVerifier(); + + + /** Set the private key to use if server requires a client certificate. + * + * @param keyfile Path to the private key in PEM format + * @param passwd_callback If the private key is stored encrypted the + */ + void usePrivateKeyFile(const vmime::string& keyfile); + + /** Supply the certificate chain to present if requested by + * server. + * + * @param chainFile File in PEM format holding certificate chain + */ + void useCertificateChainFile(const vmime::string& chainFile); + + /** Get a pointer to the SSL_CTX used for this session. + * + * @return the SSL_CTX used for all connections created with this session + */ + SSL_CTX* getContext() const; + +private: + + TLSSession_OpenSSL(const TLSSession_OpenSSL&); + + SSL_CTX* m_sslctx; + + shared_ptr <security::cert::certificateVerifier> m_certVerifier; + shared_ptr <TLSProperties> m_props; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + +#endif // VMIME_BUILDING_DOC + +#endif // VMIME_NET_TLS_TLSSESSION_OPENSSL_HPP_INCLUDED + diff --git a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp index ef6647d6..ef6647d6 100644 --- a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.cpp diff --git a/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp new file mode 100644 index 00000000..410fffcf --- /dev/null +++ b/src/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp @@ -0,0 +1,132 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TLS_TLSSOCKET_OPENSSL_HPP_INCLUDED +#define VMIME_NET_TLS_TLSSOCKET_OPENSSL_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + + +#include "vmime/net/tls/TLSSocket.hpp" + +#include <memory> + +#include <openssl/ssl.h> + + +namespace vmime { +namespace net { +namespace tls { + + +class TLSSession; +class TLSSession_OpenSSL; + + +class TLSSocket_OpenSSL : public TLSSocket +{ +public: + + TLSSocket_OpenSSL(shared_ptr <TLSSession_OpenSSL> session, shared_ptr <socket> sok); + ~TLSSocket_OpenSSL(); + + + void handshake(shared_ptr <timeoutHandler> toHandler = null); + + shared_ptr <security::cert::certificateChain> getPeerCertificates() const; + + // Implementation of 'socket' + void connect(const string& address, const port_t port); + void disconnect(); + bool isConnected() const; + + void receive(string& buffer); + size_t receiveRaw(byte_t* buffer, const size_t count); + + void send(const string& buffer); + void send(const char* str); + void sendRaw(const byte_t* buffer, const size_t count); + size_t sendRawNonBlocking(const byte_t* buffer, const size_t count); + + size_t getBlockSize() const; + + unsigned int getStatus() const; + + const string getPeerName() const; + const string getPeerAddress() const; + +private: + + static BIO_METHOD sm_customBIOMethod; + + static int bio_write(BIO* bio, const char* buf, int len); + static int bio_read(BIO* bio, char* buf, int len); + static int bio_puts(BIO* bio, const char* str); + static int bio_gets(BIO* bio, char* buf, int len); + static long bio_ctrl(BIO* bio, int cmd, long num, void* ptr); + static int bio_create(BIO* bio); + static int bio_destroy(BIO* bio); + + void createSSLHandle(); + + void internalThrow(); + void handleError(int rc); + + + shared_ptr <TLSSession_OpenSSL> m_session; + + shared_ptr <socket> m_wrapped; + + bool m_connected; + + byte_t m_buffer[65536]; + + shared_ptr <timeoutHandler> m_toHandler; + + SSL* m_ssl; + + unsigned long m_status; + + // Last exception thrown from C BIO functions + std::auto_ptr <std::exception> m_ex; +}; + + +} // tls +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + +#endif // VMIME_BUILDING_DOC + +#endif // VMIME_NET_TLS_TLSSOCKET_OPENSSL_HPP_INCLUDED + diff --git a/src/net/transport.cpp b/src/vmime/net/transport.cpp index dd7281d0..dd7281d0 100644 --- a/src/net/transport.cpp +++ b/src/vmime/net/transport.cpp diff --git a/src/vmime/net/transport.hpp b/src/vmime/net/transport.hpp new file mode 100644 index 00000000..6c405cbb --- /dev/null +++ b/src/vmime/net/transport.hpp @@ -0,0 +1,137 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_NET_TRANSPORT_HPP_INCLUDED +#define VMIME_NET_TRANSPORT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/service.hpp" +#include "vmime/utility/stream.hpp" + +#include "vmime/mailboxList.hpp" + + +namespace vmime { + +class header; +class headerField; +class message; +class mailbox; +class mailboxList; + +namespace net { + + +/** A transport service. + * Encapsulate protocols that can send messages. + */ + +class VMIME_EXPORT transport : public service +{ +protected: + + transport(shared_ptr <session> sess, const serviceInfos& infos, shared_ptr <security::authenticator> auth); + +public: + + /** Send a message over this transport service. + * The default implementation simply generates the whole message into + * a string buffer and "streams" it via a inputStreamStringAdapter. + * + * @param msg message to send + * @param progress progress listener, or NULL if not used + */ + virtual void send(shared_ptr <vmime::message> msg, utility::progressListener* progress = NULL); + + /** Send a message over this transport service. + * + * @param expeditor expeditor mailbox + * @param recipients list of recipient mailboxes + * @param is input stream providing message data (header + body) + * @param size size of the message data + * @param progress progress listener, or NULL if not used + * @param sender envelope sender (if empty, expeditor will be used) + */ + virtual void send + (const mailbox& expeditor, + const mailboxList& recipients, + utility::inputStream& is, + const size_t size, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox()) = 0; + + /** Send a message over this transport service. + * The default implementation simply generates the whole message into + * a string buffer and "streams" it via a inputStreamStringAdapter. + * + * @param msg message to send + * @param expeditor expeditor mailbox + * @param recipients list of recipient mailboxes + * @param progress progress listener, or NULL if not used + * @param sender envelope sender (if empty, expeditor will be used) + */ + virtual void send + (shared_ptr <vmime::message> msg, + const mailbox& expeditor, + const mailboxList& recipients, + utility::progressListener* progress = NULL, + const mailbox& sender = mailbox()); + + + Type getType() const; + +protected: + + /** Called by processHeader(). + * Decides what to do with the specified header field. + * + * @return NULL if the header should be removed, a reference to a new headerField + * if the field is to be replaced, or a reference to the same headerField + * that was passed if the field should be left as is + */ + shared_ptr <headerField> processHeaderField(shared_ptr <headerField> field); + + /** Prepares the header before transmitting the message. + * Removes headers that should not be present (eg. "Bcc", "Return-Path"), + * or adds missing headers that are required/recommended by the RFCs. + * The header is modified inline. + * + * @param header headers to process + */ + void processHeader(shared_ptr <header> header); +}; + + +} // net +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_NET_TRANSPORT_HPP_INCLUDED diff --git a/src/object.cpp b/src/vmime/object.cpp index d07c3c19..d07c3c19 100644 --- a/src/object.cpp +++ b/src/vmime/object.cpp diff --git a/src/vmime/object.hpp b/src/vmime/object.hpp new file mode 100644 index 00000000..0b12df3c --- /dev/null +++ b/src/vmime/object.hpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_OBJECT_HPP_INCLUDED +#define VMIME_OBJECT_HPP_INCLUDED + + +#include "vmime/types.hpp" + + +namespace vmime +{ + + +/** Base object for all objects in the library. + */ + +class VMIME_EXPORT object : public enable_shared_from_this <object> +{ +protected: + + object(); + object(const object&); + + object& operator=(const object&); + + virtual ~object(); +}; + + +} // vmime + + +#endif // VMIME_OBJECT_HPP_INCLUDED + diff --git a/src/parameter.cpp b/src/vmime/parameter.cpp index b8d5b36e..b8d5b36e 100644 --- a/src/parameter.cpp +++ b/src/vmime/parameter.cpp diff --git a/src/vmime/parameter.hpp b/src/vmime/parameter.hpp new file mode 100644 index 00000000..682c391b --- /dev/null +++ b/src/vmime/parameter.hpp @@ -0,0 +1,153 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PARAMETER_HPP_INCLUDED +#define VMIME_PARAMETER_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/component.hpp" +#include "vmime/word.hpp" + + +namespace vmime +{ + + +class VMIME_EXPORT parameter : public component +{ + friend class parameterizedHeaderField; + +private: + + parameter(const parameter&); + +public: + + parameter(const string& name); + parameter(const string& name, const word& value); + parameter(const string& name, const string& value); + + +#ifndef VMIME_BUILDING_DOC + + /** A single section of a multi-section parameter, + * as defined in RFC-2231/3. This is used when + * calling parse() on the parameter. + */ + struct valueChunk + { + bool encoded; + string data; + }; + +#endif // VMIME_BUILDING_DOC + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + parameter& operator=(const parameter& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Return the name of this parameter. + * + * @return name of this parameter + */ + const string& getName() const; + + /** Return the raw value of this parameter. + * + * @return read-only value + */ + const word& getValue() const; + + /** Return the value of this object in the specified type. + * For example, the following code: + * + * <pre> + * getParameter("creation-date")->getValueAs <vmime::dateTime>() + * </pre> + * + * is equivalent to: + * + * <pre> + * shared_ptr <vmime::word> rawValue = getParameter("creation-date"); + * + * vmime::dateTime theDate; + * theDate.parse(rawValue->getBuffer()); + * </pre> + * + * @param T type to which convert the value + * @return value + */ + template <typename T> + const T getValueAs() const + { + T ret; + ret.parse(m_value->getBuffer()); + + return ret; + } + + /** Set the value of this parameter. + * + * @param value new value + */ + void setValue(const component& value); + + /** Set the raw value of this parameter. + * + * @param value new value + */ + void setValue(const word& value); + + +protected: + + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; + +private: + + void parse(const parsingContext& ctx, const std::vector <valueChunk>& chunks); + + + string m_name; + shared_ptr <word> m_value; +}; + + +} // vmime + + +#endif // VMIME_PARAMETER_HPP_INCLUDED diff --git a/src/parameterizedHeaderField.cpp b/src/vmime/parameterizedHeaderField.cpp index e2925d25..e2925d25 100644 --- a/src/parameterizedHeaderField.cpp +++ b/src/vmime/parameterizedHeaderField.cpp diff --git a/src/vmime/parameterizedHeaderField.hpp b/src/vmime/parameterizedHeaderField.hpp new file mode 100644 index 00000000..509506a9 --- /dev/null +++ b/src/vmime/parameterizedHeaderField.hpp @@ -0,0 +1,208 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PARAMETERIZEDHEADERFIELD_HPP_INCLUDED +#define VMIME_PARAMETERIZEDHEADERFIELD_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldFactory.hpp" +#include "vmime/parameter.hpp" +#include "vmime/exception.hpp" + + +namespace vmime +{ + + +/** A header field that can also contain parameters (name=value pairs). + * Parameters can be created using vmime::parameterFactory. + */ + +class VMIME_EXPORT parameterizedHeaderField : virtual public headerField +{ + friend class headerFieldFactory; + +protected: + + // Protected constructor to prevent the user from creating + // new objects without using 'headerFieldFactory' + parameterizedHeaderField(); + +public: + + ~parameterizedHeaderField(); + + void copyFrom(const component& other); + parameterizedHeaderField& operator=(const parameterizedHeaderField& other); + + /** Checks whether (at least) one parameter with this name exists. + * Parameter name is case-insensitive. + * + * @param paramName parameter name + * @return true if at least one parameter with the specified name + * exists, or false otherwise + */ + bool hasParameter(const string& paramName) const; + + /** Find the first parameter that matches the specified name. Parameter name + * is case-insensitive. If no parameter is found, NULL is returned. + * + * @param paramName parameter name + * @return first parameter with the specified name, or NULL if + * no parameter with this name exists + */ + shared_ptr <parameter> findParameter(const string& paramName) const; + + /** Find the first parameter that matches the specified name. + * Parameter name is case-insensitive. + * If no parameter is found, one will be created and inserted into + * the parameter list. + * + * @param paramName parameter name + * @return first parameter with the specified name or a new field + * if no parameter is found + */ + shared_ptr <parameter> getParameter(const string& paramName); + + /** Add a parameter at the end of the list. + * + * @param param parameter to append + */ + void appendParameter(shared_ptr <parameter> param); + + /** Insert a new parameter before the specified parameter. + * + * @param beforeParam parameter before which the new parameter will be inserted + * @param param parameter to insert + * @throw std::out_of_range if the parameter is not in the list + */ + void insertParameterBefore(shared_ptr <parameter> beforeParam, shared_ptr <parameter> param); + + /** Insert a new parameter before the specified position. + * + * @param pos position at which to insert the new parameter (0 to insert at + * the beginning of the list) + * @param param parameter to insert + * @throw std::out_of_range if the position is out of range + */ + void insertParameterBefore(const size_t pos, shared_ptr <parameter> param); + + /** Insert a new parameter after the specified parameter. + * + * @param afterParam parameter after which the new parameter will be inserted + * @param param parameter to insert + * @throw std::out_of_range if the parameter is not in the list + */ + void insertParameterAfter(shared_ptr <parameter> afterParam, shared_ptr <parameter> param); + + /** Insert a new parameter after the specified position. + * + * @param pos position of the parameter before the new parameter + * @param param parameter to insert + * @throw std::out_of_range if the position is out of range + */ + void insertParameterAfter(const size_t pos, shared_ptr <parameter> param); + + /** Remove the specified parameter from the list. + * + * @param param parameter to remove + * @throw std::out_of_range if the parameter is not in the list + */ + void removeParameter(shared_ptr <parameter> param); + + /** Remove the parameter at the specified position. + * + * @param pos position of the parameter to remove + */ + void removeParameter(const size_t pos); + + /** Remove all parameters from the list. + */ + void removeAllParameters(); + + /** Return the number of parameters in the list. + * + * @return number of parameters + */ + size_t getParameterCount() const; + + /** Tests whether the list of parameters is empty. + * + * @return true if there is no parameter, false otherwise + */ + bool isEmpty() const; + + /** Return the parameter at the specified position. + * + * @param pos position + * @return parameter at position 'pos' + */ + const shared_ptr <parameter> getParameterAt(const size_t pos); + + /** Return the parameter at the specified position. + * + * @param pos position + * @return parameter at position 'pos' + */ + const shared_ptr <const parameter> getParameterAt(const size_t pos) const; + + /** Return the parameter list. + * + * @return list of parameters + */ + const std::vector <shared_ptr <const parameter> > getParameterList() const; + + /** Return the parameter list. + * + * @return list of parameters + */ + const std::vector <shared_ptr <parameter> > getParameterList(); + + const std::vector <shared_ptr <component> > getChildComponents(); + +private: + + std::vector <shared_ptr <parameter> > m_params; + +protected: + + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_PARAMETERIZEDHEADERFIELD_HPP_INCLUDED diff --git a/src/parsedMessageAttachment.cpp b/src/vmime/parsedMessageAttachment.cpp index 242bfde0..242bfde0 100644 --- a/src/parsedMessageAttachment.cpp +++ b/src/vmime/parsedMessageAttachment.cpp diff --git a/src/vmime/parsedMessageAttachment.hpp b/src/vmime/parsedMessageAttachment.hpp new file mode 100644 index 00000000..6c96f80a --- /dev/null +++ b/src/vmime/parsedMessageAttachment.hpp @@ -0,0 +1,78 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PARSEDMESSAGEATTACHMENT_HPP_INCLUDED +#define VMIME_PARSEDMESSAGEATTACHMENT_HPP_INCLUDED + + +#ifndef VMIME_BUILDING_DOC // implementation detail + + +#include "vmime/messageAttachment.hpp" + + +namespace vmime +{ + + +/** A message attachment that can be generated into a message. + */ +class VMIME_EXPORT parsedMessageAttachment : public messageAttachment +{ +public: + + parsedMessageAttachment(shared_ptr <message> msg); + + const mediaType getType() const; + const text getDescription() const; + const word getName() const; + + const shared_ptr <const contentHandler> getData() const; + + const encoding getEncoding() const; + + shared_ptr <const object> getPart() const; + + shared_ptr <const header> getHeader() const; + + shared_ptr <message> getMessage() const; + +protected: + + void generateIn(shared_ptr <bodyPart> parent) const; + +private: + + shared_ptr <message> m_msg; + mutable shared_ptr <contentHandler> m_data; +}; + + +} // vmime + + +#endif // !VMIME_BUILDING_DOC + + +#endif // VMIME_PARSEDMESSAGEATTACHMENT_HPP_INCLUDED + diff --git a/src/vmime/parserHelpers.hpp b/src/vmime/parserHelpers.hpp new file mode 100644 index 00000000..ce3f422a --- /dev/null +++ b/src/vmime/parserHelpers.hpp @@ -0,0 +1,96 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PARSERHELPERS_HPP_INCLUDED +#define VMIME_PARSERHELPERS_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/utility/stringUtils.hpp" + +#include <algorithm> + + + +namespace vmime +{ + + +class parserHelpers +{ +public: + + static bool isSpace(const char_t c) + { + return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); + } + + static bool isSpaceOrTab(const char_t c) + { + return (c == ' ' || c == '\t'); + } + + static bool isDigit(const char_t c) + { + return (c >= '0' && c <= '9'); + } + + + static bool isAlpha(const char_t c) + { + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); + } + + + static char_t toLower(const char_t c) + { + if (c >= 'A' && c <= 'Z') + return ('a' + (c - 'A')); + else + return c; + } + + + // Checks whether a character is in the 7-bit US-ASCII charset + + static bool isAscii(const char_t c) + { + const unsigned int x = static_cast <unsigned int>(c); + return (x <= 127); + } + + + // Checks whether a character has a visual representation + + static bool isPrint(const char_t c) + { + const unsigned int x = static_cast <unsigned int>(c); + return (x >= 0x20 && x <= 0x7E); + } +}; + + +} // vmime + + +#endif // VMIME_PARSERHELPERS_HPP_INCLUDED diff --git a/src/parsingContext.cpp b/src/vmime/parsingContext.cpp index 527f4705..527f4705 100644 --- a/src/parsingContext.cpp +++ b/src/vmime/parsingContext.cpp diff --git a/src/vmime/parsingContext.hpp b/src/vmime/parsingContext.hpp new file mode 100644 index 00000000..27d14a60 --- /dev/null +++ b/src/vmime/parsingContext.hpp @@ -0,0 +1,59 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PARSINGCONTEXT_HPP_INCLUDED +#define VMIME_PARSINGCONTEXT_HPP_INCLUDED + + +#include "vmime/context.hpp" + + +namespace vmime +{ + + +/** Holds configuration parameters used for parsing messages. + */ + +class VMIME_EXPORT parsingContext : public context +{ +public: + + parsingContext(); + parsingContext(const parsingContext& ctx); + + /** Returns the default context used for parsing messages. + * + * @return a reference to the default parsing context + */ + static parsingContext& getDefaultContext(); + +protected: + +}; + + +} // vmime + + +#endif // VMIME_PARSINGCONTEXT_HPP_INCLUDED diff --git a/src/path.cpp b/src/vmime/path.cpp index 3f1bc6af..3f1bc6af 100644 --- a/src/path.cpp +++ b/src/vmime/path.cpp diff --git a/src/vmime/path.hpp b/src/vmime/path.hpp new file mode 100644 index 00000000..2ffa3c22 --- /dev/null +++ b/src/vmime/path.hpp @@ -0,0 +1,106 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PATH_HPP_INCLUDED +#define VMIME_PATH_HPP_INCLUDED + + +#include "vmime/headerFieldValue.hpp" + + +namespace vmime +{ + + +/** A path: a local part + '@' + a domain. + */ + +class VMIME_EXPORT path : public headerFieldValue +{ +public: + + path(); + path(const string& localPart, const string& domain); + path(const path& p); + + /** Return the local part of the address. + * + * @return local part of the address + */ + const string& getLocalPart() const; + + /** Set the local part of the address. + * + * @param localPart local part of the address + */ + void setLocalPart(const string& localPart); + + /** Return the domain of the address. + * + * @return domain of the address + */ + const string& getDomain() const; + + /** Set the domain of the address. + * + * @param domain domain of the address + */ + void setDomain(const string& domain); + + // Comparison + bool operator==(const path& p) const; + bool operator!=(const path& p) const; + + // Assignment + void copyFrom(const component& other); + shared_ptr <component> clone() const; + path& operator=(const path& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + +protected: + + string m_localPart; + string m_domain; + + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_PATH_HPP_INCLUDED diff --git a/src/plainTextPart.cpp b/src/vmime/plainTextPart.cpp index 7a1542d7..7a1542d7 100644 --- a/src/plainTextPart.cpp +++ b/src/vmime/plainTextPart.cpp diff --git a/src/vmime/plainTextPart.hpp b/src/vmime/plainTextPart.hpp new file mode 100644 index 00000000..72a8a71c --- /dev/null +++ b/src/vmime/plainTextPart.hpp @@ -0,0 +1,68 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLAINTEXTPART_HPP_INCLUDED +#define VMIME_PLAINTEXTPART_HPP_INCLUDED + + +#include "vmime/textPart.hpp" + + +namespace vmime +{ + + +/** Text part of type 'text/plain'. + */ + +class VMIME_EXPORT plainTextPart : public textPart +{ +public: + + plainTextPart(); + ~plainTextPart(); + + const mediaType getType() const; + + const charset& getCharset() const; + void setCharset(const charset& ch); + + const shared_ptr <const contentHandler> getText() const; + void setText(shared_ptr <contentHandler> text); + + size_t getPartCount() const; + + void generateIn(shared_ptr <bodyPart> message, shared_ptr <bodyPart> parent) const; + void parse(shared_ptr <const bodyPart> message, shared_ptr <const bodyPart> parent, shared_ptr <const bodyPart> textPart); + +private: + + shared_ptr <contentHandler> m_text; + charset m_charset; +}; + + +} // vmime + + +#endif // VMIME_PLAINTEXTPART_HPP_INCLUDED diff --git a/src/platform.cpp b/src/vmime/platform.cpp index 631d5bcf..631d5bcf 100644 --- a/src/platform.cpp +++ b/src/vmime/platform.cpp diff --git a/src/vmime/platform.hpp b/src/vmime/platform.hpp new file mode 100644 index 00000000..c72f160e --- /dev/null +++ b/src/vmime/platform.hpp @@ -0,0 +1,170 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORM_HPP_INCLUDED +#define VMIME_PLATFORM_HPP_INCLUDED + + +#include "vmime/config.hpp" +#include "vmime/dateTime.hpp" +#include "vmime/exception.hpp" +#include "vmime/charset.hpp" + +#if VMIME_HAVE_MESSAGING_FEATURES + #include "vmime/net/socket.hpp" + #include "vmime/net/timeoutHandler.hpp" +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + #include "vmime/utility/file.hpp" + #include "vmime/utility/childProcess.hpp" +#endif + +#include "vmime/utility/sync/criticalSection.hpp" + + +namespace vmime +{ + + +/** Allow setting or getting the current platform handler. + */ + +class VMIME_EXPORT platform +{ +public: + + /** Takes care of all platform-dependent operations. It offers an interface to + * access platform-dependent objects: sockets, date/time, file system, etc. + */ + + class VMIME_EXPORT handler : public object + { + public: + + virtual ~handler(); + + /** Return the current UNIX time (Epoch time): the number of + * seconds elapsed since Jan, 1st 1970 00:00. + * + * @return UNIX Epoch time + */ + virtual unsigned long getUnixTime() const = 0; + + /** Return the current date and time, in the local time zone. + * + * @return current date and time + */ + virtual const datetime getCurrentLocalTime() const = 0; + + /** Return the host name of the system. + * Used when generating message ids. + * + * @return host name + */ + virtual const string getHostName() const = 0; + + /** Return the current process identifier. + * Used when generating random strings (part boundaries or message ids). + * + * @return current process id + */ + virtual unsigned int getProcessId() const = 0; + + /** Return an unique identifier for the current thread. + * Used for multi-threading synchronization. + * + * @return current thread id + */ + virtual unsigned int getThreadId() const = 0; + + /** Return the charset used on the system. + * + * @return local charset + */ + virtual const charset getLocalCharset() const = 0; + + /** This function is called when VMime library is waiting for + * something (for example, it is called when there is no data + * available in a socket). On POSIX-compliant systems, a + * simple call to sched_yield() should suffice. + */ + virtual void wait() const = 0; + +#if VMIME_HAVE_MESSAGING_FEATURES + /** Return a pointer to the default socket factory for + * this platform. + * + * @return socket factory + */ + virtual shared_ptr <net::socketFactory> getSocketFactory() = 0; +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + /** Return a pointer to a factory that creates file-system objects. + * + * @return file-system factory + */ + virtual shared_ptr <utility::fileSystemFactory> getFileSystemFactory() = 0; + + /** Return a pointer to a factory that creates child process objects, + * which are used to spawn processes (run executable files). + * + * @return child process factory + */ + virtual shared_ptr <utility::childProcessFactory> getChildProcessFactory() = 0; +#endif + + /** Fills a buffer with cryptographically random bytes. + * + * @param buffer buffer to fill in with random bytes + * @param count number of random bytes to write in buffer + */ + virtual void generateRandomBytes(unsigned char* buffer, const unsigned int count) = 0; + + /** Creates and initializes a critical section. + */ + virtual shared_ptr <utility::sync::criticalSection> createCriticalSection() = 0; + }; + + + template <class TYPE> + static void setHandler() + { + sm_handler = vmime::make_shared <TYPE>(); + } + + static shared_ptr <handler> getDefaultHandler(); + static shared_ptr <handler> getHandler(); + +private: + + static shared_ptr <handler> sm_handler; +}; + + +} // vmime + + +#endif // VMIME_PLATFORM_HPP_INCLUDED + diff --git a/src/platforms/posix/posixChildProcess.cpp b/src/vmime/platforms/posix/posixChildProcess.cpp index 54d4cd75..54d4cd75 100644 --- a/src/platforms/posix/posixChildProcess.cpp +++ b/src/vmime/platforms/posix/posixChildProcess.cpp diff --git a/src/vmime/platforms/posix/posixChildProcess.hpp b/src/vmime/platforms/posix/posixChildProcess.hpp new file mode 100644 index 00000000..5b9fa021 --- /dev/null +++ b/src/vmime/platforms/posix/posixChildProcess.hpp @@ -0,0 +1,92 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_POSIX_POSIXCHILDPROCESS_HPP_INCLUDED +#define VMIME_PLATFORMS_POSIX_POSIXCHILDPROCESS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_POSIX && VMIME_HAVE_FILESYSTEM_FEATURES + + +#include "vmime/utility/childProcess.hpp" + +#include <sys/types.h> +#include <signal.h> + + +namespace vmime { +namespace platforms { +namespace posix { + + +class posixChildProcess : public utility::childProcess +{ +public: + + posixChildProcess(const utility::file::path& path); + ~posixChildProcess(); + + void start(const std::vector <string> args, const int flags = 0); + + shared_ptr <utility::outputStream> getStdIn(); + shared_ptr <utility::inputStream> getStdOut(); + + void waitForFinish(); + +private: + + utility::file::path m_processPath; + bool m_started; + + shared_ptr <utility::outputStream> m_stdIn; + shared_ptr <utility::inputStream> m_stdOut; + + sigset_t m_oldProcMask; + pid_t m_pid; + int m_pipe[2]; + + std::vector <string> m_argVector; + const char** m_argArray; +}; + + +class posixChildProcessFactory : public utility::childProcessFactory +{ +public: + + shared_ptr <utility::childProcess> create(const utility::file::path& path) const; +}; + + +} // posix +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_POSIX && VMIME_HAVE_FILESYSTEM_FEATURES + +#endif // VMIME_PLATFORMS_POSIX_POSIXCHILDPROCESS_HPP_INCLUDED + diff --git a/src/platforms/posix/posixCriticalSection.cpp b/src/vmime/platforms/posix/posixCriticalSection.cpp index fb2c469c..fb2c469c 100644 --- a/src/platforms/posix/posixCriticalSection.cpp +++ b/src/vmime/platforms/posix/posixCriticalSection.cpp diff --git a/src/vmime/platforms/posix/posixCriticalSection.hpp b/src/vmime/platforms/posix/posixCriticalSection.hpp new file mode 100644 index 00000000..150799cd --- /dev/null +++ b/src/vmime/platforms/posix/posixCriticalSection.hpp @@ -0,0 +1,69 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_POSIX_CRITICALSECTION_HPP_INCLUDED +#define VMIME_PLATFORMS_POSIX_CRITICALSECTION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_POSIX + + +#include "vmime/utility/sync/criticalSection.hpp" + + +#include <unistd.h> +#include <pthread.h> + + +namespace vmime { +namespace platforms { +namespace posix { + + +class posixCriticalSection : public utility::sync::criticalSection +{ +public: + + posixCriticalSection(); + ~posixCriticalSection(); + + void lock(); + void unlock(); + +private: + + pthread_mutex_t m_cs; +}; + + +} // posix +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_POSIX + +#endif // VMIME_PLATFORMS_POSIX_CRITICALSECTION_HPP_INCLUDED diff --git a/src/platforms/posix/posixFile.cpp b/src/vmime/platforms/posix/posixFile.cpp index 9387414d..9387414d 100644 --- a/src/platforms/posix/posixFile.cpp +++ b/src/vmime/platforms/posix/posixFile.cpp diff --git a/src/vmime/platforms/posix/posixFile.hpp b/src/vmime/platforms/posix/posixFile.hpp new file mode 100644 index 00000000..20a56699 --- /dev/null +++ b/src/vmime/platforms/posix/posixFile.hpp @@ -0,0 +1,220 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_POSIX_FILE_HPP_INCLUDED +#define VMIME_PLATFORMS_POSIX_FILE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_POSIX && VMIME_HAVE_FILESYSTEM_FEATURES + + +#include "vmime/utility/file.hpp" +#include "vmime/utility/seekableInputStream.hpp" + + +#include <dirent.h> + + +namespace vmime { +namespace platforms { +namespace posix { + + +class posixFileWriterOutputStream : public vmime::utility::outputStream +{ +public: + + posixFileWriterOutputStream(const vmime::utility::file::path& path, const int fd); + ~posixFileWriterOutputStream(); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + const vmime::utility::file::path m_path; + const int m_fd; +}; + + + +class posixFileReaderInputStream : public vmime::utility::seekableInputStream +{ +public: + + posixFileReaderInputStream(const vmime::utility::file::path& path, const int fd); + ~posixFileReaderInputStream(); + + bool eof() const; + + void reset(); + + size_t read(byte_t* const data, const size_t count); + + size_t skip(const size_t count); + + size_t getPosition() const; + void seek(const size_t pos); + +private: + + const vmime::utility::file::path m_path; + const int m_fd; + + bool m_eof; +}; + + + +class posixFileWriter : public vmime::utility::fileWriter +{ +public: + + posixFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath); + + shared_ptr <vmime::utility::outputStream> getOutputStream(); + +private: + + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + + +class posixFileReader : public vmime::utility::fileReader +{ +public: + + posixFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath); + + shared_ptr <vmime::utility::inputStream> getInputStream(); + +private: + + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + + +class posixFileIterator : public vmime::utility::fileIterator +{ +public: + + posixFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath); + ~posixFileIterator(); + + bool hasMoreElements() const; + shared_ptr <vmime::utility::file> nextElement(); + +private: + + void getNextElement(); + + vmime::utility::file::path m_path; + vmime::string m_nativePath; + + DIR* m_dir; + struct dirent* m_dirEntry; +}; + + + +class posixFile : public vmime::utility::file +{ +public: + + posixFile(const vmime::utility::file::path& path); + + void createFile(); + void createDirectory(const bool createAll = false); + + bool isFile() const; + bool isDirectory() const; + + bool canRead() const; + bool canWrite() const; + + length_type getLength(); + + const path& getFullPath() const; + + bool exists() const; + + shared_ptr <vmime::utility::file> getParent() const; + + void rename(const path& newName); + + void remove(); + + shared_ptr <vmime::utility::fileWriter> getFileWriter(); + shared_ptr <vmime::utility::fileReader> getFileReader(); + + shared_ptr <vmime::utility::fileIterator> getFiles() const; + +private: + + static void createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive = false); + +private: + + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + + +class posixFileSystemFactory : public vmime::utility::fileSystemFactory +{ +public: + + shared_ptr <vmime::utility::file> create(const vmime::utility::file::path& path) const; + + const vmime::utility::file::path stringToPath(const vmime::string& str) const; + const vmime::string pathToString(const vmime::utility::file::path& path) const; + + static const vmime::utility::file::path stringToPathImpl(const vmime::string& str); + static const vmime::string pathToStringImpl(const vmime::utility::file::path& path); + + bool isValidPathComponent(const vmime::utility::file::path::component& comp) const; + bool isValidPath(const vmime::utility::file::path& path) const; + + static void reportError(const vmime::utility::path& path, const int err); +}; + + +} // posix +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_POSIX && VMIME_HAVE_FILESYSTEM_FEATURES + +#endif // VMIME_PLATFORMS_POSIX_FILE_HPP_INCLUDED diff --git a/src/platforms/posix/posixHandler.cpp b/src/vmime/platforms/posix/posixHandler.cpp index 7ab0341a..7ab0341a 100644 --- a/src/platforms/posix/posixHandler.cpp +++ b/src/vmime/platforms/posix/posixHandler.cpp diff --git a/src/vmime/platforms/posix/posixHandler.hpp b/src/vmime/platforms/posix/posixHandler.hpp new file mode 100644 index 00000000..0bba372b --- /dev/null +++ b/src/vmime/platforms/posix/posixHandler.hpp @@ -0,0 +1,105 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_POSIX_HANDLER_HPP_INCLUDED +#define VMIME_PLATFORMS_POSIX_HANDLER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_POSIX + + +#include "vmime/platform.hpp" + +#if VMIME_HAVE_MESSAGING_FEATURES + #include "vmime/platforms/posix/posixSocket.hpp" +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + #include "vmime/platforms/posix/posixFile.hpp" + #include "vmime/platforms/posix/posixChildProcess.hpp" +#endif + + +namespace vmime { +namespace platforms { +namespace posix { + + +class VMIME_EXPORT posixHandler : public vmime::platform::handler +{ +public: + + posixHandler(); + ~posixHandler(); + + unsigned long getUnixTime() const; + + const vmime::datetime getCurrentLocalTime() const; + + const vmime::charset getLocalCharset() const; + + const vmime::string getHostName() const; + + unsigned int getProcessId() const; + unsigned int getThreadId() const; + +#if VMIME_HAVE_MESSAGING_FEATURES + shared_ptr <vmime::net::socketFactory> getSocketFactory(); +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + shared_ptr <vmime::utility::fileSystemFactory> getFileSystemFactory(); + + shared_ptr <vmime::utility::childProcessFactory> getChildProcessFactory(); +#endif + + void wait() const; + + void generateRandomBytes(unsigned char* buffer, const unsigned int count); + + shared_ptr <utility::sync::criticalSection> createCriticalSection(); + +private: + +#if VMIME_HAVE_MESSAGING_FEATURES + shared_ptr <posixSocketFactory> m_socketFactory; +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + shared_ptr <posixFileSystemFactory> m_fileSysFactory; + shared_ptr <posixChildProcessFactory> m_childProcFactory; +#endif +}; + + +} // posix +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_POSIX + +#endif // VMIME_PLATFORMS_POSIX_HANDLER_HPP_INCLUDED diff --git a/src/platforms/posix/posixSocket.cpp b/src/vmime/platforms/posix/posixSocket.cpp index ab434116..ab434116 100644 --- a/src/platforms/posix/posixSocket.cpp +++ b/src/vmime/platforms/posix/posixSocket.cpp diff --git a/src/vmime/platforms/posix/posixSocket.hpp b/src/vmime/platforms/posix/posixSocket.hpp new file mode 100644 index 00000000..4ec3edec --- /dev/null +++ b/src/vmime/platforms/posix/posixSocket.hpp @@ -0,0 +1,102 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_POSIX_SOCKET_HPP_INCLUDED +#define VMIME_PLATFORMS_POSIX_SOCKET_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_POSIX && VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/net/socket.hpp" + + +namespace vmime { +namespace platforms { +namespace posix { + + +class posixSocket : public vmime::net::socket +{ +public: + + posixSocket(shared_ptr <vmime::net::timeoutHandler> th); + ~posixSocket(); + + void connect(const vmime::string& address, const vmime::port_t port); + bool isConnected() const; + void disconnect(); + + void receive(vmime::string& buffer); + size_t receiveRaw(byte_t* buffer, const size_t count); + + void send(const vmime::string& buffer); + void send(const char* str); + void sendRaw(const byte_t* buffer, const size_t count); + size_t sendRawNonBlocking(const byte_t* buffer, const size_t count); + + size_t getBlockSize() const; + + unsigned int getStatus() const; + + const string getPeerName() const; + const string getPeerAddress() const; + +protected: + + static void throwSocketError(const int err); + +private: + + shared_ptr <vmime::net::timeoutHandler> m_timeoutHandler; + + byte_t m_buffer[65536]; + int m_desc; + + unsigned int m_status; + + string m_serverAddress; +}; + + + +class posixSocketFactory : public vmime::net::socketFactory +{ +public: + + shared_ptr <vmime::net::socket> create(); + shared_ptr <vmime::net::socket> create(shared_ptr <vmime::net::timeoutHandler> th); +}; + + +} // posix +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_POSIX && VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_PLATFORMS_POSIX_SOCKET_HPP_INCLUDED diff --git a/src/platforms/windows/windowsCriticalSection.cpp b/src/vmime/platforms/windows/windowsCriticalSection.cpp index d6ef0c45..d6ef0c45 100644 --- a/src/platforms/windows/windowsCriticalSection.cpp +++ b/src/vmime/platforms/windows/windowsCriticalSection.cpp diff --git a/src/vmime/platforms/windows/windowsCriticalSection.hpp b/src/vmime/platforms/windows/windowsCriticalSection.hpp new file mode 100644 index 00000000..7ed07835 --- /dev/null +++ b/src/vmime/platforms/windows/windowsCriticalSection.hpp @@ -0,0 +1,68 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_WINDOWS_CRITICALSECTION_HPP_INCLUDED +#define VMIME_PLATFORMS_WINDOWS_CRITICALSECTION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_WINDOWS + + +#include "vmime/utility/sync/criticalSection.hpp" + + +#include <windows.h> + + +namespace vmime { +namespace platforms { +namespace windows { + + +class windowsCriticalSection : public utility::sync::criticalSection +{ +public: + + windowsCriticalSection(); + ~windowsCriticalSection(); + + void lock(); + void unlock(); + +private: + + CRITICAL_SECTION m_cs; +}; + + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_WINDOWS + +#endif // VMIME_PLATFORMS_WINDOWS_CRITICALSECTION_HPP_INCLUDED diff --git a/src/platforms/windows/windowsFile.cpp b/src/vmime/platforms/windows/windowsFile.cpp index 6aa0fea8..6aa0fea8 100644 --- a/src/platforms/windows/windowsFile.cpp +++ b/src/vmime/platforms/windows/windowsFile.cpp diff --git a/src/vmime/platforms/windows/windowsFile.hpp b/src/vmime/platforms/windows/windowsFile.hpp new file mode 100644 index 00000000..3543ee8a --- /dev/null +++ b/src/vmime/platforms/windows/windowsFile.hpp @@ -0,0 +1,221 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_WINDOWS_FILE_HPP_INCLUDED +#define VMIME_PLATFORMS_WINDOWS_FILE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_FILESYSTEM_FEATURES + + +#include "vmime/utility/file.hpp" +#include "vmime/utility/seekableInputStream.hpp" + +#include <windows.h> + + +namespace vmime { +namespace platforms { +namespace windows { + + +class windowsFileSystemFactory : public vmime::utility::fileSystemFactory +{ +public: + + shared_ptr <vmime::utility::file> create(const vmime::utility::file::path& path) const; + + const vmime::utility::file::path stringToPath(const vmime::string& str) const; + const vmime::string pathToString(const vmime::utility::file::path& path) const; + + static const vmime::utility::file::path stringToPathImpl(const vmime::string& str); + static const vmime::string pathToStringImpl(const vmime::utility::file::path& path); + + bool isValidPathComponent(const vmime::utility::file::path::component& comp) const; + bool isValidPathComponent(const vmime::utility::file::path::component& comp, + bool firstComponent) const; + bool isValidPath(const vmime::utility::file::path& path) const; + + static void reportError(const vmime::utility::path& path, const int err); +}; + + +class windowsFile : public vmime::utility::file +{ +public: + + windowsFile(const vmime::utility::file::path& path); + + void createFile(); + void createDirectory(const bool createAll = false); + + bool isFile() const; + bool isDirectory() const; + + bool canRead() const; + bool canWrite() const; + + length_type getLength(); + + const path& getFullPath() const; + + bool exists() const; + + shared_ptr <file> getParent() const; + + void rename(const path& newName); + void remove(); + + shared_ptr <vmime::utility::fileWriter> getFileWriter(); + + shared_ptr <vmime::utility::fileReader> getFileReader(); + + shared_ptr <vmime::utility::fileIterator> getFiles() const; + +private: + + static void createDirectoryImpl(const vmime::utility::file::path& fullPath, const vmime::utility::file::path& path, const bool recursive = false); + +private: + + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + +class windowsFileIterator : public vmime::utility::fileIterator +{ +public: + + windowsFileIterator(const vmime::utility::file::path& path, const vmime::string& nativePath); + ~windowsFileIterator(); + + bool hasMoreElements() const; + shared_ptr <vmime::utility::file> nextElement(); + +private: + + void findFirst(); + void findNext(); + bool isCurrentOrParentDir() const; + +private: + + vmime::utility::file::path m_path; + vmime::string m_nativePath; + WIN32_FIND_DATA m_findData; + bool m_moreElements; + HANDLE m_hFind; +}; + + +class windowsFileReader : public vmime::utility::fileReader +{ +public: + + windowsFileReader(const vmime::utility::file::path& path, const vmime::string& nativePath); + +public: + + shared_ptr <vmime::utility::inputStream> getInputStream(); + +private: + + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + +class windowsFileReaderInputStream : public vmime::utility::inputStream +{ +public: + + windowsFileReaderInputStream(const vmime::utility::file::path& path, HANDLE hFile); + ~windowsFileReaderInputStream(); + +public: + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + const vmime::utility::file::path m_path; + HANDLE m_hFile; +}; + + +class windowsFileWriter : public vmime::utility::fileWriter +{ +public: + + windowsFileWriter(const vmime::utility::file::path& path, const vmime::string& nativePath); + +public: + + shared_ptr <vmime::utility::outputStream> getOutputStream(); + +private: + + vmime::utility::file::path m_path; + vmime::string m_nativePath; +}; + + +class windowsFileWriterOutputStream : public vmime::utility::outputStream +{ +public: + + windowsFileWriterOutputStream(const vmime::utility::file::path& path, HANDLE hFile); + ~windowsFileWriterOutputStream(); + +public: + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + const vmime::utility::file::path m_path; + HANDLE m_hFile; +}; + + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_FILESYSTEM_FEATURES + +#endif // VMIME_PLATFORMS_WINDOWS_FILE_HPP_INCLUDED diff --git a/src/platforms/windows/windowsHandler.cpp b/src/vmime/platforms/windows/windowsHandler.cpp index 9c96b271..9c96b271 100644 --- a/src/platforms/windows/windowsHandler.cpp +++ b/src/vmime/platforms/windows/windowsHandler.cpp diff --git a/src/vmime/platforms/windows/windowsHandler.hpp b/src/vmime/platforms/windows/windowsHandler.hpp new file mode 100644 index 00000000..4a3678eb --- /dev/null +++ b/src/vmime/platforms/windows/windowsHandler.hpp @@ -0,0 +1,103 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_WINDOWS_HANDLER_HPP_INCLUDED +#define VMIME_PLATFORMS_WINDOWS_HANDLER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_WINDOWS + + +#include "vmime/platform.hpp" + +#if VMIME_HAVE_MESSAGING_FEATURES + #include "vmime/platforms/windows/windowsSocket.hpp" +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + #include "vmime/platforms/windows/windowsFile.hpp" +#endif + + +namespace vmime { +namespace platforms { +namespace windows { + + +class VMIME_EXPORT windowsHandler : public vmime::platform::handler +{ +public: + + windowsHandler(); + ~windowsHandler(); + + unsigned long getUnixTime() const; + + const vmime::datetime getCurrentLocalTime() const; + + const vmime::charset getLocalCharset() const; + + const vmime::string getHostName() const; + + unsigned int getProcessId() const; + unsigned int getThreadId() const; + +#if VMIME_HAVE_MESSAGING_FEATURES + shared_ptr <vmime::net::socketFactory> getSocketFactory(); +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + shared_ptr <vmime::utility::fileSystemFactory> getFileSystemFactory(); + + shared_ptr <vmime::utility::childProcessFactory> getChildProcessFactory(); +#endif + + void wait() const; + + void generateRandomBytes(unsigned char* buffer, const unsigned int count); + + shared_ptr <utility::sync::criticalSection> createCriticalSection(); + +private: + +#if VMIME_HAVE_MESSAGING_FEATURES + shared_ptr <windowsSocketFactory> m_socketFactory; +#endif + +#if VMIME_HAVE_FILESYSTEM_FEATURES + shared_ptr <windowsFileSystemFactory> m_fileSysFactory; +#endif +}; + + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_WINDOWS + +#endif // VMIME_PLATFORMS_WINDOWS_HANDLER_HPP_INCLUDED diff --git a/src/platforms/windows/windowsSocket.cpp b/src/vmime/platforms/windows/windowsSocket.cpp index 40e69363..40e69363 100644 --- a/src/platforms/windows/windowsSocket.cpp +++ b/src/vmime/platforms/windows/windowsSocket.cpp diff --git a/src/vmime/platforms/windows/windowsSocket.hpp b/src/vmime/platforms/windows/windowsSocket.hpp new file mode 100644 index 00000000..e3f43b7c --- /dev/null +++ b/src/vmime/platforms/windows/windowsSocket.hpp @@ -0,0 +1,114 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PLATFORMS_WINDOWS_SOCKET_HPP_INCLUDED +#define VMIME_PLATFORMS_WINDOWS_SOCKET_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_MESSAGING_FEATURES + + +#include <winsock2.h> +#include "vmime/net/socket.hpp" + + +namespace vmime { +namespace platforms { +namespace windows { + + +class windowsSocket : public vmime::net::socket +{ +public: + + windowsSocket(); + windowsSocket(shared_ptr <vmime::net::timeoutHandler> th); + ~windowsSocket(); + +public: + + void connect(const vmime::string& address, const vmime::port_t port); + bool isConnected() const; + void disconnect(); + + void receive(vmime::string& buffer); + size_t receiveRaw(char* buffer, const size_t count); + + void send(const vmime::string& buffer); + void sendRaw(const char* buffer, const size_t count); + size_t sendRawNonBlocking(const char* buffer, const size_t count); + + size_t getBlockSize() const; + + unsigned int getStatus() const; + + const string getPeerName() const; + const string getPeerAddress() const; + +protected: + + void throwSocketError(const int err); + + enum WaitOpType + { + READ = 1, + WRITE = 2, + BOTH = 4 + }; + + void waitForData(const WaitOpType t, bool& timedOut); + +private: + + shared_ptr <vmime::net::timeoutHandler> m_timeoutHandler; + + char m_buffer[65536]; + SOCKET m_desc; + + unsigned int m_status; + + string m_serverAddress; +}; + + + +class windowsSocketFactory : public vmime::net::socketFactory +{ +public: + + shared_ptr <vmime::net::socket> create(); + shared_ptr <vmime::net::socket> create(shared_ptr <vmime::net::timeoutHandler> th); +}; + + +} // windows +} // platforms +} // vmime + + +#endif // VMIME_PLATFORM_IS_WINDOWS && VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_PLATFORMS_WINDOWS_SOCKET_HPP_INCLUDED diff --git a/src/propertySet.cpp b/src/vmime/propertySet.cpp index c22e79a6..c22e79a6 100644 --- a/src/propertySet.cpp +++ b/src/vmime/propertySet.cpp diff --git a/src/vmime/propertySet.hpp b/src/vmime/propertySet.hpp new file mode 100644 index 00000000..bf1c39bf --- /dev/null +++ b/src/vmime/propertySet.hpp @@ -0,0 +1,460 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_PROPERTY_HPP_INCLUDED +#define VMIME_PROPERTY_HPP_INCLUDED + + +#include <list> +#include <functional> +#include <algorithm> +#include <sstream> + +#include "vmime/base.hpp" +#include "vmime/exception.hpp" + +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime +{ + + +/** Manage a list of (name,value) pairs. + */ + +class VMIME_EXPORT propertySet : public object +{ +public: + + /** A property holds a (name,value) pair. + */ + class property : public object + { + public: + + property(const string& name, const string& value); + property(const string& name); + property(const property& prop); + + /** Return the name of the property. + * + * @return property name + */ + const string& getName() const; + +#ifndef _MSC_VER + + // Visual Studio errors on linking with these 2 functions, + // whereas GCC and CLang need them. + + /** Return the value of the property as a string. + * + * @return current value of the property + */ + const string& getValue() const; + + /** Set the value of the property as a string. + * + * @param value new value for property + */ + void setValue(const string& value); + +#endif // !_MSC_VER + + /** Set the value of the property as a generic type. + * + * @param value new value for property + */ + template <class TYPE> void setValue(const TYPE& value) + { + std::ostringstream oss; + oss.imbue(std::locale::classic()); // no formatting + + oss << value; + + m_value = oss.str(); + } + + /** Get the value of the property as a generic type. + * + * @throw exceptions::invalid_property_type if the specified + * type is incompatible with the string value (cannot be + * converted using std::istringstream) + * @return current value of the property + */ + template <class TYPE> TYPE getValue() const + { + TYPE val = TYPE(); + + std::istringstream iss(m_value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> val; + + if (iss.fail()) + throw exceptions::invalid_property_type(); + + return (val); + } + + +#ifdef VMIME_INLINE_TEMPLATE_SPECIALIZATION + + template <> + void propertySet::property::setValue(const string& value) + { + m_value = value; + } + + template <> + void propertySet::property::setValue(const bool& value) + { + m_value = value ? "true" : "false"; + } + + template <> + string propertySet::property::getValue() const + { + return (m_value); + } + + template <> + bool propertySet::property::getValue() const + { + if (utility::stringUtils::toLower(m_value) == "true") + return true; + else + { + int val = 0; + + std::istringstream iss(m_value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> val; + + return (!iss.fail() && val != 0); + } + } + +#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION + + private: + + const string m_name; + string m_value; + }; + +protected: + + class propertyProxy + { + public: + + propertyProxy(const string& name, propertySet* set) + : m_name(name), m_set(set) + { + } + + template <class TYPE> + propertyProxy& operator=(const TYPE& value) + { + m_set->setProperty(m_name, value); + return (*this); + } + + template <class TYPE> + void setValue(const TYPE& value) + { + m_set->setProperty(m_name, value); + } + + template <class TYPE> + const TYPE getValue() const + { + return (m_set->getProperty <TYPE>(m_name)); + } + + operator string() const + { + return (m_set->getProperty <string>(m_name)); + } + + private: + + const string m_name; + propertySet* m_set; + }; + + class constPropertyProxy + { + public: + + constPropertyProxy(const string& name, const propertySet* set) + : m_name(name), m_set(set) + { + } + + template <class TYPE> + const TYPE getValue() const + { + return (m_set->getProperty <TYPE>(m_name)); + } + + operator string() const + { + return (m_set->getProperty <string>(m_name)); + } + + private: + + const string m_name; + const propertySet* m_set; + }; + +public: + + propertySet(); + propertySet(const string& props); + propertySet(const propertySet& set); + + ~propertySet(); + + propertySet& operator=(const propertySet& set); + + /** Parse a string and extract one or more properties. + * The string format is: name[=value](;name[=value])*. + * + * @param props string representing a list of properties + */ + void setFromString(const string& props); + + /** Remove all properties from the list. + */ + void removeAllProperties(); + + /** Remove the specified property. + * + * @param name name of the property to remove + */ + void removeProperty(const string& name); + + /** Test whether the specified property is set. + * + * @param name name of the property to test + * @return true if the property is set (has a value), + * false otherwise + */ + bool hasProperty(const string& name) const; + + /** Get the value of the specified property. + * + * @throw exceptions::no_such_property if the property does not exist + * @param name property name + * @return value of the specified property + */ + template <class TYPE> + const TYPE getProperty(const string& name) const + { + const shared_ptr <property> prop = find(name); + if (!prop) throw exceptions::no_such_property(name); + + //return (prop->getValue <TYPE>()); // BUG: with g++ < 3.4 + return (prop->template getValue <TYPE>()); + } + + /** Get the value of the specified property. + * A default value can be returned if the property is not set. + * + * @param name property name + * @param defaultValue value to return if the specified property + * does not exist + * @return value of the specified property or default value + * if if does not exist + */ + template <class TYPE> + const TYPE getProperty(const string& name, const TYPE defaultValue) const + { + const shared_ptr <property> prop = find(name); + //return (prop ? prop->getValue <TYPE>() : defaultValue); // BUG: with g++ < 3.4 + return (prop ? prop->template getValue <TYPE>() : defaultValue); + } + + /** Change the value of the specified property or create + * a new property set to the specified a value. + * + * @param name property name + * @param value property value + */ + template <class TYPE> + void setProperty(const string& name, const TYPE& value) + { + findOrCreate(name)->setValue(value); + } + + /** Return a proxy object to access the specified property + * suitable for reading or writing. If the property does not + * exist and the value is changed, a new property will + * be created. + * + * @param name property name + * @return proxy object for the specified property + */ + propertyProxy operator[](const string& name); + + /** Return a proxy object to access the specified property + * suitable for reading only. + * + * @throw exceptions::no_such_property if the property does not exist + * @return read-only proxy object for the specified property + */ + const constPropertyProxy operator[](const string& name) const; + +private: + + void parse(const string& props); + + + class propFinder : public std::unary_function <shared_ptr <property>, bool> + { + public: + + propFinder(const string& name) : m_name(utility::stringUtils::toLower(name)) { } + + bool operator()(shared_ptr <property> p) const + { + return (utility::stringUtils::toLower(p->getName()) == m_name); + } + + private: + + const string m_name; + }; + + shared_ptr <property> find(const string& name) const; + shared_ptr <property> findOrCreate(const string& name); + + typedef std::list <shared_ptr <property> > list_type; + list_type m_props; + +public: + + template <typename TYPE> + static TYPE valueFromString(const string& value) + { + TYPE v = TYPE(); + + std::istringstream iss(value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> v; + + return v; + } + + template <typename TYPE> + static string valueToString(const TYPE& value) + { + std::ostringstream oss(value); + oss.imbue(std::locale::classic()); // no formatting + + oss << value; + + return oss.str(); + } + +#ifdef VMIME_INLINE_TEMPLATE_SPECIALIZATION + + template <> + static string valueFromString(const string& value) + { + return value; + } + + template <> + static string valueToString(const string& value) + { + return value; + } + + template <> + static bool valueFromString(const string& value) + { + if (utility::stringUtils::toLower(value) == "true") + return true; + else + { + int val = 0; + + std::istringstream iss(value); + iss.imbue(std::locale::classic()); // no formatting + + iss >> val; + + return (!iss.fail() && val != 0); + } + } + + template <> + static string valueToString(const bool& value) + { + return (value ? "true" : "false"); + } + +#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION + + /** Return the property list. + * + * @return list of properties + */ + const std::vector <shared_ptr <const property> > getPropertyList() const; + + /** Return the property list. + * + * @return list of properties + */ + const std::vector <shared_ptr <property> > getPropertyList(); +}; + + +#ifndef VMIME_INLINE_TEMPLATE_SPECIALIZATION + +template <> VMIME_EXPORT void propertySet::property::setValue <string>(const string& value); +template <> VMIME_EXPORT void propertySet::property::setValue(const bool& value); + +template <> VMIME_EXPORT string propertySet::property::getValue() const; +template <> VMIME_EXPORT bool propertySet::property::getValue() const; + +template <> VMIME_EXPORT string propertySet::valueFromString(const string& value); +template <> VMIME_EXPORT string propertySet::valueToString(const string& value); + +template <> VMIME_EXPORT bool propertySet::valueFromString(const string& value); +template <> VMIME_EXPORT string propertySet::valueToString(const bool& value); + +#endif // VMIME_INLINE_TEMPLATE_SPECIALIZATION + + +} // vmime + + +#endif // VMIME_PROPERTY_HPP_INCLUDED diff --git a/src/relay.cpp b/src/vmime/relay.cpp index e5d30c9e..e5d30c9e 100644 --- a/src/relay.cpp +++ b/src/vmime/relay.cpp diff --git a/src/vmime/relay.hpp b/src/vmime/relay.hpp new file mode 100644 index 00000000..35949ff1 --- /dev/null +++ b/src/vmime/relay.hpp @@ -0,0 +1,108 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_RELAY_HPP_INCLUDED +#define VMIME_RELAY_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/headerFieldValue.hpp" + +#include "vmime/dateTime.hpp" + + +namespace vmime +{ + + +/** Trace information about a relay (basic type). + */ + +class VMIME_EXPORT relay : public headerFieldValue +{ +public: + + relay(); + relay(const relay& r); + +public: + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + relay& operator=(const relay& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + const string& getFrom() const; + void setFrom(const string& from); + + const string& getVia() const; + void setVia(const string& via); + + const string& getBy() const; + void setBy(const string& by); + + const string& getId() const; + void setId(const string& id); + + const string& getFor() const; + void setFor(const string& for_); + + const datetime& getDate() const; + void setDate(const datetime& date); + + const std::vector <string>& getWithList() const; + std::vector <string>& getWithList(); + +private: + + string m_from; + string m_via; + string m_by; + string m_id; + string m_for; + std::vector <string> m_with; + + datetime m_date; + +protected: + + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; +}; + + +} // vmime + + +#endif // VMIME_RELAY_HPP_INCLUDED diff --git a/src/vmime/security/authenticator.hpp b/src/vmime/security/authenticator.hpp new file mode 100644 index 00000000..bef07b4a --- /dev/null +++ b/src/vmime/security/authenticator.hpp @@ -0,0 +1,128 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_AUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_AUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/types.hpp" + + +// Forward declarations +namespace vmime { +namespace net { + +class service; + +} // net +} // vmime + + +namespace vmime { +namespace security { + + +/** Provides required information for user authentication. The same + * information can be requested multiple time (eg. in IMAP, there is a + * new connection started each time a folder is open), so the object is + * responsible for caching the information to avoid useless interactions + * with the user. + * + * Usually, you should not inherit from this class, but instead from the + * more convenient defaultAuthenticator class. + * + * WARNING: an authenticator should be used with one and ONLY ONE messaging + * service at a time. + */ +class VMIME_EXPORT authenticator : public object +{ +public: + + /** Return the authentication identity (usually, this + * is the username). + * + * @return username + * @throw exceptions::no_auth_information if the information + * could not be provided + */ + virtual const string getUsername() const = 0; + + /** Return the password of the authentication identity. + * + * @return password + * @throw exceptions::no_auth_information if the information + * could not be provided + */ + virtual const string getPassword() const = 0; + + /** Return the local host name of the machine. + * + * @return hostname + * @throw exceptions::no_auth_information if the information + * could not be provided + */ + virtual const string getHostname() const = 0; + + /** Return the anonymous token (usually, this is the user's + * email address). + * + * @return anonymous token + * @throw exceptions::no_auth_information if the information + * could not be provided + */ + virtual const string getAnonymousToken() const = 0; + + /** Return the registered service name of the application + * service (eg: "imap"). This can be used by GSSAPI or DIGEST-MD5 + * mechanisms with SASL. + * + * @return service name + * @throw exceptions::no_auth_information if the information + * could not be provided + */ + virtual const string getServiceName() const = 0; + + /** Called by the messaging service to allow this authenticator to + * know which service is currently using it. This is called just + * before the service starts the authentication process. + * + * @param serv messaging service instance + */ + virtual void setService(shared_ptr <net::service> serv) = 0; +}; + + +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_SECURITY_AUTHENTICATOR_HPP_INCLUDED + diff --git a/src/security/cert/X509Certificate.cpp b/src/vmime/security/cert/X509Certificate.cpp index 2eebabfd..2eebabfd 100644 --- a/src/security/cert/X509Certificate.cpp +++ b/src/vmime/security/cert/X509Certificate.cpp diff --git a/src/vmime/security/cert/X509Certificate.hpp b/src/vmime/security/cert/X509Certificate.hpp new file mode 100644 index 00000000..215a86cf --- /dev/null +++ b/src/vmime/security/cert/X509Certificate.hpp @@ -0,0 +1,156 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_CERT_X509CERTIFICATE_HPP_INCLUDED +#define VMIME_SECURITY_CERT_X509CERTIFICATE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#include "vmime/security/cert/certificate.hpp" + +#include "vmime/utility/stream.hpp" + +#include "vmime/base.hpp" +#include "vmime/types.hpp" +#include "vmime/dateTime.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +/** Identity certificate based on X.509 standard. + */ +class VMIME_EXPORT X509Certificate : public certificate +{ +public: + + ~X509Certificate(); + + /** Supported encodings for X.509 certificates. */ + enum Format + { + FORMAT_DER, /**< DER encoding */ + FORMAT_PEM /**< PEM encoding */ + }; + + /** Supported digest algorithms (used for fingerprint). */ + enum DigestAlgorithm + { + DIGEST_MD5, /**< MD5 digest */ + DIGEST_SHA1 /**< SHA1 digest */ + }; + + + /** Imports a DER or PEM encoded X.509 certificate. + * + * @param is input stream to read data from + * @return a X.509 certificate, or NULL if the given data does not + * represent a valid certificate + */ + static shared_ptr <X509Certificate> import(utility::inputStream& is); + + /** Imports a DER or PEM encoded X.509 certificate. + * + * @param data points to raw data + * @param length size of data + * @return a X.509 certificate, or NULL if the given data does not + * represent a valid certificate + */ + static shared_ptr <X509Certificate> import(const byte_t* data, const size_t length); + + /** Exports this X.509 certificate to the specified format. + * + * @param os output stream into which write data + * @param format output format + */ + virtual void write(utility::outputStream& os, const Format format) const = 0; + + /** Returns the X.509 certificate's serial number. This is obtained + * by the X.509 Certificate 'serialNumber' field. Serial is not + * always a 32 or 64bit number. Some CAs use large serial numbers, + * thus it may be wise to handle it as something opaque. + * + * @return serial number of this certificate + */ + virtual const byteArray getSerialNumber() const = 0; + + /** Checks if this certificate has the given issuer. + * + * @param issuer certificate of a possible issuer + * @return true if this certificate was issued by the given issuer, + * false otherwise + */ + virtual bool checkIssuer(shared_ptr <const X509Certificate> issuer) const = 0; + + /** Verifies this certificate against a given trusted one. + * + * @param caCert a certificate that is considered to be trusted one + * @return true if the verification succeeded, false otherwise + */ + virtual bool verify(shared_ptr <const X509Certificate> caCert) const = 0; + + /** Verify certificate's subject name against the given hostname. + * + * @param hostname DNS name of the server + * @return true if the match is successful, false otherwise + */ + virtual bool verifyHostName(const string& hostname) const = 0; + + /** Gets the expiration date of this certificate. This is the date + * at which this certificate will not be valid anymore. + * + * @return expiration date of this certificate + */ + virtual const datetime getExpirationDate() const = 0; + + /** Gets the activation date of this certificate. This is the date + * at which this certificate will be valid. + * + * @return activation date of this certificate + */ + virtual const datetime getActivationDate() const = 0; + + /** Returns the fingerprint of this certificate. + * + * @return the fingerprint of this certificate + */ + virtual const byteArray getFingerprint(const DigestAlgorithm algo) const = 0; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + +#endif // VMIME_SECURITY_CERT_X509CERTIFICATE_HPP_INCLUDED + diff --git a/src/vmime/security/cert/certificate.hpp b/src/vmime/security/cert/certificate.hpp new file mode 100644 index 00000000..aef1f1f9 --- /dev/null +++ b/src/vmime/security/cert/certificate.hpp @@ -0,0 +1,84 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_CERT_CERTIFICATE_HPP_INCLUDED +#define VMIME_SECURITY_CERT_CERTIFICATE_HPP_INCLUDED + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +/** Identity certificate for a peer. + */ +class VMIME_EXPORT certificate : public object +{ +public: + + /** Returns the encoded form of this certificate (for example, + * X.509 certificates are encoded as ASN.1 DER). + * + * @return the encoded form of this certificate + */ + virtual const byteArray getEncoded() const = 0; + + /** Return the type of this certificate. + * + * @return the type of this certificate + */ + virtual const string getType() const = 0; + + /** Return the version of this certificate. + * + * @return the version of this certificate + */ + virtual int getVersion() const = 0; + + /** Checks if two certificates are the same. + * + * @param other certificate to compare with + * @return true if the two certificates are the same, + * false otherwise + */ + virtual bool equals(shared_ptr <const certificate> other) const = 0; + + /** Returns a pointer to internal binary data for this certificate. + * The actual type of data depends on the library used for TLS support. + * + * @return pointer to underlying data + */ + virtual void* getInternalData() = 0; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_SECURITY_CERT_CERTIFICATE_HPP_INCLUDED + diff --git a/src/security/cert/certificateChain.cpp b/src/vmime/security/cert/certificateChain.cpp index 3cb4e360..3cb4e360 100644 --- a/src/security/cert/certificateChain.cpp +++ b/src/vmime/security/cert/certificateChain.cpp diff --git a/src/vmime/security/cert/certificateChain.hpp b/src/vmime/security/cert/certificateChain.hpp new file mode 100644 index 00000000..0ce6bda3 --- /dev/null +++ b/src/vmime/security/cert/certificateChain.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_CERT_CERTIFICATECHAIN_HPP_INCLUDED +#define VMIME_SECURITY_CERT_CERTIFICATECHAIN_HPP_INCLUDED + + +#include "vmime/types.hpp" + +#include "vmime/security/cert/certificate.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +/** An ordered list of certificates, from the subject certificate to + * the issuer certificate. + */ +class VMIME_EXPORT certificateChain : public object +{ +public: + + /** Construct a new certificateChain object given an ordered list + * of certificates. + * + * @param certs chain of certificates + */ + certificateChain(const std::vector <shared_ptr <certificate> >& certs); + + /** Return the number of certificates in the chain. + * + * @return number of certificates in the chain + */ + unsigned int getCount() const; + + /** Return the certificate at the specified position. 0 is the + * subject certificate, 1 is the issuer's certificate, 2 is + * the issuer's issuer, etc. + * + * @param index position at which to retrieve certificate + * @return certificate at the specified position + */ + shared_ptr <certificate> getAt(const unsigned int index); + +protected: + + std::vector <shared_ptr <certificate> > m_certs; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_SECURITY_CERT_CERTIFICATECHAIN_HPP_INCLUDED + diff --git a/src/vmime/security/cert/certificateVerifier.hpp b/src/vmime/security/cert/certificateVerifier.hpp new file mode 100644 index 00000000..c72c84cb --- /dev/null +++ b/src/vmime/security/cert/certificateVerifier.hpp @@ -0,0 +1,62 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_CERT_CERTIFICATEVERIFIER_HPP_INCLUDED +#define VMIME_SECURITY_CERT_CERTIFICATEVERIFIER_HPP_INCLUDED + + +#include "vmime/types.hpp" + +#include "vmime/security/cert/certificateChain.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +/** Verify that a certificate path issued by a server can be trusted. + */ +class VMIME_EXPORT certificateVerifier : public object +{ +public: + + /** Verify that the specified certificate chain is trusted. + * + * @param chain certificate chain + * @param hostname server hostname + * @throw exceptions::certificate_verification_exception if one + * or more certificates can not be trusted, or the server identity + * cannot be verified + */ + virtual void verify(shared_ptr <certificateChain> chain, const string& hostname) = 0; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_SECURITY_CERT_CERTIFICATEVERIFIER_HPP_INCLUDED + diff --git a/src/security/cert/defaultCertificateVerifier.cpp b/src/vmime/security/cert/defaultCertificateVerifier.cpp index 1a95b353..1a95b353 100644 --- a/src/security/cert/defaultCertificateVerifier.cpp +++ b/src/vmime/security/cert/defaultCertificateVerifier.cpp diff --git a/src/vmime/security/cert/defaultCertificateVerifier.hpp b/src/vmime/security/cert/defaultCertificateVerifier.hpp new file mode 100644 index 00000000..fddcc4f5 --- /dev/null +++ b/src/vmime/security/cert/defaultCertificateVerifier.hpp @@ -0,0 +1,89 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_CERT_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED +#define VMIME_SECURITY_CERT_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED + + +#include "vmime/security/cert/certificateVerifier.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +class X509Certificate; + + +/** Default implementation for certificate verification. + */ +class VMIME_EXPORT defaultCertificateVerifier : public certificateVerifier +{ +private: + + defaultCertificateVerifier(const defaultCertificateVerifier&); + +public: + + defaultCertificateVerifier(); + ~defaultCertificateVerifier(); + + /** Sets a list of X.509 certificates that are trusted. + * + * @param trustedCerts list of trusted certificates + */ + void setX509TrustedCerts(const std::vector <shared_ptr <X509Certificate> >& trustedCerts); + + /** Sets the X.509 root CAs used for certificate verification. + * + * @param caCerts list of root CAs + */ + void setX509RootCAs(const std::vector <shared_ptr <X509Certificate> >& caCerts); + + + // Implementation of 'certificateVerifier' + void verify(shared_ptr <certificateChain> chain, const string& hostname); + +private: + + /** Verify a chain of X.509 certificates. + * + * @param chain list of X.509 certificates + * @param hostname server hostname + */ + void verifyX509(shared_ptr <certificateChain> chain, const string& hostname); + + + std::vector <shared_ptr <X509Certificate> > m_x509RootCAs; + std::vector <shared_ptr <X509Certificate> > m_x509TrustedCerts; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_SECURITY_CERT_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED + diff --git a/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp index f96ddddb..f96ddddb 100644 --- a/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp +++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp new file mode 100644 index 00000000..76ee6d4d --- /dev/null +++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp @@ -0,0 +1,92 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_CERT_X509CERTIFICATE_GNUTLS_HPP_INCLUDED +#define VMIME_SECURITY_CERT_X509CERTIFICATE_GNUTLS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + + +#include "vmime/security/cert/X509Certificate.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +class X509Certificate_GnuTLS : public X509Certificate +{ + friend class X509Certificate; + + X509Certificate_GnuTLS(const X509Certificate&); + +public: + + X509Certificate_GnuTLS(); + + ~X509Certificate_GnuTLS(); + + + void write(utility::outputStream& os, const Format format) const; + + const byteArray getSerialNumber() const; + + bool checkIssuer(shared_ptr <const X509Certificate> issuer) const; + + bool verify(shared_ptr <const X509Certificate> caCert) const; + + bool verifyHostName(const string& hostname) const; + + const datetime getExpirationDate() const; + const datetime getActivationDate() const; + + const byteArray getFingerprint(const DigestAlgorithm algo) const; + + + // Implementation of 'certificate' + const byteArray getEncoded() const; + const string getType() const; + int getVersion() const; + bool equals(shared_ptr <const certificate> other) const; + void* getInternalData(); + +private: + + struct GnuTLSX509CertificateInternalData* m_data; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + +#endif // VMIME_SECURITY_CERT_X509CERTIFICATE_GNUTLS_HPP_INCLUDED + diff --git a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp index 5f81b2bf..5f81b2bf 100644 --- a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp new file mode 100644 index 00000000..bddb4b6c --- /dev/null +++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp @@ -0,0 +1,115 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_CERT_X509CERTIFICATE_OPENSSL_HPP_INCLUDED +#define VMIME_SECURITY_CERT_X509CERTIFICATE_OPENSSL_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + + +#include "vmime/security/cert/X509Certificate.hpp" + +#include <openssl/x509.h> + + +namespace vmime { +namespace security { +namespace cert { + + +class X509Certificate_OpenSSL : public X509Certificate +{ + friend class X509Certificate; + + X509Certificate_OpenSSL(const X509Certificate_OpenSSL&); + +public: + + X509Certificate_OpenSSL(); + X509Certificate_OpenSSL(X509* cert); + + ~X509Certificate_OpenSSL(); + + + void write(utility::outputStream& os, const Format format) const; + + const byteArray getSerialNumber() const; + + bool checkIssuer(shared_ptr <const X509Certificate> issuer) const; + + bool verify(shared_ptr <const X509Certificate> caCert) const; + + bool verifyHostName(const string& hostname) const; + + const datetime getExpirationDate() const; + const datetime getActivationDate() const; + + const byteArray getFingerprint(const DigestAlgorithm algo) const; + + + static shared_ptr <X509Certificate> importInternal(X509* cert); + + + // Implementation of 'certificate' + const byteArray getEncoded() const; + const string getType() const; + int getVersion() const; + bool equals(shared_ptr <const certificate> other) const; + void* getInternalData(); + +private: + + /** Internal utility function to test whether a hostname matches + * the specified X509 Common Name (wildcard is supported). + * + * @param cnBuf pointer to buffer holding Common Name + * @param host pointer to buffer holding host name + * @return true if the hostname matches the Common Name, or + * false otherwise + */ + static bool cnMatch(const char* cnBuf, const char* host); + + /** Internal utility function to convert ASN1_TIME + * structs to vmime::datetime + * + * @param pointer to ASN1_TIME struct to convert + */ + const datetime convertX509Date(void* time) const; + + struct OpenSSLX509CertificateInternalData* m_data; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + +#endif // VMIME_SECURITY_CERT_X509CERTIFICATE_OPENSSL_HPP_INCLUDED + diff --git a/src/security/defaultAuthenticator.cpp b/src/vmime/security/defaultAuthenticator.cpp index 790196d2..790196d2 100644 --- a/src/security/defaultAuthenticator.cpp +++ b/src/vmime/security/defaultAuthenticator.cpp diff --git a/src/vmime/security/defaultAuthenticator.hpp b/src/vmime/security/defaultAuthenticator.hpp new file mode 100644 index 00000000..eead3d14 --- /dev/null +++ b/src/vmime/security/defaultAuthenticator.hpp @@ -0,0 +1,73 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_DEFAULTAUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_DEFAULTAUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/security/authenticator.hpp" + + +namespace vmime { +namespace security { + + +/** An authenticator that can provide some basic information by + * reading in the messaging session properties. + */ +class VMIME_EXPORT defaultAuthenticator : public authenticator +{ +public: + + defaultAuthenticator(); + ~defaultAuthenticator(); + + const string getUsername() const; + const string getPassword() const; + const string getHostname() const; + const string getAnonymousToken() const; + const string getServiceName() const; + + void setService(shared_ptr <net::service> serv); + weak_ptr <net::service> getService() const; + +private: + + weak_ptr <net::service> m_service; +}; + + +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_SECURITY_DEFAULTAUTHENTICATOR_HPP_INCLUDED + diff --git a/src/security/digest/md5/md5MessageDigest.cpp b/src/vmime/security/digest/md5/md5MessageDigest.cpp index a83f0623..a83f0623 100644 --- a/src/security/digest/md5/md5MessageDigest.cpp +++ b/src/vmime/security/digest/md5/md5MessageDigest.cpp diff --git a/src/vmime/security/digest/md5/md5MessageDigest.hpp b/src/vmime/security/digest/md5/md5MessageDigest.hpp new file mode 100644 index 00000000..ef94f5c8 --- /dev/null +++ b/src/vmime/security/digest/md5/md5MessageDigest.hpp @@ -0,0 +1,86 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_DIGEST_MD5_MD5MESSAGEDIGEST_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_MD5_MD5MESSAGEDIGEST_HPP_INCLUDED + + +#include "vmime/security/digest/messageDigest.hpp" + + +namespace vmime { +namespace security { +namespace digest { +namespace md5 { + + +class md5MessageDigest : public messageDigest +{ +public: + + md5MessageDigest(); + + void update(const byte_t b); + void update(const string& s); + void update(const byte_t* buffer, const size_t len); + void update(const byte_t* buffer, const size_t offset, const size_t len); + + void finalize(); + void finalize(const string& s); + void finalize(const byte_t* buffer, const size_t len); + void finalize(const byte_t* buffer, const size_t offset, const size_t len); + + size_t getDigestLength() const; + const byte_t* getDigest() const; + + void reset(); + +protected: + + void init(); + void transformHelper(); + void transform(); + + vmime_uint32 m_hash[4]; + + union BlockType + { + vmime_uint32 b32[16]; + vmime_uint8 b8[64]; + }; + + size_t m_byteCount; + BlockType m_block; + + bool m_finalized; +}; + + +} // md5 +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_MD5_MD5MESSAGEDIGEST_HPP_INCLUDED + diff --git a/src/security/digest/messageDigest.cpp b/src/vmime/security/digest/messageDigest.cpp index 18fc8628..18fc8628 100644 --- a/src/security/digest/messageDigest.cpp +++ b/src/vmime/security/digest/messageDigest.cpp diff --git a/src/vmime/security/digest/messageDigest.hpp b/src/vmime/security/digest/messageDigest.hpp new file mode 100644 index 00000000..d17dfbc2 --- /dev/null +++ b/src/vmime/security/digest/messageDigest.hpp @@ -0,0 +1,138 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_DIGEST_MESSAGEDIGEST_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_MESSAGEDIGEST_HPP_INCLUDED + + +#include "vmime/object.hpp" +#include "vmime/types.hpp" + + +namespace vmime { +namespace security { +namespace digest { + + +/** Computes message digests using standard algorithms, + * such as MD5 or SHA. + */ + +class VMIME_EXPORT messageDigest : public object +{ +public: + + /** Updates the digest using the specified string. + * + * @param s the string with which to update the digest. + */ + virtual void update(const string& s) = 0; + + /** Updates the digest using the specified byte. + * + * @param b the byte with which to update the digest. + */ + virtual void update(const byte_t b) = 0; + + /** Updates the digest using the specified array of bytes. + * + * @param buffer array of bytes + * @param len number of bytes to use in the buffer + */ + virtual void update(const byte_t* buffer, const size_t len) = 0; + + /** Updates the digest using the specified array of bytes, + * starting at the specified offset. + * + * @param buffer array of bytes + * @param offset offset to start from in the array of bytes + * @param len number of bytes to use, starting at offset + */ + virtual void update(const byte_t* buffer, + const size_t offset, + const size_t len) = 0; + + /** Completes the hash computation by performing final operations + * such as padding. + */ + virtual void finalize() = 0; + + /** Completes the hash computation by performing final operations + * such as padding. This is equivalent to calling update() and + * then finalize(). + */ + virtual void finalize(const string& s) = 0; + + /** Completes the hash computation by performing final operations + * such as padding. This is equivalent to calling update() and + * then finalize(). + */ + virtual void finalize(const byte_t* buffer, + const size_t len) = 0; + + /** Completes the hash computation by performing final operations + * such as padding. This is equivalent to calling update() and + * then finalize(). + */ + virtual void finalize(const byte_t* buffer, + const size_t offset, + const size_t len) = 0; + + /** Returns the length of the hash. + * This is the length of the array returned by getDigest(). + * + * @return length of computed hash + */ + virtual size_t getDigestLength() const = 0; + + /** Returns the hash, as computed by the algorithm. + * You must call finalize() before using this function, or the + * hash will not be correct. + * To get the size of the returned array, call getDigestLength(). + * + * @return computed hash + */ + virtual const byte_t* getDigest() const = 0; + + /** Returns the hash as an hexadecimal string. + * You must call finalize() before using this function, or the + * hash will not be correct. + * + * @return computed hash, in hexadecimal format + */ + virtual const string getHexDigest() const; + + /** Resets the algorithm to its initial state, so that you can + * compute a new hash using the same object. + */ + virtual void reset() = 0; +}; + + +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_MESSAGEDIGEST_HPP_INCLUDED + diff --git a/src/security/digest/messageDigestFactory.cpp b/src/vmime/security/digest/messageDigestFactory.cpp index 2831c5a1..2831c5a1 100644 --- a/src/security/digest/messageDigestFactory.cpp +++ b/src/vmime/security/digest/messageDigestFactory.cpp diff --git a/src/vmime/security/digest/messageDigestFactory.hpp b/src/vmime/security/digest/messageDigestFactory.hpp new file mode 100644 index 00000000..15fd8a28 --- /dev/null +++ b/src/vmime/security/digest/messageDigestFactory.hpp @@ -0,0 +1,112 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_DIGEST_MESSAGEDIGESTFACTORY_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_MESSAGEDIGESTFACTORY_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/security/digest/messageDigest.hpp" +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime { +namespace security { +namespace digest { + + +/** Creates instances of message digest algorithms. + */ + +class VMIME_EXPORT messageDigestFactory +{ +private: + + messageDigestFactory(); + ~messageDigestFactory(); + +public: + + static messageDigestFactory* getInstance(); + +private: + + class digestAlgorithmFactory : public object + { + public: + + virtual shared_ptr <messageDigest> create() const = 0; + }; + + template <class E> + class digestAlgorithmFactoryImpl : public digestAlgorithmFactory + { + public: + + shared_ptr <messageDigest> create() const + { + return vmime::make_shared <E>(); + } + }; + + + typedef std::map <string, shared_ptr <digestAlgorithmFactory> > MapType; + MapType m_algos; + +public: + + /** Register a new digest algorithm by its name. + * + * @param name algorithm name + */ + template <class E> + void registerAlgorithm(const string& name) + { + m_algos.insert(MapType::value_type(utility::stringUtils::toLower(name), + vmime::make_shared <digestAlgorithmFactoryImpl <E> >())); + } + + /** Create a new algorithm instance from its name. + * + * @param name algorithm name (eg. "md5") + * @return a new algorithm instance for the specified name + * @throw exceptions::no_digest_algorithm_available if no algorithm is + * registered with this name + */ + shared_ptr <messageDigest> create(const string& name); + + /** Return a list of supported digest algorithms. + * + * @return list of supported digest algorithms + */ + const std::vector <string> getSupportedAlgorithms() const; +}; + + +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_MESSAGEDIGESTFACTORY_HPP_INCLUDED + diff --git a/src/security/digest/sha1/sha1MessageDigest.cpp b/src/vmime/security/digest/sha1/sha1MessageDigest.cpp index aa055af5..aa055af5 100644 --- a/src/security/digest/sha1/sha1MessageDigest.cpp +++ b/src/vmime/security/digest/sha1/sha1MessageDigest.cpp diff --git a/src/vmime/security/digest/sha1/sha1MessageDigest.hpp b/src/vmime/security/digest/sha1/sha1MessageDigest.hpp new file mode 100644 index 00000000..1eb09c2f --- /dev/null +++ b/src/vmime/security/digest/sha1/sha1MessageDigest.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_DIGEST_SHA1_SHA1MESSAGEDIGEST_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_SHA1_SHA1MESSAGEDIGEST_HPP_INCLUDED + + +#include "vmime/security/digest/messageDigest.hpp" + + +namespace vmime { +namespace security { +namespace digest { +namespace sha1 { + + +class sha1MessageDigest : public messageDigest +{ +public: + + sha1MessageDigest(); + + void update(const byte_t b); + void update(const string& s); + void update(const byte_t* buffer, const size_t len); + void update(const byte_t* buffer, const size_t offset, const size_t len); + + void finalize(); + void finalize(const string& s); + void finalize(const byte_t* buffer, const size_t len); + void finalize(const byte_t* buffer, const size_t offset, const size_t len); + + size_t getDigestLength() const; + const byte_t* getDigest() const; + + void reset(); + +protected: + + void init(); + + static void transform(unsigned int state[5], const byte_t buffer[64]); + + unsigned int m_state[5]; + unsigned int m_count[2]; + byte_t m_buffer[64]; + + byte_t m_digest[20]; +}; + + +} // sha1 +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_SHA1_SHA1MESSAGEDIGEST_HPP_INCLUDED + diff --git a/src/vmime/security/sasl/SASLAuthenticator.hpp b/src/vmime/security/sasl/SASLAuthenticator.hpp new file mode 100644 index 00000000..9f1881f5 --- /dev/null +++ b/src/vmime/security/sasl/SASLAuthenticator.hpp @@ -0,0 +1,96 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/security/authenticator.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLMechanism; +class SASLSession; + + +/** SASL-aware authenticator. + * + * Usually, you should not inherit from this class, but instead from the + * more convenient defaultSASLAuthenticator class. + */ +class VMIME_EXPORT SASLAuthenticator : public authenticator +{ +public: + + /** This method is called to allow the client to choose the + * authentication mechanisms that will be used. By default, + * the most secure mechanisms are chosen. + * + * @param available available mechanisms + * @param suggested suggested mechanism (or NULL if the system + * could not suggest a mechanism) + * @return ordered list of mechanism to use among the available + * mechanisms (from the first to try to the last) + */ + virtual const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms + (const std::vector <shared_ptr <SASLMechanism> >& available, + shared_ptr <SASLMechanism> suggested) const = 0; + + /** Set the SASL session which is using this authenticator. + * + * @param sess SASL session + */ + virtual void setSASLSession(shared_ptr <SASLSession> sess) = 0; + + /** Set the SASL mechanism which has been selected for the + * SASL authentication process. This may be called several times + * if the multiple mechanisms are tried by the service which + * use this authentication. + * + * @param mech SASL mechanism + */ + virtual void setSASLMechanism(shared_ptr <SASLMechanism> mech) = 0; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED + diff --git a/src/security/sasl/SASLContext.cpp b/src/vmime/security/sasl/SASLContext.cpp index 3474cbeb..3474cbeb 100644 --- a/src/security/sasl/SASLContext.cpp +++ b/src/vmime/security/sasl/SASLContext.cpp diff --git a/src/vmime/security/sasl/SASLContext.hpp b/src/vmime/security/sasl/SASLContext.hpp new file mode 100644 index 00000000..200f78db --- /dev/null +++ b/src/vmime/security/sasl/SASLContext.hpp @@ -0,0 +1,128 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/security/sasl/SASLSession.hpp" +#include "vmime/security/sasl/SASLMechanismFactory.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +/** An SASL client context. + */ +class VMIME_EXPORT SASLContext : public object +{ + friend class SASLSession; + friend class builtinSASLMechanism; + +public: + + ~SASLContext(); + + /** Construct and initialize a new SASL context. + */ + SASLContext(); + + /** Create and initialize a new SASL session. + * + * @param serviceName name of the service which will use the session + * @param auth authenticator object to use during the session + * @param mech SASL mechanism + * @return a new SASL session + */ + shared_ptr <SASLSession> createSession + (const string& serviceName, + shared_ptr <authenticator> auth, shared_ptr <SASLMechanism> mech); + + /** Create an instance of an SASL mechanism. + * + * @param name mechanism name + * @return a new instance of the specified SASL mechanism + * @throw exceptions::no_such_mechanism if no mechanism is + * registered for the specified name + */ + shared_ptr <SASLMechanism> createMechanism(const string& name); + + /** Suggests an SASL mechanism among a set of mechanisms + * supported by the server. + * + * @param mechs list of mechanisms + * @return suggested mechanism (usually the safest mechanism + * supported by both the client and the server) + */ + shared_ptr <SASLMechanism> suggestMechanism + (const std::vector <shared_ptr <SASLMechanism> >& mechs); + + /** Helper function for decoding Base64-encoded challenge. + * + * @param input input buffer + * @param output output buffer + * @param outputLen length of output buffer + */ + void decodeB64(const string& input, byte_t** output, size_t* outputLen); + + /** Helper function for encoding challenge in Base64. + * + * @param input input buffer + * @param inputLen length of input buffer + * @return Base64-encoded challenge + */ + const string encodeB64(const byte_t* input, const size_t inputLen); + +private: + + static const string getErrorMessage(const string& fname, const int code); + + +#ifdef GSASL_VERSION + Gsasl* m_gsaslContext; +#else + void* m_gsaslContext; +#endif // GSASL_VERSION + +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED + diff --git a/src/vmime/security/sasl/SASLMechanism.hpp b/src/vmime/security/sasl/SASLMechanism.hpp new file mode 100644 index 00000000..5492e48c --- /dev/null +++ b/src/vmime/security/sasl/SASLMechanism.hpp @@ -0,0 +1,131 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLSession; + + +/** An SASL mechanism. + */ +class VMIME_EXPORT SASLMechanism : public object +{ +public: + + /** Return the name of this mechanism. + * + * @return mechanism name + */ + virtual const string getName() const = 0; + + /** Perform one step of SASL authentication. Accept data from the + * server (challenge), process it and return data to be returned + * in response to the server. + * + * @param sess SASL session + * @param challenge challenge sent from the server + * @param challengeLen length of challenge + * @param response response to send to the server (allocated by + * this function, free with delete[]) + * @param responseLen length of response buffer + * @return true if authentication terminated successfully, or + * false if the authentication process should continue + * @throw exceptions::sasl_exception if an error occured during + * authentication (in this case, the values in 'response' and + * 'responseLen' are undetermined) + */ + virtual bool step + (shared_ptr <SASLSession> sess, + const byte_t* challenge, const size_t challengeLen, + byte_t** response, size_t* responseLen) = 0; + + /** Check whether authentication has completed. If false, more + * calls to evaluateChallenge() are needed to complete the + * authentication process). + * + * @return true if the authentication has finished, or false + * otherwise + */ + virtual bool isComplete() const = 0; + + /** Encode data according to negotiated SASL mechanism. This + * might mean that data is integrity or privacy protected. + * + * @param sess SASL session + * @param input input buffer + * @param inputLen length of input buffer + * @param output output buffer (allocated bu the function, + * free with delete[]) + * @param outputLen length of output buffer + * @throw exceptions::sasl_exception if an error occured during + * the encoding of data (in this case, the values in 'output' and + * 'outputLen' are undetermined) + */ + virtual void encode(shared_ptr <SASLSession> sess, + const byte_t* input, const size_t inputLen, + byte_t** output, size_t* outputLen) = 0; + + /** Decode data according to negotiated SASL mechanism. This + * might mean that data is integrity or privacy protected. + * + * @param sess SASL session + * @param input input buffer + * @param inputLen length of input buffer + * @param output output buffer (allocated bu the function, + * free with delete[]) + * @param outputLen length of output buffer + * @throw exceptions::sasl_exception if an error occured during + * the encoding of data (in this case, the values in 'output' and + * 'outputLen' are undetermined) + */ + virtual void decode(shared_ptr <SASLSession> sess, + const byte_t* input, const size_t inputLen, + byte_t** output, size_t* outputLen) = 0; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED + diff --git a/src/security/sasl/SASLMechanismFactory.cpp b/src/vmime/security/sasl/SASLMechanismFactory.cpp index 255a13f1..255a13f1 100644 --- a/src/security/sasl/SASLMechanismFactory.cpp +++ b/src/vmime/security/sasl/SASLMechanismFactory.cpp diff --git a/src/vmime/security/sasl/SASLMechanismFactory.hpp b/src/vmime/security/sasl/SASLMechanismFactory.hpp new file mode 100644 index 00000000..3503f71b --- /dev/null +++ b/src/vmime/security/sasl/SASLMechanismFactory.hpp @@ -0,0 +1,143 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" + +#include "vmime/security/sasl/SASLMechanism.hpp" + +#include <map> + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLContext; + + +/** Constructs SASL mechanism objects. + */ +class VMIME_EXPORT SASLMechanismFactory : public object +{ +private: + + SASLMechanismFactory(); + ~SASLMechanismFactory(); + + + class registeredMechanism : public object + { + public: + + virtual shared_ptr <SASLMechanism> create + (shared_ptr <SASLContext> ctx, const string& name) = 0; + }; + + template <typename T> + class registeredMechanismImpl : public registeredMechanism + { + public: + + shared_ptr <SASLMechanism> create(shared_ptr <SASLContext> ctx, const string& name) + { + return vmime::make_shared <T>(ctx, name); + } + }; + + typedef std::map <string, shared_ptr <registeredMechanism> > MapType; + MapType m_mechs; + +public: + + static SASLMechanismFactory* getInstance(); + + /** Register a mechanism into this factory, so that subsequent + * calls to create return a valid object for this mechanism. + * + * @param name mechanism name + */ + template <typename MECH_CLASS> + void registerMechanism(const string& name) + { + m_mechs.insert(MapType::value_type(name, + vmime::make_shared <registeredMechanismImpl <MECH_CLASS> >())); + } + + /** Create a mechanism object given its name. + * + * @param ctx SASL context + * @param name mechanism name + * @return a new mechanism object + * @throw exceptions::no_such_mechanism if no mechanism is + * registered for the specified name + */ + shared_ptr <SASLMechanism> create(shared_ptr <SASLContext> ctx, const string& name); + + /** Return a list of supported mechanisms. This includes mechanisms + * registered using registerMechanism() as well as the ones that + * are built-in. + * + * @return list of supported mechanisms + */ + const std::vector <string> getSupportedMechanisms() const; + + /** Test whether an authentication mechanism is supported. + * + * @param name mechanism name + * @return true if the specified mechanism is supported, + * false otherwise + */ + bool isMechanismSupported(const string& name) const; + +private: + +#ifdef GSASL_VERSION + Gsasl* m_gsaslContext; +#else + void* m_gsaslContext; +#endif // GSASL_VERSION + +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED + diff --git a/src/security/sasl/SASLSession.cpp b/src/vmime/security/sasl/SASLSession.cpp index 087ef27b..087ef27b 100644 --- a/src/security/sasl/SASLSession.cpp +++ b/src/vmime/security/sasl/SASLSession.cpp diff --git a/src/vmime/security/sasl/SASLSession.hpp b/src/vmime/security/sasl/SASLSession.hpp new file mode 100644 index 00000000..ccf181cb --- /dev/null +++ b/src/vmime/security/sasl/SASLSession.hpp @@ -0,0 +1,162 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/security/sasl/SASLAuthenticator.hpp" +#include "vmime/security/sasl/SASLMechanism.hpp" +#include "vmime/security/sasl/SASLSocket.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLContext; + + +/** An SASL client session. + */ +class VMIME_EXPORT SASLSession : public object +{ + friend class builtinSASLMechanism; + friend class SASLSocket; + +public: + + ~SASLSession(); + + /** Construct a new SASL session. + * + * @param serviceName name of the service using this session + * @param ctx SASL context + * @param auth authenticator to use for this session + * @param mech SASL mechanism + */ + SASLSession(const string& serviceName, shared_ptr <SASLContext> ctx, + shared_ptr <authenticator> auth, shared_ptr <SASLMechanism> mech); + + /** Initialize this SASL session. This must be called before + * calling any other method on this object (except accessors). + */ + void init(); + + /** Return the authenticator used for this session. This is the + * authenticator which has been previously set with a call to + * setAuthenticator(). + * + * @return authenticator object + */ + shared_ptr <authenticator> getAuthenticator(); + + /** Return the mechanism used for this session. + * + * @return SASL mechanism + */ + shared_ptr <SASLMechanism> getMechanism(); + + /** Return the SASL context. + * + * @return SASL context + */ + shared_ptr <SASLContext> getContext(); + + /** Perform one step of SASL authentication. Accept data from the + * server (challenge), process it and return data to be returned + * in response to the server. + * + * @param challenge challenge sent from the server + * @param challengeLen length of challenge + * @param response response to send to the server (allocated by + * this function, free with delete[]) + * @param responseLen length of response buffer + * @return true if authentication terminated successfully, or + * false if the authentication process should continue + * @throw exceptions::sasl_exception if an error occured during + * authentication (in this case, the values in 'response' and + * 'responseLen' are undetermined) + */ + bool evaluateChallenge + (const byte_t* challenge, const size_t challengeLen, + byte_t** response, size_t* responseLen); + + /** Return a socket in which transmitted data is integrity + * and/or privacy protected, depending on the QOP (Quality of + * Protection) negotiated during the SASL authentication. + * + * @param sok socket to wrap + * @return secured socket + */ + shared_ptr <net::socket> getSecuredSocket(shared_ptr <net::socket> sok); + + /** Return the name of the service which is using this + * SASL session (eg. "imap"). This value should be returned + * by the authenticator when INFO_SERVICE is requested. + * + * @return service name + */ + const string getServiceName() const; + +private: + + const string m_serviceName; + + shared_ptr <SASLContext> m_context; + shared_ptr <authenticator> m_auth; + shared_ptr <SASLMechanism> m_mech; + +#ifdef GSASL_VERSION + Gsasl* m_gsaslContext; + Gsasl_session* m_gsaslSession; + + static int gsaslCallback(Gsasl* ctx, Gsasl_session* sctx, Gsasl_property prop); +#else + void* m_gsaslContext; + void* m_gsaslSession; + + static int gsaslCallback(void* ctx, void* sctx, int prop); +#endif // GSASL_VERSION + +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED + diff --git a/src/security/sasl/SASLSocket.cpp b/src/vmime/security/sasl/SASLSocket.cpp index 12d634c2..12d634c2 100644 --- a/src/security/sasl/SASLSocket.cpp +++ b/src/vmime/security/sasl/SASLSocket.cpp diff --git a/src/vmime/security/sasl/SASLSocket.hpp b/src/vmime/security/sasl/SASLSocket.hpp new file mode 100644 index 00000000..e52911b4 --- /dev/null +++ b/src/vmime/security/sasl/SASLSocket.hpp @@ -0,0 +1,97 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/net/socket.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLSession; + + +/** A socket which provides data integrity and/or privacy protection. + */ +class VMIME_EXPORT SASLSocket : public net::socket +{ +public: + + SASLSocket(shared_ptr <SASLSession> sess, shared_ptr <net::socket> wrapped); + ~SASLSocket(); + + void connect(const string& address, const port_t port); + void disconnect(); + + bool isConnected() const; + + void receive(string& buffer); + size_t receiveRaw(byte_t* buffer, const size_t count); + + void send(const string& buffer); + void send(const char* str); + void sendRaw(const byte_t* buffer, const size_t count); + size_t sendRawNonBlocking(const byte_t* buffer, const size_t count); + + size_t getBlockSize() const; + + unsigned int getStatus() const; + + const string getPeerName() const; + const string getPeerAddress() const; + +private: + + shared_ptr <SASLSession> m_session; + shared_ptr <net::socket> m_wrapped; + + byte_t* m_pendingBuffer; + size_t m_pendingPos; + size_t m_pendingLen; + + byte_t m_recvBuffer[65536]; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED + diff --git a/src/security/sasl/builtinSASLMechanism.cpp b/src/vmime/security/sasl/builtinSASLMechanism.cpp index e179e715..e179e715 100644 --- a/src/security/sasl/builtinSASLMechanism.cpp +++ b/src/vmime/security/sasl/builtinSASLMechanism.cpp diff --git a/src/vmime/security/sasl/builtinSASLMechanism.hpp b/src/vmime/security/sasl/builtinSASLMechanism.hpp new file mode 100644 index 00000000..09b46f00 --- /dev/null +++ b/src/vmime/security/sasl/builtinSASLMechanism.hpp @@ -0,0 +1,93 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED +#define VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/security/sasl/SASLMechanism.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLContext; + + +/** A built-in authentication mechanism that relies on + * the GNU SASL library. + */ +class VMIME_EXPORT builtinSASLMechanism : public SASLMechanism +{ +public: + + builtinSASLMechanism(shared_ptr <SASLContext> ctx, const string& name); + ~builtinSASLMechanism(); + + + const string getName() const; + + bool step(shared_ptr <SASLSession> sess, + const byte_t* challenge, const size_t challengeLen, + byte_t** response, size_t* responseLen); + + bool isComplete() const; + + void encode(shared_ptr <SASLSession> sess, + const byte_t* input, const size_t inputLen, + byte_t** output, size_t* outputLen); + + void decode(shared_ptr <SASLSession> sess, + const byte_t* input, const size_t inputLen, + byte_t** output, size_t* outputLen); + +private: + + /** SASL context */ + shared_ptr <SASLContext> m_context; + + /** Mechanism name */ + const string m_name; + + /** Authentication process status. */ + bool m_complete; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED + diff --git a/src/security/sasl/defaultSASLAuthenticator.cpp b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp index 7fe9b3eb..7fe9b3eb 100644 --- a/src/security/sasl/defaultSASLAuthenticator.cpp +++ b/src/vmime/security/sasl/defaultSASLAuthenticator.cpp diff --git a/src/vmime/security/sasl/defaultSASLAuthenticator.hpp b/src/vmime/security/sasl/defaultSASLAuthenticator.hpp new file mode 100644 index 00000000..6ea9af80 --- /dev/null +++ b/src/vmime/security/sasl/defaultSASLAuthenticator.hpp @@ -0,0 +1,90 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/security/sasl/SASLAuthenticator.hpp" +#include "vmime/security/defaultAuthenticator.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +/** An authenticator that is capable of providing information + * for simple authentication mechanisms (username and password). + */ +class VMIME_EXPORT defaultSASLAuthenticator : public SASLAuthenticator +{ +public: + + defaultSASLAuthenticator(); + ~defaultSASLAuthenticator(); + + const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms + (const std::vector <shared_ptr <SASLMechanism> >& available, + shared_ptr <SASLMechanism> suggested) const; + + const string getUsername() const; + const string getPassword() const; + const string getHostname() const; + const string getAnonymousToken() const; + const string getServiceName() const; + + void setService(shared_ptr <net::service> serv); + weak_ptr <net::service> getService() const; + + void setSASLSession(shared_ptr <SASLSession> sess); + shared_ptr <SASLSession> getSASLSession() const; + + void setSASLMechanism(shared_ptr <SASLMechanism> mech); + shared_ptr <SASLMechanism> getSASLMechanism() const; + +private: + + defaultAuthenticator m_default; + + weak_ptr <net::service> m_service; + weak_ptr <SASLSession> m_saslSession; + shared_ptr <SASLMechanism> m_saslMech; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED + diff --git a/src/streamContentHandler.cpp b/src/vmime/streamContentHandler.cpp index 8676cc34..8676cc34 100644 --- a/src/streamContentHandler.cpp +++ b/src/vmime/streamContentHandler.cpp diff --git a/src/vmime/streamContentHandler.hpp b/src/vmime/streamContentHandler.hpp new file mode 100644 index 00000000..9b72c073 --- /dev/null +++ b/src/vmime/streamContentHandler.hpp @@ -0,0 +1,122 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_STREAMCONTENTHANDLER_HPP_INCLUDED +#define VMIME_STREAMCONTENTHANDLER_HPP_INCLUDED + + +#include "vmime/contentHandler.hpp" + + +namespace vmime +{ + + +/** A content handler which obtains its data from a stream. + */ + +class VMIME_EXPORT streamContentHandler : public contentHandler +{ +public: + + /** Creates a new empty content handler. No data can be extracted until + * an input stream is set using setData() function. + * + * @return a reference to a new content handler + */ + streamContentHandler(); + + /** Creates a new content handler using an input stream. + * + * @param is input stream from which data will be obtained + * @param length expected stream length. May be zero, but it is highly + * recommended to set this parameter to take part of some optimizations + * and features (eg. SMTP CHUNKING/SIZE extension). + * @param enc set to anything other than NO_ENCODING if the data obtained + * from the stream is already encoded with the specified encoding + * + * @return a reference to a new content handler + */ + streamContentHandler + (shared_ptr <utility::inputStream> is, + const size_t length, + const vmime::encoding& enc = NO_ENCODING); + + ~streamContentHandler(); + + streamContentHandler(const streamContentHandler& cts); + streamContentHandler& operator=(const streamContentHandler& cts); + + shared_ptr <contentHandler> clone() const; + + /** Sets the data managed by this content handler. + * + * @param is input stream from which data will be obtained + * @param length expected stream length. May be zero, but it is highly + * recommended to set this parameter to take part of some optimizations + * and features (eg. SMTP CHUNKING/SIZE extension). + * @param enc set to anything other than NO_ENCODING if the data obtained + * from the stream is already encoded with the specified encoding + */ + void setData + (shared_ptr <utility::inputStream> is, + const size_t length, + const vmime::encoding& enc = NO_ENCODING); + + + void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + + void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; + + size_t getLength() const; + + bool isEncoded() const; + + const vmime::encoding& getEncoding() const; + + bool isEmpty() const; + + bool isBuffered() const; + + void setContentTypeHint(const mediaType& type); + const mediaType getContentTypeHint() const; + +private: + + mediaType m_contentType; + + // Equals to NO_ENCODING if data is not encoded, otherwise this + // specifies the encoding that have been used to encode the data. + vmime::encoding m_encoding; + + // Actual data + mutable shared_ptr <utility::inputStream> m_stream; + size_t m_length; +}; + + +} // vmime + + +#endif // VMIME_STREAMCONTENTHANDLER_HPP_INCLUDED diff --git a/src/stringContentHandler.cpp b/src/vmime/stringContentHandler.cpp index 9a66663c..9a66663c 100644 --- a/src/stringContentHandler.cpp +++ b/src/vmime/stringContentHandler.cpp diff --git a/src/vmime/stringContentHandler.hpp b/src/vmime/stringContentHandler.hpp new file mode 100644 index 00000000..e9d34405 --- /dev/null +++ b/src/vmime/stringContentHandler.hpp @@ -0,0 +1,101 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_STRINGCONTENTHANDLER_HPP_INCLUDED +#define VMIME_STRINGCONTENTHANDLER_HPP_INCLUDED + + +#include "vmime/contentHandler.hpp" + + +namespace vmime +{ + + +class VMIME_EXPORT stringContentHandler : public contentHandler +{ +public: + + stringContentHandler(); + stringContentHandler(const string& buffer, const vmime::encoding& enc = NO_ENCODING); + stringContentHandler(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING); + stringContentHandler(const string& buffer, const size_t start, const size_t end, const vmime::encoding& enc = NO_ENCODING); + + ~stringContentHandler(); + + stringContentHandler(const stringContentHandler& cts); + stringContentHandler& operator=(const stringContentHandler& cts); + + shared_ptr <contentHandler> clone() const; + + // Set the data contained in the body. + // + // The two first functions take advantage of the COW (copy-on-write) system that + // might be implemented into std::string. This is done using "stringProxy" object. + // + // Set "enc" parameter to anything other than NO_ENCODING if the data managed by + // this content handler is already encoded with the specified encoding (so, no + // encoding/decoding will be performed on generate()/extract()). Note that the + // data may be re-encoded (that is, decoded and encoded) if the encoding passed + // to generate() is different from this one... + void setData(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING); + void setData(const string& buffer, const vmime::encoding& enc = NO_ENCODING); + void setData(const string& buffer, const size_t start, const size_t end, const vmime::encoding& enc = NO_ENCODING); + + stringContentHandler& operator=(const string& buffer); + + void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const; + + void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const; + void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const; + + size_t getLength() const; + + bool isEncoded() const; + + const vmime::encoding& getEncoding() const; + + bool isEmpty() const; + + bool isBuffered() const; + + void setContentTypeHint(const mediaType& type); + const mediaType getContentTypeHint() const; + +private: + + mediaType m_contentType; + + // Equals to NO_ENCODING if data is not encoded, otherwise this + // specifies the encoding that have been used to encode the data. + vmime::encoding m_encoding; + + // The actual data + utility::stringProxy m_string; +}; + + +} // vmime + + +#endif // VMIME_STRINGCONTENTHANDLER_HPP_INCLUDED diff --git a/src/text.cpp b/src/vmime/text.cpp index 08fc9ba9..08fc9ba9 100644 --- a/src/text.cpp +++ b/src/vmime/text.cpp diff --git a/src/vmime/text.hpp b/src/vmime/text.hpp new file mode 100644 index 00000000..b7e25669 --- /dev/null +++ b/src/vmime/text.hpp @@ -0,0 +1,277 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_TEXT_HPP_INCLUDED +#define VMIME_TEXT_HPP_INCLUDED + + +#include "vmime/headerFieldValue.hpp" +#include "vmime/base.hpp" +#include "vmime/word.hpp" + + +namespace vmime +{ + + +/** List of encoded-words, as defined in RFC-2047 (basic type). + */ + +class VMIME_EXPORT text : public headerFieldValue +{ +public: + + text(); + text(const text& t); + text(const string& t, const charset& ch); + explicit text(const string& t); + explicit text(const word& w); + ~text(); + +public: + + bool operator==(const text& t) const; + bool operator!=(const text& t) const; + + shared_ptr <component> clone() const; + void copyFrom(const component& other); + text& operator=(const component& other); + text& operator=(const text& other); + + const std::vector <shared_ptr <component> > getChildComponents(); + + /** Add a word at the end of the list. + * + * @param w word to append + */ + void appendWord(shared_ptr <word> w); + + /** Insert a new word before the specified position. + * + * @param pos position at which to insert the new word (0 to insert at + * the beginning of the list) + * @param w word to insert + */ + void insertWordBefore(const size_t pos, shared_ptr <word> w); + + /** Insert a new word after the specified position. + * + * @param pos position of the word before the new word + * @param w word to insert + */ + void insertWordAfter(const size_t pos, shared_ptr <word> w); + + /** Remove the word at the specified position. + * + * @param pos position of the word to remove + */ + void removeWord(const size_t pos); + + /** Remove all words from the list. + */ + void removeAllWords(); + + /** Return the number of words in the list. + * + * @return number of words + */ + size_t getWordCount() const; + + /** Tests whether the list of words is empty. + * + * @return true if there is no word, false otherwise + */ + bool isEmpty() const; + + /** Return the word at the specified position. + * + * @param pos position + * @return word at position 'pos' + */ + const shared_ptr <word> getWordAt(const size_t pos); + + /** Return the word at the specified position. + * + * @param pos position + * @return word at position 'pos' + */ + const shared_ptr <const word> getWordAt(const size_t pos) const; + + /** Return the word list. + * + * @return list of words + */ + const std::vector <shared_ptr <const word> > getWordList() const; + + /** Return the word list. + * + * @return list of words + */ + const std::vector <shared_ptr <word> > getWordList(); + + + /** Return the text converted into the specified charset. + * The encoded-words are decoded and then converted in the + * specified destination charset. + * + * @param dest output charset + * @param opts options for charset conversion + * @return text decoded in the specified charset + */ + const string getConvertedText(const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()) const; + + /** Return the unconverted (raw) data of all words. This is the + * concatenation of the results returned by getBuffer() on + * the contained words. + * + * @return raw data + */ + const string getWholeBuffer() const; + + /** This function can be used to make several encoded words from a text. + * All the characters in the text must be in the same specified charset. + * + * <p>Eg: giving:</p> + * <pre> <iso-8859-1> "Linux dans un t'el'ephone mobile" + * ("=?iso-8859-1?Q?Linux_dans_un_t=E9l=E9phone_mobile?=") + * </pre><p>it will return:</p> + * <pre> <us-ascii> "Linux dans un " + * <iso-8859-1> "t'el'ephone " + * <us-ascii> "mobile" + * ("Linux dans un =?iso-8859-1?Q?t=E9l=E9phone_?= mobile") + * </pre> + * + * @param in input string + * @param ch input charset + * @return new text object + */ + static shared_ptr <text> newFromString(const string& in, const charset& ch); + + /** This function can be used to make several encoded words from a text. + * All the characters in the text must be in the same specified charset. + * + * <p>Eg: giving:</p> + * <pre> <iso-8859-1> "Linux dans un t'el'ephone mobile" + * ("=?iso-8859-1?Q?Linux_dans_un_t=E9l=E9phone_mobile?=") + * </pre><p>it will return:</p> + * <pre> <us-ascii> "Linux dans un " + * <iso-8859-1> "t'el'ephone " + * <us-ascii> "mobile" + * ("Linux dans un =?iso-8859-1?Q?t=E9l=E9phone_?= mobile") + * </pre> + * + * @param in input string + * @param ch input charset + */ + void createFromString(const string& in, const charset& ch); + + /** Flags used by "encodeAndFold" function. + */ + enum EncodeAndFoldFlags + { + // NOTE: If both "FORCE_NO_ENCODING" and "FORCE_ENCODING" are + // specified, "FORCE_NO_ENCODING" is used by default. + + FORCE_NO_ENCODING = (1 << 0), /**< Just fold lines, don't encode them. */ + FORCE_ENCODING = (1 << 1), /**< Encode lines even if they are plain ASCII text. */ + NO_NEW_LINE_SEQUENCE = (1 << 2), /**< Use CRLF instead of new-line sequence (CRLF + TAB). */ + QUOTE_IF_POSSIBLE = (1 << 3), /**< Use quoting instead of encoding when possible (even if FORCE_ENCODING is specified). */ + QUOTE_IF_NEEDED = (1 << 4) /**< Use quoting instead of encoding if needed (eg. whitespaces and/or special chars). */ + }; + + /** Encode and fold text in respect to RFC-2047. + * + * @param ctx generation context + * @param os output stream + * @param firstLineOffset the first line length (may be useful if the current output line is not empty) + * @param lastLineLength will receive the length of the last line written + * @param flags encoding flags (see EncodeAndFoldFlags) + */ + void encodeAndFold(const generationContext& ctx, utility::outputStream& os, + const size_t firstLineOffset, size_t* lastLineLength, const int flags) const; + + /** Decode and unfold text (RFC-2047), using the default parsing context. + * + * @param in input string + * @return new text object + */ + static shared_ptr <text> decodeAndUnfold(const string& in); + + /** Decode and unfold text (RFC-2047). + * + * @param ctx parsingContext + * @param in input string + * @return new text object + */ + static shared_ptr <text> decodeAndUnfold(const parsingContext& ctx, const string& in); + + /** Decode and unfold text (RFC-2047), using the default parsing context. + * + * @param in input string + * @param generateInExisting if not NULL, the resulting text will be generated + * in the specified object instead of a new created object (in this case, the + * function returns the same pointer). Can be used to avoid copying the + * resulting object into an existing object. + * @return new text object or existing object if generateInExisting != NULL + */ + static text* decodeAndUnfold(const string& in, text* generateInExisting); + + /** Decode and unfold text (RFC-2047). + * + * @param ctx parsing context + * @param in input string + * @param generateInExisting if not NULL, the resulting text will be generated + * in the specified object instead of a new created object (in this case, the + * function returns the same pointer). Can be used to avoid copying the + * resulting object into an existing object. + * @return new text object or existing object if generateInExisting != NULL + */ + static text* decodeAndUnfold(const parsingContext& ctx, const string& in, text* generateInExisting); + +protected: + + // Component parsing & assembling + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; + +private: + + std::vector <shared_ptr <word> > m_words; +}; + + +} // vmime + + +#endif // VMIME_TEXT_HPP_INCLUDED diff --git a/src/vmime/textPart.hpp b/src/vmime/textPart.hpp new file mode 100644 index 00000000..6348f8d7 --- /dev/null +++ b/src/vmime/textPart.hpp @@ -0,0 +1,112 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_TEXTPART_HPP_INCLUDED +#define VMIME_TEXTPART_HPP_INCLUDED + + +#include "vmime/bodyPart.hpp" + +#include "vmime/mediaType.hpp" +#include "vmime/charset.hpp" +#include "vmime/contentHandler.hpp" + + +namespace vmime +{ + + +/** Generic text part. + */ + +class VMIME_EXPORT textPart : public object +{ + friend class textPartFactory; + friend class messageBuilder; // for generateIn, getPartCount + friend class messageParser; // for parse + +public: + + virtual ~textPart() { } + + /** Return the type of text part (eg: "text/html"). + * + * @return type of text part + */ + virtual const mediaType getType() const = 0; + + /** Return the charset used to encode text in the + * text part. + * + * @return text charset + */ + virtual const charset& getCharset() const = 0; + + /** Set the charset used to encode text in the + * text part. + * + * @param ch text charset + */ + virtual void setCharset(const charset& ch) = 0; + + /** Return the text contained in the part. + * + * @return text of the part + */ + virtual const shared_ptr <const contentHandler> getText() const = 0; + + /** Set the text contained in the part. + * + * @param text text of the part + */ + virtual void setText(shared_ptr <contentHandler> text) = 0; + + /** Return the actual body parts this text part is composed of. + * For example, HTML parts are composed of two parts: one "text/html" + * part, and the plain text part "text/plain". + * + * @return number of body parts + */ + virtual size_t getPartCount() const = 0; + + /** Generate the text part(s) into the specified message. + * + * @param message the message + * @param parent body part into which generate this part + */ + virtual void generateIn(shared_ptr <bodyPart> message, shared_ptr <bodyPart> parent) const = 0; + + /** Parse the text part(s) from the specified message. + * + * @param message message containing the text part + * @param parent part containing the text part + * @param textPart actual text part + */ + virtual void parse(shared_ptr <const bodyPart> message, shared_ptr <const bodyPart> parent, shared_ptr <const bodyPart> textPart) = 0; +}; + + +} // vmime + + +#endif // VMIME_TEXTPART_HPP_INCLUDED diff --git a/src/textPartFactory.cpp b/src/vmime/textPartFactory.cpp index 85fea6e4..85fea6e4 100644 --- a/src/textPartFactory.cpp +++ b/src/vmime/textPartFactory.cpp diff --git a/src/vmime/textPartFactory.hpp b/src/vmime/textPartFactory.hpp new file mode 100644 index 00000000..f5ce3774 --- /dev/null +++ b/src/vmime/textPartFactory.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_TEXTPARTFACTORY_HPP_INCLUDED +#define VMIME_TEXTPARTFACTORY_HPP_INCLUDED + + +#include "vmime/textPart.hpp" +#include "vmime/mediaType.hpp" + + +namespace vmime +{ + + +class VMIME_EXPORT textPartFactory +{ +protected: + + textPartFactory(); + ~textPartFactory(); + + typedef shared_ptr <textPart> (*AllocFunc)(void); + typedef std::vector <std::pair <mediaType, AllocFunc> > MapType; + + MapType m_map; + +#ifndef VMIME_BUILDING_DOC + template <class TYPE> + class registerer + { + public: + + static shared_ptr <textPart> creator() + { + // Allocate a new object + return vmime::make_shared <TYPE>(); + } + }; +#endif // VMIME_BUILDING_DOC + +public: + + static textPartFactory* getInstance(); + + template <class T> + void registerType(const mediaType& type) + { + m_map.push_back(MapType::value_type(type, ®isterer<T>::creator)); + } + + shared_ptr <textPart> create(const mediaType& type); +}; + + +} // vmime + + +#endif // VMIME_TEXTPARTFACTORY_HPP_INCLUDED diff --git a/src/vmime/types.hpp b/src/vmime/types.hpp new file mode 100644 index 00000000..12e5bf71 --- /dev/null +++ b/src/vmime/types.hpp @@ -0,0 +1,115 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_TYPES_HPP_INCLUDED +#define VMIME_TYPES_HPP_INCLUDED + + +#include <limits> +#include <string> +#include <vector> +#include <stdexcept> +#include <cstddef> +#include <utility> + +#include "vmime/config.hpp" + + +#ifndef VMIME_BUILDING_DOC + +#if VMIME_SHARED_PTR_USE_CXX + // If we are compiling with C++11, use shared_ptr<> from the standard lib + #include <memory> + + #define VMIME_SHARED_PTR_NAMESPACE std +#elif VMIME_SHARED_PTR_USE_BOOST + // Else, use boost's shared_ptr<> + #include <boost/shared_ptr.hpp> + #include <boost/weak_ptr.hpp> + #include <boost/make_shared.hpp> + #include <boost/enable_shared_from_this.hpp> + #include <boost/shared_ptr.hpp> + + #define VMIME_SHARED_PTR_NAMESPACE boost +#else + #error Either VMIME_SHAREDPTR_USE_CXX or VMIME_SHAREDPTR_USE_BOOST must be set to ON +#endif + +namespace vmime +{ + using VMIME_SHARED_PTR_NAMESPACE::shared_ptr; + using VMIME_SHARED_PTR_NAMESPACE::weak_ptr; + using VMIME_SHARED_PTR_NAMESPACE::make_shared; + using VMIME_SHARED_PTR_NAMESPACE::enable_shared_from_this; + using VMIME_SHARED_PTR_NAMESPACE::dynamic_pointer_cast; + using VMIME_SHARED_PTR_NAMESPACE::const_pointer_cast; + + /** Custom deleter to be used with shared_ptr. + * This is does not actually delete the pointer, and is used + * only for the singleton classes allocated on the stack. + */ + template <typename T> + struct noop_shared_ptr_deleter + { + void operator()(T*) const {} + }; +} + +#undef VMIME_SHARED_PTR_NAMESPACE + +#endif // VMIME_BUILDING_DOC + + +namespace vmime +{ + typedef std::string string; + + typedef unsigned short port_t; + + typedef int char_t; + + typedef vmime_uint8 byte_t; + typedef std::vector <byte_t> byteArray; + + typedef std::size_t size_t; + + // For compatibility with versions <= 0.7.1 (deprecated) + namespace net { } + namespace messaging = net; + + // For (minimal) compatibility with legacy smart pointers (<= 0.9.1) + // Your compiler must have support for C++11 +#if VMIME_COMPAT_LEGACY_SMART_POINTERS + template <typename T> using ref = shared_ptr <T>; + class creator {}; // unused + template <typename T, typename... Args> + inline shared_ptr <T> create(Args&&... args) { return make_shared <T>(args...); } +#endif + +} + + +#include "vmime/object.hpp" + + +#endif // VMIME_TYPES_HPP_INCLUDED diff --git a/src/vmime/utility/childProcess.hpp b/src/vmime/utility/childProcess.hpp new file mode 100644 index 00000000..ebefcf0a --- /dev/null +++ b/src/vmime/utility/childProcess.hpp @@ -0,0 +1,107 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_CHILDPROCESS_HPP_INCLUDED +#define VMIME_UTILITY_CHILDPROCESS_HPP_INCLUDED + + +#include "vmime/utility/stream.hpp" +#include "vmime/utility/file.hpp" + +#include <vector> + + +namespace vmime { +namespace utility { + + +/** Spawn a process and redirect its standard input + * and/or standard output. + */ + +class VMIME_EXPORT childProcess : public object +{ +public: + + virtual ~childProcess() { } + + /** Flags used with start(). */ + enum Flags + { + FLAG_REDIRECT_STDIN = (1 << 0), + FLAG_REDIRECT_STDOUT = (1 << 1) + }; + + /** Start the child process. + * + * @param args list of arguments + * @param flags one or more childProcess::Flags + * @throws exceptions::system_error if the an error occurs + * before the process can be started + */ + virtual void start(const std::vector <string> args, const int flags = 0) = 0; + + /** Return a wrapper to the child process standard input. + * + * @return output stream wrapper for child's stdin + */ + virtual shared_ptr <utility::outputStream> getStdIn() = 0; + + /** Return a wrapper to the child process standard output. + * + * @return input stream wrapper for child's stdout + */ + virtual shared_ptr <utility::inputStream> getStdOut() = 0; + + /** Wait for the process to finish. + * + * @throws exceptions::system_error if the process does + * not exit normally + */ + virtual void waitForFinish() = 0; +}; + + +/** Create 'childProcess' objects. + */ + +class childProcessFactory : public object +{ +public: + + virtual ~childProcessFactory() { } + + /** Create a new child process. + * + * @param path full path of the process executable file + */ + virtual shared_ptr <childProcess> create(const utility::file::path& path) const = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_CHILDPROCESS_HPP_INCLUDED + diff --git a/src/utility/datetimeUtils.cpp b/src/vmime/utility/datetimeUtils.cpp index 2b55177e..2b55177e 100644 --- a/src/utility/datetimeUtils.cpp +++ b/src/vmime/utility/datetimeUtils.cpp diff --git a/src/vmime/utility/datetimeUtils.hpp b/src/vmime/utility/datetimeUtils.hpp new file mode 100644 index 00000000..a7291bb8 --- /dev/null +++ b/src/vmime/utility/datetimeUtils.hpp @@ -0,0 +1,99 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_DATETIMEUTILS_HPP_INCLUDED +#define VMIME_DATETIMEUTILS_HPP_INCLUDED + + +#include "vmime/dateTime.hpp" + + +namespace vmime { +namespace utility { + + +/** Miscellaneous functions related to date/time. + */ + +class VMIME_EXPORT datetimeUtils +{ +public: + + /** Test whether the specified year is a leap year. + * + * @param year year in 4-digit format + * @return true if year is a leap year, false otherwise + */ + static bool isLeapYear(const int year); + + /** Return the number of days in the specified month. + * + * @param year year in 4-digit format (this is needed to check + * for leap years) + * @param month month, January is 1, December is 12 (see datetime::Months enum) + * @return the number of days in the month + */ + static int getDaysInMonth(const int year, const int month); + + /** Convert the specified date/time to UT (GMT). + * + * @param date date/time to convert + * @return GMT date/time + */ + static const datetime toUniversalTime(const datetime& date); + + /** Convert the specified date/time to the specified time zone. + * + * @param date date/time to convert + * @param zone local zone to convert to (see datetime::TimeZones enum) + * @return local time and date + */ + static const datetime toLocalTime(const datetime& date, const int zone); + + /** Return the day of the week from the specified date. + * + * @param year year in 4-digit format + * @param month month (1-12), January is 1, December is 12 (see datetime::Months enum) + * @param day month day (1-31) + * @return the day of the week, Sunday is 0, Monday is 1 (see datetime::DaysOfWeek enum) + */ + static int getDayOfWeek(const int year, const int month, const int day); + + /** Return the week number in the year (ISO 8601). + * + * @param year year in 4-digit format + * @param month month (1-12), January is 1, December is 12 (see datetime::Months enum) + * @param day month day (1-31) + * @param iso if TRUE, use ISO week-numbering year (default is to use calendar year). + * For more information, read here: http://en.wikipedia.org/wiki/ISO_8601#Week_dates + * @return the week number (1 is the first week of the year) + */ + static int getWeekOfYear(const int year, const int month, const int day, const bool iso = false); +}; + + +} // utility +} // vmime + + +#endif // VMIME_DATETIMEUTILS_HPP_INCLUDED diff --git a/src/utility/encoder/b64Encoder.cpp b/src/vmime/utility/encoder/b64Encoder.cpp index 274c23c0..274c23c0 100644 --- a/src/utility/encoder/b64Encoder.cpp +++ b/src/vmime/utility/encoder/b64Encoder.cpp diff --git a/src/vmime/utility/encoder/b64Encoder.hpp b/src/vmime/utility/encoder/b64Encoder.hpp new file mode 100644 index 00000000..2d23d9e3 --- /dev/null +++ b/src/vmime/utility/encoder/b64Encoder.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_B64ENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_B64ENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Base64 encoder. + */ + +class VMIME_EXPORT b64Encoder : public encoder +{ +public: + + b64Encoder(); + + size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + + const std::vector <string> getAvailableProperties() const; + + size_t getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; + +protected: + + static const unsigned char sm_alphabet[]; + static const unsigned char sm_decodeMap[256]; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_B64ENCODER_HPP_INCLUDED diff --git a/src/utility/encoder/binaryEncoder.cpp b/src/vmime/utility/encoder/binaryEncoder.cpp index 7d7c40d1..7d7c40d1 100644 --- a/src/utility/encoder/binaryEncoder.cpp +++ b/src/vmime/utility/encoder/binaryEncoder.cpp diff --git a/src/vmime/utility/encoder/binaryEncoder.hpp b/src/vmime/utility/encoder/binaryEncoder.hpp new file mode 100644 index 00000000..1c831939 --- /dev/null +++ b/src/vmime/utility/encoder/binaryEncoder.hpp @@ -0,0 +1,52 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_BINARYENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_BINARYENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/noopEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Binary encoder. + */ + +class VMIME_EXPORT binaryEncoder : public noopEncoder +{ +public: + + binaryEncoder(); +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_BINARYENCODER_HPP_INCLUDED diff --git a/src/utility/encoder/eightBitEncoder.cpp b/src/vmime/utility/encoder/eightBitEncoder.cpp index 4ab07f06..4ab07f06 100644 --- a/src/utility/encoder/eightBitEncoder.cpp +++ b/src/vmime/utility/encoder/eightBitEncoder.cpp diff --git a/src/vmime/utility/encoder/eightBitEncoder.hpp b/src/vmime/utility/encoder/eightBitEncoder.hpp new file mode 100644 index 00000000..ee50ca95 --- /dev/null +++ b/src/vmime/utility/encoder/eightBitEncoder.hpp @@ -0,0 +1,52 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_EIGHTBITENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_EIGHTBITENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/noopEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** 8-bit encoder. + */ + +class VMIME_EXPORT eightBitEncoder : public noopEncoder +{ +public: + + eightBitEncoder(); +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_EIGHTBITENCODER_HPP_INCLUDED diff --git a/src/utility/encoder/encoder.cpp b/src/vmime/utility/encoder/encoder.cpp index b4b13249..b4b13249 100644 --- a/src/utility/encoder/encoder.cpp +++ b/src/vmime/utility/encoder/encoder.cpp diff --git a/src/vmime/utility/encoder/encoder.hpp b/src/vmime/utility/encoder/encoder.hpp new file mode 100644 index 00000000..34cd10b7 --- /dev/null +++ b/src/vmime/utility/encoder/encoder.hpp @@ -0,0 +1,128 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_ENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_ENCODER_HPP_INCLUDED + + +#include "vmime/base.hpp" +#include "vmime/propertySet.hpp" +#include "vmime/exception.hpp" +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Encode/decode data in different encodings. + */ + +class VMIME_EXPORT encoder : public object +{ +public: + + encoder(); + virtual ~encoder(); + + /** Encode data. + * + * @param in input data (decoded) + * @param out output stream for encoded data + * @param progress progress listener, or NULL if you do not + * want to receive progress notifications + * @return number of bytes written into output stream + */ + virtual size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL) = 0; + + /** Decode data. + * + * @param in input data (encoded) + * @param out output stream for decoded data + * @param progress progress listener, or NULL if you do not + * want to receive progress notifications + * @return number of bytes written into output stream + */ + virtual size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL) = 0; + + /** Return the properties of the encoder. + * + * @return properties of the encoder + */ + const propertySet& getProperties() const; + + /** Return the properties of the encoder. + * + * @return properties of the encoder + */ + propertySet& getProperties(); + + /** Return a list of property names that can be set for + * this encoder. + * + * @return list of property names + */ + virtual const std::vector <string> getAvailableProperties() const; + + /** Return the results returned by this encoder. + * + * @return results returned by the encoder + */ + const propertySet& getResults() const; + + /** Return the encoded size for the specified input (decoded) size. + * If the size is not exact, it may be an estimate which should always + * be larger than the actual encoded size. + * + * @param n count of input (decoded) bytes + * @return count of output (encoded) bytes + */ + virtual size_t getEncodedSize(const size_t n) const = 0; + + /** Return the encoded size for the specified input (encoded) size. + * If the size is not exact, it may be an estimate which should always + * be larger than the actual decoded size. + * + * @param n count of input (encoded) bytes + * @return count of output (decoded) bytes + */ + virtual size_t getDecodedSize(const size_t n) const = 0; + +protected: + + propertySet& getResults(); + +private: + + propertySet m_props; + propertySet m_results; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_ENCODER_HPP_INCLUDED diff --git a/src/utility/encoder/encoderFactory.cpp b/src/vmime/utility/encoder/encoderFactory.cpp index 098a810a..098a810a 100644 --- a/src/utility/encoder/encoderFactory.cpp +++ b/src/vmime/utility/encoder/encoderFactory.cpp diff --git a/src/vmime/utility/encoder/encoderFactory.hpp b/src/vmime/utility/encoder/encoderFactory.hpp new file mode 100644 index 00000000..763cbd5c --- /dev/null +++ b/src/vmime/utility/encoder/encoderFactory.hpp @@ -0,0 +1,148 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_ENCODERFACTORY_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_ENCODERFACTORY_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** A factory to create 'encoder' objects for the specified encoding. + */ + +class VMIME_EXPORT encoderFactory +{ +private: + + encoderFactory(); + ~encoderFactory(); + +public: + + static shared_ptr <encoderFactory> getInstance(); + + /** Information about a registered encoder. */ + class VMIME_EXPORT registeredEncoder : public object + { + protected: + + virtual ~registeredEncoder() { } + + public: + + virtual shared_ptr <encoder> create() const = 0; + + virtual const string& getName() const = 0; + }; + +private: + + template <class E> + class registeredEncoderImpl : public registeredEncoder + { + public: + + registeredEncoderImpl(const string& name) : m_name(name) { } + + shared_ptr <encoder> create() const + { + return vmime::make_shared <E>(); + } + + const string& getName() const + { + return (m_name); + } + + private: + + const string m_name; + }; + + + std::vector <shared_ptr <registeredEncoder> > m_encoders; + +public: + + /** Register a new encoder by its encoding name. + * + * @param name encoding name + */ + template <class E> + void registerName(const string& name) + { + m_encoders.push_back(vmime::make_shared <registeredEncoderImpl <E> >(utility::stringUtils::toLower(name))); + } + + /** Create a new encoder instance from an encoding name. + * + * @param name encoding name (eg. "base64") + * @return a new encoder instance for the specified encoding + * @throw exceptions::no_encoder_available if no encoder is registered + * for this encoding + */ + shared_ptr <encoder> create(const string& name); + + /** Return information about a registered encoder. + * + * @param name encoding name + * @return information about this encoder + * @throw exceptions::no_encoder_available if no encoder is registered + * for this encoding + */ + const shared_ptr <const registeredEncoder> getEncoderByName(const string& name) const; + + /** Return the number of registered encoders. + * + * @return number of registered encoders + */ + size_t getEncoderCount() const; + + /** Return the registered encoder at the specified position. + * + * @param pos position of the registered encoder to return + * @return registered encoder at the specified position + */ + const shared_ptr <const registeredEncoder> getEncoderAt(const size_t pos) const; + + /** Return a list of all registered encoders. + * + * @return list of registered encoders + */ + const std::vector <shared_ptr <const registeredEncoder> > getEncoderList() const; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_ENCODERFACTORY_HPP_INCLUDED diff --git a/src/utility/encoder/noopEncoder.cpp b/src/vmime/utility/encoder/noopEncoder.cpp index 3d991b5d..3d991b5d 100644 --- a/src/utility/encoder/noopEncoder.cpp +++ b/src/vmime/utility/encoder/noopEncoder.cpp diff --git a/src/vmime/utility/encoder/noopEncoder.hpp b/src/vmime/utility/encoder/noopEncoder.hpp new file mode 100644 index 00000000..6314812b --- /dev/null +++ b/src/vmime/utility/encoder/noopEncoder.hpp @@ -0,0 +1,58 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_NOOPENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_NOOPENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Default, no-op encoder (simple copy, no encoding/decoding is performed). + */ + +class VMIME_EXPORT noopEncoder : public encoder +{ +public: + + noopEncoder(); + + size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + + size_t getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_NOOPENCODER_HPP_INCLUDED diff --git a/src/utility/encoder/qpEncoder.cpp b/src/vmime/utility/encoder/qpEncoder.cpp index c77b5163..c77b5163 100644 --- a/src/utility/encoder/qpEncoder.cpp +++ b/src/vmime/utility/encoder/qpEncoder.cpp diff --git a/src/vmime/utility/encoder/qpEncoder.hpp b/src/vmime/utility/encoder/qpEncoder.hpp new file mode 100644 index 00000000..c666795b --- /dev/null +++ b/src/vmime/utility/encoder/qpEncoder.hpp @@ -0,0 +1,69 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_QPENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_QPENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** Quoted-printable encoder. + */ + +class VMIME_EXPORT qpEncoder : public encoder +{ +public: + + qpEncoder(); + + size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + + const std::vector <string> getAvailableProperties() const; + + static bool RFC2047_isEncodingNeededForChar(const unsigned char c); + static int RFC2047_getEncodedLength(const unsigned char c); + + size_t getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; + +protected: + + static const unsigned char sm_hexDigits[17]; + static const unsigned char sm_hexDecodeTable[256]; + static const unsigned char sm_RFC2047EncodeTable[128]; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_QPENCODER_HPP_INCLUDED diff --git a/src/utility/encoder/sevenBitEncoder.cpp b/src/vmime/utility/encoder/sevenBitEncoder.cpp index 7c76d73f..7c76d73f 100644 --- a/src/utility/encoder/sevenBitEncoder.cpp +++ b/src/vmime/utility/encoder/sevenBitEncoder.cpp diff --git a/src/vmime/utility/encoder/sevenBitEncoder.hpp b/src/vmime/utility/encoder/sevenBitEncoder.hpp new file mode 100644 index 00000000..d260cc7b --- /dev/null +++ b/src/vmime/utility/encoder/sevenBitEncoder.hpp @@ -0,0 +1,52 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_SEVENBITENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_SEVENBITENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/noopEncoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** 7-bit encoder. + */ + +class VMIME_EXPORT sevenBitEncoder : public noopEncoder +{ +public: + + sevenBitEncoder(); +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_SEVENBITENCODER_HPP_INCLUDED diff --git a/src/utility/encoder/uuEncoder.cpp b/src/vmime/utility/encoder/uuEncoder.cpp index 0375a397..0375a397 100644 --- a/src/utility/encoder/uuEncoder.cpp +++ b/src/vmime/utility/encoder/uuEncoder.cpp diff --git a/src/vmime/utility/encoder/uuEncoder.hpp b/src/vmime/utility/encoder/uuEncoder.hpp new file mode 100644 index 00000000..7365263c --- /dev/null +++ b/src/vmime/utility/encoder/uuEncoder.hpp @@ -0,0 +1,60 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_ENCODER_UUENCODER_HPP_INCLUDED +#define VMIME_UTILITY_ENCODER_UUENCODER_HPP_INCLUDED + + +#include "vmime/utility/encoder/encoder.hpp" + + +namespace vmime { +namespace utility { +namespace encoder { + + +/** UUEncode encoder. + */ + +class VMIME_EXPORT uuEncoder : public encoder +{ +public: + + uuEncoder(); + + size_t encode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + size_t decode(utility::inputStream& in, utility::outputStream& out, utility::progressListener* progress = NULL); + + const std::vector <string> getAvailableProperties() const; + + size_t getEncodedSize(const size_t n) const; + size_t getDecodedSize(const size_t n) const; +}; + + +} // encoder +} // utility +} // vmime + + +#endif // VMIME_UTILITY_ENCODER_UUENCODER_HPP_INCLUDED diff --git a/src/vmime/utility/file.hpp b/src/vmime/utility/file.hpp new file mode 100644 index 00000000..c0ba2c5b --- /dev/null +++ b/src/vmime/utility/file.hpp @@ -0,0 +1,269 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_FILE_HPP_INCLUDED +#define VMIME_UTILITY_FILE_HPP_INCLUDED + + +#include "vmime/config.hpp" + +#include "vmime/utility/path.hpp" +#include "vmime/utility/stream.hpp" + + +#if VMIME_HAVE_FILESYSTEM_FEATURES + + +namespace vmime { +namespace utility { + + +class file; + + +/** File list iterator (see file::getFiles). + */ + +class VMIME_EXPORT fileIterator : public object +{ +public: + + virtual ~fileIterator() { } + + /** Check whether the cursor has reach the end of the list. + * + * @return true if you can call nextElement(), or false + * if no more file is available + */ + virtual bool hasMoreElements() const = 0; + + /** Return the next file in the list. + * + * @return next file or NULL + */ + virtual shared_ptr <file> nextElement() = 0; +}; + + +/** Write to a file. + */ + +class VMIME_EXPORT fileWriter : public object +{ +public: + + virtual ~fileWriter() { } + + virtual shared_ptr <utility::outputStream> getOutputStream() = 0; +}; + + +/** Read from a file. + */ + +class VMIME_EXPORT fileReader : public object +{ +public: + + virtual ~fileReader() { } + + virtual shared_ptr <utility::inputStream> getInputStream() = 0; +}; + + +/** Abstract representation of a file or directory. + */ + +class VMIME_EXPORT file : public object +{ +public: + + typedef utility::path path; + typedef unsigned long length_type; + + + virtual ~file() { } + + + /** Create the file pointed by this file object. + * + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void createFile() = 0; + + /** Create the directory pointed by this file object. + * + * @param createAll if set to true, recursively create all + * parent directories if they do not exist + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void createDirectory(const bool createAll = false) = 0; + + /** Test whether this is a file. + * + * @return true if this is a file, false otherwise + */ + virtual bool isFile() const = 0; + + /** Test whether this is a directory. + * + * @return true if this is a directory, false otherwise + */ + virtual bool isDirectory() const = 0; + + /** Test whether this file is readible. + * + * @return true if we can read this file, false otherwise + */ + virtual bool canRead() const = 0; + + /** Test whether this file is writeable. + * + * @return true if we can write to this file, false otherwise + */ + virtual bool canWrite() const = 0; + + /** Return the length of this file. + * + * @return file size (in bytes) + */ + virtual length_type getLength() = 0; + + /** Return the full path of this file/directory. + * + * @return full path of the file + */ + virtual const path& getFullPath() const = 0; + + /** Test whether this file/directory exists. + * + * @return true if the file exists, false otherwise + */ + virtual bool exists() const = 0; + + /** Return the parent directory of this file/directory. + * + * @return parent directory (or NULL if root) + */ + virtual shared_ptr <file> getParent() const = 0; + + /** Rename the file/directory. + * + * @param newName full path of the new file + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void rename(const path& newName) = 0; + + /** Deletes this file/directory. + * If this is a directory, it must be empty. + * + * @throw exceptions::filesystem_exception if an error occurs + */ + virtual void remove() = 0; + + /** Return an object capable of writing to this file. + * + * @return file writer object + */ + virtual shared_ptr <fileWriter> getFileWriter() = 0; + + /** Return an object capable of reading from this file. + * + * @return file reader object + */ + virtual shared_ptr <fileReader> getFileReader() = 0; + + /** Enumerate files contained in this directory. + * + * @return file iterator to enumerate files + * @throw exceptions::not_a_directory if this is not a directory, + * exceptions::filesystem_exception if another error occurs + */ + virtual shared_ptr <fileIterator> getFiles() const = 0; + +protected: + + file() { } + +private: + + file(const file&) : object() { } +}; + + +/** Constructs 'file' objects. + */ + +class VMIME_EXPORT fileSystemFactory : public object +{ +public: + + virtual ~fileSystemFactory() { } + + /** Create a new file object from the specified path. + * + * @param path full path (absolute) of the file + * @return new file object for the path + */ + virtual shared_ptr <file> create(const file::path& path) const = 0; + + /** Parse a path contained in a string. + * + * @param str string containing a path in a system-dependent representation + * @return path object (abstract representation) + */ + virtual const file::path stringToPath(const string& str) const = 0; + + /** Return the system-dependent string representation for the specified path. + * + * @param path abstract representation of the path + * @return string representation of the path + */ + virtual const string pathToString(const file::path& path) const = 0; + + /** Test whether the specified path component is syntactically + * valid (ie: does not contain any 'special' character). + * + * @param comp path component to test + * @return true if the component is valid, false otherwise + */ + virtual bool isValidPathComponent(const file::path::component& comp) const = 0; + + /** Test whether the specified path is syntactically valid + * (ie: components do not contain any 'special' character). + * + * @param path path to test + * @return true if the path is valid, false otherwise + */ + virtual bool isValidPath(const file::path& path) const = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_FILESYSTEM_FEATURES + + +#endif // VMIME_UTILITY_FILE_HPP_INCLUDED diff --git a/src/utility/filteredStream.cpp b/src/vmime/utility/filteredStream.cpp index bb705162..bb705162 100644 --- a/src/utility/filteredStream.cpp +++ b/src/vmime/utility/filteredStream.cpp diff --git a/src/vmime/utility/filteredStream.hpp b/src/vmime/utility/filteredStream.hpp new file mode 100644 index 00000000..c60373b9 --- /dev/null +++ b/src/vmime/utility/filteredStream.hpp @@ -0,0 +1,406 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_FILTEREDSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_FILTEREDSTREAM_HPP_INCLUDED + + +#include <algorithm> + +#include "vmime/utility/inputStream.hpp" +#include "vmime/utility/outputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** A stream whose input is filtered. + */ + +class VMIME_EXPORT filteredInputStream : public inputStream +{ +public: + + virtual size_t getBlockSize(); + + /** Return a reference to the stream being filtered. + * + * @return stream being filtered + */ + virtual inputStream& getPreviousInputStream() = 0; +}; + + +/** A stream whose output is filtered. + */ + +class VMIME_EXPORT filteredOutputStream : public outputStream +{ +public: + + virtual size_t getBlockSize(); + + /** Return a reference to the stream being filtered. + * + * @return destination stream for filtered data + */ + virtual outputStream& getNextOutputStream() = 0; +}; + + +/** A filtered input stream which replaces "\n.." + * sequences with "\n." sequences. + */ + +class VMIME_EXPORT dotFilteredInputStream : public filteredInputStream +{ +public: + + /** Construct a new filter for the specified input stream. + * + * @param is stream from which to read data to be filtered + */ + dotFilteredInputStream(inputStream& is); + + inputStream& getPreviousInputStream(); + + bool eof() const; + + void reset(); + + size_t read(byte_t* const data, const size_t count); + + size_t skip(const size_t count); + +private: + + inputStream& m_stream; + + byte_t m_previousChar2; // (N - 1)th character of previous buffer + byte_t m_previousChar1; // (N)th (last) character of previous buffer +}; + + +/** A filtered output stream which replaces "\n." + * sequences with "\n.." sequences. + */ + +class VMIME_EXPORT dotFilteredOutputStream : public filteredOutputStream +{ +public: + + /** Construct a new filter for the specified output stream. + * + * @param os stream into which write filtered data + */ + dotFilteredOutputStream(outputStream& os); + + outputStream& getNextOutputStream(); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStream& m_stream; + byte_t m_previousChar; + bool m_start; +}; + + +/** A filtered output stream which replaces CRLF sequences + * with single LF characters. + */ + +class VMIME_EXPORT CRLFToLFFilteredOutputStream : public filteredOutputStream +{ +public: + + /** Construct a new filter for the specified output stream. + * + * @param os stream into which write filtered data + */ + CRLFToLFFilteredOutputStream(outputStream& os); + + outputStream& getNextOutputStream(); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStream& m_stream; + byte_t m_previousChar; +}; + + +/** A filtered output stream which replaces CR or LF characters + * with CRLF sequences. + */ + +class VMIME_EXPORT LFToCRLFFilteredOutputStream : public filteredOutputStream +{ +public: + + /** Construct a new filter for the specified output stream. + * + * @param os stream into which write filtered data + */ + LFToCRLFFilteredOutputStream(outputStream& os); + + outputStream& getNextOutputStream(); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStream& m_stream; + byte_t m_previousChar; +}; + + +/** A filtered input stream which stops when a specified sequence + * is found (eof() method will return 'true'). + */ + +template <int COUNT> +class VMIME_EXPORT stopSequenceFilteredInputStream : public filteredInputStream +{ +public: + + /** Construct a new filter for the specified input stream. + * + * @param is stream from which to read data to be filtered + * @param sequence sequence on which to stop + */ + stopSequenceFilteredInputStream(inputStream& is, const byte_t* sequence) + : m_stream(is), m_sequence(sequence), m_found(0), m_eof(false) + { + } + + /** Construct a new filter for the specified input stream. + * + * @param is stream from which to read data to be filtered + * @param sequence sequence on which to stop + */ + stopSequenceFilteredInputStream(inputStream& is, const char* sequence) + : m_stream(is), m_sequence(reinterpret_cast <const byte_t*>(sequence)), + m_found(0), m_eof(false) + { + } + + inputStream& getPreviousInputStream() + { + return (m_stream); + } + + bool eof() const + { + return (m_found == COUNT || m_eof); + } + + void reset() + { + m_found = 0; + m_stream.reset(); + } + + size_t read(byte_t* const data, const size_t count); + + size_t skip(const size_t /* count */) + { + // Not supported + return 0; + } + +private: + + inputStream& m_stream; + + const byte_t* m_sequence; + size_t m_found; + + bool m_eof; +}; + + +template <> +size_t stopSequenceFilteredInputStream <1>::read + (byte_t* const data, const size_t count); + + +template <int COUNT> +size_t stopSequenceFilteredInputStream <COUNT>::read + (byte_t* const data, const size_t count) +{ + // Read buffer must be at least 'COUNT' size + 1 byte + if (eof() || count <= COUNT) + return 0; + + if (m_stream.eof()) + { + if (m_found != 0) + { + const size_t found = m_found; + + for (size_t f = 0 ; f < found ; ++f) + data[f] = m_sequence[f]; + + m_found = 0; + m_eof = true; + + return (found); + } + else + { + m_eof = true; + return 0; + } + } + + size_t read = m_stream.read(data, count - COUNT); + + byte_t* end = data + read; + byte_t* pos = data; + + while (pos < end) + { + // Very simple case, search for the whole sequence + if (m_found == 0) + { + while (pos < end) + { + pos = std::find(pos, end, m_sequence[0]); + + if (pos == end) + return (read); + + m_found = 1; + ++pos; + + while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) + { + ++m_found; + ++pos; + } + + // Didn't found whole sequence + if (m_found != COUNT) + { + // We reached the end of the buffer + if (pos == end) + { + return (read - m_found); + } + // Common prefix but not whole sequence + else + { + m_found = 0; + } + } + // Whole sequence found + else + { + // End of stream + return (pos - data - m_found); + } + } + } + // More complex case: search for a sequence which has begun + // in a previous buffer + else + { + // Search for the end of the previously started sequence + while (pos < end && m_found < COUNT && m_sequence[m_found] == *pos) + { + ++m_found; + ++pos; + } + + if (m_found != COUNT) + { + // End of buffer + if (pos == end) + { + // No data: this buffer is a sub-sequence of the + // searched sequence + return 0; + } + // Common prefix + else + { + // We have to reinject the incomplete sequence into + // the stream data + + // -- shift right data + const size_t n = pos - data; + + byte_t* newEnd = data + read + m_found - n; + byte_t* oldEnd = data + read; + + for (size_t i = 0 ; i < read - n ; ++i) + { + --newEnd; + --oldEnd; + + *newEnd = *oldEnd; + } + + // -- copy the prefix just before data + for (size_t f = 0 ; f < m_found ; ++f) + data[f] = m_sequence[f]; + + read += m_found - n; + end += m_found - n; + + m_found = 0; + } + } + else + { + return 0; // no more data + } + } + } + + return read; +} + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_FILTEREDSTREAM_HPP_INCLUDED + diff --git a/src/utility/inputStream.cpp b/src/vmime/utility/inputStream.cpp index a7d6bc0f..a7d6bc0f 100644 --- a/src/utility/inputStream.cpp +++ b/src/vmime/utility/inputStream.cpp diff --git a/src/vmime/utility/inputStream.hpp b/src/vmime/utility/inputStream.hpp new file mode 100644 index 00000000..809996ce --- /dev/null +++ b/src/vmime/utility/inputStream.hpp @@ -0,0 +1,76 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED + + +#include "vmime/utility/stream.hpp" + + +namespace vmime { +namespace utility { + + +/** Simple input stream. + */ + +class VMIME_EXPORT inputStream : public stream +{ +public: + + /** Test for end of stream (no more data to read). + * + * @return true if we have reached the end of stream, false otherwise + */ + virtual bool eof() const = 0; + + /** Set the read pointer to the beginning of the stream. + * + * @warning WARNING: this may not work for all stream types. + */ + virtual void reset() = 0; + + /** Read data from the stream. + * + * @param data will receive the data read + * @param count maximum number of bytes to read + * @return number of bytes read + */ + virtual size_t read(byte_t* const data, const size_t count) = 0; + + /** Skip a number of bytes. + * + * @param count maximum number of bytes to ignore + * @return number of bytes skipped + */ + virtual size_t skip(const size_t count) = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAM_HPP_INCLUDED + diff --git a/src/utility/inputStreamAdapter.cpp b/src/vmime/utility/inputStreamAdapter.cpp index c0b06be4..c0b06be4 100644 --- a/src/utility/inputStreamAdapter.cpp +++ b/src/vmime/utility/inputStreamAdapter.cpp diff --git a/src/vmime/utility/inputStreamAdapter.hpp b/src/vmime/utility/inputStreamAdapter.hpp new file mode 100644 index 00000000..dd761736 --- /dev/null +++ b/src/vmime/utility/inputStreamAdapter.hpp @@ -0,0 +1,66 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + +#include <istream> + + +namespace vmime { +namespace utility { + + +/** An adapter class for C++ standard input streams. + */ + +class VMIME_EXPORT inputStreamAdapter : public seekableInputStream +{ +public: + + /** @param is input stream to wrap + */ + inputStreamAdapter(std::istream& is); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + std::istream& m_stream; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMADAPTER_HPP_INCLUDED + diff --git a/src/utility/inputStreamByteBufferAdapter.cpp b/src/vmime/utility/inputStreamByteBufferAdapter.cpp index c270ea56..c270ea56 100644 --- a/src/utility/inputStreamByteBufferAdapter.cpp +++ b/src/vmime/utility/inputStreamByteBufferAdapter.cpp diff --git a/src/vmime/utility/inputStreamByteBufferAdapter.hpp b/src/vmime/utility/inputStreamByteBufferAdapter.hpp new file mode 100644 index 00000000..f201f433 --- /dev/null +++ b/src/vmime/utility/inputStreamByteBufferAdapter.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for reading from an array of bytes. + */ + +class VMIME_EXPORT inputStreamByteBufferAdapter : public seekableInputStream +{ +public: + + inputStreamByteBufferAdapter(const byte_t* buffer, size_t length); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + const byte_t* m_buffer; + const size_t m_length; + + size_t m_pos; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMBYTEBUFFERADAPTER_HPP_INCLUDED + diff --git a/src/utility/inputStreamPointerAdapter.cpp b/src/vmime/utility/inputStreamPointerAdapter.cpp index 6bf0461a..6bf0461a 100644 --- a/src/utility/inputStreamPointerAdapter.cpp +++ b/src/vmime/utility/inputStreamPointerAdapter.cpp diff --git a/src/vmime/utility/inputStreamPointerAdapter.hpp b/src/vmime/utility/inputStreamPointerAdapter.hpp new file mode 100644 index 00000000..4fc606a9 --- /dev/null +++ b/src/vmime/utility/inputStreamPointerAdapter.hpp @@ -0,0 +1,63 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED + + +#include "vmime/utility/inputStreamAdapter.hpp" + +#include <istream> + + +namespace vmime { +namespace utility { + + +/** An adapter class for pointer to C++ standard input stream. + */ + +class VMIME_EXPORT inputStreamPointerAdapter : public inputStreamAdapter +{ +public: + + /** @param is input stream to wrap + * @param own if set to 'true', the pointer will be deleted when + * this object is destroyed + */ + inputStreamPointerAdapter(std::istream* is, const bool own = true); + ~inputStreamPointerAdapter(); + +private: + + std::istream* m_stream; + const bool m_own; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMPOINTERADAPTER_HPP_INCLUDED + diff --git a/src/utility/inputStreamSocketAdapter.cpp b/src/vmime/utility/inputStreamSocketAdapter.cpp index d78855eb..d78855eb 100644 --- a/src/utility/inputStreamSocketAdapter.cpp +++ b/src/vmime/utility/inputStreamSocketAdapter.cpp diff --git a/src/vmime/utility/inputStreamSocketAdapter.hpp b/src/vmime/utility/inputStreamSocketAdapter.hpp new file mode 100644 index 00000000..a990f628 --- /dev/null +++ b/src/vmime/utility/inputStreamSocketAdapter.hpp @@ -0,0 +1,77 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED + + +#include "vmime/utility/inputStream.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +namespace vmime { +namespace net { + class socket; // forward reference +} // net +} // vmime + + +namespace vmime { +namespace utility { + + +/** An input stream that is connected to a socket. + */ + +class VMIME_EXPORT inputStreamSocketAdapter : public inputStream +{ +public: + + inputStreamSocketAdapter(net::socket& sok); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + + size_t getBlockSize(); + +private: + + inputStreamSocketAdapter(const inputStreamSocketAdapter&); + + net::socket& m_socket; +}; + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#endif // VMIME_UTILITY_INPUTSTREAMSOCKETADAPTER_HPP_INCLUDED + diff --git a/src/utility/inputStreamStringAdapter.cpp b/src/vmime/utility/inputStreamStringAdapter.cpp index 9b897b97..9b897b97 100644 --- a/src/utility/inputStreamStringAdapter.cpp +++ b/src/vmime/utility/inputStreamStringAdapter.cpp diff --git a/src/vmime/utility/inputStreamStringAdapter.hpp b/src/vmime/utility/inputStreamStringAdapter.hpp new file mode 100644 index 00000000..4ee597e6 --- /dev/null +++ b/src/vmime/utility/inputStreamStringAdapter.hpp @@ -0,0 +1,68 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for string input. + */ + +class VMIME_EXPORT inputStreamStringAdapter : public seekableInputStream +{ +public: + + inputStreamStringAdapter(const string& buffer); + inputStreamStringAdapter(const string& buffer, const size_t begin, const size_t end); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + inputStreamStringAdapter(const inputStreamStringAdapter&); + + const string m_buffer; // do _NOT_ keep a reference... + const size_t m_begin; + const size_t m_end; + size_t m_pos; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMSTRINGADAPTER_HPP_INCLUDED + diff --git a/src/utility/inputStreamStringProxyAdapter.cpp b/src/vmime/utility/inputStreamStringProxyAdapter.cpp index 5513de80..5513de80 100644 --- a/src/utility/inputStreamStringProxyAdapter.cpp +++ b/src/vmime/utility/inputStreamStringProxyAdapter.cpp diff --git a/src/vmime/utility/inputStreamStringProxyAdapter.hpp b/src/vmime/utility/inputStreamStringProxyAdapter.hpp new file mode 100644 index 00000000..02dc2056 --- /dev/null +++ b/src/vmime/utility/inputStreamStringProxyAdapter.hpp @@ -0,0 +1,70 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + + +namespace vmime { +namespace utility { + + +class stringProxy; + + +/** An adapter class for stringProxy input. + */ + +class VMIME_EXPORT inputStreamStringProxyAdapter : public seekableInputStream +{ +public: + + /** @param buffer stringProxy object to wrap + */ + inputStreamStringProxyAdapter(const stringProxy& buffer); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + inputStreamStringProxyAdapter(const inputStreamStringProxyAdapter&); + + const stringProxy& m_buffer; + size_t m_pos; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_INPUTSTREAMSTRINGPROXYADAPTER_HPP_INCLUDED + diff --git a/src/utility/outputStream.cpp b/src/vmime/utility/outputStream.cpp index 070e28c5..070e28c5 100644 --- a/src/utility/outputStream.cpp +++ b/src/vmime/utility/outputStream.cpp diff --git a/src/vmime/utility/outputStream.hpp b/src/vmime/utility/outputStream.hpp new file mode 100644 index 00000000..62ee7336 --- /dev/null +++ b/src/vmime/utility/outputStream.hpp @@ -0,0 +1,136 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED + + +#include "vmime/utility/stream.hpp" + + +#if defined(_MSC_VER) && (_MSC_VER <= 1200) // VC++6 +# include <cstring> +#endif + + +namespace vmime { +namespace utility { + + +/** Simple output stream. + */ + +class VMIME_EXPORT outputStream : public stream +{ +public: + + /** Write data to the stream. + * + * @param data buffer containing data to write + * @param count number of bytes to write + */ + void write(const byte_t* const data, const size_t count); + + /** Write data to the stream. + * + * @param data buffer containing data to write + * @param count number of bytes to write + */ + void write(const char* const data, const size_t count); + + /** Write data to the stream. + * + * @param data buffer containing data to write + * @param N number of bytes to write, including terminating + * null (value is induced by compiler) + */ + template <int N> + void write(const char (&data)[N]) + { + write(data, N - 1); + } + + /** Flush this output stream and forces any buffered output + * bytes to be written out to the stream. + */ + virtual void flush() = 0; + +protected: + + /** Write data to the stream. + * This is the method to be implemented is subclasses. + * + * @param data buffer containing data to write + * @param count number of bytes to write + */ + virtual void writeImpl(const byte_t* const data, const size_t count) = 0; +}; + + +// Helpers functions + +VMIME_EXPORT outputStream& operator<<(outputStream& os, const string& str); +VMIME_EXPORT outputStream& operator<<(outputStream& os, const byte_t c); + + +#if defined(_MSC_VER) && (_MSC_VER <= 1200) // Internal compiler error with VC++6 + +inline outputStream& operator<<(outputStream& os, const char* str) +{ + os.write(reinterpret_cast <const byte_t*>(str), ::strlen(str)); + return (os); +} + +#else + +template <int N> +outputStream& operator<<(outputStream& os, const char (&str)[N]) +{ + os.write(reinterpret_cast <const byte_t*>(str), N - 1); + return (os); +} + +#endif // defined(_MSC_VER) && (_MSC_VER <= 1200) + + +template <typename T> +outputStream& operator<<(outputStream& os, const T& t) +{ + std::ostringstream oss; + oss.imbue(std::locale::classic()); // no formatting + + oss << t; + + os << oss.str(); + + return (os); +} + + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAM_HPP_INCLUDED + diff --git a/src/utility/outputStreamAdapter.cpp b/src/vmime/utility/outputStreamAdapter.cpp index ed90c7d3..ed90c7d3 100644 --- a/src/utility/outputStreamAdapter.cpp +++ b/src/vmime/utility/outputStreamAdapter.cpp diff --git a/src/vmime/utility/outputStreamAdapter.hpp b/src/vmime/utility/outputStreamAdapter.hpp new file mode 100644 index 00000000..f0125584 --- /dev/null +++ b/src/vmime/utility/outputStreamAdapter.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + +#include <ostream> + + +namespace vmime { +namespace utility { + + +/** An adapter class for C++ standard output streams. + */ + +class VMIME_EXPORT outputStreamAdapter : public outputStream +{ +public: + + /** @param os output stream to wrap + */ + outputStreamAdapter(std::ostream& os); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + std::ostream& m_stream; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAMADAPTER_HPP_INCLUDED + diff --git a/src/utility/outputStreamByteArrayAdapter.cpp b/src/vmime/utility/outputStreamByteArrayAdapter.cpp index 1bed735b..1bed735b 100644 --- a/src/utility/outputStreamByteArrayAdapter.cpp +++ b/src/vmime/utility/outputStreamByteArrayAdapter.cpp diff --git a/src/vmime/utility/outputStreamByteArrayAdapter.hpp b/src/vmime/utility/outputStreamByteArrayAdapter.hpp new file mode 100644 index 00000000..a2178a9c --- /dev/null +++ b/src/vmime/utility/outputStreamByteArrayAdapter.hpp @@ -0,0 +1,61 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for byte array output. + */ + +class VMIME_EXPORT outputStreamByteArrayAdapter : public outputStream +{ +public: + + outputStreamByteArrayAdapter(byteArray& array); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + byteArray& m_array; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAMBYTEARRAYADAPTER_HPP_INCLUDED + diff --git a/src/utility/outputStreamSocketAdapter.cpp b/src/vmime/utility/outputStreamSocketAdapter.cpp index 03194497..03194497 100644 --- a/src/utility/outputStreamSocketAdapter.cpp +++ b/src/vmime/utility/outputStreamSocketAdapter.cpp diff --git a/src/vmime/utility/outputStreamSocketAdapter.hpp b/src/vmime/utility/outputStreamSocketAdapter.hpp new file mode 100644 index 00000000..6cd00626 --- /dev/null +++ b/src/vmime/utility/outputStreamSocketAdapter.hpp @@ -0,0 +1,78 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +namespace vmime { +namespace net { + class socket; // forward reference +} // net +} // vmime + + +namespace vmime { +namespace utility { + + +/** An output stream that is connected to a socket. + */ + +class VMIME_EXPORT outputStreamSocketAdapter : public outputStream +{ +public: + + outputStreamSocketAdapter(net::socket& sok); + + void flush(); + + size_t getBlockSize(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + outputStreamSocketAdapter(const outputStreamSocketAdapter&); + + net::socket& m_socket; +}; + + +} // utility +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + + +#endif // VMIME_UTILITY_OUTPUTSTREAMSOCKETADAPTER_HPP_INCLUDED + diff --git a/src/utility/outputStreamStringAdapter.cpp b/src/vmime/utility/outputStreamStringAdapter.cpp index 7105480c..7105480c 100644 --- a/src/utility/outputStreamStringAdapter.cpp +++ b/src/vmime/utility/outputStreamStringAdapter.cpp diff --git a/src/vmime/utility/outputStreamStringAdapter.hpp b/src/vmime/utility/outputStreamStringAdapter.hpp new file mode 100644 index 00000000..89516827 --- /dev/null +++ b/src/vmime/utility/outputStreamStringAdapter.hpp @@ -0,0 +1,61 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED + + +#include "vmime/utility/outputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter class for string output. + */ + +class VMIME_EXPORT outputStreamStringAdapter : public outputStream +{ +public: + + outputStreamStringAdapter(string& buffer); + + void flush(); + +protected: + + void writeImpl(const byte_t* const data, const size_t count); + +private: + + string& m_buffer; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_OUTPUTSTREAMSTRINGADAPTER_HPP_INCLUDED + diff --git a/src/utility/parserInputStreamAdapter.cpp b/src/vmime/utility/parserInputStreamAdapter.cpp index 5ab26ef0..5ab26ef0 100644 --- a/src/utility/parserInputStreamAdapter.cpp +++ b/src/vmime/utility/parserInputStreamAdapter.cpp diff --git a/src/vmime/utility/parserInputStreamAdapter.hpp b/src/vmime/utility/parserInputStreamAdapter.hpp new file mode 100644 index 00000000..9b0639b1 --- /dev/null +++ b/src/vmime/utility/parserInputStreamAdapter.hpp @@ -0,0 +1,174 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + +#include <cstring> + + +namespace vmime { +namespace utility { + + +/** An adapter class used for parsing from an input stream. + */ + +class VMIME_EXPORT parserInputStreamAdapter : public seekableInputStream +{ +public: + + /** @param stream input stream to wrap + */ + parserInputStreamAdapter(shared_ptr <seekableInputStream> stream); + + shared_ptr <seekableInputStream> getUnderlyingStream(); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + + void seek(const size_t pos) + { + m_stream->seek(pos); + } + + size_t skip(const size_t count) + { + return m_stream->skip(count); + } + + size_t getPosition() const + { + return m_stream->getPosition(); + } + + /** Get the byte at the current position without updating the + * current position. + * + * @return byte at the current position + */ + byte_t peekByte() const + { + const size_t initialPos = m_stream->getPosition(); + + try + { + byte_t buffer[1]; + const size_t readBytes = m_stream->read(buffer, 1); + + m_stream->seek(initialPos); + + return (readBytes == 1 ? buffer[0] : static_cast <byte_t>(0)); + } + catch (...) + { + m_stream->seek(initialPos); + throw; + } + } + + /** Get the byte at the current position and advance current + * position by one byte. + * + * @return byte at the current position + */ + byte_t getByte() + { + byte_t buffer[1]; + const size_t readBytes = m_stream->read(buffer, 1); + + return (readBytes == 1 ? buffer[0] : static_cast <byte_t>(0)); + } + + /** Check whether the bytes following the current position match + * the specified bytes. Position is not updated. + * + * @param bytes bytes to compare + * @param length number of bytes + * @return true if the next bytes match the pattern, false otherwise + */ + template <typename T> + bool matchBytes(const T* bytes, const size_t length) const + { + const size_t initialPos = m_stream->getPosition(); + + try + { + byte_t buffer[32]; + const size_t readBytes = m_stream->read(buffer, length); + + m_stream->seek(initialPos); + + return readBytes == length && + ::memcmp(bytes, buffer, length) == 0; + } + catch (...) + { + m_stream->seek(initialPos); + throw; + } + } + + const string extract(const size_t begin, const size_t end) const; + + /** Skips bytes matching a predicate from the current position. + * The current position is updated to the next following byte + * which does not match the predicate. + * + * @param pred predicate + * @param endPosition stop at this position (or at end of the stream, + * whichever comes first) + * @return number of bytes skipped + */ + template <typename PREDICATE> + size_t skipIf(PREDICATE pred, const size_t endPosition) + { + const size_t initialPos = getPosition(); + size_t pos = initialPos; + + while (!m_stream->eof() && pos < endPosition && pred(getByte())) + ++pos; + + m_stream->seek(pos); + + return pos - initialPos; + } + + size_t findNext(const string& token, const size_t startPosition = 0); + +private: + + mutable shared_ptr <seekableInputStream> m_stream; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_PARSERINPUTSTREAMADAPTER_HPP_INCLUDED + diff --git a/src/utility/path.cpp b/src/vmime/utility/path.cpp index 9f746d54..9f746d54 100644 --- a/src/utility/path.cpp +++ b/src/vmime/utility/path.cpp diff --git a/src/vmime/utility/path.hpp b/src/vmime/utility/path.hpp new file mode 100644 index 00000000..203da246 --- /dev/null +++ b/src/vmime/utility/path.hpp @@ -0,0 +1,171 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_PATH_HPP_INCLUDED +#define VMIME_UTILITY_PATH_HPP_INCLUDED + + +#include <vector> + +#include "vmime/types.hpp" +#include "vmime/word.hpp" + + +namespace vmime { +namespace utility { + + +/** Abstract representation of a path (filesystem, mailbox, etc). + */ + +class VMIME_EXPORT path : public object +{ +public: + + typedef vmime::word component; + typedef std::vector <component> list; + + // Construct a path + path(); + path(const component& c); + path(const path& p); + explicit path(const string& s); + + // Append a component to a path + path operator/(const path& p) const; + path operator/(const component& c) const; + + path& operator/=(const path& p); + path& operator/=(const component& c); + + // Return the parent path + path getParent() const; + + // Assignment + path& operator=(const path& p); + path& operator=(const component& c); + + // Path comparison + bool operator==(const path& p) const; + bool operator!=(const path& p) const; + + /** Append a component to the path. + * + * @param c component to add + */ + void appendComponent(const component& c); + + /** Return the component at the specified position. + * + * @param pos position + * @return component at position 'pos' + */ + const component& getComponentAt(const size_t pos) const; + + /** Return the component at the specified position. + * + * @param pos position + * @return component at position 'pos' + */ + component& getComponentAt(const size_t pos); + + /** Test whether this path is empty (root). + * + * @return true if the path is empty (no components = root) + */ + bool isEmpty() const; + + /** Test whether this path is the root (alias for isEmpty()). + * + * @return true if the path is the root + */ + bool isRoot() const; + + /** Return the last component of this path (const version). + * + * @return last component + */ + const component getLastComponent() const; + + /** Return the last component of this path (non-const version). + * + * @return last component + */ + component& getLastComponent(); + + /** Return the number of components in this path. + * + * @return number of components + */ + size_t getSize() const; + + /** Return the specified component of the path (const version). + * + * @param x index of the component + * @return component at the specified index + */ + const component& operator[](const size_t x) const; + + /** Return the specified component of the path (non-const version). + * + * @param x index of the component + * @return component at the specified index + */ + component& operator[](const size_t x); + + /** Test whether this path is a direct parent of another one. + * + * @param p other path + * @return true if the specified path is a child + * of this path, false otherwise + */ + bool isDirectParentOf(const path& p) const; + + /** Test whether this path is a parent of another one. + * + * @param p other path + * @return true if the specified path is a child (direct or + * indirect) of this path, false otherwise + */ + bool isParentOf(const path& p) const; + + /** Rename a parent component in the path. + * Example: path("a/b/c/d").renameParent("a/b", "x/y/z") + * will return path("x/y/z/c/d"). + * + * @param oldPath old parent path + * @param newPath new parent path + */ + void renameParent(const path& oldPath, const path& newPath); + +private: + + list m_list; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_PATH_HPP_INCLUDED diff --git a/src/utility/progressListener.cpp b/src/vmime/utility/progressListener.cpp index cef074e5..cef074e5 100644 --- a/src/utility/progressListener.cpp +++ b/src/vmime/utility/progressListener.cpp diff --git a/src/vmime/utility/progressListener.hpp b/src/vmime/utility/progressListener.hpp new file mode 100644 index 00000000..4d0e9bf8 --- /dev/null +++ b/src/vmime/utility/progressListener.hpp @@ -0,0 +1,113 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_PROGRESSLISTENER_HPP_INCLUDED +#define VMIME_UTILITY_PROGRESSLISTENER_HPP_INCLUDED + + +#include "vmime/config.hpp" +#include "vmime/types.hpp" + + +namespace vmime { +namespace utility { + + +/** An interface to implement if you want to be notified + * of a state of progress by some objects. + */ + +class VMIME_EXPORT progressListener +{ +protected: + + virtual ~progressListener() { } + +public: + + /** Allow the caller object to cancel the current operation. + * + * @warning WARNING: this is implementation-dependent: cancelling + * may not be supported by the notifier object. + * + * @return true to cancel the operation, false otherwise + */ + virtual bool cancel() const = 0; + + /** Called at the beginning of the operation. + * + * @param predictedTotal predicted amount of units (this has + * no concrete meaning: these are not bytes, nor percentage...) + */ + virtual void start(const size_t predictedTotal) = 0; + + /** Called during the operation (can be called several times). + * + * @param current current position + * @param currentTotal adjusted total amount of units + */ + virtual void progress(const size_t current, const size_t currentTotal) = 0; + + /** Called at the end of the operation. + * + * @param total final total amount of units + */ + virtual void stop(const size_t total) = 0; +}; + + + +/** A progress listener used when total size is known by the + * receiver, but not by the notifier. + */ + +class VMIME_EXPORT progressListenerSizeAdapter : public progressListener +{ +public: + + /** Construct a new progressListenerSizeAdapter object. + * + * @param list wrapped progress listener (can be NULL) + * @param total predicted total + */ + progressListenerSizeAdapter(progressListener* list, const size_t total); + + bool cancel() const; + + void start(const size_t predictedTotal); + void progress(const size_t current, const size_t currentTotal); + void stop(const size_t total); + +private: + + progressListener* m_wrapped; + size_t m_total; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_PROGRESSLISTENER_HPP_INCLUDED + diff --git a/src/utility/random.cpp b/src/vmime/utility/random.cpp index 97d12ddc..97d12ddc 100644 --- a/src/utility/random.cpp +++ b/src/vmime/utility/random.cpp diff --git a/src/vmime/utility/random.hpp b/src/vmime/utility/random.hpp new file mode 100644 index 00000000..b667c3a2 --- /dev/null +++ b/src/vmime/utility/random.hpp @@ -0,0 +1,77 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_RANDOM_HPP_INCLUDED +#define VMIME_UTILITY_RANDOM_HPP_INCLUDED + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace utility { + + +/** Pseudo-random number generator. + */ + +class random +{ +public: + + /** Return a new random number. + * + * @return random number + */ + static unsigned int getNext(); + + /** Return the current time as a number (may be used to + * build "random" strings). + * + * @return time as a number + */ + static unsigned int getTime(); + + /** Return the current process number (may be user to + * build "random" strings). + * + * @return process number + */ + static unsigned int getProcess(); + + /** Return a random character string with the specified length. + * + * @param length length of the string to generate + * @param randomChars list of characters to use + * @return random string + */ + static const string getString(const size_t length, const string& randomChars + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_RANDOM_HPP_INCLUDED diff --git a/src/vmime/utility/seekableInputStream.hpp b/src/vmime/utility/seekableInputStream.hpp new file mode 100644 index 00000000..f56af9c4 --- /dev/null +++ b/src/vmime/utility/seekableInputStream.hpp @@ -0,0 +1,64 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED +#define VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED + + +#include "vmime/utility/inputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An input stream that allows seeking within the input. + */ + +class VMIME_EXPORT seekableInputStream : public inputStream +{ +public: + + /** Returns the current position in this stream. + * + * @return the offset from the beginning of the stream, in bytes, + * at which the next read occurs + */ + virtual size_t getPosition() const = 0; + + /** Sets the position, measured from the beginning of this stream, + * at which the next read occurs. + * + * @param pos the offset position, measured in bytes from the + * beginning of the stream, at which to set the stream pointer. + */ + virtual void seek(const size_t pos) = 0; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAM_HPP_INCLUDED + diff --git a/src/utility/seekableInputStreamRegionAdapter.cpp b/src/vmime/utility/seekableInputStreamRegionAdapter.cpp index cede1ba9..cede1ba9 100644 --- a/src/utility/seekableInputStreamRegionAdapter.cpp +++ b/src/vmime/utility/seekableInputStreamRegionAdapter.cpp diff --git a/src/vmime/utility/seekableInputStreamRegionAdapter.hpp b/src/vmime/utility/seekableInputStreamRegionAdapter.hpp new file mode 100644 index 00000000..4716d2de --- /dev/null +++ b/src/vmime/utility/seekableInputStreamRegionAdapter.hpp @@ -0,0 +1,72 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED +#define VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED + + +#include "vmime/utility/seekableInputStream.hpp" + + +namespace vmime { +namespace utility { + + +/** An adapter for reading a limited region of a seekable input stream. + */ + +class VMIME_EXPORT seekableInputStreamRegionAdapter : public seekableInputStream +{ +public: + + /** Creates a new adapter for a seekableInputStream. + * + * @param stream source stream + * @param begin start position in source stream + * @param length region length in source stream + */ + seekableInputStreamRegionAdapter(shared_ptr <seekableInputStream> stream, + const size_t begin, const size_t length); + + bool eof() const; + void reset(); + size_t read(byte_t* const data, const size_t count); + size_t skip(const size_t count); + size_t getPosition() const; + void seek(const size_t pos); + +private: + + shared_ptr <seekableInputStream> m_stream; + size_t m_begin; + size_t m_length; + size_t m_position; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SEEKABLEINPUTSTREAMREGIONADAPTER_HPP_INCLUDED + diff --git a/src/utility/stream.cpp b/src/vmime/utility/stream.cpp index 232b23c7..232b23c7 100644 --- a/src/utility/stream.cpp +++ b/src/vmime/utility/stream.cpp diff --git a/src/vmime/utility/stream.hpp b/src/vmime/utility/stream.hpp new file mode 100644 index 00000000..980a2407 --- /dev/null +++ b/src/vmime/utility/stream.hpp @@ -0,0 +1,62 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_STREAM_HPP_INCLUDED +#define VMIME_UTILITY_STREAM_HPP_INCLUDED + + +#include <sstream> + +#include "vmime/config.hpp" +#include "vmime/types.hpp" +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { + + + +/** Base class for input/output stream. + */ + +class VMIME_EXPORT stream : public object, private noncopyable +{ +public: + + virtual ~stream() { } + + /** Return the preferred maximum block size when reading + * from or writing to this stream. + * + * @return block size, in bytes + */ + virtual size_t getBlockSize(); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_STREAM_HPP_INCLUDED diff --git a/src/utility/streamUtils.cpp b/src/vmime/utility/streamUtils.cpp index f3cc69ef..f3cc69ef 100644 --- a/src/utility/streamUtils.cpp +++ b/src/vmime/utility/streamUtils.cpp diff --git a/src/vmime/utility/streamUtils.hpp b/src/vmime/utility/streamUtils.hpp new file mode 100644 index 00000000..406b6b64 --- /dev/null +++ b/src/vmime/utility/streamUtils.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED +#define VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED + + +#include "vmime/utility/inputStream.hpp" +#include "vmime/utility/outputStream.hpp" + +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace utility { + + +/** Copy data from one stream into another stream using a buffered method. + * + * @param is input stream (source data) + * @param os output stream (destination for data) + * @return number of bytes copied + */ + +VMIME_EXPORT size_t bufferedStreamCopy(inputStream& is, outputStream& os); + +/** Copy data from one stream into another stream using a buffered method + * and copying only a specified range of data. + * + * @param is input stream (source data) + * @param os output stream (destination for data) + * @param start number of bytes to ignore before starting copying + * @param length maximum number of bytes to copy + * @return number of bytes copied + */ + +VMIME_EXPORT size_t bufferedStreamCopyRange(inputStream& is, outputStream& os, + const size_t start, const size_t length); + +/** Copy data from one stream into another stream using a buffered method + * and notify progress state of the operation. + * + * @param is input stream (source data) + * @param os output stream (destination for data) + * @param length predicted number of bytes to copy + * @param progress listener to notify + * @return number of bytes copied + */ + +VMIME_EXPORT size_t bufferedStreamCopy(inputStream& is, outputStream& os, + const size_t length, progressListener* progress); + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_STREAMUTILS_HPP_INCLUDED + diff --git a/src/utility/stringProxy.cpp b/src/vmime/utility/stringProxy.cpp index 67c96816..67c96816 100644 --- a/src/utility/stringProxy.cpp +++ b/src/vmime/utility/stringProxy.cpp diff --git a/src/vmime/utility/stringProxy.hpp b/src/vmime/utility/stringProxy.hpp new file mode 100644 index 00000000..e5efa135 --- /dev/null +++ b/src/vmime/utility/stringProxy.hpp @@ -0,0 +1,92 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_STRINGPROXY_HPP_INCLUDED +#define VMIME_UTILITY_STRINGPROXY_HPP_INCLUDED + + +#include <limits> + +#include "vmime/types.hpp" +#include "vmime/utility/stream.hpp" +#include "vmime/utility/outputStream.hpp" +#include "vmime/utility/progressListener.hpp" + + +namespace vmime { +namespace utility { + + +/** This class is a proxy for the string class. This takes + * advantage of the COW (copy-on-write) system that might + * be used in "std::string" implementation. + */ + +class VMIME_EXPORT stringProxy +{ +public: + + // Consruction + stringProxy(); + stringProxy(const stringProxy& s); + stringProxy(const string& s, const size_t start = 0, const size_t end = std::numeric_limits <size_t>::max()); + + // Assignment + void set(const string& s, const size_t start = 0, const size_t end = std::numeric_limits <size_t>::max()); + void detach(); + + stringProxy& operator=(const stringProxy& s); + stringProxy& operator=(const string& s); + + // Extract some portion (or whole) of the string + // and output it into a stream. + void extract(outputStream& os, const size_t start = 0, const size_t end = std::numeric_limits <size_t>::max(), utility::progressListener* progress = NULL) const; + + // Return the "virtual" length of the string + size_t length() const; + + // Return the boundaries of the "virtual" string + size_t start() const; + size_t end() const; + + string::const_iterator it_begin() const { return (m_buffer.begin() + m_start); } + string::const_iterator it_end() const { return (m_buffer.begin() + m_end); } + +private: + + string m_buffer; + + size_t m_start; + size_t m_end; +}; + + +VMIME_EXPORT std::ostream& operator<<(std::ostream& os, const stringProxy& s); +VMIME_EXPORT outputStream& operator<<(outputStream& os, const stringProxy& s); + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_STRINGPROXY_HPP_INCLUDED diff --git a/src/utility/stringUtils.cpp b/src/vmime/utility/stringUtils.cpp index dd99d845..dd99d845 100644 --- a/src/utility/stringUtils.cpp +++ b/src/vmime/utility/stringUtils.cpp diff --git a/src/vmime/utility/stringUtils.hpp b/src/vmime/utility/stringUtils.hpp new file mode 100644 index 00000000..7d9925e2 --- /dev/null +++ b/src/vmime/utility/stringUtils.hpp @@ -0,0 +1,214 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED +#define VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" + +#include <sstream> + + +namespace vmime { +namespace utility { + + +/** Miscellaneous functions related to strings. + */ + +class VMIME_EXPORT stringUtils +{ +public: + + /** Makes a string from bytes. + * + * @param data pointer to buffer containing data + * @param count number of bytes to use from buffer + * @return a string object containing a copy of the specified data + */ + static const string makeStringFromBytes(const byte_t* data, const size_t count) + { + return string(reinterpret_cast <const char*>(data), count); + } + + /** Appends bytes to a string. + * + * @param str string to which append data + * @param data pointer to buffer containing data + * @param count number of bytes to use from buffer + * @return a reference to modified string + */ + static string& appendBytesToString(string& str, const byte_t* data, const size_t count) + { + str.append(reinterpret_cast <const char*>(data), count); + return str; + } + + /** Test two strings for equality (case insensitive). + * \warning Use this with ASCII-only strings. + * + * @param s1 first string + * @param s2 second string (must be in lower-case!) + * @param n length of the second string + * @return true if the two strings compare equally, false otherwise + */ + static bool isStringEqualNoCase(const string& s1, const char* s2, const size_t n); + + /** Test two strings for equality (case insensitive). + * \warning Use this with ASCII-only strings. + * + * @param s1 first string + * @param s2 second string + * @return true if the two strings compare equally, false otherwise + */ + static bool isStringEqualNoCase(const string& s1, const string& s2); + + /** Test two strings for equality (case insensitive). + * \warning Use this with ASCII-only strings. + * + * @param begin start position of the first string + * @param end end position of the first string + * @param s second string (must be in lower-case!) + * @param n length of the second string + * @return true if the two strings compare equally, false otherwise + */ + static bool isStringEqualNoCase(const string::const_iterator begin, const string::const_iterator end, const char* s, const size_t n); + + /** Transform all the characters in a string to lower-case. + * \warning Use this with ASCII-only strings. + * + * @param str the string to transform + * @return a new string in lower-case + */ + static const string toLower(const string& str); + + /** Transform all the characters in a string to upper-case. + * \warning Use this with ASCII-only strings. + * + * @param str the string to transform + * @return a new string in upper-case + */ + static const string toUpper(const string& str); + + /** Strip the space characters (SPC, TAB, CR, LF) at the beginning + * and at the end of the specified string. + * + * @param str string in which to strip spaces + * @return a new string with space characters removed + */ + static const string trim(const string& str); + + /** Return the number of 7-bit US-ASCII characters in a string. + * + * @param begin start position + * @param end end position + * @return number of ASCII characters + */ + static size_t countASCIIchars(const string::const_iterator begin, const string::const_iterator end); + + /** Returns whether the specified string is composed exclusively + * of 7-bit ASCII characters. + * + * @param str string to test + * @return true if the string is ASCII-only, false otherwise + */ + static bool is7bit(const string& str); + + /** Returns the position of the first non 7-bit US-ASCII character in a string. + * + * @param begin start position + * @param end end position + * @return position since begin, or string::npos + */ + static size_t findFirstNonASCIIchar(const string::const_iterator begin, const string::const_iterator end); + + /** Convert the specified value to a string value. + * + * @param value to convert + * @return value converted from type 'TYPE' + */ + template <class TYPE> + static const string toString(const TYPE& value) + { + std::ostringstream oss; + oss.imbue(std::locale::classic()); + + oss << value; + + return (oss.str()); + } + + /** Convert the specified string value to a value of + * the specified type. + * + * @param value value to convert + * @return value converted into type 'TYPE' + */ + template <class TYPE> + static const TYPE fromString(const string& value) + { + TYPE ret; + + std::istringstream iss(value); + iss.imbue(std::locale::classic()); + + iss >> ret; + + return (ret); + } + + /** Unquote the specified string and transform escaped characters. + * + * @param str string from which to remove quotes + * @return unquoted string + */ + static const string unquote(const string& str); + + /** Determines whether the specified string needs to be quoted. + * + * @param str string to test + * @param specialChars list of characters that will cause the + * string to be quoted + * @return true if the string needs to be quoted, false otherwise + */ + static bool needQuoting(const string& str, + const string& specialChars = " \t\"(),:;<>@[\\]"); + + /** Quotes the specified string. + * + * @param str string to quote + * @param escapeSpecialChars list of characters that will be escaped + * @param escapeChar character that will be used for escaping (eg. '\') + * @return quoted string + */ + static string quote(const string& str, const string& escapeSpecialChars, const string& escapeChar); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED diff --git a/src/vmime/utility/sync/autoLock.hpp b/src/vmime/utility/sync/autoLock.hpp new file mode 100644 index 00000000..c058429d --- /dev/null +++ b/src/vmime/utility/sync/autoLock.hpp @@ -0,0 +1,66 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_SYNC_AUTOLOCK_HPP_INCLUDED +#define VMIME_UTILITY_SYNC_AUTOLOCK_HPP_INCLUDED + + +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { +namespace sync { + + +/** Critical section wrapper class + */ + +template <class M> +class VMIME_EXPORT autoLock : public object +{ +public: + + autoLock(shared_ptr <M> mutex) + : m_mutex(mutex) + { + m_mutex->lock(); + } + + ~autoLock() + { + m_mutex->unlock(); + } + +private: + + shared_ptr <M> m_mutex; +}; + + +} // sync +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SYNC_AUTOLOCK_HPP_INCLUDED diff --git a/src/utility/sync/criticalSection.cpp b/src/vmime/utility/sync/criticalSection.cpp index f2512d14..f2512d14 100644 --- a/src/utility/sync/criticalSection.cpp +++ b/src/vmime/utility/sync/criticalSection.cpp diff --git a/src/vmime/utility/sync/criticalSection.hpp b/src/vmime/utility/sync/criticalSection.hpp new file mode 100644 index 00000000..9703d73c --- /dev/null +++ b/src/vmime/utility/sync/criticalSection.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_SYNC_CRITICALSECTION_HPP_INCLUDED +#define VMIME_UTILITY_SYNC_CRITICALSECTION_HPP_INCLUDED + + +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { +namespace sync { + + +/** Critical section class. + */ + +class VMIME_EXPORT criticalSection : public object +{ +public: + + virtual ~criticalSection(); + + /** Enters the critical section. + */ + virtual void lock() = 0; + + /** Leaves the critical section. + */ + virtual void unlock() = 0; + +protected: + + criticalSection(); + criticalSection(criticalSection&); +}; + + +} // sync +} // utility +} // vmime + + +#endif // VMIME_UTILITY_SYNC_CRITICALSECTION_HPP_INCLUDED diff --git a/src/utility/url.cpp b/src/vmime/utility/url.cpp index ce0dc39a..ce0dc39a 100644 --- a/src/utility/url.cpp +++ b/src/vmime/utility/url.cpp diff --git a/src/vmime/utility/url.hpp b/src/vmime/utility/url.hpp new file mode 100644 index 00000000..84aba618 --- /dev/null +++ b/src/vmime/utility/url.hpp @@ -0,0 +1,207 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_URL_HPP_INCLUDED +#define VMIME_UTILITY_URL_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" +#include "vmime/propertySet.hpp" + + +namespace vmime { +namespace utility { + + +/** This class represents a Uniform Resource Locator (a pointer + * to a "resource" on the World Wide Web). + */ + +class VMIME_EXPORT url +{ +public: + + /** Means "port not specified" (use default port). */ + static const port_t UNSPECIFIED_PORT; + + /** Standard name for FILE protocol (local file-system). */ + static const string PROTOCOL_FILE; + + /** Standard name for HTTP protocol. */ + static const string PROTOCOL_HTTP; + + /** Standard name for FTP protocol. */ + static const string PROTOCOL_FTP; + + + /** Construct an URL from a string (parse the URL components). + * + * @param s full URL string (eg. http://www.vmime.org:80/download.html) + * @throw exceptions::malformed_url if URL is malformed + */ + url(const string& s); + + /** Construct an URL from another URL object. + * + * @param u other URL object + */ + url(const url& u); + + /** Construct an URL from the components. + * + * @param protocol protocol (eg. "http", "ftp"...) + * @param host host name (eg. "www.vmime.org", "123.45.67.89") + * @param port optional port number (eg. 80, 110 or UNSPECIFIED_PORT to mean "default") + * @param path optional full path (eg. "download.html") + * @param username optional user name + * @param password optional user password + */ + url(const string& protocol, const string& host, const port_t port = UNSPECIFIED_PORT, + const string& path = "", const string& username = "", const string& password = ""); + + + /** Return the protocol of the URL (eg: "http"). + * + * @return protocol of the URL + */ + const string& getProtocol() const; + + /** Set the protocol of the URL. + * + * @param protocol new protocol (eg: "http") + */ + void setProtocol(const string& protocol); + + /** Return the username specified in the URL + * or empty if not specified. + * + * @return user name + */ + const string& getUsername() const; + + /** Set the username of the URL. + * + * @param username user name + */ + void setUsername(const string& username); + + /** Return the password specified in the URL + * or empty if not specified. + * + * @return user password + */ + const string& getPassword() const; + + /** Set the password of the URL. + * + * @param password user password + */ + void setPassword(const string& password); + + /** Return the host name of the URL (server name or IP address). + * + * @return host name + */ + const string& getHost() const; + + /** Set the host name of the URL. + * + * @param host server name or IP address + */ + void setHost(const string& host); + + /** Return the port of the URL, or url::UNSPECIFIED_PORT if + * the default port if used. + * + * @return server port + */ + port_t getPort() const; + + /** Set the port of the URL. + * + * @param port server port or url::UNSPECIFIED_PORT to + * use the default port of the protocol + */ + void setPort(const port_t port); + + /** Return the path portion of the URL, + * or empty if not specified. + * + * @return path + */ + const string& getPath() const; + + /** Set the part portion of the URL. + * + * @param path path + */ + void setPath(const string& path); + + /** Return the parameters of the URL (read-only). + * + * @return parameters + */ + const std::map <string, string>& getParams() const; + + /** Return the parameters of the URL. + * + * @return parameters + */ + std::map <string, string>& getParams(); + + /** Build a string URL from this object. + */ + operator string() const; + + url& operator=(const url& u); + url& operator=(const string& s); + +private: + + const string build() const; + void parse(const string& str); + + // Format: + // "protocol://[username[:password]@]host[:port][/path]" + + string m_protocol; + + string m_username; + string m_password; + + string m_host; + + port_t m_port; + + string m_path; + + std::map <string, string> m_params; +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_URL_HPP_INCLUDED diff --git a/src/utility/urlUtils.cpp b/src/vmime/utility/urlUtils.cpp index 20818764..20818764 100644 --- a/src/utility/urlUtils.cpp +++ b/src/vmime/utility/urlUtils.cpp diff --git a/src/vmime/utility/urlUtils.hpp b/src/vmime/utility/urlUtils.hpp new file mode 100644 index 00000000..c21e7aa4 --- /dev/null +++ b/src/vmime/utility/urlUtils.hpp @@ -0,0 +1,58 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_UTILITY_URLUTILS_HPP_INCLUDED +#define VMIME_UTILITY_URLUTILS_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" + + +namespace vmime { +namespace utility { + + +/** Miscellaneous functions related to URLs. + */ + +class VMIME_EXPORT urlUtils +{ +public: + + /** Encode extended characters in a URL string (ASCII characters + * are unmodified, other are encoded as '%' followed by hex code). + */ + static const string encode(const string& s); + + /** Decode an hex-encoded URL (see encode()). + */ + static const string decode(const string& s); +}; + + +} // utility +} // vmime + + +#endif // VMIME_UTILITY_URLUTILS_HPP_INCLUDED diff --git a/src/vmime/vmime.hpp b/src/vmime/vmime.hpp new file mode 100644 index 00000000..9bb017e3 --- /dev/null +++ b/src/vmime/vmime.hpp @@ -0,0 +1,161 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should.have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_INCLUDED +#define VMIME_INCLUDED + + +// Configuration +#include "vmime/config.hpp" + +// Base definitions +#include "vmime/base.hpp" +#include "vmime/exception.hpp" +#include "vmime/platform.hpp" + +// Base components +#include "vmime/dateTime.hpp" +#include "vmime/message.hpp" +#include "vmime/bodyPart.hpp" +#include "vmime/charset.hpp" +#include "vmime/text.hpp" +#include "vmime/encoding.hpp" +#include "vmime/contentDisposition.hpp" +#include "vmime/emailAddress.hpp" +#include "vmime/mailbox.hpp" +#include "vmime/mailboxGroup.hpp" +#include "vmime/mailboxList.hpp" +#include "vmime/addressList.hpp" +#include "vmime/mediaType.hpp" +#include "vmime/messageId.hpp" +#include "vmime/messageIdSequence.hpp" +#include "vmime/relay.hpp" +#include "vmime/disposition.hpp" +#include "vmime/path.hpp" + +#include "vmime/emptyContentHandler.hpp" +#include "vmime/fileContentHandler.hpp" +#include "vmime/stringContentHandler.hpp" +#include "vmime/streamContentHandler.hpp" + +#include "vmime/generationContext.hpp" +#include "vmime/parsingContext.hpp" + +// Message components +#include "vmime/message.hpp" + +// Header fields +#include "vmime/headerFieldFactory.hpp" +#include "vmime/mailboxField.hpp" +#include "vmime/parameterizedHeaderField.hpp" + +// Encoders +#include "vmime/utility/encoder/encoderFactory.hpp" + +// Streams +#include "vmime/utility/filteredStream.hpp" +#include "vmime/utility/inputStream.hpp" +#include "vmime/utility/inputStreamAdapter.hpp" +#include "vmime/utility/inputStreamByteBufferAdapter.hpp" +#include "vmime/utility/inputStreamPointerAdapter.hpp" +#include "vmime/utility/inputStreamSocketAdapter.hpp" +#include "vmime/utility/inputStreamStringAdapter.hpp" +#include "vmime/utility/inputStreamStringProxyAdapter.hpp" +#include "vmime/utility/outputStream.hpp" +#include "vmime/utility/outputStreamAdapter.hpp" +#include "vmime/utility/outputStreamByteArrayAdapter.hpp" +#include "vmime/utility/outputStreamSocketAdapter.hpp" +#include "vmime/utility/outputStreamStringAdapter.hpp" +#include "vmime/utility/streamUtils.hpp" + +// Message builder/parser +#include "vmime/messageBuilder.hpp" +#include "vmime/messageParser.hpp" + +#include "vmime/fileAttachment.hpp" +#include "vmime/defaultAttachment.hpp" +#include "vmime/messageAttachment.hpp" + +#include "vmime/plainTextPart.hpp" +#include "vmime/htmlTextPart.hpp" + +#include "vmime/attachmentHelper.hpp" + +// MDN +#include "vmime/mdn/MDNHelper.hpp" + +// Misc +#include "vmime/misc/importanceHelper.hpp" + +// Property set +#include "vmime/propertySet.hpp" + +// Utilities +#include "vmime/utility/datetimeUtils.hpp" +#include "vmime/utility/filteredStream.hpp" +#include "vmime/charsetConverter.hpp" + +// Security +#include "vmime/security/authenticator.hpp" +#include "vmime/security/defaultAuthenticator.hpp" + +// Security/digest +#include "vmime/security/digest/messageDigestFactory.hpp" + +// Security/SASL +#if VMIME_HAVE_SASL_SUPPORT + #include "vmime/security/sasl/SASLAuthenticator.hpp" + #include "vmime/security/sasl/defaultSASLAuthenticator.hpp" + #include "vmime/security/sasl/SASLContext.hpp" + #include "vmime/security/sasl/SASLSession.hpp" +#endif // VMIME_HAVE_SASL_SUPPORT + +// Messaging features +#if VMIME_HAVE_MESSAGING_FEATURES + #include "vmime/net/socket.hpp" + + #include "vmime/net/serviceFactory.hpp" + #include "vmime/net/store.hpp" + #include "vmime/net/transport.hpp" + + #include "vmime/net/session.hpp" + + #include "vmime/net/folder.hpp" + #include "vmime/net/message.hpp" +#endif // VMIME_HAVE_MESSAGING_FEATURES + +// Net/TLS +#if VMIME_HAVE_TLS_SUPPORT + #include "vmime/security/cert/certificate.hpp" + #include "vmime/security/cert/certificateChain.hpp" + #include "vmime/security/cert/certificateVerifier.hpp" + + #include "vmime/security/cert/X509Certificate.hpp" + + #include "vmime/security/cert/defaultCertificateVerifier.hpp" + + #include "vmime/net/tls/TLSSession.hpp" +#endif // VMIME_HAVE_TLS_SUPPORT + + +#endif // VMIME_INCLUDED diff --git a/src/word.cpp b/src/vmime/word.cpp index 2ee4d3e7..2ee4d3e7 100644 --- a/src/word.cpp +++ b/src/vmime/word.cpp diff --git a/src/vmime/word.hpp b/src/vmime/word.hpp new file mode 100644 index 00000000..a6e2402e --- /dev/null +++ b/src/vmime/word.hpp @@ -0,0 +1,195 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_WORD_HPP_INCLUDED +#define VMIME_WORD_HPP_INCLUDED + + +#include "vmime/headerFieldValue.hpp" +#include "vmime/charset.hpp" +#include "vmime/charsetConverterOptions.hpp" + + +namespace vmime +{ + + +/** A class that encapsulates an encoded-word (RFC-2047): + * some text encoded into one specified charset. + */ + +class VMIME_EXPORT word : public headerFieldValue +{ + friend class text; + +public: + + word(); + word(const word& w); + word(const string& buffer); // Defaults to local charset + word(const string& buffer, const charset& charset); + + /** Return the raw data for this encoded word. + * + * @return raw data buffer + */ + const string& getBuffer() const; + + /** Return the raw data for this encoded word. + * + * @return raw data buffer + */ + string& getBuffer(); + + /** Tests whether this word is empty. + * + * @return true if the buffer is empty, false otherwise + */ + bool isEmpty() const; + + /** Set the raw data for this encoded word. + * + * @param buffer raw data buffer + */ + void setBuffer(const string& buffer); + + /** Return the charset of this word. + * + * @return charset for this word + */ + const charset& getCharset() const; + + /** Set the charset of this word. + * + * @param ch charset of this word + */ + void setCharset(const charset& ch); + + + word& operator=(const word& w); + word& operator=(const string& s); + + bool operator==(const word& w) const; + bool operator!=(const word& w) const; + + /** Return the contained text converted to the specified charset. + * + * @param dest output charset + * @param opts options for charset conversion + * @return word converted to the specified charset + */ + const string getConvertedText(const charset& dest, + const charsetConverterOptions& opts = charsetConverterOptions()) const; + + /** Replace data in this word by data in other word. + * + * @param other other word to copy data from + */ + void copyFrom(const component& other); + + /** Clone this word. + * + * @return a copy of this word + */ + shared_ptr <component> clone() const; + + +#ifndef VMIME_BUILDING_DOC + class generatorState + { + public: + + generatorState() + : isFirstWord(true), prevWordIsEncoded(false), lastCharIsSpace(false) + { + } + + bool isFirstWord; + bool prevWordIsEncoded; + bool lastCharIsSpace; + }; +#endif + + +protected: + + void parseImpl + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition = NULL); + + void generateImpl + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos = 0, + size_t* newLinePos = NULL) const; + +public: + + using component::generate; + +#ifndef VMIME_BUILDING_DOC + void generate + (const generationContext& ctx, + utility::outputStream& os, + const size_t curLinePos, + size_t* newLinePos, + const int flags, + generatorState* state) const; +#endif + + const std::vector <shared_ptr <component> > getChildComponents(); + +private: + + static shared_ptr <word> parseNext + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition, + bool prevIsEncoded, + bool* isEncoded, + bool isFirst); + + static const std::vector <shared_ptr <word> > parseMultiple + (const parsingContext& ctx, + const string& buffer, + const size_t position, + const size_t end, + size_t* newPosition); + + + // The "m_buffer" of this word holds the data, and this data is encoded + // in the specified "m_charset". + string m_buffer; + charset m_charset; +}; + + +} // vmime + + +#endif // VMIME_WORD_HPP_INCLUDED diff --git a/src/wordEncoder.cpp b/src/vmime/wordEncoder.cpp index 421a9ecd..421a9ecd 100644 --- a/src/wordEncoder.cpp +++ b/src/vmime/wordEncoder.cpp diff --git a/src/vmime/wordEncoder.hpp b/src/vmime/wordEncoder.hpp new file mode 100644 index 00000000..6f652fa2 --- /dev/null +++ b/src/vmime/wordEncoder.hpp @@ -0,0 +1,112 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002-2013 Vincent Richard <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of +// the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// Linking this library statically or dynamically with other modules is making +// a combined work based on this library. Thus, the terms and conditions of +// the GNU General Public License cover the whole combination. +// + +#ifndef VMIME_WORDENCODER_HPP_INCLUDED +#define VMIME_WORDENCODER_HPP_INCLUDED + + +#include "vmime/charset.hpp" + + +namespace vmime +{ + + +namespace utility { +namespace encoder { + +class encoder; + +} // encoder +} // utility + + +/** Encodes words following RFC-2047. + */ + +class VMIME_EXPORT wordEncoder +{ +public: + + /** Available encodings for RFC-2047. */ + enum Encoding + { + ENCODING_AUTO, + ENCODING_QP, + ENCODING_B64 + }; + + + wordEncoder(const string& buffer, const charset& charset, const Encoding encoding = ENCODING_AUTO); + + + /** Return the next chunk in the word. + * + * @param maxLength maximal length of the chunk + * @return next chunk, of maximal length 'maxLength' if possible + */ + const string getNextChunk(const size_t maxLength); + + /** Return the encoding used. + * + * @return encoding + */ + Encoding getEncoding() const; + + /** Test whether RFC-2047 encoding is needed. + * + * @param ctx generation context + * @param buffer buffer to analyze + * @param charset charset of the buffer + * @return true if encoding is needed, false otherwise. + */ + static bool isEncodingNeeded(const generationContext& ctx, const string& buffer, const charset& charset); + + /** Guess the best RFC-2047 encoding to use for the specified buffer. + * + * @param buffer buffer to analyze + * @param charset charset of the buffer + * @return RFC-2047 encoding + */ + static Encoding guessBestEncoding(const string& buffer, const charset& charset); + +private: + + string m_buffer; + size_t m_pos; + size_t m_length; + + bool m_simple; + + charset m_charset; + Encoding m_encoding; + + shared_ptr <utility::encoder::encoder> m_encoder; +}; + + +} // vmime + + +#endif // VMIME_WORDENCODER_HPP_INCLUDED + |