00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "services.h"
00014 #include "mail.h"
00015 #include "config.h"
00016
00017 Mail::Message::Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &a, const Anope::string &s, const Anope::string &m) : Thread(), sendmail_path(Config->SendMailPath), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->DontQuoteAddresses), success(false)
00018 {
00019 }
00020
00021 Mail::Message::~Message()
00022 {
00023 if (success)
00024 Log(LOG_NORMAL, "mail") << "Successfully delivered mail for " << mail_to << " (" << addr << ")";
00025 else
00026 Log(LOG_NORMAL, "mail") << "Error delivering mail for " << mail_to << " (" << addr << ")";
00027 }
00028
00029 void Mail::Message::Run()
00030 {
00031 FILE *pipe = popen(sendmail_path.c_str(), "w");
00032
00033 if (!pipe)
00034 {
00035 SetExitState();
00036 return;
00037 }
00038
00039 fprintf(pipe, "From: %s\n", send_from.c_str());
00040 if (this->dont_quote_addresses)
00041 fprintf(pipe, "To: %s <%s>\n", mail_to.c_str(), addr.c_str());
00042 else
00043 fprintf(pipe, "To: \"%s\" <%s>\n", mail_to.c_str(), addr.c_str());
00044 fprintf(pipe, "Subject: %s\n", subject.c_str());
00045 fprintf(pipe, "%s", message.c_str());
00046 fprintf(pipe, "\n.\n");
00047
00048 pclose(pipe);
00049
00050 success = true;
00051 SetExitState();
00052 }
00053
00054 bool Mail::Send(User *u, NickCore *nc, const BotInfo *service, const Anope::string &subject, const Anope::string &message)
00055 {
00056 if (!nc || !service || subject.empty() || message.empty())
00057 return false;
00058
00059 if (!u)
00060 {
00061 if (!Config->UseMail)
00062 return false;
00063 else if (nc->email.empty())
00064 return false;
00065
00066 nc->lastmail = Anope::CurTime;
00067 Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
00068 t->Start();
00069 return true;
00070 }
00071 else
00072 {
00073 if (!Config->UseMail)
00074 u->SendMessage(service, _("Services have been configured to not send mail."));
00075 else if (Anope::CurTime - u->lastmail < Config->MailDelay)
00076 u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), Config->MailDelay - (Anope::CurTime - u->lastmail));
00077 else if (nc->email.empty())
00078 u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->display.c_str());
00079 else
00080 {
00081 u->lastmail = nc->lastmail = Anope::CurTime;
00082 Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
00083 t->Start();
00084 return true;
00085 }
00086
00087 return false;
00088 }
00089 }
00090
00091 bool Mail::Send(NickCore *nc, const Anope::string &subject, const Anope::string &message)
00092 {
00093 if (!Config->UseMail || !nc || nc->email.empty() || subject.empty() || message.empty())
00094 return false;
00095
00096 nc->lastmail = Anope::CurTime;
00097 Thread *t = new Mail::Message(Config->SendFrom, nc->display, nc->email, subject, message);
00098 t->Start();
00099
00100 return true;
00101 }
00102
00112 bool Mail::Validate(const Anope::string &email)
00113 {
00114 bool has_period = false;
00115
00116 static char specials[] = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' '};
00117
00118 if (email.empty())
00119 return false;
00120 Anope::string copy = email;
00121
00122 size_t at = copy.find('@');
00123 if (at == Anope::string::npos)
00124 return false;
00125 Anope::string domain = copy.substr(at + 1);
00126 copy = copy.substr(0, at);
00127
00128
00129 if (copy.empty() || domain.empty())
00130 return false;
00131
00132
00133 for (unsigned i = 0, end = copy.length(); i < end; ++i)
00134 {
00135 if (copy[i] <= 31 || copy[i] >= 127)
00136 return false;
00137 for (unsigned int j = 0; j < 13; ++j)
00138 if (copy[i] == specials[j])
00139 return false;
00140 }
00141
00142
00143 for (unsigned i = 0, end = domain.length(); i < end; ++i)
00144 {
00145 if (domain[i] <= 31 || domain[i] >= 127)
00146 return false;
00147 for (unsigned int j = 0; j < 13; ++j)
00148 if (domain[i] == specials[j])
00149 return false;
00150 if (domain[i] == '.')
00151 {
00152 if (!i || i == end - 1)
00153 return false;
00154 has_period = true;
00155 }
00156 }
00157
00158 return has_period;
00159 }