Anope IRC Services  Version 2.0
mail.cpp
Go to the documentation of this file.
1 /*
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  *
11  */
12 
13 #include "services.h"
14 #include "mail.h"
15 #include "config.h"
16 
17 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->GetBlock("mail")->Get<const Anope::string>("sendmailpath")), send_from(sf), mail_to(mailto), addr(a), subject(s), message(m), dont_quote_addresses(Config->GetBlock("mail")->Get<bool>("dontquoteaddresses")), success(false)
18 {
19 }
20 
22 {
23  if (success)
24  Log(LOG_NORMAL, "mail") << "Successfully delivered mail for " << mail_to << " (" << addr << ")";
25  else
26  Log(LOG_NORMAL, "mail") << "Error delivering mail for " << mail_to << " (" << addr << ")";
27 }
28 
30 {
31  FILE *pipe = popen(sendmail_path.c_str(), "w");
32 
33  if (!pipe)
34  {
35  SetExitState();
36  return;
37  }
38 
39  fprintf(pipe, "From: %s\n", send_from.c_str());
40  if (this->dont_quote_addresses)
41  fprintf(pipe, "To: %s <%s>\n", mail_to.c_str(), addr.c_str());
42  else
43  fprintf(pipe, "To: \"%s\" <%s>\n", mail_to.c_str(), addr.c_str());
44  fprintf(pipe, "Subject: %s\n", subject.c_str());
45  fprintf(pipe, "%s", message.c_str());
46  fprintf(pipe, "\n.\n");
47 
48  pclose(pipe);
49 
50  success = true;
51  SetExitState();
52 }
53 
54 bool Mail::Send(User *u, NickCore *nc, BotInfo *service, const Anope::string &subject, const Anope::string &message)
55 {
56  if (!nc || !service || subject.empty() || message.empty())
57  return false;
58 
59  Configuration::Block *b = Config->GetBlock("mail");
60 
61  if (!u)
62  {
63  if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty())
64  return false;
65  else if (nc->email.empty())
66  return false;
67 
69  Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
70  t->Start();
71  return true;
72  }
73  else
74  {
75  if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty())
76  u->SendMessage(service, _("Services have been configured to not send mail."));
77  else if (Anope::CurTime - u->lastmail < b->Get<time_t>("delay"))
78  u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), b->Get<time_t>("delay") - (Anope::CurTime - u->lastmail));
79  else if (nc->email.empty())
80  u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nc->display.c_str());
81  else
82  {
83  u->lastmail = nc->lastmail = Anope::CurTime;
84  Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
85  t->Start();
86  return true;
87  }
88 
89  return false;
90  }
91 }
92 
93 bool Mail::Send(NickCore *nc, const Anope::string &subject, const Anope::string &message)
94 {
95  Configuration::Block *b = Config->GetBlock("mail");
96  if (!b->Get<bool>("usemail") || b->Get<const Anope::string>("sendfrom").empty() || !nc || nc->email.empty() || subject.empty() || message.empty())
97  return false;
98 
100  Thread *t = new Mail::Message(b->Get<const Anope::string>("sendfrom"), nc->display, nc->email, subject, message);
101  t->Start();
102 
103  return true;
104 }
105 
115 bool Mail::Validate(const Anope::string &email)
116 {
117  bool has_period = false;
118 
119  static char specials[] = {'(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' '};
120 
121  if (email.empty())
122  return false;
123  Anope::string copy = email;
124 
125  size_t at = copy.find('@');
126  if (at == Anope::string::npos)
127  return false;
128  Anope::string domain = copy.substr(at + 1);
129  copy = copy.substr(0, at);
130 
131  /* Don't accept empty copy or domain. */
132  if (copy.empty() || domain.empty())
133  return false;
134 
135  /* Check for forbidden characters in the name */
136  for (unsigned i = 0, end = copy.length(); i < end; ++i)
137  {
138  if (copy[i] <= 31 || copy[i] >= 127)
139  return false;
140  for (unsigned int j = 0; j < 13; ++j)
141  if (copy[i] == specials[j])
142  return false;
143  }
144 
145  /* Check for forbidden characters in the domain */
146  for (unsigned i = 0, end = domain.length(); i < end; ++i)
147  {
148  if (domain[i] <= 31 || domain[i] >= 127)
149  return false;
150  for (unsigned int j = 0; j < 13; ++j)
151  if (domain[i] == specials[j])
152  return false;
153  if (domain[i] == '.')
154  {
155  if (!i || i == end - 1)
156  return false;
157  has_period = true;
158  }
159  }
160 
161  return has_period;
162 }
Definition: bots.h:24
time_t lastmail
Definition: users.h:94
Definition: users.h:34
void Start()
CoreExport time_t CurTime
Definition: main.cpp:41
Message(const Anope::string &sf, const Anope::string &mailto, const Anope::string &addr, const Anope::string &subject, const Anope::string &message)
Definition: mail.cpp:17
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
size_type length() const
Definition: anope.h:131
Definition: Config.cs:26
CoreExport bool Validate(const Anope::string &email)
Definition: mail.cpp:115
static const size_type npos
Definition: anope.h:44
Anope::string display
Definition: account.h:113
CoreExport bool Send(User *from, NickCore *to, BotInfo *service, const Anope::string &subject, const Anope::string &message)
Definition: mail.cpp:54
bool empty() const
Definition: anope.h:126
std::basic_string< char, ci_char_traits, std::allocator< char > > string
Definition: hashcomp.h:133
int pipe(int fds[2])
Definition: pipe.cpp:11
time_t lastmail
Definition: account.h:138
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
T Get(const Anope::string &tag)
Definition: config.h:44
void Run() anope_override
Definition: mail.cpp:29
Anope::string email
Definition: account.h:116
void SendMessage(BotInfo *source, const char *fmt,...)
Definition: users.cpp:320
size_type find(const string &_str, size_type pos=0) const
Definition: anope.h:192
#define _(x)
Definition: services.h:50
Definition: anope.h:20