commit 18786d2015ed381869f4d998ee36f3f4f914cfba Author: Your Name Date: Tue Aug 30 21:59:16 2011 +0300 upload project 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