mailer.h | mailer.h | |||
---|---|---|---|---|
skipping to change at line 33 | skipping to change at line 33 | |||
#include <string> | #include <string> | |||
#include <vector> | #include <vector> | |||
#include "compat.h" | #include "compat.h" | |||
namespace jwsmtp { | namespace jwsmtp { | |||
class mailer | class mailer | |||
{ | { | |||
public: | public: | |||
// if MXLookup is true: | // if MXLookup is true: | |||
// 'server' is a nameserver to lookup an MX record by. | // 'server' is a nameserver to lookup an MX record by. | |||
// if MXLookup is false. | // if MXLookup is false. | |||
// 'server' is an SMTP server which will be attempted directly fo | // 'server' is an SMTP server which will be attempted directly for ma | |||
r mailing | iling | |||
// if an IP address is not found, either MX record or direct to SMTP | // if an IP address is not found, either MX record or direct to SMTP ser | |||
server, | ver, | |||
// an attempt will be made to send mail directly to the server in th | // an attempt will be made to send mail directly to the server in the ma | |||
e mail address. | il address. | |||
// e.g. mail to fred@somewhere.com will have a connection attempt ma | // e.g. mail to fred@somewhere.com will have a connection attempt made d | |||
de directly to: | irectly to: | |||
// somewhere.com (which is probably wrong and therefore will s | // somewhere.com (which is probably wrong and therefore will still | |||
till fail) | fail) | |||
mailer(const char* TOaddress, const char* FROMaddress, | mailer(const char* TOaddress, const char* FROMaddress, | |||
const char* Subject, const std::vector<char>& Message, | const char* Subject, const std::vector<char>& Message, | |||
const char* server = "127.0.0.1"/*default to localhost*/, | const char* server = "127.0.0.1"/*default to localhost*/, | |||
unsigned short Port = SMTP_PORT, // default SMTP port | unsigned short Port = SMTP_PORT, // default SMTP port | |||
bool MXLookup = true); | bool MXLookup = true); | |||
mailer(const char* TOaddress, const char* FROMaddress, | mailer(const char* TOaddress, const char* FROMaddress, | |||
const char* Subject, const char* Message, | const char* Subject, const char* Message, | |||
const char* server = "127.0.0.1"/*default to localhost*/, | const char* server = "127.0.0.1"/*default to localhost*/, | |||
unsigned short Port = SMTP_PORT, // default SMTP port | unsigned short Port = SMTP_PORT, // default SMTP port | |||
bool MXLookup = true); | bool MXLookup = true); | |||
// defaults to SMTP_PORT & no MX lookup. | // defaults to SMTP_PORT & no MX lookup. | |||
// now we can do: | // now we can do: | |||
// mailer m; // mail an smtp server dir ect. | // mailer m; // mail an smtp server dir ect. | |||
// mailer m2(true); // use MX lookup. | // mailer m2(true); // use MX lookup. | |||
// mailer m2(false, weirdportnumber); // SMTP to a non standard port. | // mailer m2(false, weirdportnumber); // SMTP to a non standard port. | |||
mailer(bool MXLookup = false, unsigned short Port = SMTP_PORT); | mailer(bool MXLookup = false, unsigned short Port = SMTP_PORT); | |||
~mailer(); | ~mailer(); | |||
// call this operator to have the mail mailed. | // call this operator to have the mail mailed. | |||
// This is to facilitate using multiple threads | // This is to facilitate using multiple threads | |||
// i.e. using boost::thread. (see http://www.boost.org) | // i.e. using boost::thread. (see http://www.boost.org) | |||
// | // | |||
// e.g. | // e.g. | |||
// mailer mail(args...); | // mailer mail(args...); | |||
// boost::thread thrd(mail); // operator()() implicitly called. | // boost::thread thrd(mail); // operator()() implicitly called. | |||
// thrd.join(); // if needed. | // thrd.join(); // if needed. | |||
// | // | |||
// or: | // or: | |||
// mailer mail(args...); | // mailer mail(args...); | |||
// mail.operator()(); | // mail.operator()(); | |||
void operator()(); | void operator()(); | |||
void send(); | void send(); | |||
// attach a file to the mail. (MIME 1.0) | // attach a file to the mail. (MIME 1.0) | |||
// returns false if !filename.length() or | // returns false if !filename.length() or | |||
// the file could not be opened for reading...etc. | // the file could not be opened for reading...etc. | |||
bool attach(const std::string& filename); | bool attach(const std::string& filename); | |||
// remove an attachment from the list of attachments. | // remove an attachment from the list of attachments. | |||
// returns false if !filename.length() or | // returns false if !filename.length() or | |||
// the file is not attached or there are no attachments. | // the file is not attached or there are no attachments. | |||
bool removeattachment(const std::string& filename); | bool removeattachment(const std::string& filename); | |||
// Set a new message (replacing the old) | // Set a new message (replacing the old) | |||
// will return false and not change the message if newmessage is emp | // will return false and not change the message if newmessage is empty. | |||
ty. | bool setmessage(const std::string& newmessage); | |||
bool setmessage(const std::string& newmessage); | bool setmessage(const std::vector<char>& newmessage); | |||
bool setmessage(const std::vector<char>& newmessage); | ||||
// Set a new HTML message (replacing the old) | // Set a new HTML message (replacing the old) | |||
// will return false and not change the message if newmessage is emp | // will return false and not change the message if newmessage is empty. | |||
ty. | bool setmessageHTML(const std::string& newmessage); | |||
bool setmessageHTML(const std::string& newmessage); | bool setmessageHTML(const std::vector<char>& newmessage); | |||
bool setmessageHTML(const std::vector<char>& newmessage); | ||||
// use a file for the data | // use a file for the data | |||
bool setmessageHTMLfile(const std::string& filename); | bool setmessageHTMLfile(const std::string& filename); | |||
// Set a new Subject for the mail (replacing the old) | // Set a new Subject for the mail (replacing the old) | |||
// will return false if newSubject is empty. | // will return false if newSubject is empty. | |||
bool setsubject(const std::string& newSubject); | bool setsubject(const std::string& newSubject); | |||
// sets the nameserver or smtp server to connect to | // sets the nameserver or smtp server to connect to | |||
// dependant on the constructor call, i.e. whether | // dependant on the constructor call, i.e. whether | |||
// 'lookupMXRecord' was set to false or true. | // 'lookupMXRecord' was set to false or true. | |||
// (see constructor comment for details) | // (see constructor comment for details) | |||
bool setserver(const std::string& nameserver_or_smtpserver); | bool setserver(const std::string& nameserver_or_smtpserver); | |||
// sets the senders address (fromAddress variable) | // sets the senders address (fromAddress variable) | |||
bool setsender(const std::string& newsender); | bool setsender(const std::string& newsender); | |||
// add a recipient to the recipient list. (maximum allowed recipient | // add a recipient to the recipient list. (maximum allowed recipients 10 | |||
s 100). | 0). | |||
// returns true if the address could be added to the | // returns true if the address could be added to the | |||
// recipient list, otherwise false. | // recipient list, otherwise false. | |||
// recipient_type must be in the range mailer::TO -> mailer::BCC if | // recipient_type must be in the range mailer::TO -> mailer::BCC if | |||
// not recipient_type defaults to BCC (blind copy), see const enum b | // not recipient_type defaults to BCC (blind copy), see const enum below | |||
elow. | . | |||
bool addrecipient(const std::string& newrecipient, short recipient_t | bool addrecipient(const std::string& newrecipient, short recipient_type | |||
ype = TO /*CC, BCC*/); | = TO /*CC, BCC*/); | |||
// remove a recipient from the recipient list. | // remove a recipient from the recipient list. | |||
// returns true if the address could be removed from the | // returns true if the address could be removed from the | |||
// recipient list, otherwise false. | // recipient list, otherwise false. | |||
bool removerecipient(const std::string& recipient); | bool removerecipient(const std::string& recipient); | |||
// clear all recipients from the recipient list. | // clear all recipients from the recipient list. | |||
void clearrecipients(); | void clearrecipients(); | |||
// clear all attachments from the mail. | // clear all attachments from the mail. | |||
void clearattachments(); | void clearattachments(); | |||
// clear all recipients, message, attachments, errors. | // clear all recipients, message, attachments, errors. | |||
// does not reset the name/smtp server (use setserver for this) | // does not reset the name/smtp server (use setserver for this) | |||
// does not set the senders address (use setsender for this) | // does not set the senders address (use setsender for this) | |||
void reset(); | void reset(); | |||
// returns the return code sent by the smtp server or a local error. | // returns the return code sent by the smtp server or a local error. | |||
// this is the only way to find if there is an error in processing. | // this is the only way to find if there is an error in processing. | |||
// if the mail is sent correctly this string will begin with 250 | // if the mail is sent correctly this string will begin with 250 | |||
// see smtp RFC 821 section 4.2.2 for response codes. | // see smtp RFC 821 section 4.2.2 for response codes. | |||
const std::string& response() const; | const std::string& response() const; | |||
// Constants | // Constants | |||
// in unix we have to have a named object. | // in unix we have to have a named object. | |||
const static enum {TO, Cc, Bcc, SMTP_PORT = 25, DNS_PORT = 53} consts; | const static enum {TO, Cc, Bcc, SMTP_PORT = 25, DNS_PORT = 53} consts; | |||
// what type of authentication are we using. | // what type of authentication are we using. | |||
// (if using authentication that is). | // (if using authentication that is). | |||
enum authtype {LOGIN = 1, PLAIN} type; | enum authtype {LOGIN = 1, PLAIN} type; | |||
// set the authentication type | // set the authentication type | |||
// currently LOGIN or PLAIN only. | // currently LOGIN or PLAIN only. | |||
// The default login type is LOGIN, set in the constructor | // The default login type is LOGIN, set in the constructor | |||
void authtype(const enum authtype Type); | void authtype(const enum authtype Type); | |||
// set the username for authentication. | // set the username for authentication. | |||
// If this function is called with a non empty string | // If this function is called with a non empty string | |||
// jwSMTP will try to use authentication. | // jwSMTP will try to use authentication. | |||
// To not use authentication after this, call again | // To not use authentication after this, call again | |||
// with the empty string e.g. | // with the empty string e.g. | |||
// mailerobject.username(""); | // mailerobject.username(""); | |||
void username(const std::string& User); | void username(const std::string& User); | |||
// set the password for authentication | // set the password for authentication | |||
void password(const std::string& Pass); | void password(const std::string& Pass); | |||
private: | private: | |||
// create a header with current message and attachments. | // create a header with current message and attachments. | |||
std::string makesmtpmessage() const; | std::string makesmtpmessage() const; | |||
// make sure the message body has lines less than 1000 characters | // this breaks a message line up to be less than 1000 chars per line. | |||
// add line breaks if necessary. | // keeps words intact also --- rfc821 | |||
// rfc821 | // Check line returns are in the form "\r\n" | |||
void checklinesarelessthan1000chars(); | // (qmail balks otherwise, i.e. LAME server) | |||
// also if a period is on a line by itself add a period | ||||
// stops prematurely ending the mail before whole message is sent. | ||||
void checkRFCcompat(); | ||||
// helper function. | // helper function. | |||
// returns the part of the string toaddress after the @ symbol. | // returns the part of the string toaddress after the @ symbol. | |||
// i.e. the 'toaddress' is an email address eg. someone@somewhere.co | // i.e. the 'toaddress' is an email address eg. someone@somewhere.com | |||
m | // this function returns 'somewhere.com' | |||
// this function returns 'somewhere.com' | std::string getserveraddress(const std::string& toaddress) const; | |||
std::string getserveraddress(const std::string& toaddress) const; | ||||
// Does the work of getting MX records for the server returned by 'g | // Does the work of getting MX records for the server returned by 'getse | |||
etserveraddress' | rveraddress' | |||
// will use the dns server passed to this's constructor in 'nameserv | // will use the dns server passed to this's constructor in 'nameserver' | |||
er' | // or if MXlookup is false in the constuctor, will return an address | |||
// or if MXlookup is false in the constuctor, will return an address | // for the server that 'getserveraddress' returns. | |||
// for the server that 'getserveraddress' returns. | // returns false on failure, true on success | |||
// returns false on failure, true on success | bool gethostaddresses(std::vector<SOCKADDR_IN>& adds); | |||
bool gethostaddresses(std::vector<SOCKADDR_IN>& adds); | ||||
// Parses a dns Resource Record (see TCP/IP illustrated, STEVENS, pa | // Parses a dns Resource Record (see TCP/IP illustrated, STEVENS, page 1 | |||
ge 194) | 94) | |||
bool parseRR(int& pos, const unsigned char dns[], std::string& name, | bool parseRR(int& pos, const unsigned char dns[], std::string& name, in_ | |||
in_addr& address); | addr& address); | |||
// Parses a dns name returned in a dns query (see TCP/IP illustrated | // Parses a dns name returned in a dns query (see TCP/IP illustrated, ST | |||
, STEVENS, page 192) | EVENS, page 192) | |||
void parsename(int& pos, const unsigned char dns[], std::string& nam | void parsename(int& pos, const unsigned char dns[], std::string& name); | |||
e); | ||||
// email address wrapper struct | // email address wrapper struct | |||
struct Address { | struct Address { | |||
std::string name; // e.g. freddy foobar | std::string name; // e.g. freddy foobar | |||
std::string address; // e.g. someone@mail.com | std::string address; // e.g. someone@mail.com | |||
}; | }; | |||
// authenticate against a server. | // authenticate against a server. | |||
bool authenticate(const std::string& servergreeting, const SOCKET& s); | bool authenticate(const std::string& servergreeting, const SOCKET& s); | |||
// less typing later, these are definately abominations! | // less typing later, these are definately abominations! | |||
typedef std::vector<std::pair<std::vector<char>, std::string> >::con | typedef std::vector<std::pair<std::vector<char>, std::string> >::const_i | |||
st_iterator vec_pair_char_str_const_iter; | terator vec_pair_char_str_const_iter; | |||
typedef std::vector<std::pair<Address, short> >::const_iterator reci | typedef std::vector<std::pair<Address, short> >::const_iterator recipien | |||
pient_const_iter; | t_const_iter; | |||
typedef std::vector<std::pair<Address, short> >::iterator recipient_ | typedef std::vector<std::pair<Address, short> >::iterator recipient_iter | |||
iter; | ; | |||
typedef std::vector<std::string>::const_iterator vec_str_const_iter; | typedef std::vector<std::string>::const_iterator vec_str_const_iter; | |||
// split an address into its relevant parts i.e. | // split an address into its relevant parts i.e. | |||
// name and actual address and return it in Address. | // name and actual address and return it in Address. | |||
// this may be usefull out of the class maybe | // this may be usefull out of the class maybe | |||
// it should be a static function or a global? thinking about it. | // it should be a static function or a global? thinking about it. | |||
Address parseaddress(const std::string& addresstoparse); | Address parseaddress(const std::string& addresstoparse); | |||
// The addresses to send the mail to | // The addresses to send the mail to | |||
std::vector<std::pair<Address, short> > recipients; | std::vector<std::pair<Address, short> > recipients; | |||
// The address the mail is from. | // The address the mail is from. | |||
Address fromAddress; | Address fromAddress; | |||
// Subject of the mail | // Subject of the mail | |||
std::string subject; | std::string subject; | |||
// The contents of the mail message | // The contents of the mail message | |||
std::vector<char> message; | std::vector<char> message; | |||
// The contents of the mail message in html format. | // The contents of the mail message in html format. | |||
std::vector<char> messageHTML; | std::vector<char> messageHTML; | |||
// attachments: the file as a stream of char's and the name of the f | // attachments: the file as a stream of char's and the name of the file. | |||
ile. | std::vector<std::pair<std::vector<char>, std::string> > attachments; | |||
std::vector<std::pair<std::vector<char>, std::string> > attachments; | // This will be filled in from the toAddress by getserveraddress | |||
// This will be filled in from the toAddress by getserveraddress | std::string server; | |||
std::string server; | // Name of a nameserver to query | |||
// Name of a nameserver to query | std::string nameserver; | |||
std::string nameserver; | // The port to mail to on the smtp server. | |||
// The port to mail to on the smtp server. | const unsigned short port; | |||
const unsigned short port; | // use dns to query for MX records | |||
// use dns to query for MX records | const bool lookupMXRecord; | |||
const bool lookupMXRecord; | // using authentication | |||
// using authentication | bool auth; | |||
bool auth; | ||||
// username for authenticated smtp | // username for authenticated smtp | |||
std::string user; | std::string user; | |||
// password for authenticated smtp | // password for authenticated smtp | |||
std::string pass; | std::string pass; | |||
// filled in with server return strings | // filled in with server return strings | |||
std::string returnstring; | std::string returnstring; | |||
}; | }; | |||
} // end namespace jwsmtp | } // end namespace jwsmtp | |||
End of changes. 30 change blocks. | ||||
164 lines changed or deleted | 161 lines changed or added | |||