diff options
author | Adam <Adam@drink-coca-cola.info> | 2010-05-09 19:02:50 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2010-06-18 21:01:09 -0400 |
commit | 4e1286ca109d079f32d32f07c344a1ab93899032 (patch) | |
tree | ef55488a4cc068f8954a8862ab2e67f2d1872281 /src/mail.cpp | |
parent | 4149afd45d2c0b9f464d1b4434f7bdaa61873d44 (diff) |
Rewrote the mail system to use threading
Diffstat (limited to 'src/mail.cpp')
-rw-r--r-- | src/mail.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/mail.cpp b/src/mail.cpp new file mode 100644 index 000000000..9e1c60c6b --- /dev/null +++ b/src/mail.cpp @@ -0,0 +1,151 @@ +#include "services.h" +#include "language.h" + +MailThread::~MailThread() +{ + if (Success) + Alog() << "Successfully delivered mail for " << MailTo << " (" << Addr << ")"; + else + Alog() << "Error delivering mail for " << MailTo << " (" << Addr << ")"; +} + +void MailThread::Run() +{ + FILE *pipe = popen(Config.SendMailPath, "w"); + + if (!pipe) + { + return; + } + + fprintf(pipe, "From: %s\n", Config.SendFrom); + if (Config.DontQuoteAddresses) + fprintf(pipe, "To: %s <%s>\n", MailTo.c_str(), Addr.c_str()); + else + fprintf(pipe, "To: \"%s\" <%s>\n", MailTo.c_str(), Addr.c_str()); + fprintf(pipe, "Subject: %s\n", Subject.c_str()); + fprintf(pipe, "%s", Message.c_str()); + fprintf(pipe, "\n.\n"); + + pclose(pipe); + + Success = true; +} + +bool Mail(User *u, NickRequest *nr, const std::string &service, const std::string &subject, const std::string &message) +{ + if (!u || !nr || subject.empty() || service.empty() || message.empty()) + return false; + + time_t t = time(NULL); + + if (!Config.UseMail) + notice_lang(service.c_str(), u, MAIL_DISABLED); + else if (t - u->lastmail < Config.MailDelay) + notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail); + else if (!nr->email) + notice_lang(service.c_str(), u, MAIL_INVALID, nr->nick); + else + { + u->lastmail = nr->lastmail = t; + threadEngine.Start(new MailThread(nr->nick, nr->email, subject, message)); + return true; + } + + return false; +} + +bool Mail(User *u, NickCore *nc, const std::string &service, const std::string &subject, const std::string &message) +{ + if (!u || !nc || subject.empty() || service.empty() || message.empty()) + return false; + + time_t t = time(NULL); + + if (!Config.UseMail) + notice_lang(service.c_str(), u, MAIL_DISABLED); + else if (t - u->lastmail < Config.MailDelay) + notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail); + else if (!nc->email) + notice_lang(service.c_str(), u, MAIL_INVALID, nc->display); + else + { + u->lastmail = nc->lastmail = t; + threadEngine.Start(new MailThread(nc->display, nc->email, subject, message)); + return true; + } + + return false; +} + +bool Mail(NickCore *nc, const std::string &subject, const std::string &message) +{ + if (!Config.UseMail || !nc || !nc->email || subject.empty() || message.empty()) + return false; + + nc->lastmail = time(NULL); + threadEngine.Start(new MailThread(nc->display, nc->email, subject, message)); + + return true; +} + +/** + * Checks whether we have a valid, common e-mail address. + * This is NOT entirely RFC compliant, and won't be so, because I said + * *common* cases. ;) It is very unlikely that e-mail addresses that + * are really being used will fail the check. + * + * @param email Email to Validate + * @return bool + */ +bool MailValidate(const std::string &email) +{ + bool has_period = false; + char copy[BUFSIZE]; + + static char specials[] = { + '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' ' + }; + + if (email.empty()) + return false; + strlcpy(copy, email.c_str(), sizeof(copy)); + + char *domain = strchr(copy, '@'); + if (!domain) + return false; + *domain++ = '\0'; + + /* Don't accept NULL copy or domain. */ + if (!*copy || !*domain) + return false; + + /* Check for forbidden characters in the name */ + for (unsigned int i = 0; i < strlen(copy); i++) + { + if (copy[i] <= 31 || copy[i] >= 127) + return false; + for (unsigned int j = 0; j < 13; j++) + if (copy[i] == specials[j]) + return false; + } + + /* Check for forbidden characters in the domain */ + for (unsigned int i = 0; i < strlen(domain); i++) + { + if (domain[i] <= 31 || domain[i] >= 127) + return false; + for (unsigned int j = 0; j < 13; j++) + if (domain[i] == specials[j]) + return false; + if (domain[i] == '.') + { + if (i == 0 || i == strlen(domain) - 1) + return false; + has_period = true; + } + } + + return has_period; +} + |