Anope IRC Services  Version 1.8
mail.c
Go to the documentation of this file.
1 /* Mail utility routines.
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 
14 #include "services.h"
15 #include "language.h"
16 
17 /*************************************************************************/
18 
29 MailInfo *MailRegBegin(User * u, NickRequest * nr, char *subject,
30  char *service)
31 {
32  int timeToWait = 0;
33  if (!u || !nr || !subject || !service) {
34  return NULL;
35  }
36 
37  if (!UseMail) {
38  notice_lang(service, u, MAIL_DISABLED);
39  } else if ((time(NULL) - u->lastmail < MailDelay)) {
40  timeToWait = MailDelay - (time(NULL) - u->lastmail);
41  notice_lang(service, u, MAIL_DELAYED, timeToWait);
42  } else if (!nr->email) {
43  notice_lang(service, u, MAIL_INVALID, nr->nick);
44  } else {
45  MailInfo *mail;
46  int pipefds[2];
47 
48  mail = scalloc(sizeof(MailInfo), 1);
49  mail->sender = u;
50  mail->recipient = NULL;
51  mail->recip = nr;
52  mail->pipe = mail->writepipe = mail->readpipe = NULL;
53 
54 #if HAVE_FORK
55  if (ForkForMail && !pipe(pipefds))
56  {
57  mail->writepipe = fdopen(pipefds[1], "w");
58  mail->readpipe = fdopen(pipefds[0], "r");
59  mail->pipe = mail->writepipe;
60  }
61 #endif
62  if (!mail->pipe && !(mail->pipe = popen(SendMailPath, "w"))) {
63  free(mail);
64  notice_lang(service, u, MAIL_LATER);
65  return NULL;
66  }
67 
68  fprintf(mail->pipe, "From: %s\n", SendFrom);
69  if (DontQuoteAddresses) {
70  fprintf(mail->pipe, "To: %s <%s>\n", nr->nick, nr->email);
71  } else {
72  fprintf(mail->pipe, "To: \"%s\" <%s>\n", nr->nick, nr->email);
73  }
74  fprintf(mail->pipe, "Subject: %s\n", subject);
75  return mail;
76  }
77 
78  return NULL;
79 }
80 
81 /*************************************************************************/
82 
93 MailInfo *MailBegin(User * u, NickCore * nc, char *subject, char *service)
94 {
95  if (!u || !nc || !subject || !service) {
96  return NULL;
97  }
98 
99  if (!UseMail) {
100  notice_lang(service, u, MAIL_DISABLED);
101  } else if (((time(NULL) - u->lastmail < MailDelay)
102  || (time(NULL) - nc->lastmail < MailDelay))
103  && !is_services_root(u)) {
104  notice_lang(service, u, MAIL_DELAYED, MailDelay);
105  } else if (!nc->email) {
106  notice_lang(service, u, MAIL_INVALID, nc->display);
107  } else {
108  MailInfo *mail;
109  int pipefds[2];
110 
111  mail = scalloc(sizeof(MailInfo), 1);
112  mail->sender = u;
113  mail->recipient = nc;
114  mail->recip = NULL;
115  mail->pipe = mail->writepipe = mail->readpipe = NULL;
116 
117 #if HAVE_FORK
118  if (ForkForMail && !pipe(pipefds))
119  {
120  mail->writepipe = fdopen(pipefds[1], "w");
121  mail->readpipe = fdopen(pipefds[0], "r");
122  mail->pipe = mail->writepipe;
123  }
124 #endif
125  if (!mail->pipe && !(mail->pipe = popen(SendMailPath, "w"))) {
126  free(mail);
127  notice_lang(service, u, MAIL_LATER);
128  return NULL;
129  }
130 
131  fprintf(mail->pipe, "From: %s\n", SendFrom);
132  if (DontQuoteAddresses) {
133  fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email);
134  } else {
135  fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display,
136  nc->email);
137  }
138  fprintf(mail->pipe, "Subject: %s\n", subject);
139 
140  return mail;
141  }
142 
143  return NULL;
144 }
145 
146 /*************************************************************************/
147 
154 {
155 
156  if (!nc)
157  return NULL;
158 
159  if (!UseMail || !nc->email) {
160  return NULL;
161 
162  } else {
163  MailInfo *mail;
164  int pipefds[2];
165 
166  mail = scalloc(sizeof(MailInfo), 1);
167  mail->sender = NULL;
168  mail->recipient = nc;
169  mail->recip = NULL;
170  mail->pipe = mail->writepipe = mail->readpipe = NULL;
171 
172 #if HAVE_FORK
173  if (ForkForMail && !pipe(pipefds))
174  {
175  mail->writepipe = fdopen(pipefds[1], "w");
176  mail->readpipe = fdopen(pipefds[0], "r");
177  mail->pipe = mail->writepipe;
178  }
179 #endif
180  if (!mail->pipe && !(mail->pipe = popen(SendMailPath, "w"))) {
181  free(mail);
182  return NULL;
183  }
184 
185  fprintf(mail->pipe, "From: %s\n", SendFrom);
186  if (DontQuoteAddresses) {
187  fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email);
188  } else {
189  fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display,
190  nc->email);
191  }
192  fprintf(mail->pipe, "Subject: %s\n",
193  getstring2(NULL, MEMO_MAIL_SUBJECT));
194  return mail;
195  }
196  return NULL;
197 }
198 
199 /*************************************************************************/
200 
207 {
208  int pid = -1;
209  /* - param checking modified because we don't
210  have an user sending this mail.
211  Certus, 02.04.2004 */
212 
213  if (!mail || !mail->pipe) { /* removed sender check */
214  return;
215  }
216 
217  if (!mail->recipient && !mail->recip) {
218  return;
219  }
220 
221 #if HAVE_FORK
222  if (ForkForMail && mail->writepipe && mail->readpipe && !(pid = fork()))
223  {
224  FILE *fd;
225  int ret;
226 
227  fputc(255, mail->writepipe);
228  fclose(mail->writepipe);
229 
230  fd = popen(SendMailPath, "w");
231 
232  if (fd)
233  {
234  while ((ret = fgetc(mail->readpipe)) != 255)
235  fputc(ret, fd);
236  pclose(fd);
237  }
238 
239  fclose(mail->readpipe);
240  _exit(EXIT_SUCCESS);
241  }
242  else
243 #endif
244  {
245  if (mail->pipe != mail->writepipe)
246  pclose(mail->pipe);
247  else
248  {
249  if (mail->writepipe)
250  fclose(mail->writepipe);
251  if (mail->readpipe)
252  fclose(mail->readpipe);
253  }
254  }
255 
256  if (mail->sender) /* added sender check */
257  mail->sender->lastmail = time(NULL);
258 
259  if (mail->recipient)
260  mail->recipient->lastmail = time(NULL);
261  else
262  mail->recip->lastmail = time(NULL);
263 
264 
265  free(mail);
266 }
267 
268 /*************************************************************************/
269 
276 void MailReset(User * u, NickCore * nc)
277 {
278  if (u)
279  u->lastmail = 0;
280  if (nc)
281  nc->lastmail = 0;
282 }
283 
284 /*************************************************************************/
285 
296 int MailValidate(const char *email)
297 {
298  int i, j, has_period = 0, len;
299  char copy[BUFSIZE], *domain;
300 
301  static char specials[] =
302  { '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']',
303  ' '
304  };
305 
306  if (!email)
307  return 0;
308  strscpy(copy, email, sizeof(copy));
309 
310  domain = strchr(copy, '@');
311  if (!domain)
312  return 0;
313  *domain = '\0';
314  domain++;
315 
316  /* Don't accept NULL copy or domain. */
317  if (*copy == 0 || *domain == 0)
318  return 0;
319 
320  /* Check for forbidden characters in the name */
321  for (i = 0; i < strlen(copy); i++) {
322 
323  if (copy[i] <= 31 || copy[i] >= 127)
324  return 0;
325  for (j = 0; j < 13; j++)
326  if (copy[i] == specials[j])
327  return 0;
328  }
329 
330  /* Check for forbidden characters in the domain, and if it seems to be valid. */
331  for (i = 0; i < (len = strlen(domain)); i++) {
332  if (domain[i] <= 31 || domain[i] >= 127)
333  return 0;
334  for (j = 0; j < 13; j++)
335  if (domain[i] == specials[j])
336  return 0;
337  if (domain[i] == '.') {
338  if (i == 0 || i == len - 1)
339  return 0;
340  has_period = 1;
341  }
342  }
343 
344  if (!has_period)
345  return 0;
346 
347  return 1;
348 }
char * email
Definition: services.h:519
E char * SendFrom
Definition: extern.h:371
void MailEnd(MailInfo *mail)
Definition: mail.c:206
E int DontQuoteAddresses
Definition: extern.h:374
E int MailDelay
Definition: extern.h:373
E int UseMail
Definition: extern.h:369
#define getstring2(nc, index)
Definition: extern.h:733
FILE * readpipe
Definition: services.h:1071
E char * strscpy(char *d, const char *s, size_t len)
Definition: db-merger.c:1886
E void notice_lang(char *source, User *dest, int message,...)
Definition: send.c:169
NickRequest * recip
Definition: services.h:1074
E void * scalloc(long elsize, long els)
Definition: memory.c:55
E char * SendMailPath
Definition: extern.h:370
char * display
Definition: services.h:542
E int is_services_root(User *u)
Definition: operserv.c:577
struct smtp_message mail
Definition: smtp.h:125
MailInfo * MailBegin(User *u, NickCore *nc, char *subject, char *service)
Definition: mail.c:93
FILE * pipe
Definition: services.h:1068
time_t lastmail
Definition: services.h:558
time_t lastmail
Definition: services.h:914
User * sender
Definition: services.h:1072
E int ForkForMail
Definition: extern.h:375
int MailValidate(const char *email)
Definition: mail.c:296
MailInfo * MailRegBegin(User *u, NickRequest *nr, char *subject, char *service)
Definition: mail.c:29
time_t lastmail
Definition: services.h:521
void MailReset(User *u, NickCore *nc)
Definition: mail.c:276
MailInfo * MailMemoBegin(NickCore *nc)
Definition: mail.c:153
FILE * writepipe
Definition: services.h:1070
char * nick
Definition: services.h:516
NickCore * recipient
Definition: services.h:1073
#define BUFSIZE
Definition: config.h:47
char * email
Definition: services.h:544