From 18786d2015ed381869f4d998ee36f3f4f914cfba Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 30 Aug 2011 21:59:16 +0300 Subject: [PATCH] upload project --- SMTPEmail.pro | 33 +++++ SMTPEmail.pro.user | 307 +++++++++++++++++++++++++++++++++++++++++ emailaddress.cpp | 42 ++++++ emailaddress.h | 41 ++++++ mail.cpp | 101 ++++++++++++++ mail.h | 81 +++++++++++ mimeattachment.cpp | 27 ++++ mimeattachment.h | 29 ++++ mimefile.cpp | 59 ++++++++ mimefile.h | 49 +++++++ mimehtml.cpp | 66 +++++++++ mimehtml.h | 49 +++++++ mimeinlinefile.cpp | 45 ++++++ mimeinlinefile.h | 41 ++++++ mimemessage.cpp | 93 +++++++++++++ mimemessage.h | 55 ++++++++ mimepart.cpp | 62 +++++++++ mimepart.h | 68 +++++++++ mimetext.cpp | 66 +++++++++ mimetext.h | 49 +++++++ smtpclient.cpp | 337 +++++++++++++++++++++++++++++++++++++++++++++ smtpclient.h | 140 +++++++++++++++++++ 22 files changed, 1840 insertions(+) create mode 100644 SMTPEmail.pro create mode 100644 SMTPEmail.pro.user create mode 100644 emailaddress.cpp create mode 100644 emailaddress.h create mode 100644 mail.cpp create mode 100644 mail.h create mode 100644 mimeattachment.cpp create mode 100644 mimeattachment.h create mode 100644 mimefile.cpp create mode 100644 mimefile.h create mode 100644 mimehtml.cpp create mode 100644 mimehtml.h create mode 100644 mimeinlinefile.cpp create mode 100644 mimeinlinefile.h create mode 100644 mimemessage.cpp create mode 100644 mimemessage.h create mode 100644 mimepart.cpp create mode 100644 mimepart.h create mode 100644 mimetext.cpp create mode 100644 mimetext.h create mode 100644 smtpclient.cpp create mode 100644 smtpclient.h diff --git a/SMTPEmail.pro b/SMTPEmail.pro new file mode 100644 index 0000000..9ffaa64 --- /dev/null +++ b/SMTPEmail.pro @@ -0,0 +1,33 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2011-08-11T20:59:25 +# +#------------------------------------------------- + +QT += core gui network + +TARGET = SMTPEmail +TEMPLATE = app + + +SOURCES += main.cpp \ + smtpclient.cpp \ + mimemessage.cpp \ + mimepart.cpp \ + mimetext.cpp \ + mimeattachment.cpp \ + mimehtml.cpp \ + emailaddress.cpp \ + mimefile.cpp \ + mimeinlinefile.cpp + +HEADERS += \ + smtpclient.h \ + mimemessage.h \ + mimepart.h \ + mimetext.h \ + mimeattachment.h \ + mimehtml.h \ + emailaddress.h \ + mimefile.h \ + mimeinlinefile.h diff --git a/SMTPEmail.pro.user b/SMTPEmail.pro.user new file mode 100644 index 0000000..06650b1 --- /dev/null +++ b/SMTPEmail.pro.user @@ -0,0 +1,307 @@ + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + System + false + false + 4 + true + 1 + true + false + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + Qt4ProjectManager.Target.DesktopTarget + 0 + 0 + 0 + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + + + qmake + + QtProjectManager.QMakeBuildStep + false + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.3 for GCC (Qt SDK) Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /home/bluetiger/Dev/Qt/SMTPEmail-build-desktop + 3 + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + + + qmake + + QtProjectManager.QMakeBuildStep + false + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Desktop Qt 4.7.3 for GCC (Qt SDK) Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /home/bluetiger/Dev/Qt/SMTPEmail-build-desktop + 3 + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + + + qmake + + QtProjectManager.QMakeBuildStep + false + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt in PATH Release + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + /home/bluetiger/Dev/Qt/SMTPEmail-build-desktop + 4 + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + true + + + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + + + qmake + + QtProjectManager.QMakeBuildStep + false + + false + + + Make + + Qt4ProjectManager.MakeStep + false + + + + 2 + Build + + ProjectExplorer.BuildSteps.Build + + + + Make + + Qt4ProjectManager.MakeStep + true + clean + + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Qt in PATH Debug + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + /home/bluetiger/Dev/Qt/SMTPEmail-build-desktop + 4 + ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-64bit. + true + + 4 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + No deployment + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + true + 25 + + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + SMTPEmail + + Qt4ProjectManager.Qt4RunConfiguration + 2 + + SMTPEmail.pro + false + false + + + 3768 + true + false + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {b0e80f08-a784-4568-bc8d-4b27a017e1d9} + + + ProjectExplorer.Project.Updater.FileVersion + 9 + + diff --git a/emailaddress.cpp b/emailaddress.cpp new file mode 100644 index 0000000..cc6c55a --- /dev/null +++ b/emailaddress.cpp @@ -0,0 +1,42 @@ +#include "emailaddress.h" + +/* [1] Constructors and Destructors */ + +EmailAddress::EmailAddress(const QString & address, const QString & name) +{ + this->address = address; + this->name = name; +} + +EmailAddress::~EmailAddress() +{ +} + +/* [1] --- */ + + +/* [2] Getters and Setters */ + +void EmailAddress::setName(const QString & name) +{ + this->name = name; + +} + +void EmailAddress::setAddress(const QString & address) +{ + this->address = address; +} + +const QString & EmailAddress::getName() const +{ + return name; +} + +const QString & EmailAddress::getAddress() const +{ + return address; +} + +/* [2] --- */ + diff --git a/emailaddress.h b/emailaddress.h new file mode 100644 index 0000000..cb2d68f --- /dev/null +++ b/emailaddress.h @@ -0,0 +1,41 @@ +#ifndef EMAILADDRESS_H +#define EMAILADDRESS_H + +#include + +class EmailAddress : public QObject +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + EmailAddress(); + EmailAddress(const QString & address, const QString & name=""); + + ~EmailAddress(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + void setName(const QString & name); + void setAddress(const QString & address); + + const QString & getName() const; + const QString & getAddress() const; + + /* [2] --- */ + + +private: + + /* [3] Private members */ + + QString name; + QString address; + + /* [3] --- */ +}; + +#endif // EMAILADDRESS_H diff --git a/mail.cpp b/mail.cpp new file mode 100644 index 0000000..34616cc --- /dev/null +++ b/mail.cpp @@ -0,0 +1,101 @@ +#include "mail.h" +#include + +Mail::Mail() +{ +} + +void Mail::setSender(QString address, QString name) +{ + this->sender = new EmailAddress(address, name); +} + +void Mail::addRecipient(QString rcpt, QString name) +{ + this->recipients << EmailAddress (rcpt, name); +} + +void Mail::setSubject(QString subject) +{ + this->subject = subject; +} + +void Mail::setContent(QString text) +{ + this->text = text; +} + +EmailAddress & Mail::getSender() +{ + return *sender; +} + +QList & Mail::getRecipients() +{ + return recipients; +} + +QString & Mail::getSubject() +{ + return subject; +} + +QString & Mail::getText() +{ + return text; + +} + +void Mail::addAttachment(QFile *file, QString type) +{ + attachments << Attachment (*file, type); +} + +QList & Mail::getAttachments() +{ + return attachments; +} + + + +/****** Email Address *******/ +EmailAddress::EmailAddress(QString address, QString name) +{ + this->address = address; + this->name = name; +} + +QString EmailAddress::getAddress() const +{ + return address; +} + +QString EmailAddress::getName() const +{ + return name; +} + + +/****** Attachment *******/ +Attachment::Attachment(QFile& file, QString type) : + file(file) +{ + //this->file = file; + this->type = type; + this->name = QFileInfo(file).fileName(); +} + +QFile& Attachment::getFile() const +{ + return file; +} + +QString Attachment::getName() const +{ + return name; +} + +QString Attachment::getType() const +{ + return type; +} diff --git a/mail.h b/mail.h new file mode 100644 index 0000000..74585bb --- /dev/null +++ b/mail.h @@ -0,0 +1,81 @@ +#ifndef MAIL_H +#define MAIL_H + +#include +#include + +class EmailAddress; +class Attachment; + +class Mail : public QObject +{ + Q_OBJECT +public: + Mail(); + + enum ContentType + { + Html, + PlainText + }; + + + void setSender(QString sender, QString name=""); + void setSender(EmailAddress adr); + + void addRecipient(QString rcpt, QString name=""); + void setSubject(QString title); + void setContent(QString text); + void setEncoding(QString text); + void addAttachment(QFile* file, QString type="application/octet-stream"); + + EmailAddress& getSender(); + QList& getRecipients(); + QString& getSubject(); + QString& getText(); + QList& getAttachments(); + + +private: + EmailAddress* sender; + QList recipients; + QString subject; + QString text; + QList attachments; + +}; +/* +class EmailAddress +{ +public: + EmailAddress(QString address, QString name=""); + + QString getName() const; + QString getAddress() const; + +private: + QString name; + QString address; +}; +*/ + +class Attachment +{ +public: + Attachment(QFile& file, QString type = "application/octet-stream"); + + QString getName() const; + QFile& getFile() const; + QString getType() const; + + void setName(QString name); + void setType(QString type); + +private: + QFile& file; + QString name; + QString type; +}; + + +#endif // MAIL_H diff --git a/mimeattachment.cpp b/mimeattachment.cpp new file mode 100644 index 0000000..4316c8e --- /dev/null +++ b/mimeattachment.cpp @@ -0,0 +1,27 @@ +#include "mimeattachment.h" +#include + +/* [1] Constructors and Destructors */ + +MimeAttachment::MimeAttachment(QFile *file) + : MimeFile(file) +{ +} + +MimeAttachment::~MimeAttachment() +{ +} + +/* [1] --- */ + + +/* [2] Protected methods */ + +void MimeAttachment::prepare() +{ + MimeFile::prepare(); + + this->header += "Content-disposition: attachment;\n"; +} + +/* [2] --- */ diff --git a/mimeattachment.h b/mimeattachment.h new file mode 100644 index 0000000..9892742 --- /dev/null +++ b/mimeattachment.h @@ -0,0 +1,29 @@ +#ifndef MIMEATTACHMENT_H +#define MIMEATTACHMENT_H + +#include +#include "mimepart.h" +#include "mimefile.h" + +class MimeAttachment : public MimeFile +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + MimeAttachment(QFile* file); + ~MimeAttachment(); + + /* [1] --- */ + +protected: + + /* [2] Protected methods */ + + void prepare(); + + /* [2] --- */ +}; + +#endif // MIMEATTACHMENT_H diff --git a/mimefile.cpp b/mimefile.cpp new file mode 100644 index 0000000..525bad1 --- /dev/null +++ b/mimefile.cpp @@ -0,0 +1,59 @@ +#include "mimefile.h" + +#include + +/* [1] Constructors and Destructors */ + +MimeFile::MimeFile(QFile *file) +{ + this->file = file; + this->type = "application/octet-stream"; + this->name = QFileInfo(*file).fileName(); +} + +MimeFile::~MimeFile() +{ +} + +/* [1] --- */ + + +/* [2] Getters and setters */ + +void MimeFile::setName(const QString & name) +{ + this->name = name; +} + +void MimeFile::setType(const QString & type) +{ + this->type = type; +} + +const QString & MimeFile::getName() const +{ + return name; +} + +const QString & MimeFile::getType() const +{ + return type; +} + +/* [2] --- */ + + +/* [3] Protected methods */ + +void MimeFile::prepare() +{ + this->header = "Content-Type: " + type + "; name=" + name + "\n"; + this->header += "Content-Transfer-Encoding: base64\n"; + + file->open(QIODevice::ReadOnly); + this->content = file->readAll().toBase64() + "\n"; + file->close(); +} + +/* [3] --- */ + diff --git a/mimefile.h b/mimefile.h new file mode 100644 index 0000000..dc55284 --- /dev/null +++ b/mimefile.h @@ -0,0 +1,49 @@ +#ifndef MIMEFILE_H +#define MIMEFILE_H + +#include "mimepart.h" +#include + +class MimeFile : public MimePart +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + MimeFile(QFile *f); + ~MimeFile(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + void setName(const QString & name); + void setType(const QString & type); + + const QString & getName() const; + const QString & getType() const; + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + QFile* file; + QString name; + QString type; + + /* [3] --- */ + + + /* [4] Protected methods */ + + void prepare(); + + /* [4] --- */ + +}; + +#endif // MIMEFILE_H diff --git a/mimehtml.cpp b/mimehtml.cpp new file mode 100644 index 0000000..fd54385 --- /dev/null +++ b/mimehtml.cpp @@ -0,0 +1,66 @@ +#include "mimehtml.h" + +/* [1] Constructors and Destructors */ + +MimeHtml::MimeHtml() +{ + this->html = ""; + this->encoding = PlainText; + this->charset = "utf-8"; +} + +MimeHtml::~MimeHtml() {} + +/* [1] --- */ + + +/* [2] Getters and Setters */ + +void MimeHtml::setHtml(const QString & html) +{ + this->html = html; +} + +void MimeHtml::setEncoding(MimePart::Encoding enc) +{ + this->encoding = enc; +} + +void MimeHtml::setCharset(const QString & charset) +{ + this->charset = charset; +} + +const QString & MimeHtml::getHtml() const +{ + return html; +} + +const QString & MimeHtml::getCharset() const +{ + return charset; +} + +MimePart::Encoding MimeHtml::getEncoding() const +{ + return encoding; +} + +/* [2] --- */ + + +/* [3] Protected methods */ + +void MimeHtml::prepare() +{ + this->header = "Content-Type: text/html; charset=" + + this->charset + "\n"; + + this->header += "Content-Transfer-Encoding: "; + this->header += (this->encoding == PlainText) ? "7bit\n" : "base64\n"; + + this->content = (this->encoding == PlainText) ? this->html.toAscii() : QByteArray().append(this->html).toBase64(); + this->content += "\n"; +} + +/* [3] --- */ diff --git a/mimehtml.h b/mimehtml.h new file mode 100644 index 0000000..366c52c --- /dev/null +++ b/mimehtml.h @@ -0,0 +1,49 @@ +#ifndef MIMEHTML_H +#define MIMEHTML_H + +#include "mimepart.h" + +class MimeHtml : public MimePart +{ + Q_OBJECT +public: + + /* [1] Constructors and Destructors */ + + MimeHtml(); + ~MimeHtml(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + void setHtml(const QString & html); + void setEncoding(Encoding enc); + void setCharset(const QString & charset); + + const QString& getHtml() const; + const QString& getCharset() const; + Encoding getEncoding() const; + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + QString html; + QString charset; + Encoding encoding; + + /* [3] --- */ + + + /* [4] Protected methods */ + + void prepare(); + + /* [4] --- */ +}; + +#endif // MIMEHTML_H diff --git a/mimeinlinefile.cpp b/mimeinlinefile.cpp new file mode 100644 index 0000000..bdf580e --- /dev/null +++ b/mimeinlinefile.cpp @@ -0,0 +1,45 @@ +#include "mimeinlinefile.h" + +/* [1] Constructors and Destructors */ + +MimeInlineFile::MimeInlineFile(QFile *f) + : MimeFile(f) +{ + return; +} + +MimeInlineFile::~MimeInlineFile() +{} + +/* [1] --- */ + + +/* [2] Getters and Setters */ + +void MimeInlineFile::setContentId(const QString & cid) +{ + this->cid = cid; +} + +const QString & MimeInlineFile::getContentId() const +{ + return cid; +} + +/* [2] --- */ + + +/* [3] Protected methods */ + +void MimeInlineFile::prepare() +{ + MimeFile::prepare(); + + this->header += "Content-id: <" + cid + ">\n"; + this->header += "Content-disposition: inline\n"; +} + +/* [3] --- */ + + + diff --git a/mimeinlinefile.h b/mimeinlinefile.h new file mode 100644 index 0000000..c538934 --- /dev/null +++ b/mimeinlinefile.h @@ -0,0 +1,41 @@ +#ifndef MIMEINLINEFILE_H +#define MIMEINLINEFILE_H + +#include "mimefile.h" + +class MimeInlineFile : public MimeFile +{ +public: + + /* [1] Constructors and Destructors */ + + MimeInlineFile(QFile *f); + ~MimeInlineFile(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + void setContentId(const QString & cid); + const QString & getContentId() const; + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + QString cid; + + /* [3] --- */ + + + /* [4] Protected methods */ + + void prepare(); + + /* [4] --- */ +}; + +#endif // MIMEINLINEFILE_H diff --git a/mimemessage.cpp b/mimemessage.cpp new file mode 100644 index 0000000..e4123be --- /dev/null +++ b/mimemessage.cpp @@ -0,0 +1,93 @@ +#include "mimemessage.h" + +#include + +/* [1] Constructors and Destructors */ + +MimeMessage::MimeMessage() +{ +} + +MimeMessage::~MimeMessage() +{ + +} + +/* [1] --- */ + + +/* [2] Getters and Setters */ + +void MimeMessage::setSender(EmailAddress* e) +{ + this->sender = e; +} + +void MimeMessage::addRecipient(EmailAddress* rcpt) +{ + this->recipients << rcpt; +} + +void MimeMessage::setSubject(const QString & subject) +{ + this->subject = subject; +} + +void MimeMessage::addPart(MimePart *part) +{ + this->parts << part; +} + +const EmailAddress & MimeMessage::getSender() const +{ + return *sender; +} + +const QList & MimeMessage::getRecipients() const +{ + return recipients; +} + +const QString & MimeMessage::getSubject() const +{ + return subject; +} + +const QList & MimeMessage::getParts() const +{ + return parts; +} + +/* [2] --- */ + + +/* [3] Public Methods */ + +QString MimeMessage::toString() +{ + QString mime; + mime = "From: " + sender->getName() + " <" + sender->getAddress() + ">\n"; + + QList::iterator it; + for (it = recipients.begin(); it != recipients.end(); ++it) + mime += "To: " + (*it)->getName() + " <" + (*it)->getAddress() + ">\n"; + + mime += "Subject: " + subject + "\n"; + + QString boundary = "----MIME-part-boundary=" + QByteArray().append(QDateTime::currentDateTime().toString()).toBase64() + "-end"; + + mime += "MIME-Version: 1.0\n"; + mime += "Content-type: multipart/mixed; boundary=\"" + boundary + "\"\n\n"; + + boundary = "--" + boundary; + + QList::iterator i; + for (i = parts.begin(); i != parts.end(); ++i) + mime += boundary + "\n" + (*i)->toString(); + + mime += boundary + "--\n"; + + return mime; +} + +/* [3] --- */ diff --git a/mimemessage.h b/mimemessage.h new file mode 100644 index 0000000..2afb378 --- /dev/null +++ b/mimemessage.h @@ -0,0 +1,55 @@ +#ifndef MIMEMESSAGE_H +#define MIMEMESSAGE_H + +#include +#include +#include + +class MimeMessage : public QObject +{ +public: + + /* [1] Constructors and Destructors */ + + MimeMessage(); + ~MimeMessage(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + void setSender(EmailAddress* e); + void addRecipient(EmailAddress* rcpt); + void setSubject(const QString & subject); + void addPart(MimePart* part); + + const EmailAddress & getSender() const; + const QList & getRecipients() const; + const QString & getSubject() const; + const QList & getParts() const; + + /* [2] --- */ + + + /* [3] Public methods */ + + QString toString(); + + /* [3] --- */ + +protected: + + /* [4] Protected members */ + + EmailAddress* sender; + QList recipients; + QString subject; + QList parts; + + /* [4] --- */ + + +}; + +#endif // MIMEMESSAGE_H diff --git a/mimepart.cpp b/mimepart.cpp new file mode 100644 index 0000000..4f181a7 --- /dev/null +++ b/mimepart.cpp @@ -0,0 +1,62 @@ +#include "mimepart.h" + +/* [1] Constructors and Destructors */ + +MimePart::MimePart() +{ +} + +MimePart::~MimePart() +{ + return; +} + +/* [1] --- */ + + +/* [2] Getters and Setters */ + +void MimePart::setContent(const QString & content) +{ + this->content = content; +} + +void MimePart::setHeader(const QString & header) +{ + this->header = header; +} + +void MimePart::addHeaderLine(const QString & line) +{ + this->header += line; +} + +const QString& MimePart::getHeader() const +{ + return header; +} + +const QString& MimePart::getContent() const +{ + return content; +} + +/* [2] --- */ + + +/* [3] Public methods */ + +QString MimePart::toString() +{ + prepare(); + return header + "\n" + content; +} + +/* [3] --- */ + + +/* [4] Protected methods */ + +void MimePart::prepare() {} + +/* [4] --- */ diff --git a/mimepart.h b/mimepart.h new file mode 100644 index 0000000..504b6f3 --- /dev/null +++ b/mimepart.h @@ -0,0 +1,68 @@ +#ifndef MIMEPART_H +#define MIMEPART_H + +#include + +class MimePart : public QObject +{ + Q_OBJECT +public: + + /* [0] Enumerations */ + + enum Encoding { + PlainText, + Base64, + _7Bit, + _8Bit, + QuotedPrintable // not implemented + }; + + /* [0] --- */ + + + /* [1] Constructors and Destructors */ + + MimePart(); + ~MimePart(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + const QString& getHeader() const; + const QString& getContent() const; + + void setContent(const QString & content); + void setHeader(const QString & header); + + void addHeaderLine(const QString & line); + + /* [2] --- */ + + + /* [3] Public methods */ + + QString toString(); + + /* [3] --- */ + +protected: + + /* [4] Protected members */ + + QString header; + QString content; + + /* [4] --- */ + + + /* [5] Protected methods */ + + virtual void prepare(); + + /* [5] --- */ +}; + +#endif // MIMEPART_H diff --git a/mimetext.cpp b/mimetext.cpp new file mode 100644 index 0000000..1fa0c24 --- /dev/null +++ b/mimetext.cpp @@ -0,0 +1,66 @@ +#include "mimetext.h" + +/* [1] Constructors and Destructors */ + +MimeText::MimeText() +{ + this->charset = "utf-8"; + this->encoding = PlainText; +} + +MimeText::~MimeText() { } + +/* [1] --- */ + + +/* [2] Getters and Setters */ + +void MimeText::setText(const QString & text) +{ + this->text = text; +} + +void MimeText::setEncoding(MimePart::Encoding enc) +{ + this->encoding = enc; +} + +void MimeText::setCharset(const QString & charset) +{ + this->charset = charset; +} + +const QString & MimeText::getText() const +{ + return text; +} + +MimePart::Encoding MimeText::getEncoding() const +{ + return encoding; +} + +const QString & MimeText::getCharset() const +{ + return charset; +} + +/* [2] --- */ + + +/* [3] Protected Methods */ + +void MimeText::prepare() +{ + this->header = "Content-Type: text/plain; charset: " + + this->charset + "\n"; + + this->header += "Content-Transfer-Encoding: "; + this->header += (this->encoding == PlainText) ? "7bit\n" : "base64\n"; + + this->content = (this->encoding == PlainText) ? this->text.toAscii() : QByteArray().append(this->text).toBase64(); + this->content += "\n"; + +} + +/* [3] --- */ diff --git a/mimetext.h b/mimetext.h new file mode 100644 index 0000000..1d22018 --- /dev/null +++ b/mimetext.h @@ -0,0 +1,49 @@ +#ifndef MIMETEXT_H +#define MIMETEXT_H + +#include "mimepart.h" + +class MimeText : public MimePart +{ +public: + + /* [1] Constructors and Destructors */ + + MimeText(); + ~MimeText(); + + /* [1] --- */ + + + /* [2] Getters and Setters*/ + + void setText(const QString & text); + void setEncoding(Encoding enc); + void setCharset(const QString & charset); + + const QString & getText() const; + MimePart::Encoding getEncoding() const; + const QString & getCharset() const; + + /* [2] --- */ + +protected: + + /* [3] Protected members */ + + QString text; + QString charset; + Encoding encoding; + + /* [3] --- */ + + + /* [4] Protected methods */ + + void prepare(); + + /* [4] --- */ + +}; + +#endif // MIMETEXT_H diff --git a/smtpclient.cpp b/smtpclient.cpp new file mode 100644 index 0000000..6786979 --- /dev/null +++ b/smtpclient.cpp @@ -0,0 +1,337 @@ +/* + Copyright (c) Tőkés Attila (bluetiger9) + + Released under LGPL 2.0 +*/ + +#include "smtpclient.h" + +#include +#include + + +/* [1] Constructors and destructors */ + +SmtpClient::SmtpClient(QString host, int port, ConnectionType ct) : + authMethod(AuthPlain), + connectionTimeout(5000), + responseTimeout(5000) +{ + if (ct == TcpConnection) + this->useSsl = false; + else if (ct == SslConnection) + this->useSsl = true; + + if (useSsl == false) + socket = new QTcpSocket(this); + else + socket = new QSslSocket(this); + + this->host = host; + this->port = port; + + connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(socketStateChanged(QAbstractSocket::SocketState))); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(socketError(QAbstractSocket::SocketError))); + connect(socket, SIGNAL(readyRead()), + this, SLOT(socketReadyRead())); +} + +SmtpClient::~SmtpClient() {} + +/* [1] --- */ + + +/* [2] Getters and Setters */ + +void SmtpClient::setUser(const QString &user) +{ + this->user = user; +} + +void SmtpClient::setPassword(const QString &password) +{ + this->password = password; +} + +void SmtpClient::setAuthMethod(AuthMethod method) +{ + this->authMethod = method; +} + +void SmtpClient::setHost(QString &host) +{ + this->host = host; +} + +void SmtpClient::setPort(int port) +{ + this->port = port; +} + +void SmtpClient::setConnectionType(ConnectionType ct) +{ + if (ct == TcpConnection) + this->useSsl = false; + else if (ct == SslConnection) + this->useSsl = true; + + if (useSsl == false) + socket = new QTcpSocket(this); + else + socket = new QSslSocket(this); +} + +const QString& SmtpClient::getHost() const +{ + return this->host; +} + +const QString& SmtpClient::getUser() const +{ + return this->user; +} + +const QString& SmtpClient::getPassword() const +{ + return this->password; +} + +SmtpClient::AuthMethod SmtpClient::getAuthMethod() const +{ + return this->authMethod; +} + +int SmtpClient::getPort() const +{ + return this->port; +} + +SmtpClient::ConnectionType SmtpClient::getConnectionType() const +{ + if (useSsl) + return SslConnection; + else + return TcpConnection; +} + +/* [2] --- */ + + +/* [3] Public methods */ + +bool SmtpClient::connectToHost() +{ + if (useSsl) + ((QSslSocket*) socket)->connectToHostEncrypted(host, port); + else + socket->connectToHost(host, port); + + // Tries to connect to server + if (!socket->waitForConnected(connectionTimeout)) + { + emit smtpError(ConnectionTimeoutError); + return false; + } + + try + { + // Wait for the server's response + waitForResponse(); + + // If the response code is not 220 (Service ready) + // means that is something wrong with the server + if (responseCode != 220) + { + emit smtpError(ServerError); + return false; + } + + // Send a EHLO/HELO message to the server + // The client's first command must be EHLO/HELO + sendMessage("EHLO SmtpClient for Qt/C++"); + + // Wait for the server's response + waitForResponse(); + + // The response code needs to be 250. + if (responseCode != 250) + { + emit smtpError(ServerError); + return false; + } + } + catch (ResponseTimeoutException) + { + return false; + } + + // If no errors occured the function returns true. + return true; +} + +bool SmtpClient::login() +{ + return login(user, password, authMethod); +} + +bool SmtpClient::login(const QString &user, const QString &password, AuthMethod method) +{ + try { + if (method == AuthPlain) + { + // Sending command: AUTH PLAIN base64('\0' + username + '\0' + password) + sendMessage("AUTH PLAIN " + QByteArray().append((char) 0).append(user).append((char) 0).append(password).toBase64()); + + // Wait for the server's response + waitForResponse(); + + // If the response is not 235 then the authification was faild + if (responseCode != 235) + { + emit smtpError(AuthentificationFailedError); + return false; + } + } + else if (method == AuthLogin) + { + // Sending command: AUTH LOGIN + sendMessage("AUTH LOGIN"); + + // Wait for 334 response code + waitForResponse(); + if (responseCode != 334) { emit smtpError(AuthentificationFailedError); return false; } + + // Send the username in base64 + sendMessage(QByteArray().append(user).toBase64()); + + // Wait for 334 + waitForResponse(); + if (responseCode != 334) { emit smtpError(AuthentificationFailedError); return false; } + + // Send the password in base64 + sendMessage(QByteArray().append(password).toBase64()); + + // Wait for the server's responce + waitForResponse(); + + // If the response is not 235 then the authification was faild + if (responseCode != 235) + { + emit smtpError(AuthentificationFailedError); + return false; + } + } + } + catch (ResponseTimeoutException e) + { + // Responce Timeout exceeded + emit smtpError(AuthentificationFailedError); + return false; + } + + return true; +} + +bool SmtpClient::sendMail(MimeMessage& email) +{ + try + { + // Send the MAIL command with the sender + sendMessage("MAIL FROM: <" + email.getSender().getAddress() + ">"); + + waitForResponse(); + + if (responseCode != 250) return false; + + // Send RCPT command for each recipient + for (int i = 0; i < email.getRecipients().size(); ++i) + { + sendMessage("RCPT TO: <" + email.getRecipients().at(i)->getAddress() + ">"); + waitForResponse(); + + if (responseCode != 250) return false; + } + + // Send DATA command + sendMessage("DATA"); + waitForResponse(); + + if (responseCode != 354) return false; + + sendMessage(email.toString()); + + // Send \n.\n to end the mail data + sendMessage("."); + + waitForResponse(); + + if (responseCode != 250) return false; + } + catch (ResponseTimeoutException) + { + return false; + } + + return true; +} + +void SmtpClient::quit() +{ + sendMessage("QUIT"); +} + +/* [3] --- */ + + +/* [4] Protected methods */ + +void SmtpClient::waitForResponse() throw (ResponseTimeoutException) +{ + if (!socket->waitForReadyRead(responseTimeout)) + { + emit smtpError(ResponseTimeoutError); + throw ResponseTimeoutException(); + } + + // Save the server's response + responseText = socket->readAll(); + + // Extract the respose code from the server's responce (first 3 digits) + responseCode = responseText.left(3).toInt(); + + if (responseCode / 100 == 4) + emit smtpError(ServerError); + + if (responseCode / 100 == 5) + emit smtpError(ClientError); +} + +void SmtpClient::sendMessage(const QString &text) +{ + socket->write(text.toUtf8() + "\r\n"); +} + +/* [4] --- */ + + +/* [5] Slots for the socket's signals */ + +void SmtpClient::socketStateChanged(QAbstractSocket::SocketState state) +{ +} + +void SmtpClient::socketError(QAbstractSocket::SocketError socketError) +{ +} + +void SmtpClient::socketReadyRead() +{ +} + +/* [5] --- */ + + + + diff --git a/smtpclient.h b/smtpclient.h new file mode 100644 index 0000000..6bfd29c --- /dev/null +++ b/smtpclient.h @@ -0,0 +1,140 @@ +#ifndef SMTPCLIENT_H +#define SMTPCLIENT_H + +#include +#include + +#include "mimemessage.h" + + +class SmtpClient : public QObject +{ + Q_OBJECT +public: + + /* [0] Enumerations */ + + enum AuthMethod + { + AuthPlain, + AuthLogin + }; + + enum SmtpError + { + ConnectionTimeoutError, + ResponseTimeoutError, + AuthentificationFailedError, + ServerError, // 4xx smtp error + ClientError // 5xx smtp error + }; + + enum ConnectionType + { + TcpConnection, + SslConnection + }; + + /* [0] --- */ + + + /* [1] Constructors and Destructors */ + + SmtpClient(QString host = "locahost", int port = 25, ConnectionType ct = TcpConnection); + + ~SmtpClient(); + + /* [1] --- */ + + + /* [2] Getters and Setters */ + + const QString& getHost() const; + void setHost(QString &host); + + int getPort() const; + void setPort(int port); + + ConnectionType getConnectionType() const; + void setConnectionType(ConnectionType ct); + + const QString & getUser() const; + void setUser(const QString &host); + + const QString & getPassword() const; + void setPassword(const QString &password); + + SmtpClient::AuthMethod getAuthMethod() const; + void setAuthMethod(AuthMethod method); + + /* [2] --- */ + + + /* [3] Public methods */ + + bool connectToHost(); + + bool login(); + bool login(const QString &user, const QString &password, AuthMethod method = AuthLogin); + + bool sendMail(MimeMessage& email); + + void quit(); + + /* [3] --- */ + +protected: + + /* [4] Protected members */ + + QTcpSocket *socket; + + QString host; + int port; + bool useSsl; + + QString user; + QString password; + AuthMethod authMethod; + + int connectionTimeout; + int responseTimeout; + + QString responseText; + int responseCode; + + class ResponseTimeoutException {}; + + /* [4] --- */ + + + /* [5] Protected methods */ + + void waitForResponse() throw (ResponseTimeoutException); + + void sendMessage(const QString &text); + + /* [5] --- */ + +protected slots: + + /* [6] Protected slots */ + + void socketStateChanged(QAbstractSocket::SocketState state); + void socketError(QAbstractSocket::SocketError error); + void socketReadyRead(); + + /* [6] --- */ + + +signals: + + /* [7] Signals */ + + void smtpError(SmtpError e); + + /* [7] --- */ + +}; + +#endif // SMTPCLIENT_H